diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-03-23 23:43:33 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-23 16:43:33 +0100 |
| commit | 345a52b1538facefb5430922ca7503c2bc897b32 (patch) | |
| tree | af9ad4c300d8cdf9129088d514bfba93345d94e0 | |
| parent | 2accb00adc4a6d0c87737d7ca0c3b3fb9f661825 (diff) | |
| download | box64-345a52b1538facefb5430922ca7503c2bc897b32.tar.gz box64-345a52b1538facefb5430922ca7503c2bc897b32.zip | |
[RV64_DYNAREC] Added more opcodes (#628)
* [RV64_DYNAREC] Added D0 /7 SAR opcode * [RV64_DYNAREC] Added 22 AND opcode
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 25 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_logic.c | 32 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 |
3 files changed, 58 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index c53679b2..4a27a396 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -147,6 +147,15 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_and32(dyn, ninst, rex, ed, gd, x3, x4); WBACK; break; + case 0x22: + INST_NAME("AND Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB(x2, 0); + GETGB(x1); + emit_and8(dyn, ninst, x1, x2, x3, x4); + GBBACK(x5); + break; case 0x23: INST_NAME("AND Gd, Ed"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -1073,6 +1082,22 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni UFLAG_RES(ed); UFLAG_DF(x3, d_shr8); break; + case 7: + if(opcode==0xD0) { + INST_NAME("SAR Eb, 1"); + MOV32w(x2, 1); + } else { + INST_NAME("SAR Eb, CL"); + ANDI(x2, xRCX, 0x1f); + } + SETFLAGS(X_ALL, SF_PENDING); + GETSEB(x1, 0); + UFLAG_OP12(ed, x2) + SRA(ed, ed, x2); + EBBACK(x3); + UFLAG_RES(ed); + UFLAG_DF(x3, d_sar8); + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_emit_logic.c b/src/dynarec/rv64/dynarec_rv64_emit_logic.c index 495453e0..0e928939 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_logic.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_logic.c @@ -200,6 +200,38 @@ void emit_or32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in } } + +// emit AND8 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed) +void emit_and8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4) +{ + + CLEAR_FLAGS(); + IFX(X_PEND) { + SET_DF(s3, d_and8); + } else IFX(X_ALL) { + SET_DFNONE(); + } + + AND(s1, s1, s2); + + IFX(X_PEND) { + SB(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 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) { diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 986b5ac8..60ab271b 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -784,7 +784,7 @@ void emit_or8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); //void emit_or8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); //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_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_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); |