about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-11-11 17:27:06 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-11-11 17:27:06 +0100
commit2ed8557ea63399b199fadc4739a2eced35295fad (patch)
tree12321756cabfe0a3ab9310155c21cb87a505eab6
parentda3373ae42fe9e9cc3ed078562c7db7eee098622 (diff)
downloadbox64-2ed8557ea63399b199fadc4739a2eced35295fad.tar.gz
box64-2ed8557ea63399b199fadc4739a2eced35295fad.zip
[ARM64_DYNAREC] Added emit_shr8 helper
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c16
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c51
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h2
3 files changed, 55 insertions, 14 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 06d10a4e..d00c3229 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -2309,14 +2309,18 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 5:
                     INST_NAME("SHR Eb, CL");
-                    ANDSw_mask(x2, xRCX, 0, 0b00100);
-                    SETFLAGS(X_ALL, SF_PENDING);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    UFLAG_IF {
+                        ANDSw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    } else {
+                        ANDw_mask(x2, xRCX, 0, 0b00100);  //mask=0x00000001f
+                    }
                     GETEB(x1, 0);
-                    UFLAG_OP12(ed, x2);
-                    LSRw_REG(ed, ed, x2);
+                    UFLAG_IF {
+                        B_NEXT(cEQ);
+                    }
+                    emit_shr8(dyn, ninst, x1, x2, x5, x4);
                     EBBACK;
-                    UFLAG_RES(ed);
-                    UFLAG_DF(x3, d_shr8);
                     break;
                 case 7:
                     INST_NAME("SAR Eb, CL");
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index 526364ee..75caa99c 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -141,14 +141,6 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
-    IFX(X_ALL) {
-        CMPSxw_U12(s2, 0); //if(!c)
-            IFX(X_PEND) {
-                Bcond(cNE, +12);
-                STRxw_U12(s1, xEmu, offsetof(x64emu_t, res));
-            }
-            B_NEXT(cEQ);
-    }
     IFX(X_CF) {
         SUBxw_U12(s3, s2, 1);
         LSRxw_REG(s3, s1, s3);
@@ -367,6 +359,49 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     }
 }
 
+// emit SHR8 instruction, from s1 , s2, store result in s1 using s3 and s4 as scratch, s2 can be same as s3
+void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
+{
+    MAYUSE(s2);
+    int64_t j64;
+    MAYUSE(j64);
+
+    IFX(X_PEND) {
+        STRB_U12(s1, xEmu, offsetof(x64emu_t, op1));
+        STRB_U12(s2, xEmu, offsetof(x64emu_t, op2));
+        SET_DF(s4, d_shr8);
+    } else IFX(X_ALL) {
+        SET_DFNONE(s4);
+    }
+    IFX(X_CF) {
+        SUBw_U12(s3, s2, 1);
+        LSRw_REG(s3, s1, s3);
+        BFIw(xFlags, s3, 0, 1);
+    }
+    IFX(X_OF) {
+        CMPSw_U12(s2, 1);   // if s2==1
+            Bcond(cNE, 4+2*4);
+            LSRw(s4, s1, 7);
+            BFIw(xFlags, s4, F_OF, 1);
+    }
+    LSRw_REG(s1, s1, s2);
+    IFX(X_PEND) {
+        STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
+    }
+    IFX(X_ZF) {
+        TSTw_mask(s1, 0, 7);
+        CSETw(s4, cEQ);
+        BFIw(xFlags, s4, F_ZF, 1);
+    }
+    IFX(X_SF) {
+        LSRw(s4, s1, 7);
+        BFIw(xFlags, s4, F_SF, 1);
+    }
+    IFX(X_PF) {
+        emit_pf(dyn, ninst, s1, s3, s4);
+    }
+}
+
 // emit ROL32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
 void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4)
 {
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index c141ea8b..ac7ef7fd 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -1025,6 +1025,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
 #define emit_sar32c     STEPNAME(emit_sar32c)
 #define emit_shl8       STEPNAME(emit_shl8)
 #define emit_shl8c      STEPNAME(emit_shl8c)
+#define emit_shr8       STEPNAME(emit_shr8)
 #define emit_rol32c     STEPNAME(emit_rol32c)
 #define emit_ror32c     STEPNAME(emit_ror32c)
 #define emit_rol8c      STEPNAME(emit_rol8c)
@@ -1160,6 +1161,7 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
 void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
 void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
 void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);
+void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
 void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
 void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4);
 void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4);