about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-31 18:30:17 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-03-31 18:30:17 +0200
commitd119ae5ed49cde2f7cd912ed6408c74228b5106c (patch)
tree79e238bcada377bd25234fd187dbfb1f706f42ec /src
parentd78dbbe4c72f48d8c8b74b304192c783eb0649e3 (diff)
downloadbox64-d119ae5ed49cde2f7cd912ed6408c74228b5106c.tar.gz
box64-d119ae5ed49cde2f7cd912ed6408c74228b5106c.zip
[DYNAREC] Add 66 0F E4 opcode
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h15
-rwxr-xr-xsrc/dynarec/dynarec_arm64_660f.c13
2 files changed, 28 insertions, 0 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index d4666ae9..0e4d41a6 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -1392,4 +1392,19 @@
 #define SXTL_32(Vd, Vn)             SSHLL_32(Vd, Vn, 0)
 #define SXTL2_32(Vd, Vn)            SSHLL2_32(Vd, Vn, 0)
 
+// SHRN
+#define QSHRN_vector(Q, U, immh, immb, op, Rn, Rd)  ((Q)<<30 | (U)<<29 | 0b011110<<23 | (immh)<<19 | (immb)<<16 | 0b1001<<12 | (op)<<11 | 1<<10 | (Rn)<<5 | (Rd))
+#define UQSHRN_8(Vd, Vn, imm)       EMIT(QSHRN_vector(0, 1, 0b0001, (8-(imm))&0x7, 0, Vn, Vd))
+#define UQSHRN2_8(Vd, Vn, imm)      EMIT(QSHRN_vector(1, 1, 0b0001, (8-(imm))&0x7, 0, Vn, Vd))
+#define SQSHRN_8(Vd, Vn, imm)       EMIT(QSHRN_vector(0, 0, 0b0001, (8-(imm))&0x7, 0, Vn, Vd))
+#define SQSHRN2_8(Vd, Vn, imm)      EMIT(QSHRN_vector(1, 0, 0b0001, (8-(imm))&0x7, 0, Vn, Vd))
+#define UQSHRN_16(Vd, Vn, imm)      EMIT(QSHRN_vector(0, 1, 0b0010|(((16-(imm))>>3)&1), (16-(imm))&0x7, 0, Vn, Vd))
+#define UQSHRN2_16(Vd, Vn, imm)     EMIT(QSHRN_vector(1, 1, 0b0010|(((16-(imm))>>3)&1), (16-(imm))&0x7, 0, Vn, Vd))
+#define SQSHRN_16(Vd, Vn, imm)      EMIT(QSHRN_vector(0, 0, 0b0010|(((16-(imm))>>3)&1), (16-(imm))&0x7, 0, Vn, Vd))
+#define SQSHRN2_16(Vd, Vn, imm)     EMIT(QSHRN_vector(1, 0, 0b0010|(((16-(imm))>>3)&1), (16-(imm))&0x7, 0, Vn, Vd))
+#define UQSHRN_32(Vd, Vn, imm)      EMIT(QSHRN_vector(0, 1, 0b0100|(((32-(imm))>>3)&3), (32-(imm))&0x7, 0, Vn, Vd))
+#define UQSHRN2_32(Vd, Vn, imm)     EMIT(QSHRN_vector(1, 1, 0b0100|(((32-(imm))>>3)&3), (32-(imm))&0x7, 0, Vn, Vd))
+#define SQSHRN_32(Vd, Vn, imm)      EMIT(QSHRN_vector(0, 0, 0b0100|(((32-(imm))>>3)&3), (32-(imm))&0x7, 0, Vn, Vd))
+#define SQSHRN2_32(Vd, Vn, imm)     EMIT(QSHRN_vector(1, 0, 0b0100|(((32-(imm))>>3)&3), (32-(imm))&0x7, 0, Vn, Vd))
+
 #endif  //__ARM64_EMITTER_H__
diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c
index 5e001b6a..ec01d35c 100755
--- a/src/dynarec/dynarec_arm64_660f.c
+++ b/src/dynarec/dynarec_arm64_660f.c
@@ -1002,6 +1002,19 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             VBICQ(v0, q0, v0);

             break;

 

+        case 0xE4:

+            INST_NAME("PMULHUW Gx,Ex");

+            nextop = F8;

+            GETGX(v0);

+            GETEX(v1, 0);

+            q0 = fpu_get_scratch(dyn);

+            q1 = fpu_get_scratch(dyn);

+            VUMULL_16(q0, v0, v1);

+            VUMULL2_16(q1, v0, v1);

+            UQSHRN_16(v0, q0, 16);

+            UQSHRN2_16(v0, q1, 16);

+            break;

+

         case 0xEB:

             INST_NAME("POR Gx,Ex");

             nextop = F8;