about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-04-18 12:21:01 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-04-18 12:21:01 +0200
commit802c5a9d5b8faa2a103be6aed5ad7e25d3604c17 (patch)
treedf0c07e663a4b5a2412c1e8fc99feeaa53d4b8d9 /src
parent3a22c36d0437386119e8e57aed1e9376be7a9e75 (diff)
downloadbox64-802c5a9d5b8faa2a103be6aed5ad7e25d3604c17.tar.gz
box64-802c5a9d5b8faa2a103be6aed5ad7e25d3604c17.zip
[DYNAREC] Added 0F 64/65/66/6B/72/75/76/D3/F5 opcodes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h8
-rwxr-xr-xsrc/dynarec/dynarec_arm64_0f.c126
2 files changed, 131 insertions, 3 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index c986edc3..56a28b0d 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -741,6 +741,7 @@
 
 #define SHL_scalar(U, size, Rm, R, S, Rn, Rd)   (0b01<<30 | (U)<<29 | 0b11110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 0b010<<13 | (R)<<12 | (S)<<11 | 1<<10 | (Rn)<<5 | (Rd))
 #define SSHL_R_64(Vd, Vn, Vm)               EMIT(SHL_scalar(0, 0b11, Vm, 0, 0, Vn, Vd))
+#define USHL_R_64(Vd, Vn, Vm)               EMIT(SHL_scalar(1, 0b11, Vm, 0, 0, Vn, Vd))
 
 #define SHL_scalar_imm(U, immh, immb, Rn, Rd)   (0b01<<30 | 0b111110<<23 | (immh)<<19 | (immb)<<16 | 0b01010<<11 | 1<<10 | (Rn)<<5 | (Rd))
 #define SHL_64(Vd, Vn, shift)               EMIT(SHL_scalar_imm(0, 0b1000 | (((shift)>>3)&7), (shift)&7, Vn, Vd))
@@ -831,6 +832,10 @@
 #define ABSQ_32(Vd, Vn)                     EMIT(NEGABS_vector(1, 0, 0b10, Vn, Vd))
 #define ABSQ_64(Vd, Vn)                     EMIT(NEGABS_vector(1, 0, 0b11, Vn, Vd))
 
+#define NEGABS_vector_scalar(U, size, Rn, Rd)   (0b01<<30 | (U)<<29 | 0b11110<<24 | (size)<<22 | 0b10000<<17 | 0b01011<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
+#define NEG_64(Vd, Vn)                     EMIT(NEGABS_vector_scalar(1, 0b11, Vn, Vd))
+#define ABS_64(Vd, Vn)                     EMIT(NEGABS_vector_scalar(0, 0b11, Vn, Vd))
+
 // FMOV
 #define FMOV_general(sf, type, mode, opcode, Rn, Rd)    ((sf)<<31 | 0b11110<<24 | (type)<<22 | 1<<21 | (mode)<<19 | (opcode)<<16 | (Rn)<<5 | (Rd))
 // 32-bit to single-precision
@@ -1343,6 +1348,9 @@
 #define VCMGTQ_16(Rd, Rn, Rm)       EMIT(CMG_vector(1, 0, 0b01, 0, Rm, Rn, Rd))
 #define VCMGTQ_32(Rd, Rn, Rm)       EMIT(CMG_vector(1, 0, 0b10, 0, Rm, Rn, Rd))
 #define VCMGTQ_64(Rd, Rn, Rm)       EMIT(CMG_vector(1, 0, 0b11, 0, Rm, Rn, Rd))
+#define VCMGT_8(Rd, Rn, Rm)         EMIT(CMG_vector(0, 0, 0b00, 0, Rm, Rn, Rd))
+#define VCMGT_16(Rd, Rn, Rm)        EMIT(CMG_vector(0, 0, 0b01, 0, Rm, Rn, Rd))
+#define VCMGT_32(Rd, Rn, Rm)        EMIT(CMG_vector(0, 0, 0b10, 0, Rm, Rn, Rd))
 // Unsigned Higher
 #define VCHIQQ_8(Rd, Rn, Rm)        EMIT(CMG_vector(1, 1, 0b00, 0, Rm, Rn, Rd))
 #define VCHIQQ_16(Rd, Rn, Rm)       EMIT(CMG_vector(1, 1, 0b01, 0, Rm, Rn, Rd))
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c
index cff67cf9..2e41435f 100755
--- a/src/dynarec/dynarec_arm64_0f.c
+++ b/src/dynarec/dynarec_arm64_0f.c
@@ -478,7 +478,27 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             VMOVeD(q0, 1, d1, 0);

             SQXTN_8(d0, q0);

             break;

-

+        case 0x64:

+            INST_NAME("PCMPGTB Gx,Ex");

+            nextop = F8;

+            GETGM(v0);

+            GETEM(v1, 0);

+            VCMGT_8(v0, v0, v1);

+            break;

+        case 0x65:

+            INST_NAME("PCMPGTW Gx,Ex");

+            nextop = F8;

+            GETGM(v0);

+            GETEM(v1, 0);

+            VCMGT_16(v0, v0, v1);

+            break;

+        case 0x66:

+            INST_NAME("PCMPGTD Gx,Ex");

+            nextop = F8;

+            GETGM(v0);

+            GETEM(v1, 0);

+            VCMGT_32(v0, v0, v1);

+            break;

         case 0x67:

             INST_NAME("PACKUSWB Gm, Em");

             nextop = F8;

@@ -515,6 +535,22 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             GETEM(q1, 1);

             VZIP2_32(q0, q0, q1);

             break;

+        case 0x6B:

+            INST_NAME("PACKSSDW Gm,Em");

+            nextop = F8;

+            GETGM(v0);

+            if(MODREG) {

+                GETEM(v1, 0);

+                q0 = fpu_get_scratch(dyn);

+                VMOVeD(q0, 1, v1, 0);

+            } else {

+                q0 = fpu_get_scratch(dyn);

+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, rex, 0, 0);

+                VLD1_64(q0, 1, ed);

+            }

+            VMOVeD(q0, 0, v0, 0);

+            SQXTN_16(v0, q0);

+            break;

 

         case 0x6E:

             INST_NAME("MOVD Gm, Ed");

@@ -662,7 +698,55 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     DEFAULT;

             }

             break;

-            

+        case 0x72:

+            nextop = F8;

+            switch((nextop>>3)&7) {

+                case 2:

+                    INST_NAME("PSRLD Em, Ib");

+                    GETEM(d0, 1);

+                    u8 = F8;

+                    if(u8) {

+                        if (u8>31) {

+                            VEOR(d0, d0, d0);

+                        } else if(u8) {

+                            VSHR_32(d0, d0, u8);

+                        }

+                        if(!MODREG) {

+                            VSTR64_U12(d0, ed, fixedaddress);

+                        }

+                    }

+                    break;

+                case 4:

+                    INST_NAME("PSRAD Em, Ib");

+                    GETEM(d0, 1);

+                    u8 = F8;

+                    if(u8>31) u8=31;

+                    if(u8) {

+                        VSSHR_32(d0, d0, u8);

+                    }

+                    if(!MODREG) {

+                        VSTR64_U12(d0, ed, fixedaddress);

+                    }

+                    break;

+                case 6:

+                    INST_NAME("PSLLD Em, Ib");

+                    GETEM(d0, 1);

+                    u8 = F8;

+                    if(u8) {

+                        if (u8>31) {

+                            VEOR(d0, d0, d0);

+                        } else {

+                            VSHL_32(d0, d0, u8);

+                        }

+                        if(!MODREG) {

+                            VSTR64_U12(d0, ed, fixedaddress);

+                        }

+                    }

+                    break;

+                default:

+                    DEFAULT;

+            }

+            break;

         case 0x73:

             nextop = F8;

             switch((nextop>>3)&7) {

@@ -703,7 +787,20 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             GETEM(d1, 0);

             VCMEQ_8(d0, d0, d1);

             break;

-

+        case 0x75:

+            INST_NAME("PCMPEQW Gm,Em");

+            nextop = F8;

+            GETGM(v0);

+            GETEM(q0, 0);

+            VCMEQ_16(v0, v0, q0);

+            break;

+        case 0x76:

+            INST_NAME("PCMPEQD Gm,Em");

+            nextop = F8;

+            GETGM(v0);

+            GETEM(v1, 0);

+            VCMEQ_32(v0, v0, v1);

+            break;

         case 0x77:

             INST_NAME("EMMS");

             // empty MMX, FPU now usable

@@ -1335,6 +1432,19 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             REVxw(gd, gd);

             break;

 

+        case 0xD3:

+            INST_NAME("PSRLQ Gm,Em");

+            nextop = F8;

+            GETGM(d0);

+            GETEM(d1, 0);

+            if(MODREG)

+                q0 = fpu_get_scratch(dyn);

+            else

+                q0 = d1;

+            NEG_64(q0, d1);

+            USHL_R_64(d0, d0, q0);

+            break;

+

         case 0xD5:

             INST_NAME("PMULLW Gm, Em");

             nextop = F8;

@@ -1501,6 +1611,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             SSHL_32(d0, d0, v0);

             break;

 

+        case 0xF5:

+            INST_NAME("PMADDWD Gx, Ex");

+            nextop = F8;

+            GETGM(v0);

+            GETEM(v1, 0);

+            q0 = fpu_get_scratch(dyn);

+            VSMULL_16(q0, v0, v1);

+            VADDPQ_32(q0, q0, q0); //ADDP from Q to non-Q?

+            VMOVQ(v0, q0);

+            break;

         case 0xF6:

             INST_NAME("PSADBW Gm, Em");

             nextop = F8;