about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-04-02 14:41:19 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-04-02 14:41:19 +0200
commit817c3d7058e9a7ee6b7c8edaccd880075d762271 (patch)
treeef76949f9b5f1680f6a6b839e7570e21f1572cce /src
parente2a7dd0f1760b0567067d20e55021746b57b2a37 (diff)
downloadbox64-817c3d7058e9a7ee6b7c8edaccd880075d762271.tar.gz
box64-817c3d7058e9a7ee6b7c8edaccd880075d762271.zip
Added 0F E0 opcode ([DYNAREC] too)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h29
-rwxr-xr-xsrc/dynarec/arm64_printer.c13
-rwxr-xr-xsrc/dynarec/dynarec_arm64_0f.c8
-rw-r--r--src/emu/x64run0f.c8
4 files changed, 57 insertions, 1 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index e4d130a1..bea887dc 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -1467,4 +1467,33 @@
 #define UMINQ_32(Vd, Vn, Vm)        EMIT(MINMAX_vector(1, 1, 0b10, Vm, 1, Vn, Vd))
 #define UMINQ_64(Vd, Vn, Vm)        EMIT(MINMAX_vector(1, 1, 0b11, Vm, 1, Vn, Vd))
 
+// HADD vector
+#define HADD_vector(Q, U, size, Rm, Rn, Rd)     ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 1<<10 | (Rn)<<5 | (Rd))
+#define SHADD_8(Vd, Vn, Vm)         EMIT(HADD_vector(0, 0, 0b00, Vm, Vn, Vd))
+#define SHADD_16(Vd, Vn, Vm)        EMIT(HADD_vector(0, 0, 0b01, Vm, Vn, Vd))
+#define SHADD_32(Vd, Vn, Vm)        EMIT(HADD_vector(0, 0, 0b10, Vm, Vn, Vd))
+#define SHADDQ_8(Vd, Vn, Vm)        EMIT(HADD_vector(1, 0, 0b00, Vm, Vn, Vd))
+#define SHADDQ_16(Vd, Vn, Vm)       EMIT(HADD_vector(1, 0, 0b01, Vm, Vn, Vd))
+#define SHADDQ_32(Vd, Vn, Vm)       EMIT(HADD_vector(1, 0, 0b10, Vm, Vn, Vd))
+#define UHADD_8(Vd, Vn, Vm)         EMIT(HADD_vector(0, 1, 0b00, Vm, Vn, Vd))
+#define UHADD_16(Vd, Vn, Vm)        EMIT(HADD_vector(0, 1, 0b01, Vm, Vn, Vd))
+#define UHADD_32(Vd, Vn, Vm)        EMIT(HADD_vector(0, 1, 0b10, Vm, Vn, Vd))
+#define UHADDQ_8(Vd, Vn, Vm)        EMIT(HADD_vector(1, 1, 0b00, Vm, Vn, Vd))
+#define UHADDQ_16(Vd, Vn, Vm)       EMIT(HADD_vector(1, 1, 0b01, Vm, Vn, Vd))
+#define UHADDQ_32(Vd, Vn, Vm)       EMIT(HADD_vector(1, 1, 0b10, Vm, Vn, Vd))
+
+#define RHADD_vector(Q, U, size, Rm, Rn, Rd)    ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 0b00010<<11 | 1<<10 | (Rn)<<5 | (Rd))
+#define SRHADD_8(Vd, Vn, Vm)        EMIT(RHADD_vector(0, 0, 0b00, Vm, Vn, Vd))
+#define SRHADD_16(Vd, Vn, Vm)       EMIT(RHADD_vector(0, 0, 0b01, Vm, Vn, Vd))
+#define SRHADD_32(Vd, Vn, Vm)       EMIT(RHADD_vector(0, 0, 0b10, Vm, Vn, Vd))
+#define SRHADDQ_8(Vd, Vn, Vm)       EMIT(RHADD_vector(1, 0, 0b00, Vm, Vn, Vd))
+#define SRHADDQ_16(Vd, Vn, Vm)      EMIT(RHADD_vector(1, 0, 0b01, Vm, Vn, Vd))
+#define SRHADDQ_32(Vd, Vn, Vm)      EMIT(RHADD_vector(1, 0, 0b10, Vm, Vn, Vd))
+#define URHADD_8(Vd, Vn, Vm)        EMIT(RHADD_vector(0, 1, 0b00, Vm, Vn, Vd))
+#define URHADD_16(Vd, Vn, Vm)       EMIT(RHADD_vector(0, 1, 0b01, Vm, Vn, Vd))
+#define URHADD_32(Vd, Vn, Vm)       EMIT(RHADD_vector(0, 1, 0b10, Vm, Vn, Vd))
+#define URHADDQ_8(Vd, Vn, Vm)       EMIT(RHADD_vector(1, 1, 0b00, Vm, Vn, Vd))
+#define URHADDQ_16(Vd, Vn, Vm)      EMIT(RHADD_vector(1, 1, 0b01, Vm, Vn, Vd))
+#define URHADDQ_32(Vd, Vn, Vm)      EMIT(RHADD_vector(1, 1, 0b10, Vm, Vn, Vd))
+
 #endif  //__ARM64_EMITTER_H__
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index bd2aaa65..556b2a2a 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -1176,6 +1176,19 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         snprintf(buff, sizeof(buff), "%cADDLV V%d.%s, V%d.%s", a.U?'U':'S', Rd, Z[sf], Rn, Vd);

         return buff;

     }

+    // HADD

+    if(isMask(opcode, "0QU01110ff1mmmmm000001nnnnnddddd", &a)) {

+        const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "???"};

+        const char* Vd = Y[(sf<<1) | a.Q];

+        snprintf(buff, sizeof(buff), "%cHADD V%d.%s, V%d.%s, V%d.%s", a.U?'U':'S', Rd, Vd, Rn, Vd, Rm, Vd);

+        return buff;

+    }

+    if(isMask(opcode, "0QU01110ff1mmmmm000101nnnnnddddd", &a)) {

+        const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "???"};

+        const char* Vd = Y[(sf<<1) | a.Q];

+        snprintf(buff, sizeof(buff), "%cRHADD V%d.%s, V%d.%s, V%d.%s", a.U?'U':'S', Rd, Vd, Rn, Vd, Rm, Vd);

+        return buff;

+    }

     

     // MOV immediate

     if(isMask(opcode, "0Q00111100000iii111001iiiiiddddd", &a)) {

diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c
index 58380dfe..194f4f69 100755
--- a/src/dynarec/dynarec_arm64_0f.c
+++ b/src/dynarec/dynarec_arm64_0f.c
@@ -1275,6 +1275,14 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             VMUL_16(q0, q0, q1);

             break;

 

+         case 0xE0:

+            INST_NAME("PAVGB Gm, Em");

+            nextop = F8;

+            GETGM(v0);

+            GETEM(v1, 0);

+            URHADD_8(v0, v0, v1);

+            break;

+

         case 0xE7:

             INST_NAME("MOVNTQ Em, Gm"); // Non Temporal par not handled for now

             nextop = F8;

diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 3aeb8c9a..6037f073 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -1308,7 +1308,13 @@ int Run0F(x64emu_t *emu, rex_t rex)
             GETGM;

             GM->q = (~GM->q) & EM->q;

             break;

-

+        case 0xE0:                   /* PAVGB Gm, Em */

+            nextop = F8;

+            GETEM(0);

+            GETGM;

+            for(int i=0; i<8; ++i)

+                    GM->ub[i] = ((uint32_t)GM->ub[i]+EM->ub[i]+1)>>1;

+            break;

         case 0xE1:                   /* PSRAW Gm, Em */

             nextop = F8;

             GETEM(0);