diff options
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f30f.c | 35 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 26 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_emitter.h | 18 |
3 files changed, 78 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c index 4aa1a12b..c50196e0 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f.c @@ -85,6 +85,41 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int nextop = F8; FAKEED; break; + + case 0x2A: + INST_NAME("CVTSI2SS Gx, Ed"); + nextop = F8; + GETGXSS(v0); + GETED(0); + if(rex.w) { + FCVTSL(v0, ed); + } else { + FCVTSW(v0, ed); + } + break; + + case 0x58: + INST_NAME("ADDSS Gx, Ex"); + nextop = F8; + GETGXSS(v0); + GETEXSS(d0, 0); + FADDS(v0, v0, d0); + break; + case 0x59: + INST_NAME("MULSS Gx, Ex"); + nextop = F8; + GETGXSS(v0); + GETEXSS(d0, 0); + FMULS(v0, v0, d0); + break; + case 0x5A: + INST_NAME("CVTSS2SD Gx, Ex"); + nextop = F8; + GETEXSS(v1, 0); + GETGXSD_empty(v0); + FCVTDS(v0, v1); + break; + default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 17247fb7..986b5ac8 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -272,6 +272,32 @@ // Generic get GD, but reg value in gd (R_RAX is not added) #define GETG gd = ((nextop&0x38)>>3)+(rex.r<<3) +// Get GX as a Single (might use x1) +#define GETGXSS(a) \ + gd = ((nextop&0x38)>>3)+(rex.r<<3); \ + a = sse_get_reg(dyn, ninst, x1, gd, 1) + +// Get GX as a Double (might use x1) +#define GETGXSD(a) \ + gd = ((nextop&0x38)>>3)+(rex.r<<3); \ + a = sse_get_reg(dyn, ninst, x1, gd, 0) + +// Get GX as a Double (might use x1), no fetching old value +#define GETGXSD_empty(a) \ + gd = ((nextop&0x38)>>3)+(rex.r<<3); \ + a = sse_get_reg_empty(dyn, ninst, x1, gd, 0) + +// Get Ex as a single, not a quad (warning, x1 get used, x2 might too) +#define GETEXSS(a, D) \ + if(MODREG) { \ + a = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1); \ + } else { \ + SMREAD(); \ + a = fpu_get_scratch(dyn); \ + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \ + FLW(a, ed, fixedaddress); \ + } + // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1) // R0 will not be pushed/popd if ret is -2 #define CALL(F, ret) call_c(dyn, ninst, F, x6, ret, 1, 0) diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index 242f27ee..cda28da2 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -383,7 +383,15 @@ f28–31 ft8–11 FP temporaries Caller // Move to Single #define FMVWX(frd, rs1) EMIT(R_type(0b1111000, 0b00000, rs1, 0b000, frd, 0b1010011)) // Convert from signed 32bits to Single -#define FCVTSW(frd, rs1) EMIT(R_type(0b1101000, 0b00000, rs1, 0b000, frd, 0b1010011)) +#define FCVTSW(frd, rs1) EMIT(R_type(0b1101000, 0b00000, rs1, 0b000, frd, 0b1010011)) + +#define FADDS(frd, frs1, frs2) EMIT(R_type(0b0000000, frs2, frs1, 0b000, frd, 0b1010011)) +#define FSUBS(frd, frs1, frs2) EMIT(R_type(0b0000100, frs2, frs1, 0b000, frd, 0b1010011)) +#define FMULS(frd, frs1, frs2) EMIT(R_type(0b0001000, frs2, frs1, 0b000, frd, 0b1010011)) +#define FDIVS(frd, frs1, frs2) EMIT(R_type(0b0001100, frs2, frs1, 0b000, frd, 0b1010011)) +#define FSQRTS(frd, frs1) EMIT(R_type(0b0101100, 0b00000, frs1, 0b000, frd, 0b1010011)) +#define FMINS(frd, frs1, frs2) EMIT(R_type(0b0010100, frs2, frs1, 0b000, frd, 0b1010011)) +#define FMAXS(frd, frs1, frs2) EMIT(R_type(0b0010100, frs2, frs1, 0b001, frd, 0b1010011)) // RV64F // Convert from signed 64bits to Single @@ -414,6 +422,14 @@ f28–31 ft8–11 FP temporaries Caller // Convert from signed 32bits to Double #define FCVTDW(frd, rs1) EMIT(R_type(0b1101001, 0b00000, rs1, 0b000, frd, 0b1010011)) +#define FADDD(frd, frs1, frs2) EMIT(R_type(0b0000001, frs2, frs1, 0b000, frd, 0b1010011)) +#define FSUBD(frd, frs1, frs2) EMIT(R_type(0b0000101, frs2, frs1, 0b000, frd, 0b1010011)) +#define FMULD(frd, frs1, frs2) EMIT(R_type(0b0001001, frs2, frs1, 0b000, frd, 0b1010011)) +#define FDIVD(frd, frs1, frs2) EMIT(R_type(0b0001101, frs2, frs1, 0b000, frd, 0b1010011)) +#define FSQRTD(frd, frs1) EMIT(R_type(0b0101101, 0b00000, frs1, 0b000, frd, 0b1010011)) +#define FMIND(frd, frs1, frs2) EMIT(R_type(0b0010101, frs2, frs1, 0b000, frd, 0b1010011)) +#define FMAXD(frd, frs1, frs2) EMIT(R_type(0b0010101, frs2, frs1, 0b001, frd, 0b1010011)) + //RV64D // Move from Double #define FMVXD(rd, frs1) EMIT(R_type(0b1110001, 0b00000, frs1, 0b000, rd, 0b1010011)) |