about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64primop.h192
-rw-r--r--src/emu/x64run66.c4
-rw-r--r--src/emu/x64run_private.c137
3 files changed, 246 insertions, 87 deletions
diff --git a/src/emu/x64primop.h b/src/emu/x64primop.h
index a0f465a3..83f8b00b 100644
--- a/src/emu/x64primop.h
+++ b/src/emu/x64primop.h
@@ -304,145 +304,193 @@ uint64_t     sbb64 (x64emu_t *emu, uint64_t d, uint64_t s);
 
 static inline uint8_t shl8(x64emu_t *emu, uint8_t d, uint8_t s)
 {
-	emu->df = d_shl8;
-	emu->op1.u8 = d;
+	if(s&0x1f) {
+		s &= 0x1f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x1f;
-	emu->op2.u8 = s;
-	emu->res.u8 = d << s;
+		emu->df = d_shl8;
+		emu->op1.u8 = d;
+		emu->op2.u8 = s;
+		emu->res.u8 = d << s;
 
-	return emu->res.u8;
+		return emu->res.u8;
+	} else 
+		return d;
 }
 
 static inline uint16_t shl16(x64emu_t *emu, uint16_t d, uint8_t s)
 {
-	emu->df = d_shl16;
-	emu->op1.u16 = d;
+	if(s&0x1f) {
+		s &= 0x1f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x1f;
-	emu->op2.u16 = s;
-	emu->res.u16 = d << s;
-	return emu->res.u16;
+		emu->df = d_shl16;
+		emu->op1.u16 = d;
+		emu->op2.u16 = s;
+		emu->res.u16 = d << s;
+		return emu->res.u16;
+	} else
+		return d;
 }
 
 static inline uint32_t shl32(x64emu_t *emu, uint32_t d, uint8_t s)
 {
-	emu->df = d_shl32;
-	emu->op1.u32 = d;
+	if(s&0x1f) {
+		s &= 0x1f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x1f;
-	emu->op2.u32 = s;
-	emu->res.u32 = d << s;
+		emu->df = d_shl32;
+		emu->op1.u32 = d;
+		emu->op2.u32 = s;
+		emu->res.u32 = d << s;
 
-	return emu->res.u32;
+		return emu->res.u32;
+	} else
+		return d;
 }
 
 static inline uint64_t shl64(x64emu_t *emu, uint64_t d, uint8_t s)
 {
-	emu->df = d_shl64;
-	emu->op1.u64 = d;
+	if(s&0x3f) {
+		s &= 0x3f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x3f;
-	emu->op2.u64 = s;
-	emu->res.u64 = d << s;
+		emu->df = d_shl64;
+		emu->op1.u64 = d;
+		emu->op2.u64 = s;
+		emu->res.u64 = d << s;
 
-	return emu->res.u64;
+		return emu->res.u64;
+	} else
+		return d;
 }
 
 static inline uint8_t shr8(x64emu_t *emu, uint8_t d, uint8_t s)
 {
-	emu->df = d_shr8;
-	emu->op1.u8 = d;
+	if(s&0x1f) {
+		s &= 0x1f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x1f;
-	emu->op2.u8 = s;
-	emu->res.u8 = d >> s;
+		emu->df = d_shr8;
+		emu->op1.u8 = d;
+		emu->op2.u8 = s;
+		emu->res.u8 = d >> s;
 
-	return emu->res.u8;
+		return emu->res.u8;
+	} else
+		return d;
 }
 
 static inline uint16_t shr16(x64emu_t *emu, uint16_t d, uint8_t s)
 {
-	emu->df = d_shr16;
-	emu->op1.u16 = d;
+	if(s&0x1f) {
+		s &= 0x1f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x1f;
-	emu->op2.u16 = s;
-	emu->res.u16 = d >> s;
+		emu->df = d_shr16;
+		emu->op1.u16 = d;
+		emu->op2.u16 = s;
+		emu->res.u16 = d >> s;
 
-	return emu->res.u16;
+		return emu->res.u16;
+	} else
+		return d;
 }
 
 static inline uint32_t shr32(x64emu_t *emu, uint32_t d, uint8_t s)
 {
-	emu->df = d_shr32;
-	emu->op1.u32 = d;
+	if(s&0x1f) {
+		s &= 0x1f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x1f;
-	emu->op2.u32 = s;
-	emu->res.u32 = d >> s;
+		emu->df = d_shr32;
+		emu->op1.u32 = d;
+		emu->op2.u32 = s;
+		emu->res.u32 = d >> s;
 
-    return emu->res.u32;
+		return emu->res.u32;
+	} else
+		return d;
 }
 
 static inline uint64_t shr64(x64emu_t *emu, uint64_t d, uint8_t s)
 {
-	emu->df = d_shr64;
-	emu->op1.u64 = d;
+	if(s&0x3f) {
+		s &= 0x3f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x3f;
-	emu->op2.u64 = s;
-	emu->res.u64 = d >> s;
+		emu->df = d_shr64;
+		emu->op1.u64 = d;
+		emu->op2.u64 = s;
+		emu->res.u64 = d >> s;
 
-    return emu->res.u64;
+		return emu->res.u64;
+	} else
+		return d;
 }
 
 static inline uint8_t sar8(x64emu_t *emu, uint8_t d, uint8_t s)
 {
-	emu->df = d_sar8;
-	emu->op1.u8 = d;
+	if(s&0x1f) {
+		s &= 0x1f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x1f;
-	emu->op2.u8 = s;
-	emu->res.u8 = (uint8_t)(((int8_t)d)>>s);
+		emu->df = d_sar8;
+		emu->op1.u8 = d;
+		emu->op2.u8 = s;
+		emu->res.u8 = (uint8_t)(((int8_t)d)>>s);
 
-	return emu->res.u8;
+		return emu->res.u8;
+	} else
+		return d;
 }
 
 static inline uint16_t sar16(x64emu_t *emu, uint16_t d, uint8_t s)
 {
-	emu->df = d_sar16;
-	emu->op1.u16 = d;
+	if(s&0x1f) {
+		s &= 0x1f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x1f;
-	emu->op2.u16 = s;
-	emu->res.u16 = (uint16_t)(((int16_t)d)>>s);
+		emu->df = d_sar16;
+		emu->op1.u16 = d;
+		emu->op2.u16 = s;
+		emu->res.u16 = (uint16_t)(((int16_t)d)>>s);
 
-	return emu->res.u16;
+		return emu->res.u16;
+	} else
+		return d;
 }
 
 static inline uint32_t sar32(x64emu_t *emu, uint32_t d, uint8_t s)
 {
-	emu->df = d_sar32;
-	emu->op1.u32 = d;
+	if(s&0x1f) {
+		s &= 0x1f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x1f;
-	emu->op2.u32 = s;
-	emu->res.u32 = (uint32_t)(((int32_t)d)>>s);
+		emu->df = d_sar32;
+		emu->op1.u32 = d;
+		emu->op2.u32 = s;
+		emu->res.u32 = (uint32_t)(((int32_t)d)>>s);
 
-	return emu->res.u32;
+		return emu->res.u32;
+	} else
+		return d;
 }
 
 static inline uint64_t sar64(x64emu_t *emu, uint64_t d, uint8_t s)
 {
-	emu->df = d_sar64;
-	emu->op1.u64 = d;
+	if(s&0x3f) {
+		s &= 0x3f;
+		if(s!=1) CHECK_FLAGS(emu);	// for OF, need to find something more elegant here, using sav stuffs
 
-	s &= 0x3f;
-	emu->op2.u64 = s;
-	emu->res.u64 = (uint64_t)(((int64_t)d)>>s);
+		emu->df = d_sar64;
+		emu->op1.u64 = d;
+		emu->op2.u64 = s;
+		emu->res.u64 = (uint64_t)(((int64_t)d)>>s);
 
-	return emu->res.u64;
+		return emu->res.u64;
+	} else
+		return d;
 }
 
 static inline uint8_t sub8(x64emu_t *emu, uint8_t d, uint8_t s)
diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c
index 79553512..3ba3af50 100644
--- a/src/emu/x64run66.c
+++ b/src/emu/x64run66.c
@@ -218,8 +218,8 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)
     case 0x56:

     case 0x57:                      /* PUSH Reg */

         if(rex.is32bits) {

-            tmp8u = opcode&7;

-            Push16(emu, emu->regs[tmp8u].word[0]);

+            tmp16u = emu->regs[opcode&7].word[0];

+            Push16(emu, tmp16u);

         } else

             return 0;

         break;

diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index bb18971a..fa61d2c1 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -297,7 +297,13 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF);
+            if(box64_dynarec_test) {
+                // to avoid noise in tests
+                CLEAR_FLAG(F_SF);
+                CLEAR_FLAG(F_ZF);
+                CLEAR_FLAG(F_AF);
+                CLEAR_FLAG(F_PF);
+            }
             break;
         case d_imul16:
             lo = (uint16_t)emu->res.u32;
@@ -310,18 +316,30 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF);
+            if(box64_dynarec_test) {
+                // to avoid noise in tests
+                CLEAR_FLAG(F_SF);
+                CLEAR_FLAG(F_ZF);
+                CLEAR_FLAG(F_AF);
+                CLEAR_FLAG(F_PF);
+            }
             break;
         case d_imul32:
-            if (((emu->res.u32 & 0x80000000) == 0 && emu->op1.u32 == 0x00) ||
-                ((emu->res.u32 & 0x80000000) != 0 && emu->op1.u32 == 0xFFFFFFFF)) {
+            if ((((emu->res.u32 & 0x80000000) == 0) && emu->op1.u32 == 0x00) ||
+                (((emu->res.u32 & 0x80000000) != 0) && emu->op1.u32 == 0xFFFFFFFF)) {
                 CLEAR_FLAG(F_CF);
                 CLEAR_FLAG(F_OF);
             } else {
                 SET_FLAG(F_CF);
-                SET_FLAG(F_OF);
+                SET_FLAG(F_OF); 
+            }
+            if(box64_dynarec_test) {
+                // to avoid noise in tests
+                CLEAR_FLAG(F_SF);
+                CLEAR_FLAG(F_ZF);
+                CLEAR_FLAG(F_AF);
+                CLEAR_FLAG(F_PF);
             }
-            CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
             break;
         case d_imul64:
             if (((emu->res.u64 & 0x8000000000000000LL) == 0 && emu->op1.u64 == 0x00) ||
@@ -332,7 +350,13 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
+            if(box64_dynarec_test) {
+                // to avoid noise in tests
+                CLEAR_FLAG(F_SF);
+                CLEAR_FLAG(F_ZF);
+                CLEAR_FLAG(F_AF);
+                CLEAR_FLAG(F_PF);
+            }
             break;
         case d_mul8:
             lo = emu->res.u16 & 0xff;
@@ -344,7 +368,13 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF);
+            if(box64_dynarec_test) {
+                // to avoid noise in tests
+                CLEAR_FLAG(F_SF);
+                CLEAR_FLAG(F_ZF);
+                CLEAR_FLAG(F_AF);
+                CLEAR_FLAG(F_PF);
+            }
             break;
         case d_mul16:
             lo = (uint16_t)emu->res.u32;
@@ -356,7 +386,13 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF);
+            if(box64_dynarec_test) {
+                // to avoid noise in tests
+                CLEAR_FLAG(F_SF);
+                CLEAR_FLAG(F_ZF);
+                CLEAR_FLAG(F_AF);
+                CLEAR_FLAG(F_PF);
+            }
             break;
         case d_mul32:
             if (emu->op1.u32 == 0) {
@@ -366,7 +402,13 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
+            if(box64_dynarec_test) {
+                // to avoid noise in tests
+                CLEAR_FLAG(F_SF);
+                CLEAR_FLAG(F_ZF);
+                CLEAR_FLAG(F_AF);
+                CLEAR_FLAG(F_PF);
+            }
             break;
         case d_mul64:
             if (emu->op1.u64 == 0) {
@@ -376,7 +418,13 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_CF);
                 SET_FLAG(F_OF);
             }
-            CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
+            if(box64_dynarec_test) {
+                // to avoid noise in tests
+                CLEAR_FLAG(F_SF);
+                CLEAR_FLAG(F_ZF);
+                CLEAR_FLAG(F_AF);
+                CLEAR_FLAG(F_PF);
+            }
             break;
         case d_or8:
             CLEAR_FLAG(F_OF);
@@ -460,6 +508,9 @@ void UpdateFlags(x64emu_t *emu)
                     } else {
                         CLEAR_FLAG(F_OF);
                     }
+                    if(box64_dynarec_test) {
+                        CLEAR_FLAG(F_AF);
+                    }
                 }
             } else {
                 CONDITIONAL_SET_FLAG((emu->op1.u8 << (emu->op2.u8-1)) & 0x80, F_CF);
@@ -467,6 +518,9 @@ void UpdateFlags(x64emu_t *emu)
                 CLEAR_FLAG(F_SF);
                 SET_FLAG(F_PF);
                 SET_FLAG(F_ZF);
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_shl16:
@@ -483,6 +537,9 @@ void UpdateFlags(x64emu_t *emu)
                     } else {
                         CLEAR_FLAG(F_OF);
                     }
+                    if(box64_dynarec_test) {
+                        CLEAR_FLAG(F_AF);
+                    }
                 }
             } else {
                 CONDITIONAL_SET_FLAG((emu->op1.u16 << (emu->op2.u16-1)) & 0x8000, F_CF);
@@ -490,6 +547,9 @@ void UpdateFlags(x64emu_t *emu)
                 CLEAR_FLAG(F_SF);
                 SET_FLAG(F_PF);
                 SET_FLAG(F_ZF);
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_shl32:
@@ -507,6 +567,9 @@ void UpdateFlags(x64emu_t *emu)
                     } else {
                         CLEAR_FLAG(F_OF);
                     }
+                    if(box64_dynarec_test) {
+                        CLEAR_FLAG(F_AF);
+                    }
                 }
             } else {
                 CONDITIONAL_SET_FLAG((emu->op1.u32 << (emu->op2.u32-1)) & 0x80000000, F_CF);
@@ -514,6 +577,9 @@ void UpdateFlags(x64emu_t *emu)
                 CLEAR_FLAG(F_SF);
                 SET_FLAG(F_PF);
                 SET_FLAG(F_ZF);
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_shl64:
@@ -529,6 +595,9 @@ void UpdateFlags(x64emu_t *emu)
                 } else {
                     CLEAR_FLAG(F_OF);
                 }
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_sar8:
@@ -541,19 +610,25 @@ void UpdateFlags(x64emu_t *emu)
                     CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
                     if(emu->op2.u8==1)
                         CLEAR_FLAG(F_OF);
+                    if(box64_dynarec_test) {
+                        CLEAR_FLAG(F_AF);
+                    }
                 }
             } else {
                 if (emu->op1.u8&0x80) {
                     SET_FLAG(F_CF);
-                    CLEAR_FLAG(F_ZF);
                     SET_FLAG(F_SF);
+                    CLEAR_FLAG(F_ZF);
                     SET_FLAG(F_PF);
                 } else {
                     CLEAR_FLAG(F_CF);
-                    SET_FLAG(F_ZF);
                     CLEAR_FLAG(F_SF);
+                    SET_FLAG(F_ZF);
                     SET_FLAG(F_PF);
                 }
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_sar16:
@@ -566,6 +641,9 @@ void UpdateFlags(x64emu_t *emu)
                     CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF);
                     if(emu->op2.u16==1)
                         CLEAR_FLAG(F_OF);
+                    if(box64_dynarec_test) {
+                        CLEAR_FLAG(F_AF);
+                    }
                 }
             } else {
                 if (emu->op1.u16&0x8000) {
@@ -579,6 +657,9 @@ void UpdateFlags(x64emu_t *emu)
                     CLEAR_FLAG(F_SF);
                     SET_FLAG(F_PF);
                 }
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_sar32:
@@ -591,6 +672,9 @@ void UpdateFlags(x64emu_t *emu)
                     CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
                     if(emu->op2.u32==1)
                         CLEAR_FLAG(F_OF);
+                    if(box64_dynarec_test) {
+                        CLEAR_FLAG(F_AF);
+                    }
                 }
             } else {
                 if (emu->op1.u32&0x80000000) {
@@ -604,6 +688,9 @@ void UpdateFlags(x64emu_t *emu)
                     CLEAR_FLAG(F_SF);
                     SET_FLAG(F_PF);
                 }
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_sar64:
@@ -615,6 +702,9 @@ void UpdateFlags(x64emu_t *emu)
                 CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF);
                 if(emu->op2.u64==1)
                     CLEAR_FLAG(F_OF);
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_shr8:
@@ -626,6 +716,9 @@ void UpdateFlags(x64emu_t *emu)
                     CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF);
                     CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
                     CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF);
+                    if(box64_dynarec_test) {
+                        CLEAR_FLAG(F_AF);
+                    }
                 }
                 if (cnt == 1) {
                     CONDITIONAL_SET_FLAG(emu->op1.u8 & 0x80, F_OF);
@@ -635,6 +728,9 @@ void UpdateFlags(x64emu_t *emu)
                 CLEAR_FLAG(F_SF);
                 SET_FLAG(F_PF);
                 SET_FLAG(F_ZF);
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_shr16:
@@ -646,6 +742,9 @@ 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(box64_dynarec_test) {
+                        CLEAR_FLAG(F_AF);
+                    }
                 }
                 if (cnt == 1) {
                     CONDITIONAL_SET_FLAG(emu->op1.u16 & 0x8000, F_OF);
@@ -655,6 +754,9 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_ZF);
                 CLEAR_FLAG(F_SF);
                 SET_FLAG(F_PF);
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_shr32:
@@ -666,6 +768,9 @@ 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(box64_dynarec_test) {
+                        CLEAR_FLAG(F_AF);
+                    }
                 }
                 if (cnt == 1) {
                     CONDITIONAL_SET_FLAG(emu->op1.u32 & 0x80000000, F_OF);
@@ -675,6 +780,9 @@ void UpdateFlags(x64emu_t *emu)
                 SET_FLAG(F_ZF);
                 CLEAR_FLAG(F_SF);
                 SET_FLAG(F_PF);
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_shr64:
@@ -688,6 +796,9 @@ void UpdateFlags(x64emu_t *emu)
                 if (cnt == 1) {
                     CONDITIONAL_SET_FLAG(emu->op1.u64 & 0x8000000000000000LL, F_OF);
                 }
+                if(box64_dynarec_test) {
+                    CLEAR_FLAG(F_AF);
+                }
             }
             break;
         case d_shrd16: