diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-04-01 18:42:59 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-04-01 18:42:59 +0000 |
| commit | f21ecb32bbd2bb1452cda4db10ed63a14afa86cc (patch) | |
| tree | 88cc31926ccc3b8454ed0aafe2bd6f43e9a0866b /src | |
| parent | f810fa262d48108e107604ce38c78ee0ae4e8961 (diff) | |
| download | box64-f21ecb32bbd2bb1452cda4db10ed63a14afa86cc.tar.gz box64-f21ecb32bbd2bb1452cda4db10ed63a14afa86cc.zip | |
[RV64_DYNAREC] Added F3 0F 2C opcode, and worked on rounding
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_df.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f30f.c | 27 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_emitter.h | 51 |
3 files changed, 68 insertions, 14 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c index 9eb96ad1..b1e24231 100644 --- a/src/dynarec/rv64/dynarec_rv64_df.c +++ b/src/dynarec/rv64/dynarec_rv64_df.c @@ -106,9 +106,9 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni addr = geted(dyn, addr, ninst, nextop, &wback, x3, x4, &fixedaddress, rex, NULL, 1, 0); LH(x1, wback, fixedaddress); if(ST_IS_F(0)) { - FCVTSL(v1, x1); + FCVTSL(v1, x1, RD_RNE); } else { - FCVTDL(v1, x1); + FCVTDL(v1, x1, RD_RNE); } break; default: diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c index 53e1daa9..9c11eec8 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f.c @@ -92,9 +92,32 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETGXSS(v0); GETED(0); if(rex.w) { - FCVTSL(v0, ed); + FCVTSL(v0, ed, RD_RNE); } else { - FCVTSW(v0, ed); + FCVTSW(v0, ed, RD_RNE); + } + break; + + case 0x2C: + INST_NAME("CVTTSS2SI Gd, Ex"); + nextop = F8; + GETGD; + GETEXSS(d0, 0); + if(!box64_dynarec_fastround) { + FSFLAGSI(xZR); // // reset all bits + } + FCVTSxw(gd, d0, RD_RTZ); + if(!rex.w) + ZEROUP(gd); + if(!box64_dynarec_fastround) { + FRFLAGS(x5); // get back FPSR to check the IOC bit + ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF)); + CBZ_NEXT(x5); + if(rex.w) { + MOV64x(gd, 0x8000000000000000LL); + } else { + MOV32w(gd, 0x80000000); + } } break; diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index 225b4cb3..3e2bcbd6 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -369,6 +369,34 @@ f28–31 ft8–11 FP temporaries Caller #define FRRM(rd) CSRRS(rd, xZR, 0x002) // Swap round mode with rd #define FSRM(rd) CSRRWI(rd, 0b111, 0x002) +// Write FP exception flags, immediate +#define FSFLAGSI(imm) CSRRWI(xZR, imm, 0x0001) +// Read FP exception flags to rd +#define FRFLAGS(rd) CSRRS(rd, xZR, 0x0001) +// Inexact +#define FR_NX 0 +// Underflow +#define FR_UF 1 +// Overflow +#define FR_OF 2 +// Divide by Zero +#define FR_DZ 3 +// Invalid Operation +#define FR_NV 4 + +// Round to Nearest, ties to Even +#define RD_RNE 0b000 +// Round towards Zero +#define RD_RTZ 0b001 +// Round Down (towards −∞) +#define RD_RDN 0b010 +// Round Up (towards +∞) +#define RD_RUP 0b011 +// Round to Nearest, ties to Max Magnitude +#define RD_RMM 0b100 +// In instruction’s rm field, selects dynamic rounding mode; +#define RD_RM 0b111 + // load single precision from rs1+imm12 to frd #define FLW(frd, rs1, imm12) EMIT(I_type(imm12, rs1, 0b010, frd, 0b0000111)) // store single precision frs2 to rs1+imm12 @@ -390,7 +418,9 @@ 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, rm) EMIT(R_type(0b1101000, 0b00000, rs1, rm, frd, 0b1010011)) +// Convert from Single to signed 32bits (trucated) +#define FCVTWS(rd, frs1, tm) EMIT(R_type(0b1100000, 0b00000, frs1, rm, rd, 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)) @@ -407,14 +437,15 @@ f28–31 ft8–11 FP temporaries Caller // RV64F // Convert from signed 64bits to Single -#define FCVTSL(frd, rs1) EMIT(R_type(0b1101000, 0b00010, rs1, 0b000, frd, 0b1010011)) +#define FCVTSL(frd, rs1, rm) EMIT(R_type(0b1101000, 0b00010, rs1, rm, frd, 0b1010011)) // Convert from unsigned 64bits to Single -#define FCVTSLU(frd, rs1) EMIT(R_type(0b1101000, 0b00011, rs1, 0b000, frd, 0b1010011)) +#define FCVTSLU(frd, rs1, rm) EMIT(R_type(0b1101000, 0b00011, rs1, rm, frd, 0b1010011)) // Convert from Single to signed 64bits -#define FCVTLS(rd, frs1) EMIT(R_type(0b1100000, 0b00010, frs1, 0b000, rd, 0b1010011)) +#define FCVTLS(rd, frs1, rm) EMIT(R_type(0b1100000, 0b00010, frs1, rm, rd, 0b1010011)) // Convert from Single to unsigned 64bits -#define FCVTLUS(rd, frs1) EMIT(R_type(0b1100000, 0b00011, frs1, 0b000, rd, 0b1010011)) - +#define FCVTLUS(rd, frs1, rm) EMIT(R_type(0b1100000, 0b00011, frs1, rm, rd, 0b1010011)) +// onvert from Single to signed 32/64bits (trucated) +#define FCVTSxw(rd, frs1, rm) EMIT(R_type(0b1100000, rex.w?0b00010:0b00000, frs1, rm, rd, 0b1010011)) // RV32D // load double precision from rs1+imm12 to frd @@ -458,12 +489,12 @@ f28–31 ft8–11 FP temporaries Caller // Move to Double #define FMVDX(frd, rs1) EMIT(R_type(0b1111001, 0b00000, rs1, 0b000, frd, 0b1010011)) // Convert from signed 64bits to Double -#define FCVTDL(frd, rs1) EMIT(R_type(0b1101001, 0b00010, rs1, 0b000, frd, 0b1010011)) +#define FCVTDL(frd, rs1, rm) EMIT(R_type(0b1101001, 0b00010, rs1, rm, frd, 0b1010011)) // Convert from unsigned 64bits to Double -#define FCVTDLU(frd, rs1) EMIT(R_type(0b1101001, 0b00011, rs1, 0b000, frd, 0b1010011)) +#define FCVTDLU(frd, rs1, rm) EMIT(R_type(0b1101001, 0b00011, rs1, rm, frd, 0b1010011)) // Convert from Double to signed 64bits -#define FCVTLD(rd, frs1) EMIT(R_type(0b1100001, 0b00010, frs1, 0b000, rd, 0b1010011)) +#define FCVTLD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00010, frs1, rm, rd, 0b1010011)) // Convert from Double to unsigned 64bits -#define FCVTLUD(rd, frs1) EMIT(R_type(0b1100001, 0b00011, frs1, 0b000, rd, 0b1010011)) +#define FCVTLUD(rd, frs1, rm) EMIT(R_type(0b1100001, 0b00011, frs1, rm, rd, 0b1010011)) #endif //__RV64_EMITTER_H__ |