diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-04-22 18:59:57 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-04-22 18:59:57 +0200 |
| commit | 17b7ec6358b58fc887135be78d368642397fc839 (patch) | |
| tree | 9aa4c121589bfd3066a678af4618272ae7717646 /src | |
| parent | 73c3190c86f72c542fc0b60e7ee8d69e28eb2546 (diff) | |
| download | box64-17b7ec6358b58fc887135be78d368642397fc839.tar.gz box64-17b7ec6358b58fc887135be78d368642397fc839.zip | |
[ARM64_DYNAREC] Small optim on flags handling
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 62 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 10 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_64.c | 18 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66.c | 14 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_660f.c | 9 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_67.c | 14 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.c | 4 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 2 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_pass0.h | 4 | ||||
| -rw-r--r-- | src/dynarec/dynarec_private.h | 2 |
10 files changed, 69 insertions, 70 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 638c41de..1b5915b8 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -401,7 +401,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("DAA"); MESSAGE(LOG_DUMP, "Need Optimization DAA\n"); READFLAGS(X_AF|X_CF); - SETFLAGS(X_ALL, SF_SET); + SETFLAGS(X_ALL, SF_SET_DF); UXTBx(x1, xRAX); CALL_(daa8, x1, 0); BFIz(xRAX, x1, 0, 8); @@ -466,7 +466,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("DAS"); MESSAGE(LOG_DUMP, "Need Optimization DAS\n"); READFLAGS(X_AF|X_CF); - SETFLAGS(X_ALL, SF_SET); + SETFLAGS(X_ALL, SF_SET_DF); UXTBx(x1, xRAX); CALL_(das8, x1, 0); BFIz(xRAX, x1, 0, 8); @@ -531,7 +531,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("AAA"); MESSAGE(LOG_DUMP, "Need Optimization AAA\n"); READFLAGS(X_AF); - SETFLAGS(X_ALL, SF_SET); + SETFLAGS(X_ALL, SF_SET_DF); UXTHx(x1, xRAX); CALL_(aaa16, x1, 0); BFIz(xRAX, x1, 0, 16); @@ -599,7 +599,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("AAS"); MESSAGE(LOG_DUMP, "Need Optimization AAS\n"); READFLAGS(X_AF); - SETFLAGS(X_ALL, SF_SET); + SETFLAGS(X_ALL, SF_SET_DF); UXTHw(x1, xRAX); CALL_(aas16, x1, 0); BFIx(xRAX, x1, 0, 16); @@ -973,7 +973,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x6C: case 0x6D: INST_NAME(opcode == 0x6C ? "INSB" : "INSD"); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_priv, -1); @@ -985,7 +985,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x6E: case 0x6F: INST_NAME(opcode == 0x6C ? "OUTSB" : "OUTSD"); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_priv, -1); @@ -2076,7 +2076,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f; - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); GETEDW(x4, x1, 1); u8 = F8; MOV32w(x2, u8); @@ -2088,7 +2088,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f; - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); GETEDW(x4, x1, 1); u8 = F8; MOV32w(x2, u8); @@ -2157,7 +2157,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xC2: INST_NAME("RETN"); - //SETFLAGS(X_ALL, SF_SET); // Hack, set all flags (to an unknown state...) + //SETFLAGS(X_ALL, SF_SET_NODF); // Hack, set all flags (to an unknown state...) if(box64_dynarec_safeflags) { READFLAGS(X_PEND); // lets play safe here too } @@ -2169,7 +2169,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xC3: INST_NAME("RET"); - // SETFLAGS(X_ALL, SF_SET); // Hack, set all flags (to an unknown state...) + // SETFLAGS(X_ALL, SF_SET_NODF); // Hack, set all flags (to an unknown state...) if(box64_dynarec_safeflags) { READFLAGS(X_PEND); // so instead, force the deferred flags, so it's not too slow, and flags are not lost } @@ -2285,7 +2285,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xCC: - SETFLAGS(X_ALL, SF_SET); // Hack, set all flags (to an unknown state...) + SETFLAGS(X_ALL, SF_SET_NODF); // Hack, set all flags (to an unknown state...) NOTEST(x1); if(PK(0)=='S' && PK(1)=='C') { addr+=2; @@ -2383,7 +2383,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin jump_to_epilog(dyn, 0, xRIP, ninst); } else { INST_NAME("INT n"); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_int, -1); @@ -2396,7 +2396,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xCF: INST_NAME("IRET"); - SETFLAGS(X_ALL, SF_SET); // Not a hack, EFLAGS are restored + SETFLAGS(X_ALL, SF_SET_NODF); // Not a hack, EFLAGS are restored BARRIER(BARRIER_FLOAT); iret_to_epilog(dyn, ninst, rex.w); *need_epilog = 0; @@ -2480,7 +2480,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCL Ed, 1"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); MOV32w(x2, 1); GETEDW(x4, x1, 0); CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4); @@ -2490,7 +2490,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCR Ed, 1"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); MOV32w(x2, 1); GETEDW(x4, x1, 0); CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4); @@ -2580,7 +2580,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin READFLAGS(X_CF); if(box64_dynarec_safeflags>1) MAYSETFLAGS(); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); ANDSw_mask(x2, xRCX, 0, 0b00100); GETEB(x1, 0); CALL_(rcl8, x1, x3); @@ -2592,7 +2592,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin READFLAGS(X_CF); if(box64_dynarec_safeflags>1) MAYSETFLAGS(); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); ANDSw_mask(x2, xRCX, 0, 0b00100); GETEB(x1, 0); CALL_(rcr8, x1, x3); @@ -2726,7 +2726,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCL Ed, CL"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); if(box64_dynarec_safeflags>1) MAYSETFLAGS(); if(rex.w) { @@ -2744,7 +2744,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCR Ed, CL"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); if(box64_dynarec_safeflags>1) MAYSETFLAGS(); if(rex.w) { @@ -2845,7 +2845,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xD4: if(rex.is32bits) { INST_NAME("AAM Ib"); - SETFLAGS(X_ALL, SF_SET); + SETFLAGS(X_ALL, SF_SET_DF); UBFXx(x1, xRAX, 0, 8); // load AL u8 = F8; MOV32w(x2, u8); @@ -2858,7 +2858,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xD5: if(rex.is32bits) { INST_NAME("AAD Ib"); - SETFLAGS(X_ALL, SF_SET); + SETFLAGS(X_ALL, SF_SET_DF); UBFXx(x1, xRAX, 0, 16); // load AX u8 = F8; MOV32w(x2, u8); @@ -2954,7 +2954,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xE6: /* OUT Ib, AL */ case 0xE7: /* OUT Ib, EAX */ INST_NAME(opcode==0xE4?"IN AL, Ib":(opcode==0xE5?"IN EAX, Ib":(opcode==0xE6?"OUT Ib, AL":"OUT Ib, EAX"))); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state u8 = F8; GETIP(ip); STORE_XEMU_CALL(xRIP); @@ -2982,7 +2982,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin #endif switch(tmp) { case 3: - SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags to "dont'care" state if(dyn->last_ip && (addr-dyn->last_ip<0x1000)) { ADDx_U12(x2, xRIP, addr-dyn->last_ip); } else { @@ -3038,7 +3038,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin if((box64_dynarec_safeflags>1) || (ninst && dyn->insts[ninst-1].x64.set_flags)) { READFLAGS(X_PEND); // that's suspicious } else { - SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags to "dont'care" state } // regular call if(box64_dynarec_callret && box64_dynarec_bigblock>1) { @@ -3123,7 +3123,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xEE: /* OUT DX, AL */ case 0xEF: /* OUT DX, EAX */ INST_NAME(opcode==0xEC?"IN AL, DX":(opcode==0xED?"IN EAX, DX":(opcode==0xEE?"OUT DX, AL":"OUT DX, EAX"))); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_priv, -1); @@ -3139,7 +3139,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xF4: INST_NAME("HLT"); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_priv, -1); @@ -3202,6 +3202,7 @@ 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) { @@ -3223,6 +3224,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("IDIV Eb"); SKIPTEST(x1); SETFLAGS(X_ALL, SF_SET); + SET_DFNONE(x1); GETSEB(x1, 0); if(box64_dynarec_div0) { CBNZw_MARK3(ed); @@ -3389,8 +3391,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("IDIV Ed"); SKIPTEST(x1); SETFLAGS(X_ALL, SF_SET); + SET_DFNONE(x2) if(!rex.w) { - SET_DFNONE(x2) GETSEDw(0); if(box64_dynarec_div0) { CBNZx_MARK3(wb); @@ -3413,7 +3415,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)==0x48 && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) { - SET_DFNONE(x2) GETED(0); if(box64_dynarec_div0) { CBNZx_MARK3(ed); @@ -3456,7 +3457,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SDIVx(x2, xRAX, ed); MSUBx(xRDX, x2, ed, xRAX); MOVx_REG(xRAX, x2); - SET_DFNONE(x2) } } break; @@ -3477,7 +3477,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xFA: /* STI */ case 0xFB: /* CLI */ INST_NAME(opcode==0xFA?"CLI":"STI"); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_priv, -1); @@ -3541,7 +3541,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin { READFLAGS(X_PEND); // that's suspicious } else { - SETFLAGS(X_ALL, SF_SET); //Hack to put flag in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); //Hack to put flag in "don't care" state } GETEDz(0); if(box64_dynarec_callret && box64_dynarec_bigblock>1) { diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 8e8ec00e..35caadcb 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -69,7 +69,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch(nextop) { case 0xD0: INST_NAME("FAKE xgetbv"); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_ud, -1); @@ -166,7 +166,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x09: INST_NAME("WBINVD"); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_ud, -1); @@ -178,7 +178,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x0B: INST_NAME("UD2"); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_ud, -1); @@ -202,7 +202,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x0E: INST_NAME("femms"); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); CALL(native_ud, -1); @@ -486,7 +486,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin // no special check... case 0x2F: if(opcode==0x2F) {INST_NAME("COMISS Gx, Ex");} else {INST_NAME("UCOMISS Gx, Ex");} - SETFLAGS(X_ALL, SF_SET); + SETFLAGS(X_ALL, SF_SET_NODF); nextop = F8; GETGX(v0, 0); GETEXSS(s0, 0, 0); diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c index 028fc343..a7bc2aef 100644 --- a/src/dynarec/arm64/dynarec_arm64_64.c +++ b/src/dynarec/arm64/dynarec_arm64_64.c @@ -784,7 +784,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCL Ed, 1"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); MOV32w(x2, 1); GETEDO(x6, 0); if(wback) {ADDx_REG(x6, x6, wback); wback=x6;} @@ -796,7 +796,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCR Ed, 1"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); MOV32w(x2, 1); GETEDO(x6, 0); if(wback) {ADDx_REG(x6, x6, wback); wback=x6;} @@ -887,7 +887,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCL Ed, CL"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); if(rex.w) { ANDSx_mask(x2, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f } else { @@ -904,7 +904,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCR Ed, CL"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); if(rex.w) { ANDSx_mask(x2, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f } else { @@ -1031,8 +1031,8 @@ 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) { - SET_DFNONE(x2); GETEDO(x6, 0); if(box64_dynarec_div0) { CBNZx_MARK3(ed); @@ -1059,7 +1059,6 @@ uintptr_t dynarec64_64(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); GETEDO(x6, 0); if(box64_dynarec_div0) { CBNZx_MARK3(ed); @@ -1094,7 +1093,6 @@ uintptr_t dynarec64_64(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); } } break; @@ -1102,8 +1100,8 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("IDIV Ed"); NOTEST(x1); SETFLAGS(X_ALL, SF_SET); + SET_DFNONE(x2) if(!rex.w) { - SET_DFNONE(x2) GETSEDOw(x6, 0); MOVw_REG(x3, xRAX); ORRx_REG_LSL(x3, x3, xRDX, 32); @@ -1126,7 +1124,6 @@ uintptr_t dynarec64_64(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)==0x48 && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) { - SET_DFNONE(x2) GETEDO(x6, 0); if(box64_dynarec_div0) { CBNZx_MARK3(ed); @@ -1163,7 +1160,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SDIVx(x2, xRAX, ed); MSUBx(xRDX, x2, ed, xRAX); MOVx_REG(xRAX, x2); - SET_DFNONE(x2) } } break; @@ -1196,7 +1192,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin { READFLAGS(X_PEND); // that's suspicious } else { - SETFLAGS(X_ALL, SF_SET); //Hack to put flag in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); //Hack to put flag in "don't care" state } GETEDOz(x6, 0); if(box64_dynarec_callret && box64_dynarec_bigblock>1) { diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c index 8945b365..e6761c63 100644 --- a/src/dynarec/arm64/dynarec_arm64_66.c +++ b/src/dynarec/arm64/dynarec_arm64_66.c @@ -978,7 +978,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f; - SETFLAGS(X_OF | X_CF, SF_SET); + SETFLAGS(X_OF | X_CF, SF_SET_DF); GETEW(x1, 1); u8 = F8; MOV32w(x2, u8); @@ -990,7 +990,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); u8 = geted_ib(dyn, addr, ninst, nextop) & 0x1f; - SETFLAGS(X_OF | X_CF, SF_SET); + SETFLAGS(X_OF | X_CF, SF_SET_DF); GETEW(x1, 1); u8 = F8; MOV32w(x2, u8); @@ -1078,7 +1078,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCL Ew, 1"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); MOV32w(x2, 1); GETEW(x1, 0); CALL_(rcl16, x1, x3); @@ -1088,7 +1088,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCR Ew, 1"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); MOV32w(x2, 1); GETEW(x1, 0); CALL_(rcr16, x1, x3); @@ -1179,7 +1179,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin READFLAGS(X_CF); if(box64_dynarec_safeflags>1) MAYSETFLAGS(); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); ANDw_mask(x2, xRCX, 0, 0b00100); GETEW(x1, 0); CALL_(rcl16, x1, x3); @@ -1191,7 +1191,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin READFLAGS(X_CF); if(box64_dynarec_safeflags>1) MAYSETFLAGS(); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); ANDw_mask(x2, xRCX, 0, 0b00100); GETEW(x1, 0); CALL_(rcr16, x1, x3); @@ -1299,6 +1299,7 @@ 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); @@ -1321,6 +1322,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("IDIV Ew"); SKIPTEST(x1); SETFLAGS(X_ALL, SF_SET); + SET_DFNONE(x1); GETSEW(x1, 0); if(box64_dynarec_div0) { CBNZw_MARK3(ed); diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index bed76d36..2b9a413e 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -1229,7 +1229,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n case 0x60: INST_NAME("PCMPESTRM Gx, Ex, Ib"); - SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET); + SETFLAGS(X_ALL, SF_SET_DF); nextop = F8; GETG; sse_forget_reg(dyn, ninst, gd); @@ -1284,11 +1284,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n break; case 0x61: INST_NAME("PCMPESTRI Gx, Ex, Ib"); - SETFLAGS(X_ALL, SF_SET); nextop = F8; GETG; u8 = geted_ib(dyn, addr, ninst, nextop); if((u8&0b1100)==0b1000) { + SETFLAGS(X_ALL, SF_SET); // this case is (un)signed word, equal each GETGX(v0, 0); GETEX(v1, 0, 1); @@ -1397,6 +1397,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } } } else { + SETFLAGS(X_ALL, SF_SET_DF); if(gd>7) // no need to reflect cache as xmm0-xmm7 will be saved before the function call anyway sse_reflect_reg(dyn, ninst, gd); ADDx_U12(x3, xEmu, offsetof(x64emu_t, xmm[gd])); @@ -1433,7 +1434,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n break; case 0x62: INST_NAME("PCMPISTRM Gx, Ex, Ib"); - SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET); + SETFLAGS(X_ALL, SF_SET_DF); nextop = F8; GETG; sse_forget_reg(dyn, ninst, gd); @@ -1486,7 +1487,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n break; case 0x63: INST_NAME("PCMPISTRI Gx, Ex, Ib"); - SETFLAGS(X_OF|X_CF|X_AF|X_ZF|X_SF|X_PF, SF_SET); + SETFLAGS(X_ALL, SF_SET_DF); nextop = F8; GETG; if(gd>7) diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c index 82dd7a27..e1a3fc4c 100644 --- a/src/dynarec/arm64/dynarec_arm64_67.c +++ b/src/dynarec/arm64/dynarec_arm64_67.c @@ -936,7 +936,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCL Ed, Ib"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); GETED32W(x4, x1, 1); u8 = F8; MOV32w(x2, u8); @@ -947,7 +947,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("RCR Ed, Ib"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); - SETFLAGS(X_OF|X_CF, SF_SET); + SETFLAGS(X_OF|X_CF, SF_SET_DF); GETED32W(x4, x1, 1); u8 = F8; MOV32w(x2, u8); @@ -1160,8 +1160,8 @@ 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) { - SET_DFNONE(x2); GETED32(0); MOVw_REG(x3, xRAX); ORRx_REG_LSL(x3, x3, xRDX, 32); @@ -1178,7 +1178,6 @@ uintptr_t dynarec64_67(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); GETED32(0); UDIVx(x2, xRAX, ed); MSUBx(xRDX, x2, ed, xRAX); @@ -1193,7 +1192,6 @@ uintptr_t dynarec64_67(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); } } break; @@ -1201,8 +1199,8 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("IDIV Ed"); NOTEST(x1); SETFLAGS(X_ALL, SF_SET); + SET_DFNONE(x2); if(!rex.w) { - SET_DFNONE(x2) GETSED32w(0); MOVw_REG(x3, xRAX); ORRx_REG_LSL(x3, x3, xRDX, 32); @@ -1215,7 +1213,6 @@ uintptr_t dynarec64_67(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)==0x48 && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) { - SET_DFNONE(x2) GETED32(0); SDIVx(x2, xRAX, ed); MSUBx(xRDX, x2, ed, xRAX); @@ -1232,7 +1229,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SDIVx(x2, xRAX, ed); MSUBx(xRDX, x2, ed, xRAX); MOVx_REG(xRAX, x2); - SET_DFNONE(x2) } } break; @@ -1249,7 +1245,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin { READFLAGS(X_PEND); // that's suspicious } else { - SETFLAGS(X_ALL, SF_SET); //Hack to put flag in "don't care" state + SETFLAGS(X_ALL, SF_SET_NODF); //Hack to put flag in "don't care" state } GETED32(0); if(box64_dynarec_callret && box64_dynarec_bigblock>1) { diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c index 69850eb6..b8eb06f2 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.c +++ b/src/dynarec/arm64/dynarec_arm64_helper.c @@ -776,7 +776,7 @@ void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int save if(saveflags) { LDRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags)); } - SET_NODF(); + //SET_NODF(); } void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w) @@ -822,7 +822,7 @@ void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w) fpu_popcache(dyn, ninst, x3, 1); LDRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags)); - SET_NODF(); + //SET_NODF(); } void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int segment) diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 665b27ee..617aecab 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -881,6 +881,8 @@ if(dyn->insts[ninst].x64.gen_flags) switch(B) { \ case SF_SUBSET: \ case SF_SET: dyn->f.pending = SF_SET; break; \ + case SF_SET_DF: dyn->f.pending = SF_SET; dyn->f.dfnone = 1; break; \ + case SF_SET_NODF: dyn->f.pending = SF_SET; dyn->f.dfnone = 0; break; \ case SF_PENDING: dyn->f.pending = SF_PENDING; break; \ case SF_SUBSET_PENDING: \ case SF_SET_PENDING: \ diff --git a/src/dynarec/arm64/dynarec_arm64_pass0.h b/src/dynarec/arm64/dynarec_arm64_pass0.h index d86981b3..e8a4b0a8 100644 --- a/src/dynarec/arm64/dynarec_arm64_pass0.h +++ b/src/dynarec/arm64/dynarec_arm64_pass0.h @@ -12,9 +12,9 @@ dyn->f.pending=SF_SET #define SETFLAGS(A,B) \ dyn->insts[ninst].x64.set_flags = A; \ - dyn->insts[ninst].x64.state_flags = B; \ + dyn->insts[ninst].x64.state_flags = (B)&~SF_DF; \ dyn->f.pending=(B)&SF_SET_PENDING; \ - dyn->f.dfnone=((B)&SF_SET)?1:0; + dyn->f.dfnone=((B)&SF_SET)?(((B)==SF_SET_NODF)?0:1):0; #define EMIT(A) dyn->native_size+=4 #define JUMP(A, C) add_jump(dyn, ninst); add_next(dyn, (uintptr_t)A); SMEND(); dyn->insts[ninst].x64.jmp = A; dyn->insts[ninst].x64.jmp_cond = C #define BARRIER(A) if(A!=BARRIER_MAYBE) {fpu_purgecache(dyn, ninst, 0, x1, x2, x3); dyn->insts[ninst].x64.barrier = A;} else dyn->insts[ninst].barrier_maybe = 1 diff --git a/src/dynarec/dynarec_private.h b/src/dynarec/dynarec_private.h index 0c1094d3..d5678c71 100644 --- a/src/dynarec/dynarec_private.h +++ b/src/dynarec/dynarec_private.h @@ -26,6 +26,8 @@ #define SF_SUBSET_PENDING (SF_SUBSET|SF_PENDING) #define SF_DF 8 #define SF_SET_DF (SF_SET|SF_DF) +#define SF_NODF 16 +#define SF_SET_NODF (SF_SET|SF_NODF) typedef struct instruction_x64_s { uintptr_t addr; //address of the instruction |