diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-19 20:09:38 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-19 20:09:38 +0100 |
| commit | 27b7382be5ac9f57f6c8269b1b5c00abfd7093d7 (patch) | |
| tree | 841b3b40f056c663babd34c8d05750704061f45f /src | |
| parent | 25d342f829d9cbb9d28a7d8b4f44694f60727c84 (diff) | |
| download | box64-27b7382be5ac9f57f6c8269b1b5c00abfd7093d7.tar.gz box64-27b7382be5ac9f57f6c8269b1b5c00abfd7093d7.zip | |
Added 0F B3 and 66 0F B3 BTR opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/dynarec_arm64_0f.c | 44 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_660f.c | 18 |
2 files changed, 62 insertions, 0 deletions
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c index 6509050d..41db02ee 100755 --- a/src/dynarec/dynarec_arm64_0f.c +++ b/src/dynarec/dynarec_arm64_0f.c @@ -152,6 +152,45 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin GOCOND(0x90, "SET", "Eb"); #undef GO + case 0xB3: + INST_NAME("BTR Ed, Gd"); + SETFLAGS(X_CF, SF_SET); + nextop = F8; + GETGD; + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + wback = 0; + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); + UBFXw(x1, gd, 5+rex.w, 3-rex.w); // r1 = (gd>>5); + ADDx_REG_LSL(x3, wback, x1, 2); //(&ed)+=r1*4; + LDRxw_U12(x1, x3, fixedaddress); + ed = x1; + wback = x3; + } + if(rex.w) { + ANDx_mask(x2, gd, 1, 0, 0b00101); //mask=0x000000000000003f + } else { + ANDw_mask(x2, gd, 0, 0b00100); //mask=0x00000001f + } + LSRxw_REG(x4, ed, x2); + if(rex.w) { + ANDSx_mask(x4, x4, 1, 0, 0); //mask=1 + } else { + ANDSw_mask(x4, x4, 0, 0); //mask=1 + } + BFIw(xFlags, x4, F_CF, 1); + //B_MARK3(cEQ); // bit already clear, jump to end of instruction + MOV32w(x4, 1); + LSLxw_REG(x4, x4, x2); + EORxw_REG(x4, ed, x4); + CSELxw(ed, ed, x4, cEQ); + if(wback) { + STRxw_U12(ed, wback, fixedaddress); + } + //MARK3; + break; + case 0xBB: INST_NAME("BTC Ed, Gd"); SETFLAGS(X_CF, SF_SET); @@ -174,6 +213,11 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ANDw_mask(x2, gd, 0, 0b00100); //mask=0x00000001f } LSRxw_REG(x4, ed, x2); + if(rex.w) { + ANDx_mask(x4, x4, 1, 0, 0); //mask=1 + } else { + ANDw_mask(x4, x4, 0, 0); //mask=1 + } BFIw(xFlags, x4, F_CF, 1); MOV32w(x4, 1); LSLxw_REG(x4, x4, x2); diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c index efcd2198..0d4a55f5 100755 --- a/src/dynarec/dynarec_arm64_660f.c +++ b/src/dynarec/dynarec_arm64_660f.c @@ -68,6 +68,23 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n FAKEED; break; + case 0xB3: + INST_NAME("BTR Ew, Gw"); + SETFLAGS(X_CF, SF_SET); + nextop = F8; + gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); // GETGD + GETEW(x4, 0); + ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f + LSRw_REG(x1, ed, x2); + BFIw(xFlags, x1, F_CF, 1); + ANDSw_mask(x1, x1, 0, 0); //mask=1 + B_NEXT(cEQ); + MOV32w(x1, 1); + LSLxw_REG(x1, x1, x2); + EORxw_REG(ed, ed, x1); + EWBACK; + break; + case 0xBB: INST_NAME("BTC Ew, Gw"); SETFLAGS(X_CF, SF_SET); @@ -77,6 +94,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f LSRw_REG(x1, ed, x2); BFIw(xFlags, x1, F_CF, 1); + ANDw_mask(x1, x1, 0, 0); //mask=1 MOV32w(x1, 1); LSLxw_REG(x1, x1, x2); EORxw_REG(ed, ed, x1); |