Skip to content

Commit

Permalink
[ARM64_DYNAREC] Improved div/idiv opcode flags (non)handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed Nov 13, 2024
1 parent 506cb98 commit f66aa57
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 12 deletions.
30 changes: 24 additions & 6 deletions src/dynarec/arm64/dynarec_arm64_00.c
Original file line number Diff line number Diff line change
Expand Up @@ -3270,7 +3270,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 6:
INST_NAME("DIV Eb");
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x1);
GETEB(x1, 0);
UXTHw(x2, xRAX);
if(box64_dynarec_div0) {
Expand All @@ -3287,12 +3286,17 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed)
BFIx(xRAX, x3, 0, 8);
BFIx(xRAX, x4, 8, 8);
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
case 7:
INST_NAME("IDIV Eb");
SKIPTEST(x1);
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x1);
GETSEB(x1, 0);
if(box64_dynarec_div0) {
CBNZw_MARK3(ed);
Expand All @@ -3309,6 +3313,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed)
BFIx(xRAX, x3, 0, 8);
BFIx(xRAX, x4, 8, 8);
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
}
break;
Expand Down Expand Up @@ -3410,7 +3420,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("DIV Ed");
SETFLAGS(X_ALL, SF_SET);
if(!rex.w) {
SET_DFNONE(x2);
GETED(0);
if(ninst && (nextop==0xF0)
&& dyn->insts[ninst-1].x64.addr
Expand Down Expand Up @@ -3449,7 +3458,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
&& dyn->insts[ninst-1].x64.addr
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x31
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0xD2) {
SET_DFNONE(x2);
GETED(0);
if(box64_dynarec_div0) {
CBNZx_MARK3(ed);
Expand Down Expand Up @@ -3484,15 +3492,19 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
UDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
MOVx_REG(xRAX, x2);
SET_DFNONE(x2);
}
}
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
case 7:
INST_NAME("IDIV Ed");
SKIPTEST(x1);
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x2)
if(!rex.w) {
GETSEDw(0);
if(box64_dynarec_div0) {
Expand Down Expand Up @@ -3560,6 +3572,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
}
break;
Expand Down
14 changes: 12 additions & 2 deletions src/dynarec/arm64/dynarec_arm64_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 6:
INST_NAME("DIV Ed");
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x2);
if(!rex.w) {
GETEDO(x6, 0);
if(box64_dynarec_div0) {
Expand Down Expand Up @@ -1452,12 +1451,17 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
case 7:
INST_NAME("IDIV Ed");
NOTEST(x1);
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x2)
if(!rex.w) {
GETSEDOw(x6, 0);
MOVw_REG(x3, xRAX);
Expand Down Expand Up @@ -1519,6 +1523,12 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
}
break;
Expand Down
14 changes: 12 additions & 2 deletions src/dynarec/arm64/dynarec_arm64_66.c
Original file line number Diff line number Diff line change
Expand Up @@ -1374,7 +1374,6 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 6:
INST_NAME("DIV Ew");
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x1);
GETEW(x1, 0);
UXTHw(x2, xRAX);
BFIw(x2, xRDX, 16, 16);
Expand All @@ -1392,12 +1391,17 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed)
BFIz(xRAX, x3, 0, 16);
BFIz(xRDX, x4, 0, 16);
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
case 7:
INST_NAME("IDIV Ew");
SKIPTEST(x1);
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x1);
GETSEW(x1, 0);
if(box64_dynarec_div0) {
CBNZw_MARK3(ed);
Expand All @@ -1415,6 +1419,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed)
BFIz(xRAX, x3, 0, 16);
BFIz(xRDX, x4, 0, 16);
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
}
break;
Expand Down
14 changes: 12 additions & 2 deletions src/dynarec/arm64/dynarec_arm64_67.c
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 6:
INST_NAME("DIV Ed");
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x2);
if(!rex.w) {
GETED32(0);
MOVw_REG(x3, xRAX);
Expand Down Expand Up @@ -1551,12 +1550,17 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
case 7:
INST_NAME("IDIV Ed");
NOTEST(x1);
SETFLAGS(X_ALL, SF_SET);
SET_DFNONE(x2);
if(!rex.w) {
GETSED32w(0);
MOVw_REG(x3, xRAX);
Expand Down Expand Up @@ -1588,6 +1592,12 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE(x2);
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if(box64_dynarec_test) {
MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF));
BICw(xFlags, xFlags, x1);
}
break;
}
break;
Expand Down

0 comments on commit f66aa57

Please sign in to comment.