about summary refs log tree commit diff stats
path: root/src/emu
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-12-26 19:10:27 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-12-26 19:10:27 +0100
commite86c6359d654d2d1d91da873b7e8c2168619141e (patch)
tree69cbeff5ef003a12ebd8a2d0a5debc10a5913393 /src/emu
parentacce64b268a55a0fcec896d160c87b3e71a6e597 (diff)
downloadbox64-e86c6359d654d2d1d91da873b7e8c2168619141e.tar.gz
box64-e86c6359d654d2d1d91da873b7e8c2168619141e.zip
[INTERPRETER] Improved some shift operands nd [AR64_DYNAREC] Improved shift operands and [COSIM] reduce noise on shift operands
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/x64primop.c42
-rw-r--r--src/emu/x64run_private.c28
2 files changed, 59 insertions, 11 deletions
diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c
index 9f5092e4..4898a0d8 100644
--- a/src/emu/x64primop.c
+++ b/src/emu/x64primop.c
@@ -104,6 +104,8 @@
 #include "x64emu_private.h"
 #include "x64run_private.h"
 
+extern int box64_dynarec_test;
+
 /*------------------------- Global Variables ------------------------------*/
 
 #define PARITY(x)   (((emu->x64emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
@@ -778,6 +780,8 @@ uint8_t rol8(x64emu_t *emu, uint8_t d, uint8_t s)
 	/* 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(box64_dynarec_test) {
+		CLEAR_FLAG(F_OF);
 	}
 
 	/* set new CF; note that it is the LSB of the result */
@@ -801,6 +805,8 @@ uint16_t rol16(x64emu_t *emu, uint16_t d, uint8_t s)
 	/* 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(box64_dynarec_test) {
+		CLEAR_FLAG(F_OF);
 	}
 
 	/* set new CF; note that it is the LSB of the result */
@@ -824,6 +830,8 @@ uint32_t rol32(x64emu_t *emu, uint32_t d, uint8_t s)
 	/* 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(box64_dynarec_test) {
+		CLEAR_FLAG(F_OF);
 	}
 
 	/* set new CF; note that it is the LSB of the result */
@@ -847,6 +855,8 @@ uint64_t rol64(x64emu_t *emu, uint64_t d, uint8_t s)
 	/* 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(box64_dynarec_test) {
+		CLEAR_FLAG(F_OF);
 	}
 
 	/* set new CF; note that it is the LSB of the result */
@@ -874,6 +884,8 @@ uint8_t ror8(x64emu_t *emu, uint8_t d, uint8_t s)
 	/* 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(box64_dynarec_test) {
+		CLEAR_FLAG(F_OF);
 	}
 
 	/* set new CF; note that it is the MSB of the result */
@@ -897,6 +909,8 @@ uint16_t ror16(x64emu_t *emu, uint16_t d, uint8_t s)
 	/* 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(box64_dynarec_test) {
+		CLEAR_FLAG(F_OF);
 	}
 
 	/* set new CF; note that it is the MSB of the result */
@@ -920,6 +934,8 @@ uint32_t ror32(x64emu_t *emu, uint32_t d, uint8_t s)
 	/* 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(box64_dynarec_test) {
+		CLEAR_FLAG(F_OF);
 	}
 
 	/* set new CF; note that it is the MSB of the result */
@@ -943,6 +959,8 @@ uint64_t ror64(x64emu_t *emu, uint64_t d, uint8_t s)
 	/* 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(box64_dynarec_test) {
+		CLEAR_FLAG(F_OF);
 	}
 
 	/* set new CF; note that it is the MSB of the result */
@@ -977,7 +995,7 @@ uint16_t shld16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 		if (cnt == 1) {
 			CONDITIONAL_SET_FLAG(((res ^ d) >> 15)&1, F_OF);
 		} else {
-			CONDITIONAL_SET_FLAG((d >> 15)&1, F_OF);
+			CLEAR_FLAG(F_OF);
 		}
 	} else {
 		res = (fill << (cnt)) | (d >> (16 - cnt));
@@ -991,6 +1009,8 @@ uint16_t shld16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 		CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
 		CLEAR_FLAG(F_OF);
 	}
+	if(box64_dynarec_test)
+		CLEAR_FLAG(F_AF);
 	return (uint16_t)res;
 }
 
@@ -1016,8 +1036,10 @@ uint32_t shld32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s)
 	if (cnt == 1) {
 		CONDITIONAL_SET_FLAG(((res ^ d) >> 31)&1, F_OF);
 	} else {
-		CONDITIONAL_SET_FLAG((d >> 31)&1, F_OF);
+		CLEAR_FLAG(F_OF);
 	}
+	if(box64_dynarec_test)
+		CLEAR_FLAG(F_AF);
 	return res;
 }
 
@@ -1043,8 +1065,10 @@ uint64_t shld64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s)
 	if (cnt == 1) {
 		CONDITIONAL_SET_FLAG(((res ^ d) >> 63)&1, F_OF);
 	} else {
-		CONDITIONAL_SET_FLAG((d >> 63)&1, F_OF);
+		CLEAR_FLAG(F_OF);
 	}
+	if(box64_dynarec_test)
+		CLEAR_FLAG(F_AF);
 	return res;
 }
 
@@ -1076,7 +1100,7 @@ uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 		if (cnt == 1) {
 			CONDITIONAL_SET_FLAG(((res ^ d) >> 15)&1, F_OF);
         } else {
-			CONDITIONAL_SET_FLAG((d >> 15)&1, F_OF);
+			CLEAR_FLAG(F_OF);
         }
 	} else {
 		if(s==16)
@@ -1098,6 +1122,8 @@ uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 		CLEAR_FLAG(F_PF);
 	#endif
     }
+	if(box64_dynarec_test)
+		CLEAR_FLAG(F_AF);
 	return (uint16_t)res;
 }
 
@@ -1123,8 +1149,10 @@ uint32_t shrd32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s)
 	if (cnt == 1) {
 		CONDITIONAL_SET_FLAG(((res ^ d) >> 31)&1, F_OF);
 	} else {
-		CONDITIONAL_SET_FLAG((d >> 31)&1, F_OF);
+		CLEAR_FLAG(F_OF);
 	}
+	if(box64_dynarec_test)
+		CLEAR_FLAG(F_AF);
 	return res;
 }
 
@@ -1151,8 +1179,10 @@ uint64_t shrd64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s)
 	if (cnt == 1) {
 		CONDITIONAL_SET_FLAG(((res ^ d) >> 63)&1, F_OF);
 	} else {
-		CONDITIONAL_SET_FLAG((d >> 63)&1, F_OF);
+		CLEAR_FLAG(F_OF);
 	}
+	if(box64_dynarec_test)
+		CLEAR_FLAG(F_AF);
 	return res;
 }
 /****************************************************************************
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 8bc99819..5cfc4625 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -656,7 +656,7 @@ 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)
+                if(emu->op2.u8==1 || box64_dynarec_test)
                     CLEAR_FLAG(F_OF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
@@ -670,7 +670,7 @@ 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)
+                if(emu->op2.u16==1 || box64_dynarec_test)
                     CLEAR_FLAG(F_OF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
@@ -684,7 +684,7 @@ 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)
+                if(emu->op2.u32==1 || box64_dynarec_test)
                     CLEAR_FLAG(F_OF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
@@ -698,7 +698,7 @@ 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)
+                if(emu->op2.u64==1 || box64_dynarec_test)
                     CLEAR_FLAG(F_OF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
@@ -715,6 +715,9 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
+                    if(cnt>1) {
+                        CLEAR_FLAG(F_OF);
+                    }
                 }
             }
             if (cnt == 1) {
@@ -731,6 +734,9 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
+                    if(cnt>1) {
+                        CLEAR_FLAG(F_OF);
+                    }
                 }
             }
             if (cnt == 1) {
@@ -747,6 +753,9 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
+                    if(cnt>1) {
+                        CLEAR_FLAG(F_OF);
+                    }
                 }
             }
             if (cnt == 1) {
@@ -766,6 +775,9 @@ void UpdateFlags(x64emu_t *emu)
                 }
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
+                    if(cnt>1) {
+                        CLEAR_FLAG(F_OF);
+                    }
                 }
             }
             break;
@@ -779,7 +791,9 @@ void UpdateFlags(x64emu_t *emu)
                 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);
+               }
             }
             break;
         case d_shrd32:
@@ -792,6 +806,8 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
                 if (cnt == 1) {
                     CONDITIONAL_SET_FLAG((emu->op1.u32 ^ emu->res.u32) & 0x80000000, F_OF);
+                } else {
+                    CLEAR_FLAG(F_OF);
                 }
             }
             break;
@@ -805,6 +821,8 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u8), F_PF);
                 if (cnt == 1) {
                     CONDITIONAL_SET_FLAG((emu->op1.u64 ^ emu->res.u64) & 0x8000000000000000LL, F_OF);
+                } else {
+                    CLEAR_FLAG(F_OF);
                 }
             }
             break;