about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-06-24 17:34:02 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-06-24 17:34:02 +0200
commit579ae99d1b96f44709a4b4396d59d3e15bda26f7 (patch)
treec1bed6fe2c904d7f4b711bc4d6ad49d5fdefe209 /src
parentfa702c0240d0741def3955697067b562cc7a7fcd (diff)
downloadbox64-579ae99d1b96f44709a4b4396d59d3e15bda26f7.tar.gz
box64-579ae99d1b96f44709a4b4396d59d3e15bda26f7.zip
[ARM64_DYNAREC] Added 0F C7 /6 opcode, with hardware support if present
Diffstat (limited to 'src')
-rw-r--r--src/core.c9
-rw-r--r--src/dynarec/arm64/arm64_emitter.h2
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c19
-rw-r--r--src/include/debug.h1
4 files changed, 31 insertions, 0 deletions
diff --git a/src/core.c b/src/core.c
index 3d940b4d..88a14416 100644
--- a/src/core.c
+++ b/src/core.c
@@ -100,6 +100,7 @@ int arm64_flagm = 0;
 int arm64_flagm2 = 0;
 int arm64_frintts = 0;
 int arm64_afp = 0;
+int arm64_rndr = 0;
 #elif defined(RV64)
 int rv64_zba = 0;
 int rv64_zbb = 0;
@@ -386,6 +387,8 @@ HWCAP2_MTE
     Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0010. => Full Memory Tagging Extension is implemented.
 HWCAP2_ECV
     Functionality implied by ID_AA64MMFR0_EL1.ECV == 0b0001.
+HWCAP2_AFP
+    AFP = 0b0001 => The AArch64-FPCR.{AH, FIZ, NEP} fields are supported. (Alternate floating-point behavior)
 */
     unsigned long hwcap = real_getauxval(AT_HWCAP);
     if(!hwcap)  // no HWCap: provide a default...
@@ -433,6 +436,10 @@ HWCAP2_ECV
     if(hwcap2&HWCAP2_AFP)
         arm64_afp = 1;
     #endif
+    #ifdef HWCAP2_RNG
+    if(hwcap2&HWCAP2_RNG)
+        arm64_rndr = 1;
+    #endif
     printf_log(LOG_INFO, "Dynarec for ARM64, with extension: ASIMD");
     if(arm64_aes)
         printf_log(LOG_INFO, " AES");
@@ -456,6 +463,8 @@ HWCAP2_ECV
         printf_log(LOG_INFO, " FRINT");
     if(arm64_afp)
         printf_log(LOG_INFO, " AFP");
+    if(arm64_rndr)
+        printf_log(LOG_INFO, " RNDR");
 #elif defined(LA64)
     printf_log(LOG_INFO, "Dynarec for LoongArch ");
     char* p = getenv("BOX64_DYNAREC_LA64NOEXT");
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index f0d4c4b8..69871657 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -784,6 +784,8 @@ int convert_bitmask(uint64_t bitmask);
 #define MRS_cntvct_el0(Rt)              EMIT(MRS_gen(1, 1, 0b011, 0b1110, 0b0000, 0b010, Rt))
 // mrs   x0, cntpctss_el0     op0=0b11 op1=0b011 CRn=0b1110 CRm=0b0000 op2=0b101
 #define MRS_cntpctss_el0(Rt)            EMIT(MRS_gen(1, 1, 0b011, 0b1110, 0b0000, 0b101, Rt))
+// mrs   rt, rndr           op0=0b11	op1=0b011	CRn=0b0010	CRm=0b0100	op2=0b000
+#define MRS_rndr(Rt)                    EMIT(MRS_gen(1, 1, 0b011, 0b0010, 0b0100, 0b000, Rt))
 // NEON Saturation Bit
 #define FPSR_QC 27
 // NEON Input Denormal Cumulative
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 545a9554..8544d805 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -2369,6 +2369,25 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 FAKEED;

                 UDF(0);

                 break;

+            case 6:

+                INST_NAME("RNDR Ed");

+                SETFLAGS(X_ALL, SF_SET_DF);

+                SET_DFNONE(x1);

+                IFX(F_OF|F_SF|F_ZF|F_PF|F_AF) {

+                    MOV32w(x1, (1<<F_OF)|(1<<F_SF)|(1<<F_ZF)|(1<<F_PF)|(1<<F_AF));

+                    BICw(xFlags, xFlags, x1);

+                }

+                if(arm64_rndr) {

+                    MRS_rndr(x1);

+                    IFX(X_CF) { CSETw(x3, cNE); }

+                } else {

+                    CALL(rex.w?((void*)get_random64):((void*)get_random32), x1);

+                    IFX(X_CF) { MOV32w(x3, 1); }

+                }

+                IFX(X_CF) { BFIw(xFlags, x3, F_CF, 1); }

+                addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0);

+                STxw(x1, wback, fixedaddress);

+                break;

             default:

                 DEFAULT;

             }

diff --git a/src/include/debug.h b/src/include/debug.h
index 4af3b0cb..a6892097 100644
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -47,6 +47,7 @@ extern int arm64_uscat;
 extern int arm64_flagm;
 extern int arm64_flagm2;
 extern int arm64_frintts;
+extern int arm64_rndr;
 #elif defined(RV64)
 extern int rv64_zba;
 extern int rv64_zbb;