diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-10 11:02:54 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-10 11:02:54 +0100 |
| commit | 85c74c6bf8e361108423da996ee62a53ffeb01d1 (patch) | |
| tree | 326398514f4fe533f367835715c6e537743d8e3a /src | |
| parent | 93f665eb9cbba62968114f73c09085f427c75f17 (diff) | |
| download | box64-85c74c6bf8e361108423da996ee62a53ffeb01d1.tar.gz box64-85c74c6bf8e361108423da996ee62a53ffeb01d1.zip | |
Fixed some edge-case with some of the shift opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64primop.c | 48 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 20 |
2 files changed, 33 insertions, 35 deletions
diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c index b0270491..a9e99742 100644 --- a/src/emu/x64primop.c +++ b/src/emu/x64primop.c @@ -520,10 +520,8 @@ 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. */ - /* parenthesized this expression since it appears to - be causing OF to be misset */ - CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)), - F_OF); + if(cnt == 1) + CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF); } return (uint8_t)res; @@ -545,8 +543,8 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s) res |= 1 << (cnt - 1); } CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)), - F_OF); + if(cnt == 1) + CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF); } return (uint16_t)res; } @@ -567,8 +565,8 @@ uint32_t rcl32(x64emu_t *emu, uint32_t d, uint8_t s) res |= 1 << (cnt - 1); } CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), - F_OF); + if(cnt == 1) + CONDITIONAL_SET_FLAG((cf ^ (res >> 31)) & 0x1, F_OF); } return res; } @@ -589,8 +587,8 @@ uint64_t rcl64(x64emu_t *emu, uint64_t d, uint8_t s) res |= 1LL << (cnt - 1); } CONDITIONAL_SET_FLAG(cf, F_CF); - CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 62) & 0x2)), - F_OF); + if(cnt == 1) + CONDITIONAL_SET_FLAG((cf ^ (res >> 63)) & 0x1, F_OF); } return res; } @@ -641,6 +639,11 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s) (i.e. packed bit array or unpacked.) */ ocf = ACCESS_FLAG(F_CF) != 0; + /* OVERFLOW is set *IFF* cnt==1, then it is the + xor of CF and the most significant bit. Blecck. */ + /* parenthesized... */ + CONDITIONAL_SET_FLAG((ocf ^ (d >> 7)) & 0x1, + F_OF); } else cf = (d >> (cnt - 1)) & 0x1; @@ -669,13 +672,6 @@ 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); - /* OVERFLOW is set *IFF* cnt==1, then it is the - xor of CF and the most significant bit. Blecck. */ - /* parenthesized... */ - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), - F_OF); - } } return (uint8_t)res; } @@ -693,6 +689,8 @@ uint16_t rcr16(x64emu_t *emu, uint16_t d, uint8_t s) if (cnt == 1) { cf = d & 0x1; ocf = ACCESS_FLAG(F_CF) != 0; + CONDITIONAL_SET_FLAG((ocf ^ (d >> 15)) & 0x1, + F_OF); } else cf = (d >> (cnt - 1)) & 0x1; mask = (1 << (16 - cnt)) - 1; @@ -702,10 +700,6 @@ uint16_t rcr16(x64emu_t *emu, uint16_t d, uint8_t s) res |= 1 << (16 - cnt); } CONDITIONAL_SET_FLAG(cf, F_CF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), - F_OF); - } } return (uint16_t)res; } @@ -723,6 +717,8 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s) if (cnt == 1) { cf = d & 0x1; ocf = ACCESS_FLAG(F_CF) != 0; + CONDITIONAL_SET_FLAG((ocf ^ (d >> 31)) & 0x1, + F_OF); } else cf = (d >> (cnt - 1)) & 0x1; mask = (1 << (32 - cnt)) - 1; @@ -733,10 +729,6 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s) res |= 1 << (32 - cnt); } CONDITIONAL_SET_FLAG(cf, F_CF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), - F_OF); - } } return res; } @@ -754,6 +746,8 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s) if (cnt == 1) { cf = d & 0x1; ocf = ACCESS_FLAG(F_CF) != 0; + CONDITIONAL_SET_FLAG((ocf ^ (d >> 63)) & 0x1, + F_OF); } else cf = (d >> (cnt - 1)) & 0x1; mask = (1LL << (64 - cnt)) - 1; @@ -764,10 +758,6 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s) res |= 1LL << (64 - cnt); } CONDITIONAL_SET_FLAG(cf, F_CF); - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 62) & 0x2)), - F_OF); - } } return res; } diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index b6e258ac..ebae674d 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -541,6 +541,8 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); + if(emu->op2.u8==1) + CLEAR_FLAG(F_OF); } } else { if (emu->op1.u8&0x80) { @@ -564,6 +566,8 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); + if(emu->op2.u16==1) + CLEAR_FLAG(F_OF); } } else { if (emu->op1.u16&0x8000) { @@ -587,6 +591,8 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffffffff) == 0, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + if(emu->op2.u32==1) + CLEAR_FLAG(F_OF); } } else { if (emu->op1.u32&0x80000000) { @@ -609,6 +615,8 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(emu->res.u64 == 0, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + if(emu->op2.u64==1) + CLEAR_FLAG(F_OF); } break; case d_shr8: @@ -622,7 +630,7 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res.u8 >> 6), F_OF); + CONDITIONAL_SET_FLAG(emu->op1.u8 & 0x80, F_OF); } } else { CONDITIONAL_SET_FLAG((emu->op1.u8 >> (emu->op2.u8-1)) & 0x1, F_CF); @@ -642,7 +650,7 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res.u16 >> 14), F_OF); + CONDITIONAL_SET_FLAG(emu->op1.u16 & 0x8000, F_OF); } } else { CLEAR_FLAG(F_CF); @@ -662,7 +670,7 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); } if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res.u32 >> 30), F_OF); + CONDITIONAL_SET_FLAG(emu->op1.u32 & 0x80000000, F_OF); } } else { CLEAR_FLAG(F_CF); @@ -680,9 +688,9 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(emu->res.u64 & 0x8000000000000000LL, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); } - if (cnt == 1) { - CONDITIONAL_SET_FLAG(XOR2(emu->res.u64 >> 62), F_OF); - } + if (cnt == 1) { + CONDITIONAL_SET_FLAG(emu->op1.u64 & 0x8000000000000000LL, F_OF); + } break; case d_sub8: CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); |