[ARM64_DYNAREC] Some small improvments to ROR/ROL/RCR/RCL opcodes

This commit is contained in:
ptitSeb 2024-08-11 14:56:13 +02:00
parent 3760be946f
commit 730eb1f472
5 changed files with 36 additions and 110 deletions

View File

@ -1933,7 +1933,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("ROL Eb, Ib");
u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
if(u8) {
SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEB(x1, 1);
u8 = F8&0x1f;
emit_rol8c(dyn, ninst, x1, u8, x4, x5);
@ -1947,7 +1947,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("ROR Eb, Ib");
u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
if(u8) {
SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEB(x1, 1);
u8 = F8&0x1f;
emit_ror8c(dyn, ninst, x1, u8, x4, x5);
@ -1962,7 +1962,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
if(u8) {
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEB(x1, 1);
u8 = F8&0x1f;
emit_rcl8c(dyn, ninst, x1, u8, x4, x5);
@ -1977,7 +1977,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
if(u8) {
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEB(x1, 1);
u8 = F8&0x1f;
emit_rcr8c(dyn, ninst, x1, u8, x4, x5);
@ -2039,7 +2039,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("ROL Ed, Ib");
u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
if(u8) {
SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
@ -2058,7 +2058,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("ROR Ed, Ib");
u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
if(u8) {
SETFLAGS(X_CF|X_OF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
@ -2470,14 +2470,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Eb, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEB(x1, 0);
emit_rol8c(dyn, ninst, ed, 1, x4, x5);
EBBACK;
break;
case 1:
INST_NAME("ROR Eb, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEB(x1, 0);
emit_ror8c(dyn, ninst, ed, 1, x4, x5);
EBBACK;
@ -2527,14 +2527,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ed, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED(0);
emit_rol32c(dyn, ninst, rex, ed, 1, x3, x4);
WBACK;
break;
case 1:
INST_NAME("ROR Ed, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED(0);
emit_ror32c(dyn, ninst, rex, ed, 1, x3, x4);
WBACK;

View File

@ -797,14 +797,14 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ed, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEDO(x6, 0);
emit_rol32c(dyn, ninst, rex, ed, 1, x3, x4);
WBACKO(x6);
break;
case 1:
INST_NAME("ROR Ed, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEDO(x6, 0);
emit_ror32c(dyn, ninst, rex, ed, 1, x3, x4);
WBACKO(x6);

View File

@ -977,7 +977,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("ROL Ew, Ib");
u8 = geted_ib(dyn, addr, ninst, nextop) & 15;
if (u8) {
SETFLAGS(X_CF | X_OF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 1);
u8 = (F8)&0x1f;
emit_rol16c(dyn, ninst, x1, u8, x4, x5);
@ -990,7 +990,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 1:
INST_NAME("ROR Ew, Ib");
if (geted_ib(dyn, addr, ninst, nextop) & 15) {
SETFLAGS(X_CF | X_OF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 1);
u8 = (F8)&0x1f;
emit_ror16c(dyn, ninst, x1, u8, x4, x5);
@ -1006,7 +1006,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 1);
u8 = F8;
u8 = (F8)&0x1f;
emit_rcl16c(dyn, ninst, ed, u8, x4, x5);
EWBACK;
} else {
@ -1020,7 +1020,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 1);
u8 = F8;
u8 = (F8)&0x1f;
emit_rcr16c(dyn, ninst, ed, u8, x4, x5);
EWBACK;
} else {
@ -1093,14 +1093,14 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ew, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 0);
emit_rol16c(dyn, ninst, x1, 1, x5, x4);
EWBACK;
break;
case 1:
INST_NAME("ROR Ew, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETEW(x1, 0);
emit_ror16c(dyn, ninst, x1, 1, x5, x4);
EWBACK;

View File

@ -1050,7 +1050,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ed, Ib");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
@ -1058,7 +1058,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 1:
INST_NAME("ROR Ed, Ib");
SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_OF|X_CF, SF_SUBSET); // removed PENDING on purpose
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);

View File

@ -804,23 +804,9 @@ void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
if (!c) return;
IFX(X_PEND) {
MOV32w(s3, c);
STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, rex.w?d_rol64:d_rol32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
if(!c) {
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
return;
}
SET_DFNONE(s4);
RORxw(s1, s1, (rex.w?64:32)-c);
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
BFIw(xFlags, s1, F_CF, 1);
}
@ -839,23 +825,9 @@ void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
if (!c) return;
IFX(X_PEND) {
MOV32w(s3, c);
STRxw_U12(s3, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, rex.w?d_ror64:d_ror32);
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
if(!c) {
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
return;
}
SET_DFNONE(s4);
RORxw(s1, s1, c);
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
BFXILxw(xFlags, s1, rex.w?63:31, 1);
}
@ -875,21 +847,13 @@ void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
if (!c) return;
IFX(X_PEND) {
MOV32w(s3, c);
STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, d_rol8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
SET_DFNONE(s4);
if(c&7) {
int rc = 8-(c&7);
ORRw_REG_LSL(s1, s1, s1, 8);
LSRw(s1, s1, rc);
}
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
BFIw(xFlags, s1, F_CF, 1);
}
@ -908,20 +872,12 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
if (!c) return;
IFX(X_PEND) {
MOV32w(s3, c);
STRB_U12(s3, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, d_ror8);
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
SET_DFNONE(s4);
if(c&7) {
ORRw_REG_LSL(s1, s1, s1, 8);
LSRw(s1, s1, c&7);
}
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
BFXILw(xFlags, s1, 7, 1);
}
@ -941,21 +897,13 @@ void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
if (!c) return;
IFX(X_PEND) {
MOV32w(s3, c);
STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, d_rol16);
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
SET_DFNONE(s4);
if(c&15) {
int rc = 16-(c&15);
ORRw_REG_LSL(s1, s1, s1, 16);
LSRw(s1, s1, rc);
}
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
BFIw(xFlags, s1, F_CF, 1);
}
@ -974,20 +922,12 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
if (!c) return;
IFX(X_PEND) {
MOV32w(s3, c);
STRH_U12(s3, xEmu, offsetof(x64emu_t, op2));
SET_DF(s4, d_ror16);
} else IFX(X_ALL) {
SET_DFNONE(s4);
}
SET_DFNONE(s4);
if(c&15) {
ORRw_REG_LSL(s1, s1, s1, 16);
LSRw(s1, s1, c&15);
}
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
BFXILw(xFlags, s1, 15, 1);
}
@ -1020,9 +960,6 @@ void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
}
ORRw_REG_LSL(s1, s1, s1, 9); // insert s1 again
LSRw_IMM(s1, s1, 9-c); // do the rcl
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_OF|X_CF) {
IFX(X_CF) {
BFIw(xFlags, s3, F_CF, 1);
@ -1063,9 +1000,6 @@ void emit_rcr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
BFIw(xFlags, s3, F_OF, 1);
}
}
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
}
}
// emit RCL16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
@ -1088,9 +1022,6 @@ void emit_rcl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
}
ORRx_REG_LSL(s1, s1, s1, 17); // insert s1 again
LSRx_IMM(s1, s1, 17-c); // do the rcl
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
BFIw(xFlags, s3, F_CF, 1);
}
@ -1129,9 +1060,6 @@ void emit_rcr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
BFIw(xFlags, s3, F_OF, 1);
}
}
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
}
// emit RCL32/RCL64 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
@ -1139,6 +1067,8 @@ void emit_rcl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
{
MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
if(!c) return;
SET_DFNONE(s4);
IFX(X_OF|X_CF) {
@ -1152,9 +1082,6 @@ void emit_rcl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
BFIxw(s4, xFlags, c-1, 1);
ORRxw_REG_LSR(s1, s4, s1, (rex.w?65:33)-c);
}
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_CF) {
BFIw(xFlags, s3, F_CF, 1);
}
@ -1170,6 +1097,8 @@ void emit_rcr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
{
MAYUSE(s1); MAYUSE(s3); MAYUSE(s4);
if(!c) return;
SET_DFNONE(s4);
IFX(X_OF) {
@ -1192,9 +1121,6 @@ void emit_rcr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
IFX(X_CF) {
BFIw(wFlags, s3, 0, 1);
}
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
}
// emit SHRD32 instruction, from s1, fill s2 , constant c, store result in s1 using s3 and s4 as scratch