Skip to content

Commit

Permalink
[ARM64_DYNAREC] Continue work on UD flags
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed Feb 17, 2025
1 parent 9ec7930 commit d49fc43
Show file tree
Hide file tree
Showing 9 changed files with 539 additions and 397 deletions.
79 changes: 48 additions & 31 deletions src/dynarec/arm64/dynarec_arm64_00.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0x69:
INST_NAME("IMUL Gd, Ed, Id");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
nextop = F8;
GETGD;
GETED(4);
Expand Down Expand Up @@ -934,13 +938,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MULxw(gd, ed, x4);
}
}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {
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, gd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
IFX(X_PF) emit_pf(dyn, ninst, gd, x3);
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, gd, x3);
break;
case 0x6A:
INST_NAME("PUSH Ib");
Expand All @@ -951,7 +955,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0x6B:
INST_NAME("IMUL Gd, Ed, Ib");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
nextop = F8;
GETGD;
GETED(1);
Expand Down Expand Up @@ -997,13 +1005,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MULxw(gd, ed, x4);
}
}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {
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, gd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
IFX(X_PF) emit_pf(dyn, ninst, gd, x3);
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, gd, x3);
break;
case 0x6C:
case 0x6D:
Expand Down Expand Up @@ -2981,17 +2989,20 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
UFLAG_DF(x2, d_none);
}
GETED(0);
UFLAG_IF {
if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
CBZw_NEXT(x3);
if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
CBZw_NEXT(x3);
IFX2(X_OF, && !BOX64ENV(cputype)) {
LSRxw(x4, ed, rex.w?62:30);
EORw_REG_LSR(x4, x4, x4, 1);
BFIw(xFlags, x4, F_OF, 1);
}
MOV64xw(x4, (rex.w?64:32));
SUBx_REG(x3, x4, x3);
RORxw_REG(ed, ed, x3);
WBACK;
IFX(X_OF) {
EORxw_REG_LSR(x3, ed, ed, rex.w?63:31);
BFIw(xFlags, x3, F_OF, 1);
IFX2(X_OF, && BOX64ENV(cputype)) {
EORxw_REG_LSR(x4, ed, ed, rex.w?63:31);
BFIw(xFlags, x4, F_OF, 1);
}
IFX(X_CF) {
BFIw(xFlags, ed, F_CF, 1);
Expand All @@ -3010,10 +3021,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
SET_DFNONE();
GETED(0);
UFLAG_IF {
if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
CBZw_NEXT(x3);
}
if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);}
CBZw_NEXT(x3);
IFX2(X_OF, && !BOX64ENV(cputype)) {
EORxw_REG_LSR(x4, ed, ed, rex.w?63:31);
BFIw(xFlags, x4, F_OF, 1);
Expand Down Expand Up @@ -3537,7 +3546,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 5:
INST_NAME("IMUL AL, Eb");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
GETSEB(x1, 0);
SXTBw(x2, xRAX);
MULw(x1, x2, x1);
Expand All @@ -3554,14 +3567,14 @@ 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) {BFCw(xFlags, F_AF, 1);}
IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {
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);
}
IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3);
break;
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 6:
INST_NAME("DIV Eb");
SETFLAGS(X_ALL, SF_SET);
Expand Down Expand Up @@ -3677,7 +3690,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 5:
INST_NAME("IMUL EAX, Ed");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags)>1 && 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;
Expand All @@ -3700,13 +3717,13 @@ 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) {BFCw(xFlags, F_AF, 1);}
IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {
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);
}
IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3);
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3);
break;
case 6:
INST_NAME("DIV Ed");
Expand Down
117 changes: 49 additions & 68 deletions src/dynarec/arm64/dynarec_arm64_0f.c
Original file line number Diff line number Diff line change
Expand Up @@ -1722,8 +1722,11 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xA3:
INST_NAME("BT Ed, Gd");
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
SET_DFNONE();
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
} else {
SETFLAGS(X_CF, SF_SUBSET);
}
nextop = F8;
GETGD;
if(MODREG) {
Expand All @@ -1746,12 +1749,6 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
LSRxw_REG(x4, ed, x2);
BFIw(xFlags, x4, F_CF, 1);
}
if (BOX64ENV(dynarec_test)) {
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
}
break;
case 0xA4:
nextop = F8;
Expand Down Expand Up @@ -1803,8 +1800,11 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin

case 0xAB:
INST_NAME("BTS Ed, Gd");
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
SET_DFNONE();
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
} else {
SETFLAGS(X_CF, SF_SUBSET);
}
nextop = F8;
GETGD;
if(MODREG) {
Expand Down Expand Up @@ -1836,12 +1836,6 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STxw(ed, wback, fixedaddress);
SMWRITE();
}
if (BOX64ENV(dynarec_test)) {
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
}
break;
case 0xAC:
nextop = F8;
Expand Down Expand Up @@ -2001,7 +1995,11 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 0xAF:
INST_NAME("IMUL Gd, Ed");
SETFLAGS(X_ALL, SF_SET);
if(BOX64ENV(dynarec_safeflags)>1 && BOX64ENV(cputype)) {
SETFLAGS(X_OF|X_CF, SF_SET);
} else {
SETFLAGS(X_ALL, SF_SET);
}
nextop = F8;
GETGD;
GETED(0);
Expand Down Expand Up @@ -2045,13 +2043,13 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MULxw(gd, gd, ed);
}
}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);}
IFX(X_SF) {
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, gd, rex.w?63:31);
BFIw(xFlags, x3, F_SF, 1);
}
IFX(X_PF) emit_pf(dyn, ninst, gd, x3);
IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, gd, x3);
break;

case 0xB1:
Expand Down Expand Up @@ -2083,7 +2081,11 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin

case 0xB3:
INST_NAME("BTR Ed, Gd");
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
} else {
SETFLAGS(X_CF, SF_SUBSET);
}
SET_DFNONE();
nextop = F8;
GETGD;
Expand Down Expand Up @@ -2116,12 +2118,6 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STxw(ed, wback, fixedaddress);
SMWRITE();
}
if (BOX64ENV(dynarec_test)) {
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
}
break;

case 0xB6:
Expand Down Expand Up @@ -2163,8 +2159,11 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
switch((nextop>>3)&7) {
case 4:
INST_NAME("BT Ed, Ib");
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
SET_DFNONE();
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
} else {
SETFLAGS(X_CF, SF_SUBSET);
}
gd = x2;
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
Expand All @@ -2179,17 +2178,14 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
IFX(X_CF) {
BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
}
if (BOX64ENV(dynarec_test)) {
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
}
break;
case 5:
INST_NAME("BTS Ed, Ib");
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
SET_DFNONE();
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
} else {
SETFLAGS(X_CF, SF_SUBSET);
}
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
wback = 0;
Expand All @@ -2210,17 +2206,14 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STxw(ed, wback, fixedaddress);
SMWRITE();
}
if (BOX64ENV(dynarec_test)) {
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
}
break;
case 6:
INST_NAME("BTR Ed, Ib");
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
SET_DFNONE();
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
} else {
SETFLAGS(X_CF, SF_SUBSET);
}
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
wback = 0;
Expand All @@ -2240,17 +2233,14 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STxw(ed, wback, fixedaddress);
SMWRITE();
}
if (BOX64ENV(dynarec_test)) {
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
}
break;
case 7:
INST_NAME("BTC Ed, Ib");
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
SET_DFNONE();
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
} else {
SETFLAGS(X_CF, SF_SUBSET);
}
if(MODREG) {
ed = TO_NAT((nextop & 7) + (rex.b << 3));
wback = 0;
Expand All @@ -2271,21 +2261,18 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STxw(ed, wback, fixedaddress);
SMWRITE();
}
if (BOX64ENV(dynarec_test)) {
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
}
break;
default:
DEFAULT;
}
break;
case 0xBB:
INST_NAME("BTC Ed, Gd");
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
SET_DFNONE();
if(!BOX64ENV(dynarec_safeflags)) {
SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
} else {
SETFLAGS(X_CF, SF_SUBSET);
}
nextop = F8;
GETGD;
if(MODREG) {
Expand Down Expand Up @@ -2317,12 +2304,6 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STxw(ed, wback, fixedaddress);
SMWRITE();
}
if (BOX64ENV(dynarec_test)) {
IFX(X_OF) {BFCw(xFlags, F_OF, 1);}
IFX(X_SF) {BFCw(xFlags, F_SF, 1);}
IFX(X_AF) {BFCw(xFlags, F_AF, 1);}
IFX(X_PF) {BFCw(xFlags, F_PF, 1);}
}
break;
case 0xBC:
INST_NAME("BSF Gd, Ed");
Expand Down
Loading

0 comments on commit d49fc43

Please sign in to comment.