about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-31 11:17:21 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-03-31 11:17:21 +0200
commitd53c9c1e87714d3e68e99790b6787c4d7e10713a (patch)
tree5bf978980d25eed0fcb993a14518cbb0f9a1532f /src
parent424a08607cdb4bb03e1ba2c443adae55db72243c (diff)
downloadbox64-d53c9c1e87714d3e68e99790b6787c4d7e10713a.tar.gz
box64-d53c9c1e87714d3e68e99790b6787c4d7e10713a.zip
[DYNAREC] Added F2 0F 70 opcode
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h1
-rwxr-xr-xsrc/dynarec/dynarec_arm64_f20f.c26
2 files changed, 27 insertions, 0 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index 0446bde6..fc4784ce 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -1117,6 +1117,7 @@
 #define TBL_gen(Q, Rm, len, op, Rn, Rd) ((Q)<<30 | 0b001110<<24 | (Rm)<<16 | (len)<<13 | (op)<<12 | (Rn)<<5 | (Rd))
 //Use Rm[] to pick from Rn element and store in Rd. Out-of-range element gets 0
 #define VTBLQ1_8(Rd, Rn, Rm)        EMIT(TBL_gen(1, Rm, 0b00, 0, Rn, Rd))
+#define VTBL1_8(Rd, Rn, Rm)         EMIT(TBL_gen(0, Rm, 0b00, 0, Rn, Rd))
 //Use Rm[] to pick from Rn, Rn+1 element and store in Rd. Out-of-range element gets 0
 #define VTBLQ2_8(Rd, Rn, Rm)        EMIT(TBL_gen(1, Rm, 0b01, 0, Rn, Rd))
 //Use Rm[] to pick from Rn, Rn+1, Rn+2 element and store in Rd. Out-of-range element gets 0
diff --git a/src/dynarec/dynarec_arm64_f20f.c b/src/dynarec/dynarec_arm64_f20f.c
index 8fe7cc3a..ceb212ae 100755
--- a/src/dynarec/dynarec_arm64_f20f.c
+++ b/src/dynarec/dynarec_arm64_f20f.c
@@ -37,6 +37,9 @@
 #define GETGX(a)    gd = ((nextop&0x38)>>3)+(rex.r<<3); \

                     a = sse_get_reg(dyn, ninst, x1, gd)

 

+#define GETGX_empty(a)  gd = ((nextop&0x38)>>3)+(rex.r<<3); \

+                        a = sse_get_reg_empty(dyn, ninst, x1, gd)

+

 uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)

 {

     uint8_t opcode = F8;

@@ -44,6 +47,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
     uint8_t gd, ed;

     uint8_t wback;

     uint8_t u8;

+    uint64_t u64;

     int v0, v1;

     int q0;

     int d0, d1;

@@ -233,6 +237,28 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             VMOVeD(v0, 0, d0, 0);   // to not erase uper part

             break;

 

+        case 0x70:

+            INST_NAME("PSHUFLW Gx, Ex, Ib");

+            nextop = F8;

+            GETEX(v1, 1);

+            GETGX_empty(v0);

+

+            u8 = F8;

+            // only low part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits

+            u64 = 0;

+            for (int i=0; i<4; ++i) {

+                u64 |= ((uint64_t)((u8>>(i*2))&3)*2+0)<<(i*16+0);

+                u64 |= ((uint64_t)((u8>>(i*2))&3)*2+1)<<(i*16+8);

+            }

+            MOV64x(x2, u64);

+            d0 = fpu_get_scratch(dyn);

+            VMOVQDfrom(d0, 0, x2);

+            VTBL1_8(v0, v1, d0);

+            if(v0!=v1) {

+                VMOVeD(v0, 1, v1, 1);

+            }

+            break;

+

         case 0x7C:

             INST_NAME("HADDPS Gx, Ex");

             nextop = F8;