From c9177ec2596044fcfce619994a94c41228285bbe Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 18 Oct 2023 17:46:31 +0200 Subject: [ARM64_DYNAREC] Preparing handling of FLAGM and FLAGM2 extensions --- src/dynarec/arm64/arm64_emitter.h | 22 +++++++++++++++++++++- src/dynarec/arm64/arm64_printer.c | 26 +++++++++++++++++++++++++- src/include/debug.h | 2 ++ src/main.c | 10 ++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) (limited to 'src') 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<