about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorliuli <liuli@uniontech.com>2023-12-15 15:20:05 +0800
committerGitHub <noreply@github.com>2023-12-15 08:20:05 +0100
commit211fee2e4e4ce1f7132660469df613df5a74ac88 (patch)
tree8c5dff79974bbf78772bde06286065056a8f0df3 /src
parent9b7b91651de28bb5b95cef6e07e4e4f3f333c30c (diff)
downloadbox64-211fee2e4e4ce1f7132660469df613df5a74ac88.tar.gz
box64-211fee2e4e4ce1f7132660469df613df5a74ac88.zip
[ARM64_DYNAREC] fix emit_shld16(c) (#1141)
0x1a46b618: 66 44 0F A4 F8 5B  SHLD Ew, Gw, Ib
0x7f53749bdc: 7 emitted opcodes, inst=2, barrier=0 state=3/1(1), set=3F/1, use=0, need=0/1, sm=0/0, pred=1, last_ip=0x1a46b610
        53003d41        UXTH w1, wEAX
        53003f22        UXTH w2, wR15
        2a024021        ORR w1, w1, w2, LSL 16
        fff57c24        247CF5FF ???
        3300009a        BFXIL wFlags, w4, 0, 1
        13811421        ROR w1, w1, 5
        b3403c2a        BFXIL xRAX, x1, 0, 16
??? rases SIGILL...

Change-Id: I8f4afe3a814f8ee012bfc467261b32a9585d354b
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index b3803353..d69231ee 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -1289,7 +1289,10 @@ void emit_shld16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int
     }
     ORRw_REG_LSL(s1, s1, s2, 16);   // create concat first
     IFX(X_CF) {
-        LSRw(s3, s1, 16-c);
+        if(c<16)
+            LSRw(s3, s1, 16-c);
+        else
+            MOVx_REG(s3, s1);
         BFIw(xFlags, s3, F_CF, 1);
     }
     IFX(X_OF) {
@@ -1327,9 +1330,12 @@ void emit_shld16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3,
     }
     ORRw_REG_LSL(s1, s1, s2, 16);   // create concat first
     IFX(X_CF) {
-        MOV32w(s3, 16);
-        SUBw_REG(s3, s3, s5);
-        LSRw_REG(s3, s1, s3);
+        MOVw_REG(s3, s1);
+        CMPSw_U12(s5, 16);
+        Bcond(cGE, 4+3*4);
+            MOV32w(s3, 16);
+            SUBw_REG(s3, s3, s5);
+            LSRw_REG(s3, s1, s3);
         BFIw(xFlags, s3, F_CF, 1);
     }
     IFX(X_OF) {