diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-06-24 17:34:02 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-06-24 17:34:02 +0200 |
| commit | 579ae99d1b96f44709a4b4396d59d3e15bda26f7 (patch) | |
| tree | c1bed6fe2c904d7f4b711bc4d6ad49d5fdefe209 /src | |
| parent | fa702c0240d0741def3955697067b562cc7a7fcd (diff) | |
| download | box64-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.c | 9 | ||||
| -rw-r--r-- | src/dynarec/arm64/arm64_emitter.h | 2 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 19 | ||||
| -rw-r--r-- | src/include/debug.h | 1 |
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; |