diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-02-21 11:40:08 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-02-21 11:40:15 +0100 |
| commit | e868c8923386b5f184458e84df4c1352b96a3221 (patch) | |
| tree | b9917b78dbfdd707df74796685c76892b2417bc7 /src | |
| parent | c517d7196d270c164b642e3ec9f043b5e66c259d (diff) | |
| download | box64-e868c8923386b5f184458e84df4c1352b96a3221.tar.gz box64-e868c8923386b5f184458e84df4c1352b96a3221.zip | |
[INTERP] Work on UD flags
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64primop.c | 294 | ||||
| -rw-r--r-- | src/emu/x64primop.h | 11 | ||||
| -rw-r--r-- | src/emu/x64run0f.c | 36 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 282 |
4 files changed, 308 insertions, 315 deletions
diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c index 8a17da5a..b201900f 100644 --- a/src/emu/x64primop.c +++ b/src/emu/x64primop.c @@ -491,7 +491,6 @@ uint8_t rcl8(x64emu_t *emu, uint8_t d, uint8_t s) 3) B_(n-1) <- cf 4) B_(n-2) .. B_0 <- b_7 .. b_(8-(n-1)) */ - res = d; if ((cnt = s % 9) != 0) { /* extract the new CARRY FLAG. */ /* CF <- b_(8-n) */ @@ -525,8 +524,11 @@ uint8_t rcl8(x64emu_t *emu, uint8_t d, uint8_t s) 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); + } else if(s) { + res = d; + if(BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 7)) & 0x1, F_OF); + } return (uint8_t)res; } @@ -536,7 +538,6 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s) CHECK_FLAGS(emu); s = s&0x1f; - res = d; if ((cnt = s % 17) != 0) { cf = (d >> (16 - cnt)) & 0x1; res = (d << cnt) & 0xffff; @@ -550,8 +551,11 @@ 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); + } else if(s) { + res = d; + if(BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 15)) & 0x1, F_OF); + } return (uint16_t)res; } @@ -792,18 +796,16 @@ uint8_t rol8(x64emu_t *emu, uint8_t d, uint8_t s) s = s&0x1f; if(!s) return d; + /* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */ + + if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d>>6), F_OF); if((cnt = s % 8) != 0) { d = (d << cnt) + ((d >> (8 - cnt)) & ((1 << cnt) - 1)); } CHECK_FLAGS(emu); - /* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */ - if(s == 1) { - CONDITIONAL_SET_FLAG((d + (d >> 7)) & 1, F_OF); - } else if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - } + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((d + (d >> 7)) & 1, F_OF); /* set new CF; note that it is the LSB of the result */ CONDITIONAL_SET_FLAG(d & 0x1, F_CF); @@ -818,19 +820,14 @@ uint16_t rol16(x64emu_t *emu, uint16_t d, uint8_t s) s = s&0x1f; if(!s) return d; + if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d>>14), F_OF); if((cnt = s % 16) != 0) { d = (d << cnt) + ((d >> (16 - cnt)) & ((1 << cnt) - 1)); } CHECK_FLAGS(emu); - /* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */ - if(s == 1) { - CONDITIONAL_SET_FLAG((d + (d >> 15)) & 1, F_OF); - } else if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - } + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((d + (d >> 15)) & 1, F_OF); - /* set new CF; note that it is the LSB of the result */ CONDITIONAL_SET_FLAG(d & 0x1, F_CF); return d; @@ -843,19 +840,14 @@ uint32_t rol32(x64emu_t *emu, uint32_t d, uint8_t s) s = s&0x1f; if(!s) return d; + if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d>>30), F_OF); if((cnt = s % 32) != 0) { d = (d << cnt) + ((d >> (32 - cnt)) & ((1 << cnt) - 1)); } CHECK_FLAGS(emu); - /* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */ - if(s == 1) { - CONDITIONAL_SET_FLAG((d + (d >> 31)) & 1, F_OF); - } else if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - } + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((d + (d >> 31)) & 1, F_OF); - /* set new CF; note that it is the LSB of the result */ CONDITIONAL_SET_FLAG(d & 0x1, F_CF); return d; @@ -868,19 +860,14 @@ uint64_t rol64(x64emu_t *emu, uint64_t d, uint8_t s) s = s&0x3f; if(!s) return d; + if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d>>62), F_OF); if((cnt = s % 64) != 0) { d = (d << cnt) + ((d >> (64 - cnt)) & ((1L << cnt) - 1)); } CHECK_FLAGS(emu); - /* OF flag is set if s == 1; OF = CF _XOR_ MSB of result */ - if(s == 1) { - CONDITIONAL_SET_FLAG((d + (d >> 63)) & 1, F_OF); - } else if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - } + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((d + (d >> 63)) & 1, F_OF); - /* set new CF; note that it is the LSB of the result */ CONDITIONAL_SET_FLAG(d & 0x1, F_CF); return d; @@ -897,17 +884,14 @@ uint8_t ror8(x64emu_t *emu, uint8_t d, uint8_t s) s = s&0x1f; if(!s) return d; + if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(((d >> 7)^d)&1, F_OF); + if((cnt = s % 8) != 0) { - d = (d << (8 - cnt)) + ((d >> (cnt)) & ((1 << (8 - cnt)) - 1)); + d = (d << (8 - cnt)) + ((d >> (cnt)) & ((1 << (8 - cnt)) - 1)); } CHECK_FLAGS(emu); - /* OF flag is set if s == 1; OF = MSB _XOR_ (M-1)SB of result */ - if(s == 1) { - CONDITIONAL_SET_FLAG(XOR2(d >> 6), F_OF); - } else if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - } + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d >> 6), F_OF); /* set new CF; note that it is the MSB of the result */ CONDITIONAL_SET_FLAG(d & (1 << 7), F_CF); @@ -922,17 +906,14 @@ uint16_t ror16(x64emu_t *emu, uint16_t d, uint8_t s) s = s&0x1f; if(!s) return d; + if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(((d >> 15)^d)&1, F_OF); + if((cnt = s % 16) != 0) { - d = (d << (16 - cnt)) + ((d >> (cnt)) & ((1 << (16 - cnt)) - 1)); + d = (d << (16 - cnt)) + ((d >> (cnt)) & ((1 << (16 - cnt)) - 1)); } CHECK_FLAGS(emu); - /* OF flag is set if s == 1; OF = MSB _XOR_ (M-1)SB of result */ - if(s == 1) { - CONDITIONAL_SET_FLAG(XOR2(d >> 14), F_OF); - } else if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - } + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d >> 14), F_OF); /* set new CF; note that it is the MSB of the result */ CONDITIONAL_SET_FLAG(d & (1 << 15), F_CF); @@ -947,17 +928,14 @@ uint32_t ror32(x64emu_t *emu, uint32_t d, uint8_t s) s = s&0x1f; if(!s) return d; + if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(((d >> 31)^d)&1, F_OF); + if((cnt = s % 32) != 0) { - d = (d << (32 - cnt)) + ((d >> (cnt)) & ((1 << (32 - cnt)) - 1)); + d = (d << (32 - cnt)) + ((d >> (cnt)) & ((1 << (32 - cnt)) - 1)); } CHECK_FLAGS(emu); - /* OF flag is set if s == 1; OF = MSB _XOR_ (M-1)SB of result */ - if(s == 1) { - CONDITIONAL_SET_FLAG(XOR2(d >> 30), F_OF); - } else if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - } + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d >> 30), F_OF); /* set new CF; note that it is the MSB of the result */ CONDITIONAL_SET_FLAG(d & (1 << 31), F_CF); @@ -972,17 +950,14 @@ uint64_t ror64(x64emu_t *emu, uint64_t d, uint8_t s) s = s&0x3f; if(!s) return d; + if(!BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(((d >> 63)^d)&1, F_OF); + if((cnt = s % 64) != 0) { - d = (d << (64 - cnt)) + ((d >> (cnt)) & ((1L << (64 - cnt)) - 1L)); + d = (d << (64 - cnt)) + ((d >> (cnt)) & ((1L << (64 - cnt)) - 1L)); } CHECK_FLAGS(emu); - /* OF flag is set if s == 1; OF = MSB _XOR_ (M-1)SB of result */ - if(s == 1) { - CONDITIONAL_SET_FLAG(XOR2(d >> 62), F_OF); - } else if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - } + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(d >> 62), F_OF); /* set new CF; note that it is the MSB of the result */ CONDITIONAL_SET_FLAG(d & (1L << 63), F_CF); @@ -1003,34 +978,38 @@ uint16_t shld16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s) return d; RESET_FLAGS(emu); if (s < 16) { - if (cnt > 0) { - res = (d << cnt) | (fill >> (16-cnt)); - cf = d & (1 << (16 - cnt)); - CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); - CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); - CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - } else { - res = d; - } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(((res ^ d) >> 15)&1, F_OF); - } else { - CLEAR_FLAG(F_OF); - } + res = (d << cnt) | (fill >> (16-cnt)); + cf = d & (1 << (16 - cnt)); + CONDITIONAL_SET_FLAG(cf, F_CF); + CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); + CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); + CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); } else { res = (fill << (cnt)) | (d >> (16 - cnt)); if(s==16) cf = d & 1; else cf = fill & (1 << (16 - cnt)); - CONDITIONAL_SET_FLAG(cf, F_CF); + if(BOX64ENV(cputype) && (s>16)) { + CLEAR_FLAG(F_CF); + } else { + CONDITIONAL_SET_FLAG(cf, F_CF); + } CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - CLEAR_FLAG(F_OF); } - if(BOX64ENV(dynarec_test)) + if (BOX64ENV(cputype)) { + if(s>15) + CONDITIONAL_SET_FLAG(ACCESS_FLAG(F_CF), F_OF); + else + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res>>15))&1, F_OF); + } else { + CONDITIONAL_SET_FLAG(XOR2(d>>14), F_OF); + } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); return (uint16_t)res; } @@ -1054,12 +1033,14 @@ uint32_t shld32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s) } else { res = d; } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(((res ^ d) >> 31)&1, F_OF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res>>31))&1, F_OF); } else { - CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(XOR2(d>>30), F_OF); } - if(BOX64ENV(dynarec_test)) + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); return res; } @@ -1083,12 +1064,14 @@ uint64_t shld64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s) } else { res = d; } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(((res ^ d) >> 63)&1, F_OF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res>>63))&1, F_OF); } else { - CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(XOR2(d>>62), F_OF); } - if(BOX64ENV(dynarec_test)) + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); return res; } @@ -1118,22 +1101,20 @@ uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s) res = d; } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(((res ^ d) >> 15)&1, F_OF); - } else { - CLEAR_FLAG(F_OF); - } } else { if(s==16) cf = d & (1 << 15); else cf = fill & (1 << (cnt - 1)); res = (fill >> cnt) | (d << (16 - cnt)); - CONDITIONAL_SET_FLAG(cf, F_CF); + if(BOX64ENV(cputype) && (s>16)) { + CLEAR_FLAG(F_CF); + } else { + CONDITIONAL_SET_FLAG(cf, F_CF); + } CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF); CONDITIONAL_SET_FLAG(res & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF); - CLEAR_FLAG(F_OF); #if 0 res = 0; CLEAR_FLAG(F_CF); @@ -1143,7 +1124,14 @@ uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s) CLEAR_FLAG(F_PF); #endif } - if(BOX64ENV(dynarec_test)) + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(XOR2(res>>14), F_OF); + } else { + CONDITIONAL_SET_FLAG((fill^(d>>15))&1, F_OF); + } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); return (uint16_t)res; } @@ -1167,12 +1155,14 @@ uint32_t shrd32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s) } else { res = d; } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(((res ^ d) >> 31)&1, F_OF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(XOR2(res>>30), F_OF); } else { - CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG((fill^(d>>31))&1, F_OF); } - if(BOX64ENV(dynarec_test)) + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); return res; } @@ -1197,12 +1187,14 @@ uint64_t shrd64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s) } else { res = d; } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(((res ^ d) >> 63)&1, F_OF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(XOR2(res>>62), F_OF); } else { - CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG((fill^(d>>63))&1, F_OF); } - if(BOX64ENV(dynarec_test)) + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); return res; } @@ -1370,14 +1362,12 @@ Implements the IDIV instruction and side effects. void idiv8(x64emu_t *emu, uint8_t s) { int32_t dvd, quot, mod; - RESET_FLAGS(emu); - if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); + if(BOX64ENV(cputype)) { + CHECK_FLAGS(emu); + SET_FLAG(F_AF); CLEAR_FLAG(F_PF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_OF); } dvd = (int16_t)R_AX; @@ -1399,14 +1389,12 @@ void idiv8(x64emu_t *emu, uint8_t s) void idiv16(x64emu_t *emu, uint16_t s) { int32_t dvd, quot, mod; - RESET_FLAGS(emu); - if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); + if(BOX64ENV(cputype)) { + CHECK_FLAGS(emu); + SET_FLAG(F_AF); CLEAR_FLAG(F_PF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_OF); } dvd = (((int32_t)R_DX) << 16) | R_AX; @@ -1429,14 +1417,12 @@ void idiv16(x64emu_t *emu, uint16_t s) void idiv32(x64emu_t *emu, uint32_t s) { int64_t dvd, quot, mod; - RESET_FLAGS(emu); - if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); + if(BOX64ENV(cputype)) { + CHECK_FLAGS(emu); + SET_FLAG(F_AF); CLEAR_FLAG(F_PF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_OF); } dvd = (((int64_t)R_EDX) << 32) | R_EAX; @@ -1459,14 +1445,12 @@ void idiv32(x64emu_t *emu, uint32_t s) void idiv64(x64emu_t *emu, uint64_t s) { __int128 dvd, quot, mod; - RESET_FLAGS(emu); - if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); + if(BOX64ENV(cputype)) { + CHECK_FLAGS(emu); + SET_FLAG(F_AF); CLEAR_FLAG(F_PF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_OF); } dvd = (((__int128)R_RDX) << 64) | R_RAX; @@ -1493,13 +1477,17 @@ void div8(x64emu_t *emu, uint8_t s) { uint32_t dvd, div, mod; RESET_FLAGS(emu); - if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_OF); + if(BOX64ENV(cputype)) { + SET_FLAG(F_AF); CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_PF); + } else { + CLEAR_FLAG(F_AF); + SET_FLAG(F_ZF); + SET_FLAG(F_PF); } dvd = R_AX; @@ -1521,13 +1509,17 @@ void div16(x64emu_t *emu, uint16_t s) { uint32_t dvd, div, mod; RESET_FLAGS(emu); - if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_OF); + if(BOX64ENV(cputype)) { + SET_FLAG(F_AF); CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_PF); + } else { + CLEAR_FLAG(F_AF); + SET_FLAG(F_ZF); + SET_FLAG(F_PF); } dvd = (((uint32_t)R_DX) << 16) | R_AX; @@ -1550,13 +1542,17 @@ void div32(x64emu_t *emu, uint32_t s) { uint64_t dvd, div, mod; RESET_FLAGS(emu); - if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_OF); + if(BOX64ENV(cputype)) { + SET_FLAG(F_AF); CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_PF); + } else { + CLEAR_FLAG(F_AF); + SET_FLAG(F_ZF); + SET_FLAG(F_PF); } dvd = (((uint64_t)R_EDX) << 32) | R_EAX; @@ -1579,13 +1575,17 @@ void div64(x64emu_t *emu, uint64_t s) { __int128 dvd, div, mod; RESET_FLAGS(emu); - if(BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_CF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CLEAR_FLAG(F_CF); + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_OF); + if(BOX64ENV(cputype)) { + SET_FLAG(F_AF); CLEAR_FLAG(F_ZF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_OF); + CLEAR_FLAG(F_PF); + } else { + CLEAR_FLAG(F_AF); + SET_FLAG(F_ZF); + SET_FLAG(F_PF); } dvd = (((__int128)R_RDX) << 64) | R_RAX; diff --git a/src/emu/x64primop.h b/src/emu/x64primop.h index e02fd9e7..2ad7d294 100644 --- a/src/emu/x64primop.h +++ b/src/emu/x64primop.h @@ -533,12 +533,14 @@ static inline uint64_t xor64(x64emu_t *emu, uint64_t d, uint64_t s) static inline void imul8(x64emu_t *emu, uint8_t s) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_imul8; R_AX = emu->res.u16 = ((int16_t)(int8_t)R_AL) * (int8_t)s; } static inline void imul16_eax(x64emu_t *emu, uint16_t s) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_imul16; emu->res.u32 = ((int32_t)(int16_t)R_AX) * (int16_t)s; R_AX = (uint16_t)emu->res.u32; @@ -547,6 +549,7 @@ static inline void imul16_eax(x64emu_t *emu, uint16_t s) static inline uint16_t imul16(x64emu_t *emu, uint16_t op1, uint16_t op2) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_imul16; emu->res.u32 = ((int32_t)(int16_t)op1) * (int16_t)op2; return emu->res.u16; @@ -562,6 +565,7 @@ static inline void imul32_direct(uint32_t *res_lo, uint32_t* res_hi,uint32_t d, static inline uint32_t imul32(x64emu_t *emu, uint32_t op1, uint32_t op2) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_imul32; uint32_t _res, _op1; imul32_direct(&_res,&_op1,op1,op2); @@ -572,6 +576,7 @@ static inline uint32_t imul32(x64emu_t *emu, uint32_t op1, uint32_t op2) static inline void imul32_eax(x64emu_t *emu, uint32_t s) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_imul32; imul32_direct(&emu->res.u32,&emu->op1.u32,R_EAX,s); R_EAX = emu->res.u32; @@ -588,6 +593,7 @@ static inline void imul64_direct(uint64_t *res_lo, uint64_t* res_hi,uint64_t d, static inline uint64_t imul64(x64emu_t *emu, uint64_t op1, uint64_t op2) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_imul64; imul64_direct(&emu->res.u64,&emu->op1.u64,op1,op2); return emu->res.u64; @@ -595,6 +601,7 @@ static inline uint64_t imul64(x64emu_t *emu, uint64_t op1, uint64_t op2) static inline void imul64_rax(x64emu_t *emu, uint64_t s) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_imul64; imul64_direct(&emu->res.u64,&emu->op1.u64,R_RAX,s); R_RAX = emu->res.u64; @@ -603,12 +610,14 @@ static inline void imul64_rax(x64emu_t *emu, uint64_t s) static inline void mul8(x64emu_t *emu, uint8_t s) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_mul8; R_AX = emu->res.u16 = (uint16_t)(R_AL) * s; } static inline void mul16(x64emu_t *emu, uint16_t s) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_mul16; emu->res.u32 = (uint32_t)R_AX * s; R_AX = (uint16_t)emu->res.u32; @@ -617,6 +626,7 @@ static inline void mul16(x64emu_t *emu, uint16_t s) static inline void mul32_eax(x64emu_t *emu, uint32_t s) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_mul32; uint64_t res = (uint64_t)R_EAX * s; emu->res.u32 = R_EAX = (uint32_t)res; @@ -625,6 +635,7 @@ static inline void mul32_eax(x64emu_t *emu, uint32_t s) static inline void mul64_rax(x64emu_t *emu, uint64_t s) { + if (BOX64ENV(cputype)) CHECK_FLAGS(emu); emu->df = d_mul64; unsigned __int128 res = (unsigned __int128)R_RAX * s; emu->res.u64 = R_RAX = (uint64_t)res; diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c index 6f600a67..556ad1f8 100644 --- a/src/emu/x64run0f.c +++ b/src/emu/x64run0f.c @@ -1182,12 +1182,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) else CLEAR_FLAG(F_CF); } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } break; case 0xA4: /* SHLD Ed,Gd,Ib */ nextop = F8; @@ -1479,12 +1473,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) else CLEAR_FLAG(F_CF); } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } break; case 5: /* BTS Ed, Ib */ CHECK_FLAGS(emu); @@ -1509,12 +1497,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) if(MODREG) ED->dword[1] = 0; } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } break; case 6: /* BTR Ed, Ib */ CHECK_FLAGS(emu); @@ -1537,12 +1519,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) if(MODREG) ED->dword[1] = 0; } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } break; case 7: /* BTC Ed, Ib */ CHECK_FLAGS(emu); @@ -1565,12 +1541,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) if(MODREG) ED->dword[1] = 0; } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } break; default: @@ -1612,12 +1582,6 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) if(MODREG) ED->dword[1] = 0; } - if (BOX64ENV(dynarec_test)) { - CLEAR_FLAG(F_OF); - CLEAR_FLAG(F_SF); - CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); - } break; case 0xBC: /* BSF Ed,Gd */ RESET_FLAGS(emu); diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index f462361e..4f3d5b4c 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -381,12 +381,11 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - if (BOX64ENV(dynarec_test)) { - // to avoid noise in tests - CLEAR_FLAG(F_SF); + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u8>>7)&1, F_SF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); } break; case d_imul16: @@ -400,12 +399,11 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - if (BOX64ENV(dynarec_test)) { - // to avoid noise in tests - CLEAR_FLAG(F_SF); + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u16>>15)&1, F_SF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); } break; case d_imul32: @@ -417,12 +415,11 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - if (BOX64ENV(dynarec_test)) { - // to avoid noise in tests - CLEAR_FLAG(F_SF); + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u32>>31)&1, F_SF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); } break; case d_imul64: @@ -434,12 +431,11 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - if (BOX64ENV(dynarec_test)) { - // to avoid noise in tests - CLEAR_FLAG(F_SF); + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u64>>63)&1, F_SF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); } break; case d_mul8: @@ -451,12 +447,11 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - if (BOX64ENV(dynarec_test)) { - // to avoid noise in tests - CLEAR_FLAG(F_SF); + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u8>>7)&1, F_SF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); } break; case d_mul16: @@ -468,12 +463,11 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - if (BOX64ENV(dynarec_test)) { - // to avoid noise in tests - CLEAR_FLAG(F_SF); + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u16>>15)&1, F_SF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); } break; case d_mul32: @@ -484,12 +478,11 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - if (BOX64ENV(dynarec_test)) { - // to avoid noise in tests - CLEAR_FLAG(F_SF); + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u32>>31)&1, F_SF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); } break; case d_mul64: @@ -500,12 +493,11 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - if (BOX64ENV(dynarec_test)) { - // to avoid noise in tests - CLEAR_FLAG(F_SF); + if (!BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u64>>63)&1, F_SF); CLEAR_FLAG(F_ZF); CLEAR_FLAG(F_AF); - CLEAR_FLAG(F_PF); + CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); } break; case d_or8: @@ -584,12 +576,11 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(((emu->res.u8>>7) ^ ACCESS_FLAG(F_CF))&0x01, F_OF); + SET_FLAG(F_AF); } else { - CLEAR_FLAG(F_OF); - } - if (BOX64ENV(dynarec_test)) { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u8>>6), F_OF); CLEAR_FLAG(F_AF); } } @@ -602,12 +593,11 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG(((!!(emu->res.u16 & 0x8000)) ^(ACCESS_FLAG(F_CF) != 0)), F_OF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(((emu->res.u16>>15) ^ ACCESS_FLAG(F_CF))&0x01, F_OF); + SET_FLAG(F_AF); } else { - CLEAR_FLAG(F_OF); - } - if (BOX64ENV(dynarec_test)) { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16>>14), F_OF); CLEAR_FLAG(F_AF); } } @@ -620,13 +610,11 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG(((!!(emu->res.u32 & 0x80000000)) ^ - (ACCESS_FLAG(F_CF) != 0)), F_OF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(((emu->res.u32>>31) ^ ACCESS_FLAG(F_CF))&0x01, F_OF); + SET_FLAG(F_AF); } else { - CLEAR_FLAG(F_OF); - } - if (BOX64ENV(dynarec_test)) { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32>>30), F_OF); CLEAR_FLAG(F_AF); } } @@ -638,13 +626,11 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (emu->op2.u64 == 1) { - CONDITIONAL_SET_FLAG(((!!(emu->res.u64 & 0x8000000000000000LL)) ^ - (ACCESS_FLAG(F_CF) != 0)), F_OF); + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG(((emu->res.u64>>63) ^ ACCESS_FLAG(F_CF))&0x01, F_OF); + SET_FLAG(F_AF); } else { - CLEAR_FLAG(F_OF); - } - if (BOX64ENV(dynarec_test)) { + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64>>62), F_OF); CLEAR_FLAG(F_AF); } } @@ -656,11 +642,11 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); - if (emu->op2.u8 == 1 || BOX64ENV(dynarec_test)) - CLEAR_FLAG(F_OF); - if (BOX64ENV(dynarec_test)) { + CLEAR_FLAG(F_OF); + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); - } } break; case d_sar16: @@ -670,11 +656,11 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (emu->op2.u16 == 1 || BOX64ENV(dynarec_test)) - CLEAR_FLAG(F_OF); - if (BOX64ENV(dynarec_test)) { + CLEAR_FLAG(F_OF); + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); - } } break; case d_sar32: @@ -684,11 +670,11 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (emu->op2.u32 == 1 || BOX64ENV(dynarec_test)) - CLEAR_FLAG(F_OF); - if (BOX64ENV(dynarec_test)) { + CLEAR_FLAG(F_OF); + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); - } } break; case d_sar64: @@ -698,11 +684,11 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (emu->op2.u64 == 1 || BOX64ENV(dynarec_test)) - CLEAR_FLAG(F_OF); - if (BOX64ENV(dynarec_test)) { + CLEAR_FLAG(F_OF); + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else CLEAR_FLAG(F_AF); - } } break; case d_shr8: @@ -713,16 +699,14 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u8, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(dynarec_test)) { + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u8>>6)&0x1, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG((emu->op1.u8>>7)&0x1, F_OF); CLEAR_FLAG(F_AF); - if(cnt>1) { - CLEAR_FLAG(F_OF); - } } } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(emu->op1.u8 & 0x80, F_OF); - } break; case d_shr16: cnt = emu->op2.u16 & 0x1f; @@ -732,11 +716,12 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(dynarec_test)) { + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u16>>14)&0x1, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG((emu->op1.u16>>15)&0x1, F_OF); CLEAR_FLAG(F_AF); - if(cnt>1) { - CLEAR_FLAG(F_OF); - } } } if (cnt == 1) { @@ -751,16 +736,14 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (BOX64ENV(dynarec_test)) { + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u32>>30)&0x1, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG((emu->op1.u32>>31)&0x1, F_OF); CLEAR_FLAG(F_AF); - if(cnt>1) { - CLEAR_FLAG(F_OF); - } } } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(emu->op1.u32 & 0x80000000, F_OF); - } break; case d_shr64: cnt = emu->op2.u64; @@ -770,14 +753,12 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG(emu->op1.u64 & 0x8000000000000000LL, F_OF); - } - if (BOX64ENV(dynarec_test)) { + if (BOX64ENV(cputype)) { + CONDITIONAL_SET_FLAG((emu->res.u64>>62)&0x1, F_OF); + SET_FLAG(F_AF); + } else { + CONDITIONAL_SET_FLAG((emu->op1.u64>>63)&0x1, F_OF); CLEAR_FLAG(F_AF); - if(cnt>1) { - CLEAR_FLAG(F_OF); - } } } break; @@ -785,16 +766,22 @@ void UpdateFlags(x64emu_t *emu) cnt = emu->op2.u16; if (cnt > 0) { cc = emu->op1.u16 & (1 << (cnt - 1)); + if(cnt>15 && BOX64ENV(cputype)) + cc = 0; CONDITIONAL_SET_FLAG(cc, F_CF); CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG((emu->op1.u16 ^ emu->res.u16) & 0x8000, F_OF); - } else { - CLEAR_FLAG(F_OF); - } } + if BOX64ENV(cputype) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u16>>14), F_OF); + } else { + CONDITIONAL_SET_FLAG(((emu->res.u16>>(16-(cnt&15))) ^ (emu->op1.u16>>15))&1, F_OF); + } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); break; case d_shrd32: cnt = emu->op2.u32; @@ -804,11 +791,15 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG((emu->op1.u32 ^ emu->res.u32) & 0x80000000, F_OF); + if BOX64ENV(cputype) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u32>>30), F_OF); } else { - CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(((emu->res.u32>>(32-cnt)) ^ (emu->op1.u32>>31))&1, F_OF); } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); } break; case d_shrd64: @@ -819,11 +810,15 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG((emu->op1.u64 ^ emu->res.u64) & 0x8000000000000000LL, F_OF); + if BOX64ENV(cputype) { + CONDITIONAL_SET_FLAG(XOR2(emu->res.u64>>62), F_OF); } else { - CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(((emu->res.u64>>(64-cnt)) ^ (emu->op1.u64>>63))&1, F_OF); } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); } break; case d_shld16: @@ -834,11 +829,18 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u16, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG((emu->op1.u16 ^ emu->res.u16) & 0x8000, F_OF); + if BOX64ENV(cputype) { + if(cnt>15) + CONDITIONAL_SET_FLAG(ACCESS_FLAG(F_CF), F_OF); + else + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u16>>15))&1, F_OF); } else { - CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16>>14), F_OF); } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); } break; case d_shld32: @@ -849,11 +851,15 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG((emu->op1.u32 ^ emu->res.u32) & 0x80000000, F_OF); + if BOX64ENV(cputype) { + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u32>>31))&1, F_OF); } else { - CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32>>30), F_OF); } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); } break; case d_shld64: @@ -864,11 +870,15 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG((emu->op1.u64 ^ emu->res.u64) & 0x8000000000000000LL, F_OF); + if BOX64ENV(cputype) { + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (emu->res.u64>>63))&1, F_OF); } else { - CLEAR_FLAG(F_OF); + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64>>62), F_OF); } + if (BOX64ENV(cputype)) + SET_FLAG(F_AF); + else + CLEAR_FLAG(F_AF); } break; case d_sub8: @@ -1097,51 +1107,59 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); break; case d_rol8: - if(emu->op2.u8 == 1) { + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((emu->res.u8 + (emu->res.u8 >> 7)) & 1, F_OF); - } + else + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u8>>6), F_OF); CONDITIONAL_SET_FLAG(emu->res.u8 & 0x1, F_CF); - break; + break; case d_rol16: - if(emu->op2.u16 == 1) { + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((emu->res.u16 + (emu->res.u16 >> 15)) & 1, F_OF); - } + else + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u16>>14), F_OF); CONDITIONAL_SET_FLAG(emu->res.u16 & 0x1, F_CF); break; case d_rol32: - if(emu->op2.u32 == 1) { + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((emu->res.u32 + (emu->res.u32 >> 31)) & 1, F_OF); - } + else + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u32>>30), F_OF); CONDITIONAL_SET_FLAG(emu->res.u32 & 0x1, F_CF); break; case d_rol64: - if(emu->op2.u64 == 1) { + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG((emu->res.u64 + (emu->res.u64 >> 63)) & 1, F_OF); - } + else + CONDITIONAL_SET_FLAG(XOR2(emu->op1.u64>>62), F_OF); CONDITIONAL_SET_FLAG(emu->res.u64 & 0x1, F_CF); break; case d_ror8: - if(emu->op2.u8 == 1) { + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(emu->res.u8 >> 6), F_OF); - } + else + CONDITIONAL_SET_FLAG(((emu->op1.u8 >> 7)^emu->op1.u8)&1, F_OF); CONDITIONAL_SET_FLAG(emu->res.u8 & (1 << 7), F_CF); break; case d_ror16: - if(emu->op2.u16 == 1) { + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(emu->res.u16 >> 14), F_OF); - } + else + CONDITIONAL_SET_FLAG(((emu->op1.u16 >> 15)^emu->op1.u16)&1, F_OF); CONDITIONAL_SET_FLAG(emu->res.u16 & (1 << 15), F_CF); break; case d_ror32: - if(emu->op2.u32 == 1) { + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(emu->res.u32 >> 30), F_OF); - } + else + CONDITIONAL_SET_FLAG(((emu->op1.u32 >> 31)^emu->op1.u32)&1, F_OF); CONDITIONAL_SET_FLAG(emu->res.u32 & (1 << 31), F_CF); break; case d_ror64: - if(emu->op2.u64 == 1) { + if(BOX64ENV(cputype)) CONDITIONAL_SET_FLAG(XOR2(emu->res.u64 >> 62), F_OF); - } + else + CONDITIONAL_SET_FLAG(((emu->op1.u64 >> 63)^emu->op1.u64)&1, F_OF); CONDITIONAL_SET_FLAG(emu->res.u64 & (1L << 63), F_CF); break; |