mirror of
https://github.com/ptitSeb/box64.git
synced 2025-05-09 00:21:32 +08:00
[ARM64_DYNAREC] Fixed BT/BTC/BTR/BTS opcodes
This commit is contained in:
parent
1e7b4b8450
commit
a46923e494
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user