diff options
| author | xctan <xctan@cirno.icu> | 2023-12-26 11:55:25 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-26 12:55:25 +0100 |
| commit | e2abb6b6db3ed75ff60515b26bc1fd166633437d (patch) | |
| tree | be45efd393a354f2afd7b5dbdff160b275d46548 /src | |
| parent | cb63cdcd421e33449c5edde04a04a3833c950cfe (diff) | |
| download | box64-e2abb6b6db3ed75ff60515b26bc1fd166633437d.tar.gz box64-e2abb6b6db3ed75ff60515b26bc1fd166633437d.zip | |
[DYNAREC_RV64] Added more opcodes for VMP-protected GI (#1168)
* [DYNAREC_RV64] Added 66 0F B3 BTR opcode
* [DYNAREC_RV64] Added 66 0F BA /7 BTC opcode
* [DYNAREC_RV64] Added 66 {D1,D3} /{2,3} RCL/RCR opcodes
* [DYNAREC_RV64] Added 66 0F BA /{5,6} BTS/BTR opcodes
* [DYNAREC_RV64] Added 0F C1 XADD opcode
* [DYNAREC_RV64] Added 0F C0 XADD opcode
* [DYNAREC_RV64] Added D3 /2 RCL opcode
* [DYNAREC_RV64] Removed redundant declaration of wb2 in 0F
* [DYNAREC_RV64] Enable 66 0F BD BSR again
* [DYNAREC_RV64] Added 66 1D SBB opcodeDiffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_3.c | 10 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 26 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 40 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 155 |
4 files changed, 194 insertions, 37 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index eddb2ead..2f55ab16 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -648,6 +648,16 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int WBACK; if(!wback && !rex.w) ZEROUP(ed); break; + case 2: + INST_NAME("RCL Ed, CL"); + MESSAGE("LOG_DUMP", "Need optimization\n"); + READFLAGS(X_CF); + SETFLAGS(X_OF|X_CF, SF_SET); + ANDI(x2, xRCX, rex.w?0x3f:0x1f); + GETEDW(x4, x1, 0); + CALL_(rex.w ? ((void*)rcl64) : ((void*)rcl32), ed, x4); + WBACK; + break; case 3: INST_NAME("RCR Ed, CL"); MESSAGE(LOG_DUMP, "Need Optimization\n"); diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 86a5a3e7..ec2b7ae9 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -33,8 +33,9 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni uint8_t opcode = F8; uint8_t nextop, u8; uint8_t gd, ed; - uint8_t wback, wb2, gback; + uint8_t wb1, wback, wb2, gback; uint8_t eb1, eb2; + uint8_t gb1, gb2; int32_t i32, i32_; int cacheupd = 0; int v0, v1; @@ -1687,6 +1688,29 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if (!rex.w) ZEROUP(gd); break; + case 0xC0: + INST_NAME("XADD Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB(x1, 0); + GETGB(x2); + MV(x9, ed); + emit_add8(dyn, ninst, ed, gd, x4, x5); + MV(gd, x9); + EBBACK(x5, 0); + GBBACK(x5); + break; + case 0xC1: + INST_NAME("XADD Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED(0); + MV(x9, ed); + emit_add32(dyn, ninst, rex, ed, gd, x4, x5, x6); + MV(gd, x9); + WBACK; + break; case 0xC2: INST_NAME("CMPPS Gx, Ex, Ib"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index afa34d48..67c046a0 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -179,6 +179,18 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_sbb16(dyn, ninst, x1, x2, x3, x4, x5); GWBACK; break; + case 0x1D: + INST_NAME("SBB AX, Iw"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + ZEXTH(x1, xRAX); + i16 = F16; + MOV64xw(x2, i16); + emit_sbb16(dyn, ninst, x1, x2, x3, x4, x5); + SRLI(xRAX, xRAX, 16); + SLLI(xRAX, xRAX, 16); + OR(xRAX, xRAX, x1); + break; case 0x21: INST_NAME("AND Ew, Gw"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -990,6 +1002,34 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni CALL_(ror16, x1, x3); EWBACK; break; + case 2: + if(opcode==0xD1) { + INST_NAME("RCL Ew, 1"); + MOV32w(x2, 1); + } else { + INST_NAME("RCL Ew, CL"); + ANDI(x2, xRCX, 15); + } + MESSAGE("LOG_DUMP", "Need optimization\n"); + READFLAGS(X_CF); + SETFLAGS(X_OF|X_CF, SF_SET); + GETEW(x1, 1); + CALL_(rcl16, x1, x3); + EWBACK; + case 3: + if(opcode==0xD1) { + INST_NAME("RCR Ew, 1"); + MOV32w(x2, 1); + } else { + INST_NAME("RCR Ew, CL"); + ANDI(x2, xRCX, 15); + } + MESSAGE("LOG_DUMP", "Need optimization\n"); + READFLAGS(X_CF); + SETFLAGS(X_OF|X_CF, SF_SET); + GETEW(x1, 1); + CALL_(rcr16, x1, x3); + EWBACK; case 5: if(opcode==0xD1) { INST_NAME("SHR Ew, 1"); diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index e13e775d..59b2ad39 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -2074,6 +2074,23 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ZEXTH(x2, x2); GWBACK; break; + case 0xB3: + INST_NAME("BTR Ew, Gw"); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(); + nextop = F8; + GETEW(x1, 0); + GETGW(x2); + ANDI(gd, gd, 15); + BEXT(x4, ed, gd, x3); // F_CF is 1 + ANDI(xFlags, xFlags, ~1); + OR(xFlags, xFlags, x4); + ADDI(x4, xZR, 1); + SLL(x4, x4, gd); + NOT(x4, x4); + AND(ed, ed, x4); + EWBACK; + break; case 0xB6: INST_NAME("MOVZX Gw, Eb"); nextop = F8; @@ -2114,6 +2131,72 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ANDI(xFlags, xFlags, ~1); OR(xFlags, xFlags, x3); break; + case 5: + INST_NAME("BTS Ew, Ib"); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(); + GETEW(x1, 1); + u8 = F8; + u8 &= (rex.w ? 0x3f : 15); + ORI(xFlags, xFlags, 1 << F_CF); + if (u8 <= 10) { + ANDI(x6, ed, 1 << u8); + BNE_MARK(x6, xZR); + ANDI(xFlags, xFlags, ~(1 << F_CF)); + XORI(ed, ed, 1 << u8); + } else { + ORI(x6, xZR, 1); + SLLI(x6, x6, u8); + AND(x4, ed, x6); + BNE_MARK(x4, xZR); + ANDI(xFlags, xFlags, ~(1 << F_CF)); + XOR(ed, ed, x6); + } + EWBACK; + MARK; + break; + case 6: + INST_NAME("BTR Ed, Ib"); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(); + GETEW(x1, 1); + u8 = F8; + u8 &= (rex.w ? 0x3f : 15); + ANDI(xFlags, xFlags, ~(1 << F_CF)); + if (u8 <= 10) { + ANDI(x6, ed, 1 << u8); + BEQ_MARK(x6, xZR); + ORI(xFlags, xFlags, 1 << F_CF); + XORI(ed, ed, 1 << u8); + } else { + ORI(x6, xZR, 1); + SLLI(x6, x6, u8); + AND(x6, ed, x6); + BEQ_MARK(x6, xZR); + ORI(xFlags, xFlags, 1 << F_CF); + XOR(ed, ed, x6); + } + EWBACK; + MARK; + break; + case 7: + INST_NAME("BTC Ew, Ib"); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(); + GETEW(x1, 1); + u8 = F8; + u8 &= rex.w ? 0x3f : 15; + BEXTI(x3, ed, u8); // F_CF is 1 + ANDI(xFlags, xFlags, ~1); + OR(xFlags, xFlags, x3); + if (u8 <= 10) { + XORI(ed, ed, (1LL << u8)); + } else { + MOV64xw(x3, (1LL << u8)); + XOR(ed, ed, x3); + } + EWBACK; + break; default: DEFAULT; } @@ -2174,42 +2257,42 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ANDI(xFlags, xFlags, ~(1 << F_ZF)); GWBACK; break; - // case 0xBD: - // INST_NAME("BSR Gw, Ew"); - // SETFLAGS(X_ZF, SF_SUBSET); - // SET_DFNONE(); - // nextop = F8; - // GETEW(x5, 0); - // GETGW(x4); - // BNE_MARK(ed, xZR); - // ORI(xFlags, xFlags, 1 << F_ZF); - // B_NEXT_nocond; - // MARK; - // ANDI(xFlags, xFlags, ~(1 << F_ZF)); - // if (rv64_zbb) { - // MOV32w(x1, 31); - // CLZxw(gd, ed); - // SUB(gd, x1, gd); - // } else { - // u8 = gd; - // ADDI(u8, xZR, 0); - // AND(x2, ed, xMASK); - // SRLI(x3, x2, 8); - // BEQZ(x3, 4 + 2 * 4); - // ADDI(u8, u8, 8); - // MV(x2, x3); - // SRLI(x3, x2, 4); - // BEQZ(x3, 4 + 2 * 4); - // ADDI(u8, u8, 4); - // MV(x2, x3); - // ANDI(x2, x2, 0b1111); - // TABLE64(x3, (uintptr_t)&lead0tab); - // ADD(x3, x3, x2); - // LBU(x2, x3, 0); - // ADD(gd, u8, x2); - // } - // GWBACK; - // break; + case 0xBD: + INST_NAME("BSR Gw, Ew"); + SETFLAGS(X_ZF, SF_SUBSET); + SET_DFNONE(); + nextop = F8; + GETEW(x5, 0); + GETGW(x4); + BNE_MARK(ed, xZR); + ORI(xFlags, xFlags, 1 << F_ZF); + B_NEXT_nocond; + MARK; + ANDI(xFlags, xFlags, ~(1 << F_ZF)); + if (rv64_zbb) { + MOV32w(x1, rex.w ? 63 : 31); + CLZxw(gd, ed); + SUB(gd, x1, gd); + } else { + u8 = gd; + ADDI(u8, xZR, 0); + AND(x2, ed, xMASK); + SRLI(x3, x2, 8); + BEQZ(x3, 4 + 2 * 4); + ADDI(u8, u8, 8); + MV(x2, x3); + SRLI(x3, x2, 4); + BEQZ(x3, 4 + 2 * 4); + ADDI(u8, u8, 4); + MV(x2, x3); + ANDI(x2, x2, 0b1111); + TABLE64(x3, (uintptr_t)&lead0tab); + ADD(x3, x3, x2); + LBU(x2, x3, 0); + ADD(gd, u8, x2); + } + GWBACK; + break; case 0xBE: INST_NAME("MOVSX Gw, Eb"); nextop = F8; |