about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-11-10 11:02:54 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-11-10 11:02:54 +0100
commit85c74c6bf8e361108423da996ee62a53ffeb01d1 (patch)
tree326398514f4fe533f367835715c6e537743d8e3a /src
parent93f665eb9cbba62968114f73c09085f427c75f17 (diff)
downloadbox64-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.c48
-rw-r--r--src/emu/x64run_private.c20
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);