about summary refs log tree commit diff stats
path: root/src/emu
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-11-16 10:42:40 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-11-16 10:42:40 +0100
commitf7d75ca641ec6de4a35421fe206f8608ee531a20 (patch)
treec7b19d5320c0a5d0d0910d6902e066c8f27de5b9 /src/emu
parent5baa0833865379799136eea5541b62fe4044ed9a (diff)
downloadbox64-f7d75ca641ec6de4a35421fe206f8608ee531a20.tar.gz
box64-f7d75ca641ec6de4a35421fe206f8608ee531a20.zip
[ARM64_DYNAREC] Fixed shrd 32/64bits opcodes
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/x64run_private.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 1ef14725..f50c32cc 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -687,10 +687,36 @@ 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.u64 & 0xff), F_PF);
-            }
                 if (cnt == 1) {
                     CONDITIONAL_SET_FLAG(emu->op1.u64 & 0x8000000000000000LL, F_OF);
                 }
+            }
+            break;
+        case d_shrd32:
+            cnt = emu->op2.u32;
+            if (cnt > 0) {
+                cc = emu->op1.u32 & (1 << (cnt - 1));
+                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->op1.u32 ^ emu->res.u32) & 0x80000000, F_OF);
+                }
+            }
+            break;
+        case d_shrd64:
+            cnt = emu->op2.u64;
+            if (cnt > 0) {
+                cc = emu->op1.u64 & (1LL << (cnt - 1));
+                CONDITIONAL_SET_FLAG(cc, F_CF);
+                CONDITIONAL_SET_FLAG(!emu->res.u64, F_ZF);
+                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((emu->op1.u64 ^ emu->res.u64) & 0x8000000000000000LL, F_OF);
+                }
+            }
             break;
         case d_sub8:
             CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF);
@@ -975,6 +1001,7 @@ void UpdateFlags(x64emu_t *emu)
         case d_rcr16:
         case d_rcr32:
         case d_rcr64:
+        case d_shrd16:
         case d_unknown:
             printf_log(LOG_NONE, "Box64: %p trying to evaluate Unknown deferred Flags\n", (void*)R_RIP);
             break;