From 2b6fa580df14e02e9bfdf9a3b23e56b7515d5c2a Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Tue, 23 Mar 2021 10:00:29 +0100 Subject: [DYNAREC] Added F3 0F C2 opcode --- src/dynarec/arm64_emitter.h | 11 +++++++++++ src/dynarec/arm64_printer.c | 10 ++++++++++ src/dynarec/dynarec_arm64_f30f.c | 25 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+) (limited to 'src') diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index 102a381a..3f1533df 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -346,6 +346,17 @@ #define CSETw(Rd, cond) CSINCw(Rd, xZR, xZR, invCond(cond)) #define CSETxw(Rd, cond) CSINCxw(Rd, xZR, xZR, invCond(cond)) +#define CSINV_gen(sf, Rm, cond, Rn, Rd) ((sf)<<31 | 1<<30 | 0b11010100<<21 | (Rm)<<16 | (cond)<<12 | (Rn)<<5 | (Rd)) +#define CSINVx(Rd, Rn, Rm, cond) EMIT(CSINV_gen(1, Rm, cond, Rn, Rd)) +#define CSINVw(Rd, Rn, Rm, cond) EMIT(CSINV_gen(0, Rm, cond, Rn, Rd)) +#define CSINVxw(Rd, Rn, Rm, cond) EMIT(CSINV_gen(rex.w?, Rm, cond, Rn, Rd)) +#define CINVx(Rd, Rn, cond) CSINVx(Rd, Rn, Rn, invertCond(cond)) +#define CINVw(Rd, Rn, cond) CSINVw(Rd, Rn, Rn, invertCond(cond)) +#define CINVxw(Rd, Rn, cond) CSINVxw(Rd, Rn, Rn, invertCond(cond)) +#define CSETMx(Rd, cond) CSINVx(Rd, xZR, xZR, invCond(cond)) +#define CSETMw(Rd, cond) CSINVw(Rd, xZR, xZR, invCond(cond)) +#define CSETMxw(Rd, cond) CSINVxw(Rd, xZR, xZR, invCond(cond)) + #define CSEL_gen(sf, Rm, cond, Rn, Rd) ((sf<<31) | 0b11010100<<21 | (Rm)<<16 | (cond)<<12 | (Rn)<<5 | Rd) #define CSELx(Rd, Rn, Rm, cond) EMIT(CSEL_gen(1, Rm, cond, Rn, Rd)) #define CSELw(Rd, Rn, Rm, cond) EMIT(CSEL_gen(0, Rm, cond, Rn, Rd)) diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index 14255e48..8d9aedfe 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -699,6 +699,16 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) return buff; } + if(isMask(opcode, "f1011010100mmmmmdddd00nnnnnddddd", &a)) { + if(Rm!=31 && (cond&0b1110)!=0b1110 && Rn!=31 && Rn==Rm) + snprintf(buff, sizeof(buff), "CINV %s, %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond^1]); + else if(Rm==31 && (cond&0b1110)!=0b1110 && Rn==31) + snprintf(buff, sizeof(buff), "CSETM %s,%s", sf?Xt[Rd]:Wt[Rd], conds[cond^1]); + else + snprintf(buff, sizeof(buff), "CSINV %s, %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond]); + return buff; + } + if(isMask(opcode, "f1011010100mmmmmcccc01nnnnnddddd", &a)) { if((cond&0b1110)!=0b1110 && Rn==Rm) snprintf(buff, sizeof(buff), "CNEG %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], conds[cond^1]); diff --git a/src/dynarec/dynarec_arm64_f30f.c b/src/dynarec/dynarec_arm64_f30f.c index 5b0352f7..c24346a6 100755 --- a/src/dynarec/dynarec_arm64_f30f.c +++ b/src/dynarec/dynarec_arm64_f30f.c @@ -188,6 +188,31 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; + case 0xC2: + INST_NAME("CMPSS Gx, Ex, Ib"); + nextop = F8; + GETGX(v0); + GETEX(v1, 1); + u8 = F8; + if((u8&7)==6){ + FCMPS(v1, v0); + } else { + FCMPS(v0, v1); + } + MOV32w(x2, 0); + switch(u8&7) { + case 0: CSETMw(x2, cEQ); break; // Equal + case 1: CSETMw(x2, cMI); break; // Less than + case 2: CSETMw(x2, cLE); break; // Less or equal + case 3: CSETMw(x2, cVS); break; // NaN + case 4: CSETMw(x2, cNE); break; // Not Equal (or unordered on ARM, not on X86...) + case 5: CSETMw(x2, cCS); break; // Greater or equal or unordered + case 6: CSETMw(x2, cLT); break; // Greater or unordered, test inverted, N!=V so unordereded or less than (inverted) + case 7: CSETMw(x2, cVC); break; // not NaN + } + VMOVQSfrom(v0, 0, x2); + break; + default: DEFAULT; } -- cgit 1.4.1