diff options
| author | wannacu <wannacu2049@gmail.com> | 2023-08-25 10:52:23 +0800 |
|---|---|---|
| committer | wannacu <wannacu2049@gmail.com> | 2023-08-25 18:07:21 +0800 |
| commit | 539fb8e2149826ff785747f2f4524051cafd927d (patch) | |
| tree | b182392749e3315018f6058d0ee6a8f3a80b50c2 /src | |
| parent | 7b1fa28b85092ff36017f55be53c03d2d38ec516 (diff) | |
| download | box64-539fb8e2149826ff785747f2f4524051cafd927d.tar.gz box64-539fb8e2149826ff785747f2f4524051cafd927d.zip | |
[RV64_DYNAREC] Added (66) 0F 2A/2C/2D opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 61 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 58 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 37 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_private.h | 4 |
4 files changed, 147 insertions, 13 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 199068cf..9e225bd2 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -262,7 +262,20 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if(!MODREG) SMWRITE2(); break; - + case 0x2A: + INST_NAME("CVTPI2PS Gx,Em"); + nextop = F8; + GETGX(); + GETEM(x2, 0); + d0 = fpu_get_scratch(dyn); + u8 = sse_setround(dyn, ninst, x4, x5); + for (int i=0; i<2; ++i) { + LW(x3, wback, fixedaddress+i*4); + FCVTSW(d0, x3, RD_DYN); + FSW(d0, gback, gdoffset+i*4); + } + x87_restoreround(dyn, ninst, u8); + break; case 0x2B: INST_NAME("MOVNTPS Ex,Gx"); nextop = F8; @@ -273,6 +286,52 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SD(x3, wback, fixedaddress+0); SD(x4, wback, fixedaddress+8); break; + case 0x2C: + INST_NAME("CVTTPS2PI Gm,Ex"); + nextop = F8; + GETGM(); + GETEX(x2, 0); + d0 = fpu_get_scratch(dyn); + for (int i=0; i<2; ++i) { + if(!box64_dynarec_fastround) { + FSFLAGSI(0); // // reset all bits + } + FLW(d0, wback, fixedaddress+i*4); + FCVTWS(x1, d0, RD_RTZ); + if(!box64_dynarec_fastround) { + FRFLAGS(x5); // get back FPSR to check the IOC bit + ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF)); + BEQ_MARKi(x5, xZR, i); + MOV32w(x1, 0x80000000); + MARKi(i); + } + SW(x1, gback, gdoffset+i*4); + } + break; + case 0x2D: + INST_NAME("CVTPS2PI Gm, Ex"); + nextop = F8; + GETGM(); + GETEX(x2, 0); + d0 = fpu_get_scratch(dyn); + u8 = sse_setround(dyn, ninst, x6, x4); + for (int i=0; i<2; ++i) { + if(!box64_dynarec_fastround) { + FSFLAGSI(0); // // reset all bits + } + FLW(d0, wback, fixedaddress+i*4); + FCVTWS(x1, d0, RD_DYN); + if(!box64_dynarec_fastround) { + FRFLAGS(x5); // get back FPSR to check the IOC bit + ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF)); + BEQ_MARKi(x5, xZR, i); + MOV32w(x1, 0x80000000); + MARKi(i); + } + SW(x1, gback, gdoffset+i*4); + } + x87_restoreround(dyn, ninst, u8); + break; case 0x2E: // no special check... case 0x2F: diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index c60d214d..7baddf4f 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -148,6 +148,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SSE_LOOP_MV_Q2(x3); if(!MODREG) SMWRITE2(); break; + case 0x2A: + INST_NAME("CVTPI2PD Gx,Em"); + nextop = F8; + GETGX(); + GETEM(x2, 0); + d0 = fpu_get_scratch(dyn); + for (int i=0; i<2; ++i) { + LW(x1, wback, fixedaddress+i*4); + FCVTDW(d0, x1, RD_RTZ); + FSD(d0, gback, gdoffset+i*8); + } + break; case 0x2B: INST_NAME("MOVNTPD Ex, Gx"); nextop = F8; @@ -155,6 +167,52 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(x2, 0); SSE_LOOP_MV_Q2(x3); break; + case 0x2C: + INST_NAME("CVTTPD2PI Gm,Ex"); + nextop = F8; + GETGM(); + GETEX(x2, 0); + d0 = fpu_get_scratch(dyn); + for (int i=0; i<2; ++i) { + if(!box64_dynarec_fastround) { + FSFLAGSI(0); // // reset all bits + } + FLD(d0, wback, fixedaddress+i*8); + FCVTWD(x1, d0, RD_RTZ); + if(!box64_dynarec_fastround) { + FRFLAGS(x5); // get back FPSR to check the IOC bit + ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF)); + BEQ_MARKi(x5, xZR, i); + MOV32w(x1, 0x80000000); + MARKi(i); + } + SW(x1, gback, gdoffset+i*4); + } + break; + case 0x2D: + INST_NAME("CVTPD2PI Gm,Ex"); + nextop = F8; + GETGM(); + GETEX(x2, 0); + d0 = fpu_get_scratch(dyn); + u8 = sse_setround(dyn, ninst, x4, x5); + for (int i=0; i<2; ++i) { + if(!box64_dynarec_fastround) { + FSFLAGSI(0); // // reset all bits + } + FLD(d0, wback, fixedaddress+i*8); + FCVTWD(x1, d0, RD_DYN); + if(!box64_dynarec_fastround) { + FRFLAGS(x5); // get back FPSR to check the IOC bit + ANDI(x5, x5, (1<<FR_NV)|(1<<FR_OF)); + BEQ_MARKi(x5, xZR, i); + MOV32w(x1, 0x80000000); + MARKi(i); + } + SW(x1, gback, gdoffset+i*4); + } + x87_restoreround(dyn, ninst, u8); + break; case 0x2E: // no special check... case 0x2F: diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 0b1023b3..51d7817f 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -531,16 +531,22 @@ // R0 will not be pushed/popd if ret is -2. Flags are not save/restored #define CALL_S(F, ret) call_c(dyn, ninst, F, x6, ret, 0, 0) -#define MARK dyn->insts[ninst].mark = dyn->native_size -#define GETMARK dyn->insts[ninst].mark -#define MARK2 dyn->insts[ninst].mark2 = dyn->native_size -#define GETMARK2 dyn->insts[ninst].mark2 -#define MARK3 dyn->insts[ninst].mark3 = dyn->native_size -#define GETMARK3 dyn->insts[ninst].mark3 -#define MARKF dyn->insts[ninst].markf = dyn->native_size -#define GETMARKF dyn->insts[ninst].markf -#define MARKF2 dyn->insts[ninst].markf2 = dyn->native_size -#define GETMARKF2 dyn->insts[ninst].markf2 +#define MARKi(i) dyn->insts[ninst].mark[i] = dyn->native_size +#define GETMARKi(i) dyn->insts[ninst].mark[i] +#define MARK MARKi(0) +#define GETMARK GETMARKi(0) +#define MARK2 MARKi(1) +#define GETMARK2 GETMARKi(1) +#define MARK3 MARKi(2) +#define GETMARK3 GETMARKi(2) + +#define MARKFi(i) dyn->insts[ninst].markf[i] = dyn->native_size +#define GETMARKFi(i) dyn->insts[ninst].markf[i] +#define MARKF MARKFi(0) +#define GETMARKF GETMARKFi(0) +#define MARKF2 MARKFi(1) +#define GETMARKF2 GETMARKFi(1) + #define MARKSEG dyn->insts[ninst].markseg = dyn->native_size #define GETMARKSEG dyn->insts[ninst].markseg #define MARKLOCK dyn->insts[ninst].marklock = dyn->native_size @@ -550,20 +556,31 @@ j64 = GET##M - dyn->native_size; \ B##OP (reg1, reg2, j64) +#define Bxx_geni(OP, M, reg1, reg2, i) \ + j64 = GET##M##i(i) - dyn->native_size; \ + B##OP (reg1, reg2, j64) + // Branch to MARK if reg1==reg2 (use j64) #define BEQ_MARK(reg1, reg2) Bxx_gen(EQ, MARK, reg1, reg2) +#define BEQ_MARKi(reg1, reg2, i) Bxx_geni(EQ, MARK, reg1, reg2, i) // Branch to MARK if reg1!=reg2 (use j64) #define BNE_MARK(reg1, reg2) Bxx_gen(NE, MARK, reg1, reg2) +#define BNE_MARKi(reg1, reg2, i) Bxx_geni(NE, MARK, reg1, reg2, i) // Branch to MARK if reg1!=0 (use j64) #define BNEZ_MARK(reg) BNE_MARK(reg, xZR) +#define BNEZ_MARKi(reg, i) BNE_MARKi(reg, xZR, i) // Branch to MARK instruction unconditionnal (use j64) #define B_MARK_nocond Bxx_gen(__, MARK, 0, 0) +#define B_MARKi_nocond Bxx_geni(__, MARK, 0, 0, i) // Branch to MARK if reg1<reg2 (use j64) #define BLT_MARK(reg1, reg2) Bxx_gen(LT, MARK, reg1, reg2) +#define BLT_MARKi(reg1, reg2) Bxx_geni(LT, MARK, reg1, reg2, i) // Branch to MARK if reg1<reg2 (use j64) #define BLTU_MARK(reg1, reg2) Bxx_gen(LTU, MARK, reg1, reg2) +#define BLTU_MARKi(reg1, reg2) Bxx_geni(LTU, MARK, reg1, reg2, i) // Branch to MARK if reg1>=reg2 (use j64) #define BGE_MARK(reg1, reg2) Bxx_gen(GE, MARK, reg1, reg2) +#define BGE_MARKi(reg1, reg2) Bxx_geni(GE, MARK, reg1, reg2, i) // Branch to MARK2 if reg1==reg2 (use j64) #define BEQ_MARK2(reg1, reg2) Bxx_gen(EQ, MARK2, reg1,reg2) // Branch to MARK2 if reg1!=reg2 (use j64) diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h index 99135297..d377309d 100644 --- a/src/dynarec/rv64/dynarec_rv64_private.h +++ b/src/dynarec/rv64/dynarec_rv64_private.h @@ -79,8 +79,8 @@ typedef struct instruction_rv64_s { int size2; // size of the arm emitted instrucion after pass2 int pred_sz; // size of predecessor list int *pred; // predecessor array - uintptr_t mark, mark2, mark3; - uintptr_t markf, markf2; + uintptr_t mark[3]; + uintptr_t markf[2]; uintptr_t markseg; uintptr_t marklock; int pass2choice;// value for choices that are fixed on pass2 for pass3 |