about summary refs log tree commit diff stats
path: root/src
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
parent0481589615582cfd7ef737ac90ccb9a9a19f3d41 (diff)
downloadbox64-c9177ec2596044fcfce619994a94c41228285bbe.tar.gz
box64-c9177ec2596044fcfce619994a94c41228285bbe.zip
[ARM64_DYNAREC] Preparing handling of FLAGM and FLAGM2 extensions
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/arm64_emitter.h22
-rw-r--r--src/dynarec/arm64/arm64_printer.c26
-rw-r--r--src/include/debug.h2
-rw-r--r--src/main.c10
4 files changed, 58 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;

diff --git a/src/include/debug.h b/src/include/debug.h
index a426a19a..f50e8554 100644
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -37,6 +37,8 @@ extern int arm64_aes;
 extern int arm64_pmull;
 extern int arm64_crc32;
 extern int arm64_atomics;
+extern int arm64_flagm;
+extern int arm64_flagm2;
 #elif defined(RV64)
 extern int rv64_zba;
 extern int rv64_zbb;
diff --git a/src/main.c b/src/main.c
index 8fde0052..d0f01e2b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -76,6 +76,7 @@ int arm64_aes = 0;
 int arm64_pmull = 0;
 int arm64_crc32 = 0;
 int arm64_atomics = 0;
+int arm64_flagm = 0;
 #elif defined(RV64)
 int rv64_zba = 0;
 int rv64_zbb = 0;
@@ -362,6 +363,11 @@ HWCAP2_ECV
         arm64_aes = 1;
     if(hwcap&HWCAP_ATOMICS)
         arm64_atomics = 1;
+    if(hwcap&HWCAP_FLAGM)
+        arm64_flagm = 1;
+    unsigned long hwcap2 = real_getauxval(AT_HWCAP2);
+    if(hwcap2&HWCAP2_FLAGM2)
+        arm64_flagm2 = 1;
     printf_log(LOG_INFO, "Dynarec for ARM64, with extension: ASIMD");
     if(arm64_aes)
         printf_log(LOG_INFO, " AES");
@@ -371,6 +377,10 @@ HWCAP2_ECV
         printf_log(LOG_INFO, " PMULL");
     if(arm64_atomics)
         printf_log(LOG_INFO, " ATOMICS");
+    if(arm64_flagm)
+        printf_log(LOG_INFO, " FLAGM");
+    if(arm64_flagm2)
+        printf_log(LOG_INFO, " FLAGM2");
     printf_log(LOG_INFO, " PageSize:%zd ", box64_pagesize);
 #elif defined(LA464)
     printf_log(LOG_INFO, "Dynarec for LoongArch");