about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-10-18 17:46:31 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-10-18 17:46:31 +0200
commitc9177ec2596044fcfce619994a94c41228285bbe (patch)
tree4a06b4535e0f690ae1e1e0ef7f6cd565d5a902a8 /src/dynarec
parent0481589615582cfd7ef737ac90ccb9a9a19f3d41 (diff)
downloadbox64-c9177ec2596044fcfce619994a94c41228285bbe.tar.gz
box64-c9177ec2596044fcfce619994a94c41228285bbe.zip
[ARM64_DYNAREC] Preparing handling of FLAGM and FLAGM2 extensions
Diffstat (limited to 'src/dynarec')
-rw-r--r--src/dynarec/arm64/arm64_emitter.h22
-rw-r--r--src/dynarec/arm64/arm64_printer.c26
2 files changed, 46 insertions, 2 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index 3f8105ef..4924f9c1 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -1939,7 +1939,7 @@
 #define PMULL_128(Rd, Rn, Rm)   EMIT(PMULL_gen(0, 0b11, Rm, Rn, Rd))
 #define PMULL2_128(Rd, Rn, Rm)  EMIT(PMULL_gen(1, 0b11, Rm, Rn, Rd))
 
-// Atomic extension
+// ATOMIC extension
 #define ATOMIC_gen(size, A, R, Rs, opc, Rn, Rt) ((size)<<30 | 0b111<<27 | (A)<<23 | (R)<<22 | 1<<21 | (Rs)<<16 | (opc)<<12 | (Rn)<<5 | (Rt))
 // Atomic ADD
 #define LDADDxw(Rs, Rt, Rn)             EMIT(ATOMIC_gen(0b10+rex.w, 0, 0, Rs, 0b000, Rn, Rt))
@@ -2130,4 +2130,24 @@
 #define CASPALxw(Rs, Rt, Rn)            EMIT(CASP_gen(0b00+rex.w, 1, Rs, 1, Rn, Rt))
 #define CASPLxw(Rs, Rt, Rn)             EMIT(CASP_gen(0b00+rex.w, 0, Rs, 1, Rn, Rt))
 
+// FLAGM extension
+// Invert Carry Flag
+#define CFINV()             EMIT(0b1101010100<<22 | 0b0100<<12 | 0b000<<5 | 0b11111)
+
+#define RMIF_gen(imm6, Rn, mask)        (0b10111010000<<21 | (imm6)<<15 | 0b00001<<10 | (Rn)<<5 | (mask))
+// Rotate right reg and use as NZCV
+#define RMIF(Xn, shift, mask)           EMIT(RMIF_gen(shift, Xn, mask))
+
+#define SETF_gen(sz, Rn)                (0b00111010000<<21 | (sz)<<14 | 0b0010<<10 | (Rn)<<5 | 0b1101)
+// Set NZVc with 8bit value of reg: N=bit7, Z=[0..7]==0, V=bit8 eor bit7, C unchanged
+#define SETF8(Wn)                       EMIT(SETF_gen(0, Wn))
+// Set NZVc with 16bit value of reg: N=bit15, Z=[0..15]==0, V=bit16 eor bit15, C unchanged
+#define SETF16(Wn)                      EMIT(SETF_gen(1, Wn))
+
+// FLAGM2 extension
+// NZCV -> N=0 Z=C|V C=C&!V V=0
+#define AXFLAG()            EMIT(0b1101010100<<22 | 0b0100<<12 | 0b010<<5 | 0b11111)
+// NZCV -> N=!C&!Z Z=Z&C C=C|Z V=!C&Z
+#define XAFLAG()            EMIT(0b1101010100<<22 | 0b0100<<12 | 0b001<<5 | 0b11111)
+
 #endif  //__ARM64_EMITTER_H__
diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c
index 5f7433f3..1d95b6f8 100644
--- a/src/dynarec/arm64/arm64_printer.c
+++ b/src/dynarec/arm64/arm64_printer.c
@@ -1620,7 +1620,31 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         }

         return buff;

     }

-

+    // AXFLAG

+    if(isMask(opcode, "11010101000000000100000001011111", &a)) {

+        snprintf(buff, sizeof(buff), "AXFLAG");

+        return buff;

+    }

+    // XAFLAG

+    if(isMask(opcode, "11010101000000000100000000111111", &a)) {

+        snprintf(buff, sizeof(buff), "XAFLAG");

+        return buff;

+    }

+    // CFINV

+    if(isMask(opcode, "11010101000000000100000000011111", &a)) {

+        snprintf(buff, sizeof(buff), "CFINV");

+        return buff;

+    }

+    // RMIF

+    if(isMask(opcode, "10111010000iiiiii00001nnnnn0oooo", &a)) {

+        snprintf(buff, sizeof(buff), "RMIF %s, #%d, #0x%x", Xt[Rn], imm, opc);

+        return buff;

+    }

+    // SETF

+    if(isMask(opcode, "00111010000000000f0010nnnnn01101", &a)) {

+        snprintf(buff, sizeof(buff), "SETF%d %s", 8<<sf, Xt[Rn]);

+        return buff;

+    }

 

     snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(opcode));

     return buff;