about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-19 20:29:45 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-19 20:29:45 +0100
commit597a56d0ffe894e0e74ce18a10556c7d91b3a925 (patch)
treeb2df8867065c25e33196bffd2145e43331684d03 /src
parent967132b04e08e95ba9994157ffeaaced7cc6aa77 (diff)
downloadbox64-597a56d0ffe894e0e74ce18a10556c7d91b3a925.tar.gz
box64-597a56d0ffe894e0e74ce18a10556c7d91b3a925.zip
[DYNAREC] Added 0F AD and 66 0F AC/AD SHLD opcodes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h1
-rwxr-xr-xsrc/dynarec/dynarec_arm64_0f.c12
-rwxr-xr-xsrc/dynarec/dynarec_arm64_660f.c19
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h10
4 files changed, 37 insertions, 5 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index 591968a6..1095fff7 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -378,6 +378,7 @@
 #define UBFXxw(Rd, Rn, lsb, width)      EMIT(UBFM_gen(rex.w, rex.w, (lsb), (lsb)+(width)-1, Rn, Rd))
 #define UXTBx(Rd, Rn)                   EMIT(UBFM_gen(1, 1, 0, 7, Rn, Rd))
 #define UXTBw(Rd, Rn)                   EMIT(UBFM_gen(0, 0, 0, 7, Rn, Rd))
+#define UXTBxw(Rd, Rn)                  EMIT(UBFM_gen(rex.w, rex.w, 0, 7, Rn, Rd))
 #define UXTHx(Rd, Rn)                   EMIT(UBFM_gen(1, 1, 0, 15, Rn, Rd))
 #define UXTHw(Rd, Rn)                   EMIT(UBFM_gen(0, 0, 0, 15, Rn, Rd))
 #define LSRx(Rd, Rn, shift)             EMIT(UBFM_gen(1, 1, shift, 63, Rn, Rd))
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c
index 585217c5..54e5f2d5 100755
--- a/src/dynarec/dynarec_arm64_0f.c
+++ b/src/dynarec/dynarec_arm64_0f.c
@@ -214,6 +214,18 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }

             break;

 

+        case 0xAD:

+            nextop = F8;

+            INST_NAME("SHRD Ed, Gd, CL");

+            SETFLAGS(X_ALL, SF_SET);

+            UXTBw(x3, xRCX);

+            GETEDW(x4, x1, 0);

+            GETGD;

+            MOVxw_REG(x2, gd);

+            CALL_(rex.w?((void*)shrd64):((void*)shrd32), ed, x4);

+            WBACK;

+            break;

+

         case 0xB3:

             INST_NAME("BTR Ed, Gd");

             SETFLAGS(X_CF, SF_SET);

diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c
index f63fd817..e82d51ef 100755
--- a/src/dynarec/dynarec_arm64_660f.c
+++ b/src/dynarec/dynarec_arm64_660f.c
@@ -95,6 +95,25 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             EORxw_REG(ed, ed, x1);

             EWBACK;

             break;

+        case 0xAC:

+        case 0xAD:

+            nextop = F8;

+            if(opcode==0xAC) {

+                INST_NAME("SHRD Ew, Gw, Ib");

+            } else {

+                INST_NAME("SHRD Ew, Gw, CL");

+                UXTBw(x3, xRCX);

+            }

+            SETFLAGS(X_ALL, SF_SET);

+            GETEWW(x4, x1, (opcode==0xAC)?1:0);

+            GETGW(x2);

+            if(opcode==0xAC) {

+                u8 = F8;

+                MOV32w(x3, u8);

+            }

+            CALL_(shrd16, x1, wback);

+            EWBACKW(x1);

+            break;

 

         case 0xB3:

             INST_NAME("BTR Ew, Gw");

diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 5b4c68c3..2da9e799 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -98,7 +98,7 @@
                     addr = fakeed(dyn, addr, ninst, nextop); \
                 }
 // GETGW extract x64 register in gd, that is i
-#define GETGW(i) gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); UXTH(i, gd, 0); gd = i;
+#define GETGW(i) gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); UXTHw(i, gd); gd = i;
 //GETEWW will use i for ed, and can use w for wback.
 #define GETEWW(w, i, D) if(MODREG) {        \
                     wback = xRAX+(nextop&7)+(rex.b<<3);\
@@ -231,12 +231,12 @@
 // CALL will use x7 for the call address. Return value can be put in ret (unless ret is -1)
 // R0 will not be pushed/popd if ret is -2
 #define CALL(F, ret) call_c(dyn, ninst, F, x7, ret, 1, 0)
-// CALL_ will use x3 for the call address. Return value can be put in ret (unless ret is -1)
+// CALL_ will use x7 for the call address. Return value can be put in ret (unless ret is -1)
 // R0 will not be pushed/popd if ret is -2
-#define CALL_(F, ret, reg) call_c(dyn, ninst, F, x3, ret, 1, reg)
-// CALL_S will use x3 for the call address. Return value can be put in ret (unless ret is -1)
+#define CALL_(F, ret, reg) call_c(dyn, ninst, F, x7, ret, 1, reg)
+// CALL_S will use x7 for the call address. Return value can be put in ret (unless ret is -1)
 // R0 will not be pushed/popd if ret is -2. Flags are not save/restored
-#define CALL_S(F, ret) call_c(dyn, ninst, F, x3, ret, 0, 0)
+#define CALL_S(F, ret) call_c(dyn, ninst, F, x7, ret, 0, 0)
 
 #define MARK    if(dyn->insts) {dyn->insts[ninst].mark = (uintptr_t)dyn->arm_size;}
 #define GETMARK ((dyn->insts)?dyn->insts[ninst].mark:(dyn->arm_size+4))