diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-10-18 17:46:31 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-10-18 17:46:31 +0200 |
| commit | c9177ec2596044fcfce619994a94c41228285bbe (patch) | |
| tree | 4a06b4535e0f690ae1e1e0ef7f6cd565d5a902a8 /src | |
| parent | 0481589615582cfd7ef737ac90ccb9a9a19f3d41 (diff) | |
| download | box64-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.h | 22 | ||||
| -rw-r--r-- | src/dynarec/arm64/arm64_printer.c | 26 | ||||
| -rw-r--r-- | src/include/debug.h | 2 | ||||
| -rw-r--r-- | src/main.c | 10 |
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"); |