diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-21 15:09:35 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-21 15:09:35 +0100 |
| commit | 1c8683343bd00d44e02ba5e89ebb90427840d3d6 (patch) | |
| tree | eb7519fdcfcd44cb8d05bea9b286a581c04866ca /src | |
| parent | 56f37e87455c04992f5b9c39443afde85e2316d6 (diff) | |
| download | box64-1c8683343bd00d44e02ba5e89ebb90427840d3d6.tar.gz box64-1c8683343bd00d44e02ba5e89ebb90427840d3d6.zip | |
[DYNAREC] Added 66 0F 2E/2F opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 8 | ||||
| -rwxr-xr-x | src/dynarec/arm64_printer.c | 11 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_660f.c | 13 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 40 |
4 files changed, 55 insertions, 17 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index 8dd42699..8078169a 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -365,6 +365,7 @@ #define MOV_toSP(Rm) ADDx_U12(xSP, Rm, 0) #define BICx(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b00, 0b00, 1, Rm, 0, Rn, Rd)) #define BICw(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 1, Rm, 0, Rn, Rd)) +#define BICw_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 1, Rm, lsl, Rn, Rd)) #define BICSx(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b00, 0b00, 1, Rm, 0, Rn, Rd)) #define BICSw(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 1, Rm, 0, Rn, Rd)) #define BICxw(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b00, 1, Rm, 0, Rn, Rd)) @@ -644,5 +645,12 @@ #define FSQRTS(Sd, Sn) EMIT(FSQRT_scalar(0b00, Sn, Sd)) #define FSQRTD(Dd, Dn) EMIT(FSQRT_scalar(0b01, Dn, Dd)) +// CMP +#define FCMP_scalar(type, Rn, Rm, opc) (0b11110<<24 | (type)<<22 | 1<<21 | (Rm)<<16 | 0b1000<<10 | (Rn)<<5 | (opc)<<3) +#define FCMPS(Sn, Sm) EMIT(FCMP_scalar(0b00, Sn, Sm, 0b00)) +#define FCMPD(Dn, Dm) EMIT(FCMP_scalar(0b01, Dn, Dm, 0b00)) +#define FCMPS_0(Sn) EMIT(FCMP_scalar(0b00, 0, Sn, 0b01)) +#define FCMPD_0(Dn) EMIT(FCMP_scalar(0b01, 0, Dn, 0b01)) + #endif //__ARM64_EMITTER_H__ diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index a8f44fde..90d6ac2c 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -856,6 +856,17 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) return buff; } + //CMP + if(isMask(opcode, "00011110ff1mmmmm001000nnnnn0c000", &a)) { + char s = (sf==0)?'S':((sf==1)?'D':'?'); + if(opc==1) + snprintf(buff, sizeof(buff), "FCMP %c%d, #0.0", s, Rn); + else + snprintf(buff, sizeof(buff), "FCMP %c%d, %c%d", s, Rn, s, Rm); + return buff; + } + + snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(opcode)); return buff; } \ No newline at end of file diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c index 19f432ea..4ecb8f1c 100755 --- a/src/dynarec/dynarec_arm64_660f.c +++ b/src/dynarec/dynarec_arm64_660f.c @@ -98,6 +98,19 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; + case 0x2E: + // no special check... + case 0x2F: + if(opcode==0x2F) {INST_NAME("COMISD Gx, Ex");} else {INST_NAME("UCOMISD Gx, Ex");} + SETFLAGS(X_ALL, SF_SET); + nextop = F8; + gd = ((nextop&0x38)>>3) + (rex.r<<3); + v0 = sse_get_reg(dyn, ninst, x1, gd); + GETEX(q0, 0); + FCMPD(v0, q0); + FCOMI(x1, x2); + break; + #define GO(GETFLAGS, NO, YES, F) \ READFLAGS(F); \ GETFLAGS; \ diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index c814d89f..e629c9f9 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -296,35 +296,41 @@ #define IFXN(A, B) if(dyn->insts && (dyn->insts[ninst].x64.need_flags&(A) && !(dyn->insts[ninst].x64.need_flags&(B)))) // Generate FCOM with s1 and s2 scratch regs (the VCMP is already done) -#define FCOM(s1, s2) \ - VMRS_APSR(); /* 0b0100011100000000 */ \ - LDRH_IMM8(s1, xEmu, offsetof(x64emu_t, sw)); /*offset is 8bits right?*/ \ - BIC_IMM8(s1, s1, 0b01000111, 12); \ - ORR_IMM8_COND(cVS, s1, s1, 0b01000101, 12); /* unordered */ \ - ORR_IMM8_COND(cEQ, s1, s1, 0b01000000, 12); /* equal */ \ - ORR_IMM8_COND(cMI, s1, s1, 0b00000001, 12); /* less than */ \ - /* greater than leave 0 */ \ - STRH_IMM8(s1, xEmu, offsetof(x64emu_t, sw)) +#define FCOM(s1, s2, s3) \ + LDRH_U12(s3, xEmu, offsetof(x64emu_t, sw)); /*offset is 8bits right?*/\ + MOV32w(s1, 0b01000111); \ + BICw_REG_LSL(s3, s3, s1, 8); \ + CSETw(s1, cMI); /* 1 if less than, 0 else */ \ + MOV32w(s2, 0b01000101); /* unordered */ \ + CSELw(s1, s2, s1, cVS); \ + MOV32w(s2, 0b01000000); /* zero */ \ + CSELw(s1, s2, s1, cEQ); \ + /* greater than leave 0 */ \ + ORRw_REG_LSL(s3, s3, s1, 8); \ + STRH_U12(s3, xEmu, offsetof(x64emu_t, sw)) // Generate FCOMI with s1 and s2 scratch regs (the VCMP is already done) #define FCOMI(s1, s2) \ IFX(X_CF|X_PF|X_ZF|X_PEND) { \ - VMRS_APSR(); /* 0b111 */ \ - BIC_IMM8(xFlags, xFlags, 0b1000101, 0); \ - ORR_IMM8_COND(cVS, xFlags, xFlags, 0b01000101, 0); /* unordered */ \ - ORR_IMM8_COND(cEQ, xFlags, xFlags, 0b01000000, 0); /* zero */ \ - ORR_IMM8_COND(cMI, xFlags, xFlags, 0b00000001, 0); /* less than */ \ + MOV32w(s1, 0b01000101); \ + BICw_REG(xFlags, xFlags, s1); \ + CSETw(s1, cMI); /* 1 if less than, 0 else */ \ + MOV32w(s2, 0b01000101); /* unordered */ \ + CSELw(s1, s2, s1, cVS); \ + MOV32w(s2, 0b01000000); /* zero */ \ + CSELw(s1, s2, s1, cEQ); \ /* greater than leave 0 */ \ + ORRw_REG(xFlags, xFlags, s1); \ } \ SET_DFNONE(s1); \ IFX(X_OF|X_PEND) { \ - BFC(xFlags, F_OF, 1); \ + BFCw(xFlags, F_OF, 1); \ } \ IFX(X_AF|X_PEND) { \ - BFC(xFlags, F_AF, 1); \ + BFCw(xFlags, F_AF, 1); \ } \ IFX(X_SF|X_PEND) { \ - BFC(xFlags, F_SF, 1); \ + BFCw(xFlags, F_SF, 1); \ } \ |