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/x64emu_private.h4
-rw-r--r--src/emu/x64primop.c8
-rw-r--r--src/emu/x64run_private.c290
3 files changed, 96 insertions, 206 deletions
diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h
index 0c994e59..90c9b7b0 100644
--- a/src/emu/x64emu_private.h
+++ b/src/emu/x64emu_private.h
@@ -20,9 +20,13 @@ typedef struct forkpty_s {
 
 typedef union multiuint_s {
     uint8_t     u8;
+    int8_t      i8;
     uint16_t    u16;
+    int16_t     i16;
     uint32_t    u32;
+    int32_t     i32;
     uint64_t    u64;
+    int64_t     i64;
 } multiuint_t;
 
 typedef struct x64emu_s x64emu_t;
diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c
index 9bb001ba..2c8277af 100644
--- a/src/emu/x64primop.c
+++ b/src/emu/x64primop.c
@@ -556,7 +556,7 @@ uint32_t rcl32(x64emu_t *emu, uint32_t d, uint8_t s)
 	s = s&0x1f;
 
 	res = d;
-	if ((cnt = s % 33) != 0) {
+	if ((cnt = s) != 0) {
 		cf = (d >> (32 - cnt)) & 0x1;
 		res = (d << cnt);
 		mask = (1 << (cnt - 1)) - 1;
@@ -578,7 +578,7 @@ uint64_t rcl64(x64emu_t *emu, uint64_t d, uint8_t s)
 	s = s&0x3f;
 
 	res = d;
-	if ((cnt = s % 65) != 0) {
+	if ((cnt = s) != 0) {
 		cf = (d >> (64 - cnt)) & 0x1;
 		res = (d << cnt);
 		mask = (1LL << (cnt - 1)) - 1;
@@ -713,7 +713,7 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s)
 
 	/* rotate right through carry */
 	res = d;
-	if ((cnt = s % 33) != 0) {
+	if ((cnt = s) != 0) {
 		if (cnt == 1) {
 			cf = d & 0x1;
 			ocf = ACCESS_FLAG(F_CF) != 0;
@@ -742,7 +742,7 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s)
 
 	/* rotate right through carry */
 	res = d;
-	if ((cnt = s % 65) != 0) {
+	if ((cnt = s) != 0) {
 		if (cnt == 1) {
 			cf = d & 0x1;
 			ocf = ACCESS_FLAG(F_CF) != 0;
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 8d7ff9b9..cd093609 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -496,88 +496,55 @@ void UpdateFlags(x64emu_t *emu)
             CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
             break;
         case d_shl8:
-            if (emu->op2.u8 < 8) {
-                cnt = emu->op2.u8 % 8;
-                if (cnt > 0) {
-                    cc = emu->op1.u8 & (1 << (8 - cnt));
-                    CONDITIONAL_SET_FLAG(cc, F_CF);
-                    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 (cnt == 1) {
-                        CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
-                    } else {
-                        CLEAR_FLAG(F_OF);
-                    }
-                    if(box64_dynarec_test) {
-                        CLEAR_FLAG(F_AF);
-                    }
+            cnt = emu->op2.u8 & 0x1f;
+            if (cnt > 0) {
+                cc = emu->op1.u8 & (1 << (8 - cnt));
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                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 (cnt == 1) {
+                    CONDITIONAL_SET_FLAG((((emu->res.u8 & 0x80) == 0x80) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
+                } else {
+                    CLEAR_FLAG(F_OF);
                 }
-            } else {
-                CONDITIONAL_SET_FLAG((emu->op1.u8 << (emu->op2.u8-1)) & 0x80, F_CF);
-                CLEAR_FLAG(F_OF);
-                CLEAR_FLAG(F_SF);
-                SET_FLAG(F_PF);
-                SET_FLAG(F_ZF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
                 }
             }
             break;
         case d_shl16:
-            if (emu->op2.u16 < 16) {
-                cnt = emu->op2.u16 % 16;
-                if (cnt > 0) {
-                    cc = emu->op1.u16 & (1 << (16 - cnt));
-                    CONDITIONAL_SET_FLAG(cc, F_CF);
-                    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 (cnt == 1) {
-                        CONDITIONAL_SET_FLAG(((!!(emu->res.u16 & 0x8000)) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
-                    } else {
-                        CLEAR_FLAG(F_OF);
-                    }
-                    if(box64_dynarec_test) {
-                        CLEAR_FLAG(F_AF);
-                    }
+            cnt = emu->op2.u16 & 0x1f;
+            if (cnt > 0) {
+                cc = emu->op1.u16 & (1 << (16 - cnt));
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                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 (cnt == 1) {
+                    CONDITIONAL_SET_FLAG(((!!(emu->res.u16 & 0x8000)) ^(ACCESS_FLAG(F_CF) != 0)), F_OF);
+                } else {
+                    CLEAR_FLAG(F_OF);
                 }
-            } else {
-                CONDITIONAL_SET_FLAG((emu->op1.u16 << (emu->op2.u16-1)) & 0x8000, F_CF);
-                CLEAR_FLAG(F_OF);
-                CLEAR_FLAG(F_SF);
-                SET_FLAG(F_PF);
-                SET_FLAG(F_ZF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
                 }
             }
             break;
         case d_shl32:
-            if (emu->op2.u32 < 32) {
-                cnt = emu->op2.u32 % 32;
-                if (cnt > 0) {
-                    cc = emu->op1.u32 & (1 << (32 - cnt));
-                    CONDITIONAL_SET_FLAG(cc, F_CF);
-                    CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
-                    CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
-                    CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
-                    if (cnt == 1) {
-                        CONDITIONAL_SET_FLAG(((!!(emu->res.u32 & 0x80000000)) ^
-                                                (ACCESS_FLAG(F_CF) != 0)), F_OF);
-                    } else {
-                        CLEAR_FLAG(F_OF);
-                    }
-                    if(box64_dynarec_test) {
-                        CLEAR_FLAG(F_AF);
-                    }
+            cnt = emu->op2.u32 & 0x1f;
+            if (cnt > 0) {
+                cc = emu->op1.u32 & (1 << (32 - cnt));
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                CONDITIONAL_SET_FLAG(!emu->res.u32, F_ZF);
+                CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF);
+                CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF);
+                if (cnt == 1) {
+                    CONDITIONAL_SET_FLAG(((!!(emu->res.u32 & 0x80000000)) ^
+                                            (ACCESS_FLAG(F_CF) != 0)), F_OF);
+                } else {
+                    CLEAR_FLAG(F_OF);
                 }
-            } else {
-                CONDITIONAL_SET_FLAG((emu->op1.u32 << (emu->op2.u32-1)) & 0x80000000, F_CF);
-                CLEAR_FLAG(F_OF);
-                CLEAR_FLAG(F_SF);
-                SET_FLAG(F_PF);
-                SET_FLAG(F_ZF);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
                 }
@@ -602,93 +569,42 @@ void UpdateFlags(x64emu_t *emu)
             }
             break;
         case d_sar8:
-            if (emu->op2.u8 < 8) {
-                if(emu->op2.u8) {
-                    cc = emu->op1.u8 & (1 << (emu->op2.u8 - 1));
-                    CONDITIONAL_SET_FLAG(cc, F_CF);
-                    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);
-                    if(box64_dynarec_test) {
-                        CLEAR_FLAG(F_AF);
-                    }
-                }
-            } else {
-                if (emu->op1.u8&0x80) {
-                    SET_FLAG(F_CF);
-                    SET_FLAG(F_SF);
-                    CLEAR_FLAG(F_ZF);
-                    SET_FLAG(F_PF);
-                } else {
-                    CLEAR_FLAG(F_CF);
-                    CLEAR_FLAG(F_SF);
-                    SET_FLAG(F_ZF);
-                    SET_FLAG(F_PF);
-                }
+            if(emu->op2.u8) {
+                cc = (emu->op1.i8 >> (emu->op2.u8 - 1)) & 1;
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                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);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
                 }
             }
             break;
         case d_sar16:
-            if (emu->op2.u16 < 16) {
-                if(emu->op2.u16) {
-                    cc = emu->op1.u16 & (1 << (emu->op2.u16 - 1));
-                    CONDITIONAL_SET_FLAG(cc, F_CF);
-                    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);
-                    if(box64_dynarec_test) {
-                        CLEAR_FLAG(F_AF);
-                    }
-                }
-            } else {
-                if (emu->op1.u16&0x8000) {
-                    SET_FLAG(F_CF);
-                    CLEAR_FLAG(F_ZF);
-                    SET_FLAG(F_SF);
-                    SET_FLAG(F_PF);
-                } else {
-                    CLEAR_FLAG(F_CF);
-                    SET_FLAG(F_ZF);
-                    CLEAR_FLAG(F_SF);
-                    SET_FLAG(F_PF);
-                }
+            if(emu->op2.u16) {
+                cc = (emu->op1.i16 >> (emu->op2.u16 - 1)) & 1;
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                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);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
                 }
             }
             break;
         case d_sar32:
-            if (emu->op2.u32 < 32) {
-                if(emu->op2.u32) {
-                    cc = emu->op1.u32 & (1 << (emu->op2.u32 - 1));
-                    CONDITIONAL_SET_FLAG(cc, F_CF);
-                    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);
-                    if(box64_dynarec_test) {
-                        CLEAR_FLAG(F_AF);
-                    }
-                }
-            } else {
-                if (emu->op1.u32&0x80000000) {
-                    SET_FLAG(F_CF);
-                    CLEAR_FLAG(F_ZF);
-                    SET_FLAG(F_SF);
-                    SET_FLAG(F_PF);
-                } else {
-                    CLEAR_FLAG(F_CF);
-                    SET_FLAG(F_ZF);
-                    CLEAR_FLAG(F_SF);
-                    SET_FLAG(F_PF);
-                }
+            if(emu->op2.u32) {
+                cc = emu->op1.u32 & (1 << (emu->op2.u32 - 1));
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                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);
                 if(box64_dynarec_test) {
                     CLEAR_FLAG(F_AF);
                 }
@@ -709,82 +625,52 @@ void UpdateFlags(x64emu_t *emu)
             }
             break;
         case d_shr8:
-            if (emu->op2.u8 < 8) {
-                cnt = emu->op2.u8 % 8;
-                if (cnt > 0) {
-                    cc = emu->op1.u8 & (1 << (cnt - 1));
-                    CONDITIONAL_SET_FLAG(cc, F_CF);
-                    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);
-                }
-            } else {
-                CONDITIONAL_SET_FLAG((emu->op1.u8 >> (emu->op2.u8-1)) & 0x1, F_CF);
-                CLEAR_FLAG(F_SF);
-                SET_FLAG(F_PF);
-                SET_FLAG(F_ZF);
+            cnt = emu->op2.u8 & 0x1f;
+            if (cnt > 0) {
+                cc = emu->op1.u8 & (1 << (cnt - 1));
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                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);
+            }
             break;
         case d_shr16:
-            if (emu->op2.u16 < 16) {
-                cnt = emu->op2.u16 % 16;
-                if (cnt > 0) {
-                    cc = emu->op1.u16 & (1 << (cnt - 1));
-                    CONDITIONAL_SET_FLAG(cc, F_CF);
-                    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);
-                }
-            } else {
-                CLEAR_FLAG(F_CF);
-                SET_FLAG(F_ZF);
-                CLEAR_FLAG(F_SF);
-                SET_FLAG(F_PF);
+            cnt = emu->op2.u16 & 0x1f;
+            if (cnt > 0) {
+                cc = emu->op1.u16 & (1 << (cnt - 1));
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                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);
+            }
             break;
         case d_shr32:
-            if (emu->op2.u32 < 32) {
-                cnt = emu->op2.u32 % 32;
-                if (cnt > 0) {
-                    cc = emu->op1.u32 & (1 << (cnt - 1));
-                    CONDITIONAL_SET_FLAG(cc, F_CF);
-                    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);
-                }
-            } else {
-                CLEAR_FLAG(F_CF);
-                SET_FLAG(F_ZF);
-                CLEAR_FLAG(F_SF);
-                SET_FLAG(F_PF);
+            cnt = emu->op2.u32 & 0x1f;
+            if (cnt > 0) {
+                cc = emu->op1.u32 & (1 << (cnt - 1));
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                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);
+            }
             break;
         case d_shr64:
             cnt = emu->op2.u64;