Skip to content

Commit

Permalink
[ARM64_DYNAREC] Some rework on 8/16/32/64 INC/DEC opcodes
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed Nov 14, 2024
1 parent 4e568e1 commit d47b555
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 81 deletions.
12 changes: 6 additions & 6 deletions src/dynarec/arm64/dynarec_arm64_00.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0x46:
case 0x47:
INST_NAME("INC Reg (32bits)");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
gd = xRAX + (opcode&7);
emit_inc32(dyn, ninst, rex, gd, x1, x2);
break;
Expand All @@ -629,7 +629,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0x4E:
case 0x4F:
INST_NAME("DEC Reg (32bits)");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
gd = xRAX + (opcode&7);
emit_dec32(dyn, ninst, rex, gd, x1, x2);
break;
Expand Down Expand Up @@ -3622,14 +3622,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("INC Eb");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETEB(x1, 0);
emit_inc8(dyn, ninst, x1, x2, x4);
EBBACK;
break;
case 1:
INST_NAME("DEC Eb");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETEB(x1, 0);
emit_dec8(dyn, ninst, x1, x2, x4);
EBBACK;
Expand All @@ -3643,14 +3643,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0: // INC Ed
INST_NAME("INC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETED(0);
emit_inc32(dyn, ninst, rex, ed, x3, x4);
WBACK;
break;
case 1: //DEC Ed
INST_NAME("DEC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETED(0);
emit_dec32(dyn, ninst, rex, ed, x3, x4);
WBACK;
Expand Down
4 changes: 2 additions & 2 deletions src/dynarec/arm64/dynarec_arm64_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1539,14 +1539,14 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0: // INC Ed
INST_NAME("INC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETEDO(x6, 0);
emit_inc32(dyn, ninst, rex, ed, x3, x4);
WBACKO(x6);
break;
case 1: //DEC Ed
INST_NAME("DEC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETEDO(x6, 0);
emit_dec32(dyn, ninst, rex, ed, x3, x4);
WBACKO(x6);
Expand Down
8 changes: 4 additions & 4 deletions src/dynarec/arm64/dynarec_arm64_66.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0x46:
case 0x47:
INST_NAME("INC Reg16 (32bits)");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
gd = xRAX + (opcode&7);
UXTHw(x1, gd);
emit_inc16(dyn, ninst, x1, x2, x3);
Expand All @@ -338,7 +338,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0x4E:
case 0x4F:
INST_NAME("DEC Reg16 (32bits)");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
gd = xRAX + (opcode&7);
UXTHw(x1, gd);
emit_dec16(dyn, ninst, x1, x2, x3);
Expand Down Expand Up @@ -1440,14 +1440,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("INC Ew");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETEW(x1, 0);
emit_inc16(dyn, ninst, x1, x2, x4);
EWBACK;
break;
case 1:
INST_NAME("DEC Ew");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETEW(x1, 0);
emit_dec16(dyn, ninst, x1, x2, x4);
EWBACK;
Expand Down
4 changes: 2 additions & 2 deletions src/dynarec/arm64/dynarec_arm64_66f0.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
{
case 0: // INC Ew
INST_NAME("LOCK INC Ew");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
UXTHw(x6, ed);
Expand Down Expand Up @@ -583,7 +583,7 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
break;
case 1: //DEC Ew
INST_NAME("LOCK DEC Ew");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
UXTHw(x6, ed);
Expand Down
4 changes: 2 additions & 2 deletions src/dynarec/arm64/dynarec_arm64_67.c
Original file line number Diff line number Diff line change
Expand Up @@ -1603,14 +1603,14 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 0: // INC Ed
INST_NAME("INC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETED32(0);
emit_inc32(dyn, ninst, rex, ed, x3, x4);
WBACK;
break;
case 1: //DEC Ed
INST_NAME("DEC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
GETED32(0);
emit_dec32(dyn, ninst, rex, ed, x3, x4);
WBACK;
Expand Down
77 changes: 16 additions & 61 deletions src/dynarec/arm64/dynarec_arm64_emit_math.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,12 +701,7 @@ void emit_sub16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
// emit INC32 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_inc32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4)
{
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s4, rex.w?d_inc64:d_inc32);
} else IFX(X_ZF|X_OF|X_AF|X_SF|X_PF) {
SET_DFNONE(s4);
}
SET_DFNONE(s4);
IFX(X_AF) {
if(rex.w) {
ORRx_mask(s3, s1, 1, 0, 0); // s3 = op1 | op2
Expand All @@ -721,9 +716,6 @@ void emit_inc32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4
} else {
ADDxw_U12(s1, s1, 1);
}
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_AF) {
BICxw_REG(s3, s3, s1); // s3 = (op1 | op2) & ~ res
ORRxw_REG(s3, s3, s4); // s3 = (op1 & op2) | ((op1 | op2) & ~ res)
Expand Down Expand Up @@ -756,20 +748,12 @@ void emit_inc32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4
// emit INC8 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_inc8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
{
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s3, d_inc8);
} else IFX(X_ZF|X_OF|X_AF|X_SF|X_PF) {
SET_DFNONE(s3);
}
SET_DFNONE(s3);
IFX(X_AF | X_OF) {
ORRw_mask(s3, s1, 0, 0); // s3 = op1 | op2
ANDw_mask(s4, s1, 0, 0); // s4 = op1 & op2
}
ADDw_U12(s1, s1, 1);
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_AF|X_OF) {
BICw_REG(s3, s3, s1); // s3 = (op1 | op2) & ~ res
ORRw_REG(s3, s3, s4); // s4 = (op1 & op2) | ((op1 | op2) & ~ res)
Expand All @@ -792,22 +776,13 @@ void emit_inc8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
// emit INC16 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_inc16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
{
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s3, d_inc16);
} else IFX(X_ZF|X_OF|X_AF|X_SF|X_PF) {
SET_DFNONE(s3);
}
SET_DFNONE(s3);
IFX(X_AF | X_OF) {
MOVw_REG(s4, s1);
ORRw_mask(s3, s1, 0, 0); // s3 = op1 | op2
ANDw_mask(s4, s1, 0, 0); // s4 = op1 & op2
}
ADDw_U12(s1, s1, 1);
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_AF|X_OF) {
ORRw_mask(s3, s4, 0, 0); // s3 = op1 | op2
ANDw_mask(s4, s4, 0, 0); // s4 = op1 & op2
BICw_REG(s3, s3, s1); // s3 = (op1 | op2) & ~ res
ORRw_REG(s3, s3, s4); // s3 = (op1 & op2) | ((op1 | op2) & ~ res)
IFX(X_AF) {
Expand All @@ -829,12 +804,7 @@ void emit_inc16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
// emit DEC32 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_dec32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4)
{
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s4, rex.w?d_dec64:d_dec32);
} else IFX(X_ZF|X_OF|X_AF|X_SF|X_PF) {
SET_DFNONE(s4);
}
SET_DFNONE(s4);
IFX(X_AF) {
MVNxw_REG(s3, s1);
if(rex.w) {
Expand All @@ -850,9 +820,6 @@ void emit_dec32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4
} else {
SUBxw_U12(s1, s1, 1);
}
IFX(X_PEND) {
STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_AF) {
ANDxw_REG(s3, s3, s1); // s3 = (~op1 | op2) & res
ORRxw_REG(s3, s3, s4); // s4 = (~op1 & op2) | ((~op1 | op2) & ~ res)
Expand Down Expand Up @@ -885,12 +852,7 @@ void emit_dec32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4
// emit DEC8 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_dec8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
{
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s3, d_dec8);
} else IFX(X_ZF|X_OF|X_AF|X_SF|X_PF) {
SET_DFNONE(s3);
}
SET_DFNONE(s3);
IFX(X_AF|X_OF) {
MVNw_REG(s3, s1);
ANDw_mask(s4, s3, 0, 0); // s4 = ~op1 & op2
Expand All @@ -901,9 +863,6 @@ void emit_dec8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
} else {
SUBw_U12(s1, s1, 1);
}
IFX(X_PEND) {
STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_AF|X_OF) {
ANDw_REG(s3, s3, s1); // s3 = (~op1 | op2) & res
ORRw_REG(s3, s3, s4); // s3 = (~op1 & op2) | ((~op1 | op2) & res)
Expand All @@ -918,8 +877,10 @@ void emit_dec8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
}
}
IFX(X_ZF) {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRw(s3, s1, 7);
Expand All @@ -933,12 +894,7 @@ void emit_dec8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
// emit DEC16 instruction, from s1, store result in s1 using s3 and s4 as scratch
void emit_dec16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
{
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, op1));
SET_DF(s3, d_dec16);
} else IFX(X_ZF|X_OF|X_AF|X_SF|X_PF) {
SET_DFNONE(s3);
}
SET_DFNONE(s3);
IFX(X_AF|X_OF) {
MVNw_REG(s4, s1);
}
Expand All @@ -947,9 +903,6 @@ void emit_dec16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
} else {
SUBw_U12(s1, s1, 1);
}
IFX(X_PEND) {
STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
}
IFX(X_AF|X_OF) {
ORRw_mask(s3, s4, 0, 0); // s3 = ~op1 | op2
ANDw_mask(s4, s4, 0, 0); // s4 = ~op1 & op2
Expand All @@ -966,8 +919,10 @@ void emit_dec16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
}
}
IFX(X_ZF) {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
IFNATIVE(NF_EQ) {} else {
CSETw(s3, cEQ);
BFIw(xFlags, s3, F_ZF, 1);
}
}
IFX(X_SF) {
LSRw(s3, s1, 15);
Expand Down
8 changes: 4 additions & 4 deletions src/dynarec/arm64/dynarec_arm64_f0.c
Original file line number Diff line number Diff line change
Expand Up @@ -1609,7 +1609,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
{
case 0: // INC Eb
INST_NAME("LOCK INC Eb");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
if(MODREG) {
GETEB(x1, 0);
emit_inc8(dyn, ninst, x1, x2, x4);
Expand All @@ -1636,7 +1636,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 1: //DEC Eb
INST_NAME("LOCK DEC Eb");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
if(MODREG) {
GETEB(x1, 0);
emit_dec8(dyn, ninst, x1, x2, x4);
Expand Down Expand Up @@ -1671,7 +1671,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
{
case 0: // INC Ed
INST_NAME("LOCK INC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_inc32(dyn, ninst, rex, ed, x3, x4);
Expand Down Expand Up @@ -1719,7 +1719,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 1: //DEC Ed
INST_NAME("LOCK DEC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_dec32(dyn, ninst, rex, ed, x3, x4);
Expand Down

0 comments on commit d47b555

Please sign in to comment.