[ARM64_DYNAREC] More work on UD flags

This commit is contained in:
ptitSeb 2025-02-17 17:46:03 +01:00
parent 8b5b5aa3a7
commit 049cbd3783
6 changed files with 224 additions and 158 deletions

View File

@ -3521,7 +3521,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 4:
INST_NAME("MUL AL, Eb");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETEB(x1, 0);
UXTBw(x2, xRAX);
MULw(x1, x2, x1);
@ -3537,16 +3541,17 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BFIw(xFlags, x3, F_OF, 1);
}
}
IFX(X_AF | X_PF | X_ZF | X_SF)
if (BOX64ENV(dynarec_test)) {
// to avoid noise during test
MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
BICw(xFlags, xFlags, x3);
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, 7);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 5:
INST_NAME("IMUL AL, Eb");
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
@ -3570,7 +3575,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, 15);
LSRxw(x3, xRAX, 7);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
@ -3595,16 +3600,24 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BFIx(xRAX, x3, 0, 8);
BFIx(xRAX, x4, 8, 8);
SET_DFNONE();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_CF) {BFCw(xFlags, F_CF, 1);}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);} //mask=0x40
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);} //mask=0x04
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
case 7:
INST_NAME("IDIV Eb");
SKIPTEST(x1);
SETFLAGS(X_ALL, SF_SET);
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL, SF_SET);
} else if(BOX64ENV(cputype)) {
SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
}
GETSEB(x1, 0);
if(BOX64ENV(dynarec_div0)) {
CBNZw_MARK3(ed);
@ -3621,12 +3634,13 @@ 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();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
if(!BOX64ENV(dynarec_safeflags)) {
SET_DFNONE();
}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && BOX64ENV(cputype)) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
}
break;
@ -3656,7 +3670,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 4:
INST_NAME("MUL EAX, Ed");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETED(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@ -3668,29 +3686,28 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVw_REG(xRAX, xRDX);
LSRx(xRDX, xRDX, 32);
}
UFLAG_IF {
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSxw_U12(xRDX, 0);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSxw_U12(xRDX, 0);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
IFX(X_AF | X_PF | X_ZF | X_SF)
if (BOX64ENV(dynarec_test)) {
// to avoid noise during test
MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
BICw(xFlags, xFlags, x3);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 5:
INST_NAME("IMUL EAX, Ed");
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
@ -3804,16 +3821,24 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
}
SET_DFNONE();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_CF) {BFCw(xFlags, F_CF, 1);}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);} //mask=0x40
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);} //mask=0x04
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
case 7:
INST_NAME("IDIV Ed");
SKIPTEST(x1);
SETFLAGS(X_ALL, SF_SET);
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL, SF_SET);
} else if(BOX64ENV(cputype)) {
SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
}
if(!rex.w) {
GETSEDw(0);
if(BOX64ENV(dynarec_div0)) {
@ -3881,12 +3906,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
if(!BOX64ENV(dynarec_safeflags)) {
SET_DFNONE();
}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && BOX64ENV(cputype)) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
}
break;

View File

@ -1996,7 +1996,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xAF:
INST_NAME("IMUL Gd, Ed");
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);

View File

@ -1334,7 +1334,11 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 4:
INST_NAME("MUL EAX, Ed");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETEDO(x6, 0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@ -1346,29 +1350,28 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVw_REG(xRAX, xRDX);
LSRx(xRDX, xRDX, 32);
}
UFLAG_IF {
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSxw_U12(xRDX, 0);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSxw_U12(xRDX, 0);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
IFX(X_AF | X_PF | X_ZF | X_SF)
if (BOX64ENV(dynarec_test)) {
// to avoid noise during test
MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
BICw(xFlags, xFlags, x3);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 5:
INST_NAME("IMUL EAX, Ed");
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
@ -1471,16 +1474,24 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
}
SET_DFNONE();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_CF) {BFCw(xFlags, F_CF, 1);}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);} //mask=0x40
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);} //mask=0x04
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
case 7:
INST_NAME("IDIV Ed");
NOTEST(x1);
SETFLAGS(X_ALL, SF_SET);
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL, SF_SET);
} else if(BOX64ENV(cputype)) {
SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
}
if(!rex.w) {
GETSEDOw(x6, 0);
MOVw_REG(x3, xRAX);
@ -1542,12 +1553,13 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
if(!BOX64ENV(dynarec_safeflags)) {
SET_DFNONE();
}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && BOX64ENV(cputype)) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
}
break;

View File

@ -1436,35 +1436,38 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 4:
INST_NAME("MUL AX, Ew");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETEW(x1, 0);
UXTHw(x2, xRAX);
MULw(x1, x2, x1);
BFIz(xRAX, x1, 0, 16);
BFXILx(xRDX, x1, 16, 16);
UFLAG_IF {
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSw_REG_LSR(xZR, x1, 16);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSw_REG_LSR(xZR, x1, 16);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
IFX(X_AF | X_PF | X_ZF | X_SF)
if (BOX64ENV(dynarec_test)) {
// to avoid noise during test
MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
BICw(xFlags, xFlags, x3);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, 15);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 5:
INST_NAME("IMUL AX, Ew");
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
@ -1515,16 +1518,24 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BFIz(xRAX, x3, 0, 16);
BFIz(xRDX, x4, 0, 16);
SET_DFNONE();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_CF) {BFCw(xFlags, F_CF, 1);}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);} //mask=0x40
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);} //mask=0x04
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
case 7:
INST_NAME("IDIV Ew");
SKIPTEST(x1);
SETFLAGS(X_ALL, SF_SET);
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL, SF_SET);
} else if(BOX64ENV(cputype)) {
SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
}
GETSEW(x1, 0);
if(BOX64ENV(dynarec_div0)) {
CBNZw_MARK3(ed);
@ -1542,12 +1553,13 @@ 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();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
if(!BOX64ENV(dynarec_safeflags)) {
SET_DFNONE();
}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && BOX64ENV(cputype)) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
}
break;

View File

@ -1466,7 +1466,11 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 4:
INST_NAME("MUL EAX, Ed");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETED32(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
@ -1478,29 +1482,28 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVw_REG(xRAX, xRDX);
LSRx(xRDX, xRDX, 32);
}
UFLAG_IF {
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSxw_U12(xRDX, 0);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
SET_DFNONE();
IFX(X_CF|X_OF) {
CMPSxw_U12(xRDX, 0);
CSETw(x3, cNE);
IFX(X_CF) {
BFIw(xFlags, x3, F_CF, 1);
}
IFX(X_OF) {
BFIw(xFlags, x3, F_OF, 1);
}
IFX(X_AF | X_PF | X_ZF | X_SF)
if (BOX64ENV(dynarec_test)) {
// to avoid noise during test
MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF));
BICw(xFlags, xFlags, x3);
}
}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && !BOX64ENV(cputype)) {
LSRxw(x3, xRAX, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 5:
INST_NAME("IMUL EAX, Ed");
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
@ -1572,16 +1575,24 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
}
SET_DFNONE();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_CF) {BFCw(xFlags, F_CF, 1);}
IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 26, 0);} //mask=0x40
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && !BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 30, 0);} //mask=0x04
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
case 7:
INST_NAME("IDIV Ed");
NOTEST(x1);
SETFLAGS(X_ALL, SF_SET);
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL, SF_SET);
} else if(BOX64ENV(cputype)) {
SETFLAGS(X_SF|X_PF|X_ZF|X_AF, SF_SET);
}
if(!rex.w) {
GETSED32w(0);
MOVw_REG(x3, xRAX);
@ -1613,12 +1624,13 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVx_REG(xRAX, x2);
}
}
SET_DFNONE();
IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF)
if (BOX64ENV(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);
}
if(!BOX64ENV(dynarec_safeflags)) {
SET_DFNONE();
}
IFX2(X_AF, && BOX64ENV(cputype)) {ORRw_mask(xFlags, xFlags, 28, 0);} //mask=0x10
IFX2(X_ZF, && BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);}
IFX2(X_SF, && BOX64ENV(cputype)) {BFCw(xFlags, F_SF, 1);}
IFX2(X_PF, && BOX64ENV(cputype)) {BFCw(xFlags, F_PF, 1);}
break;
}
break;

View File

@ -521,9 +521,12 @@ uint8_t rcl8(x64emu_t *emu, uint8_t d, uint8_t s)
CONDITIONAL_SET_FLAG(cf, F_CF);
/* OVERFLOW is set *IFF* cnt==1, then it is the
xor of CF and the most significant bit. Blecck. */
CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF);
}
if(BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF);
else
CONDITIONAL_SET_FLAG((XOR2(d >> 6)), F_OF);
} else if(s && BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 7)) & 0x1, F_OF);
return (uint8_t)res;
}
@ -547,7 +550,8 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s)
CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF);
else
CONDITIONAL_SET_FLAG((XOR2(d >> 14)), F_OF);
}
} else if(s && BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 15)) & 0x1, F_OF);
return (uint16_t)res;
}
@ -679,9 +683,9 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s)
/* set the new carry flag, based on the variable "cf" */
CONDITIONAL_SET_FLAG(cf, F_CF);
if(BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((XOR2(res >> 6)), F_OF);
}
if(s && BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((XOR2(res >> 6)), F_OF);
return (uint8_t)res;
}
@ -709,9 +713,9 @@ uint16_t rcr16(x64emu_t *emu, uint16_t d, uint8_t s)
res |= 1 << (16 - cnt);
}
CONDITIONAL_SET_FLAG(cf, F_CF);
if(BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((XOR2(res >> 14)), F_OF);
}
if(s && BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((XOR2(res >> 14)), F_OF);
return (uint16_t)res;
}
@ -741,9 +745,9 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s)
res |= 1 << (32 - cnt);
}
CONDITIONAL_SET_FLAG(cf, F_CF);
if(BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((XOR2(res >> 30)), F_OF);
}
if(s && BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((XOR2(res >> 30)), F_OF);
return res;
}
@ -773,9 +777,9 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s)
res |= 1LL << (64 - cnt);
}
CONDITIONAL_SET_FLAG(cf, F_CF);
if(BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((XOR2(res >> 62)), F_OF);
}
if(s && BOX64ENV(cputype))
CONDITIONAL_SET_FLAG((XOR2(res >> 62)), F_OF);
return res;
}
/****************************************************************************