[ARM64_DYNAREC] Fixed BT/BTC/BTR/BTS opcodes

This commit is contained in:
wannacu 2023-08-04 16:28:33 +08:00
parent 1e7b4b8450
commit a46923e494
4 changed files with 42 additions and 31 deletions

View File

@ -537,6 +537,15 @@
#define EORx_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(1, 0b10, 0b01, 0, Rm, lsr, Rn, Rd))
#define EORw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(0, 0b10, 0b01, 0, Rm, lsr, Rn, Rd))
#define EORxw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b01, 0, Rm, lsr, Rn, Rd))
#define EONx_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b10, 0b00, 1, Rm, 0, Rn, Rd))
#define EONw_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(0, 0b10, 0b00, 1, Rm, 0, Rn, Rd))
#define EONxw_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b00, 1, Rm, 0, Rn, Rd))
#define EONx_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(1, 0b10, 0b00, 1, Rm, lsl, Rn, Rd))
#define EONw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(0, 0b10, 0b00, 1, Rm, lsl, Rn, Rd))
#define EONxw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b00, 1, Rm, lsl, Rn, Rd))
#define EONx_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(1, 0b10, 0b01, 1, Rm, lsr, Rn, Rd))
#define EONw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(0, 0b10, 0b01, 1, Rm, lsr, Rn, Rd))
#define EONxw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b01, 1, Rm, lsr, Rn, Rd))
#define MOVx_REG(Rd, Rm) ORRx_REG(Rd, xZR, Rm)
#define MOVw_REG(Rd, Rm) ORRw_REG(Rd, xZR, Rm)
#define MOVxw_REG(Rd, Rm) ORRxw_REG(Rd, xZR, Rm)
@ -563,6 +572,12 @@
#define BICx_REG BICx
#define BICw_REG BICw
#define BICxw_REG BICxw
#define BICx_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(1, 0b00, 0b00, 1, Rm, lsl, Rn, Rd))
#define BICw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 1, Rm, lsl, Rn, Rd))
#define BICxw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b00, 1, Rm, lsl, Rn, Rd))
#define BICx_REG_LSR(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(1, 0b00, 0b01, 1, Rm, lsl, Rn, Rd))
#define BICw_REG_LSR(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(0, 0b00, 0b01, 1, Rm, lsl, Rn, Rd))
#define BICxw_REG_LSR(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b01, 1, Rm, lsl, Rn, Rd))
#define TSTx_REG(Rn, Rm) ANDSx_REG(xZR, Rn, Rm)
#define TSTw_REG(Rn, Rm) ANDSw_REG(wZR, Rn, Rm)
#define TSTxw_REG(Rn, Rm) ANDSxw_REG(xZR, Rn, Rm)

View File

@ -1104,7 +1104,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0);
ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)
ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5)
ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;
LDxw(x1, x3, fixedaddress);
ed = x1;
@ -1152,7 +1152,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0);
ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)
ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5)
ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;
LDxw(x1, x3, fixedaddress);
ed = x1;
@ -1318,7 +1318,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0);
ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)
ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5)
ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;
LDxw(x1, x3, fixedaddress);
ed = x1;
@ -1331,15 +1331,14 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
LSRxw_REG(x4, ed, x2);
if(rex.w) {
ANDSx_mask(x4, x4, 1, 0, 0); //mask=1
ANDx_mask(x4, x4, 1, 0, 0); //mask=1
} else {
ANDSw_mask(x4, x4, 0, 0); //mask=1
ANDw_mask(x4, x4, 0, 0); //mask=1
}
BFIw(xFlags, x4, F_CF, 1);
MOV32w(x4, 1);
LSLxw_REG(x4, x4, x2);
EORxw_REG(x4, ed, x4);
CSELxw(ed, ed, x4, cEQ);
BICxw_REG(ed, ed, x4);
if(wback) {
STRxw_U12(ed, wback, fixedaddress);
SMWRITE();
@ -1418,7 +1417,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
TBNZ_MARK3(xFlags, 0); // bit already set, jump to next instruction
MOV32w(x4, 1);
EORxw_REG_LSL(ed, ed, x4, u8);
ORRxw_REG_LSL(ed, ed, x4, u8);
if(wback) {
STxw(ed, wback, fixedaddress);
SMWRITE();
@ -1443,7 +1442,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
TBZ_MARK3(xFlags, 0); // bit already clear, jump to next instruction
MOV32w(x4, 1);
EORxw_REG_LSL(ed, ed, x4, u8);
BICxw_REG_LSL(ed, ed, x4, u8);
if(wback) {
STxw(ed, wback, fixedaddress);
SMWRITE();
@ -1490,7 +1489,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0);
ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)
ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5)
ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;
LDxw(x1, x3, fixedaddress);
ed = x1;

View File

@ -1756,7 +1756,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);
SBFXw(x1, gd, 4, 12); // r1 = (gw>>4)
SBFXx(x1, gd, 4, 12); // r1 = (gw>>4)
ADDx_REG_LSL(x3, wback, x1, 1); //(&ed)+=r1*2;
LDH(x1, x3, fixedaddress);
ed = x1;
@ -1797,9 +1797,10 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
wback = 0;
} else {
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);
SBFXw(x4, gd, 4, 12); // r1 = (gw>>4)
SBFXx(x4, gd, 4, 12); // r1 = (gw>>4)
ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2;
LDH(x4, x3, fixedaddress);
wback = x3;
ed = x4;
}
ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f
@ -1809,7 +1810,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
B_NEXT(cNE);
MOV32w(x1, 1);
LSLxw_REG(x1, x1, x2);
EORx_REG(ed, ed, x1);
ORRx_REG(ed, ed, x1);
if(wback) {
STRH_U12(ed, wback, fixedaddress);
}
@ -1859,7 +1860,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);
SBFXw(x4, gd, 4, 12); // r1 = (gw>>4)
SBFXx(x4, gd, 4, 12); // r1 = (gw>>4)
ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2;
LDH(x4, x3, fixedaddress);
wback = x3;
@ -1872,7 +1873,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
B_NEXT(cEQ);
MOV32w(x1, 1);
LSLxw_REG(x1, x1, x2);
EORx_REG(ed, ed, x1);
BICx_REG(ed, ed, x1);
if(wback) {
STH(ed, wback, fixedaddress);
SMWRITE();
@ -1939,7 +1940,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
TBNZ_MARK3(xFlags, 0); // bit already set, jump to next instruction
MOV32w(x4, 1);
EORxw_REG_LSL(ed, ed, x4, u8);
ORRxw_REG_LSL(ed, ed, x4, u8);
EWBACK(x1);
MARK3;
break;
@ -1953,7 +1954,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
TBZ_MARK3(xFlags, 0); // bit already clear, jump to next instruction
MOV32w(x4, 1);
EORxw_REG_LSL(ed, ed, x4, u8);
BICxw_REG_LSL(ed, ed, x4, u8);
EWBACK(x1);
MARK3;
break;
@ -1985,7 +1986,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
} else {
SMREAD();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);
SBFXw(x4, gd, 4, 12); // r1 = (gw>>4)
SBFXx(x4, gd, 4, 12); // r1 = (gw>>4)
ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2;
LDH(x4, x3, fixedaddress);
wback = x3;

View File

@ -173,8 +173,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BFIw(xFlags, x4, F_CF, 1);
MOV32w(x4, 1);
LSLxw_REG(x4, x4, x2);
EORxw_REG(x4, ed, x4);
CSELxw(ed, ed, x4, cNE);
ORRxw_REG(ed, ed, x4);
} else {
// Will fetch only 1 byte, to avoid alignment issue
if(rex.w) {
@ -191,12 +190,11 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
ed = x1;
wback = x3;
LSRw_REG(x4, ed, x2);
ANDSw_mask(x4, x4, 0, 0); //mask=1
ANDw_mask(x4, x4, 0, 0); //mask=1
BFIw(xFlags, x4, F_CF, 1);
MOV32w(x4, 1);
LSLw_REG(x4, x4, x2);
EORw_REG(x4, ed, x4);
CSELw(ed, ed, x4, cNE);
ORRw_REG(ed, ed, x4);
STLXRB(x4, ed, wback);
CBNZw_MARKLOCK(x4);
SMDMB();
@ -322,15 +320,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
LSRxw_REG(x4, ed, x2);
if(rex.w) {
ANDSx_mask(x4, x4, 1, 0, 0); //mask=1
ANDx_mask(x4, x4, 1, 0, 0); //mask=1
} else {
ANDSw_mask(x4, x4, 0, 0); //mask=1
ANDw_mask(x4, x4, 0, 0); //mask=1
}
BFIw(xFlags, x4, F_CF, 1);
MOV32w(x4, 1);
LSLxw_REG(x4, x4, x2);
EORxw_REG(x4, ed, x4);
CSELxw(ed, ed, x4, cEQ);
BICxw_REG(ed, ed, x4);
} else {
// Will fetch only 1 byte, to avoid alignment issue
if(rex.w) {
@ -340,19 +337,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
SMDMB();
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
ASRxw(x1, gd, 3); // r1 = (gd>>3)
ASRx(x1, gd, 3); // r1 = (gd>>3)
ADDx_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1;
MARKLOCK;
LDAXRB(x1, wback);
ed = x1;
wback = x3;
LSRw_REG(x4, ed, x2);
ANDSw_mask(x4, x4, 0, 0); //mask=1
ANDw_mask(x4, x4, 0, 0); //mask=1
BFIw(xFlags, x4, F_CF, 1);
MOV32w(x4, 1);
LSLw_REG(x4, x4, x2);
EORw_REG(x4, ed, x4);
CSELw(ed, ed, x4, cEQ);
ORRw_REG(ed, ed, x4);
STLXRB(x4, ed, wback);
CBNZw_MARKLOCK(x4);
SMDMB();