diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-03-22 14:47:56 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-22 07:47:56 +0100 |
| commit | 3656cd66ea13833e9959598862e7a1e334bea6a0 (patch) | |
| tree | 48189638842a62b4fc22a36313b0546a88c34540 | |
| parent | da88b872790f838ad85f979a7153658bf746479a (diff) | |
| download | box64-3656cd66ea13833e9959598862e7a1e334bea6a0.tar.gz box64-3656cd66ea13833e9959598862e7a1e334bea6a0.zip | |
[RV64_DYNAREC] Added more opcode (#612)
* [RV64_DYNAREC] Added 66 {90:97} NOP opcode
* [RV64_DYNAREC] Added more 16bit opcodes| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 49 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_logic.c | 29 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_tests.c | 29 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 6 |
4 files changed, 109 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index efa69ca8..0cd1f5e8 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -65,7 +65,18 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0x0F: addr = dynarec64_660F(dyn, addr, ip, ninst, rex, ok, need_epilog); break; - + case 0x25: + INST_NAME("AND AX, Iw"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i32 = F16; + SLLI(x1, xRAX, 48); + SRLI(x1, x1, 48); + MOV32w(x2, i32); + emit_and16(dyn, ninst, x1, x2, x3, x4); + LUI(x3, 0xfff0); + AND(xRAX, xRAX, x3); + OR(xRAX, xRAX, x1); + break; case 0x3D: INST_NAME("CMP AX, Iw"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -115,6 +126,14 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni DEFAULT; } break; + case 0x85: + INST_NAME("TEST Ew, Gw"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEW(x1, 0); + GETGW(x2); + emit_test16(dyn, ninst, x1, x2, x3, x4, x5); + break; case 0x89: INST_NAME("MOV Ew, Gw"); nextop = F8; @@ -135,6 +154,34 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SMWRITELOCK(lock); } break; + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + gd = xRAX+(opcode&0x07)+(rex.b<<3); + if(gd==xRAX) { + INST_NAME("NOP"); + } else { + INST_NAME("XCHG AX, Reg"); + LUI(x4, 0xfff0); + // x2 <- rax + MV(x2, xRAX); + // rax[15:0] <- gd[15:0] + SLLI(x3, gd, 48); + SRLI(x3, x3, 48); + AND(xRAX, xRAX, x4); + OR(xRAX, xRAX, x3); + // gd[15:0] <- x2[15:0] + SLLI(x2, x2, 48); + SRLI(x2, x2, 48); + AND(gd, gd, x4); + OR(gd, gd, x2); + } + break; case 0xC1: nextop = F8; switch((nextop>>3)&7) { diff --git a/src/dynarec/rv64/dynarec_rv64_emit_logic.c b/src/dynarec/rv64/dynarec_rv64_emit_logic.c index 78bdac67..495453e0 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_logic.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_logic.c @@ -229,6 +229,33 @@ void emit_and8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s } } +void emit_and16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4) { + CLEAR_FLAGS(); + IFX(X_PEND) { + SET_DF(s3, d_tst16); + } else IFX(X_ALL) { + SET_DFNONE(); + } + + AND(s1, s1, s2); // res = s1 & s2 + + IFX(X_PEND) { + SH(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_SF) { + SRLI(s3, s1, 15); + 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) { @@ -321,4 +348,4 @@ void emit_or8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } -} \ No newline at end of file +} diff --git a/src/dynarec/rv64/dynarec_rv64_emit_tests.c b/src/dynarec/rv64/dynarec_rv64_emit_tests.c index 9b0bcf09..0abb5be2 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_tests.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_tests.c @@ -251,6 +251,35 @@ void emit_test8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, } } +// emit TEST16 instruction, from test s1, s2, using s3, s4 and s5 as scratch +void emit_test16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) +{ + CLEAR_FLAGS(); + IFX_PENDOR0 { + SET_DF(s3, d_tst16); + } else { + SET_DFNONE(); + } + + AND(s3, s1, s2); // res = s1 & s2 + + IFX_PENDOR0 { + SH(s3, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_SF) { + SRLI(s4, s3, 15); + BEQZ(s4, 8); + ORI(xFlags, xFlags, 1 << F_SF); + } + IFX(X_ZF) { + BNEZ(s3, 8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s3, s4, s5); + } +} + // emit TEST32 instruction, from test s1, s2, using s3 and s4 as scratch void emit_test32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) { diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index fd369085..0ab1a76d 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -109,6 +109,8 @@ LDxw(hint, wback, fixedaddress); \ ed = hint; \ } +// GETGW extract x64 register in gd, that is i +#define GETGW(i) gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); SLLI(i, gd, 48); SRLI(i, i, 48); gd = i; //GETEWW will use i for ed, and can use w for wback. #define GETEWW(w, i, D) if(MODREG) { \ wback = xRAX+(nextop&7)+(rex.b<<3);\ @@ -717,7 +719,7 @@ void emit_cmp8_0(dynarec_rv64_t* dyn, int ninst, int s1, int s3, int s4); void emit_cmp16_0(dynarec_rv64_t* dyn, int ninst, int s1, int s3, int s4); void emit_cmp32_0(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4); void emit_test8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); -//void emit_test16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); +void emit_test16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); void emit_test32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); void emit_test32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4, int s5); void emit_add32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); @@ -748,7 +750,7 @@ void emit_or16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); //void emit_or16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); //void emit_xor16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); //void emit_xor16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); -//void emit_and16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); +void emit_and16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); //void emit_and16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); void emit_inc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); //void emit_inc16(dynarec_rv64_t* dyn, int ninst, int s1, int s3, int s4); |