diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-03-20 15:17:54 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-20 08:17:54 +0100 |
| commit | c56ad76d18a9693908c70614e4a7d5f2f69e5d34 (patch) | |
| tree | ff64b86388ad5516b698049082eddb70d96f2f96 /src | |
| parent | b5dd04aa1216b67f0c8d05a968f209dfe9bdfef7 (diff) | |
| download | box64-c56ad76d18a9693908c70614e4a7d5f2f69e5d34.tar.gz box64-c56ad76d18a9693908c70614e4a7d5f2f69e5d34.zip | |
[RV64_DYNAREC] Added 80 /4 AND opcode (#594)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 9 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_logic.c | 29 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 17 |
3 files changed, 54 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index a0a0c9a5..4db2ce60 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -4,6 +4,7 @@ #include <pthread.h> #include <errno.h> #include <signal.h> +#include <assert.h> #include "debug.h" #include "box64context.h" @@ -299,6 +300,14 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0x80: nextop = F8; switch((nextop>>3)&7) { + case 4: // AND + INST_NAME("AND Eb, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEB(x1, 1); + u8 = F8; + emit_and8c(dyn, ninst, x1, u8, x2, x4); + EBBACK(x2); + break; case 7: // CMP INST_NAME("CMP Eb, Ib"); SETFLAGS(X_ALL, SF_SET_PENDING); diff --git a/src/dynarec/rv64/dynarec_rv64_emit_logic.c b/src/dynarec/rv64/dynarec_rv64_emit_logic.c index 6076a159..1baf214c 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_logic.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_logic.c @@ -200,6 +200,35 @@ void emit_or32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in } } +// emit AND8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch +void emit_and8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4) +{ + CLEAR_FLAGS(); + IFX(X_PEND) { + SET_DF(s3, d_and8); + } else IFX(X_ALL) { + SET_DFNONE(s3); + } + + ANDI(s1, s1, c&0xff); + + IFX(X_PEND) { + SD(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_SF) { + SRLI(s3, s1, 7); + BEQZ(s3, 8); + ORI(xFlags, xFlags, 1 << F_SF); + } + IFX(X_ZF) { + BNEZ(s1, 8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } +} + // emit AND32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch void emit_and32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4) { diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index f4a7a9a2..9532b9f2 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -190,6 +190,21 @@ if (gb2) SRLI(gd, gd, gb2*8); \ ANDI(gd, gd, 0xff); +// Write eb (ed) back to original register / memory, using s1 as scratch +#define EBBACK(s1) if(wb1) { \ + SB(ed, wback, fixedaddress); \ + SMWRITE(); \ + } else if(wb2) { \ + assert(wb2 == 8); \ + MOV64x(s1, 0xffffffffffff00ffLL); \ + AND(wback, wback, s1); \ + SLLI(s1, ed, 8); \ + OR(wback, wback, s1); \ + } else { \ + ANDI(wback, wback, ~0xff); \ + OR(wback, wback, ed); \ + } + // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1) // R0 will not be pushed/popd if ret is -2 #define CALL(F, ret) call_c(dyn, ninst, F, x6, ret, 1, 0) @@ -663,7 +678,7 @@ void emit_and32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i //void emit_xor8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); //void emit_xor8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); //void emit_and8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); -//void emit_and8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); +void emit_and8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); //void emit_add16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); //void emit_add16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); //void emit_sub16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); |