diff options
| author | Leslie Zhai <zhaixiang@loongson.cn> | 2024-12-20 23:47:18 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-20 16:47:18 +0100 |
| commit | 9fc46972337a91dc77ecff84fe62996b802a6352 (patch) | |
| tree | adbb34e8f4e433297172586cbe552a8f52c8472c /src | |
| parent | 8a37b12f81557f843e74e348830c4c639c5fde67 (diff) | |
| download | box64-9fc46972337a91dc77ecff84fe62996b802a6352.tar.gz box64-9fc46972337a91dc77ecff84fe62996b802a6352.zip | |
[LA64_DYNAREC] Added ROUNDSD and CVTDQ2PD opcodes (#2173)
* [LA64_DYNAREC] Added ROUNDSD and CVTDQ2PD opcodes * [LA64_DYNAREC] Added round_round * [LA64_DYNAREC] Remove redundant instruction * [LA64_DYNAREC] Remove useless assembler * [LA64_DYNAREC] Made round_round more readable
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_660f.c | 25 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_f30f.c | 7 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 2 |
3 files changed, 34 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c index 47f9d1c0..0380f173 100644 --- a/src/dynarec/la64/dynarec_la64_660f.c +++ b/src/dynarec/la64/dynarec_la64_660f.c @@ -49,6 +49,15 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int MAYUSE(eb1); MAYUSE(eb2); MAYUSE(j64); + #if STEP > 1 + static const int8_t round_round[] = { + 0xE, // round to nearest with ties to even + 0x2, // round toward minus infinity + 0x6, // round toward plus infinity + 0xA // round toward zero + }; +#endif + switch (opcode) { case 0x10: @@ -528,6 +537,22 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int case 0x3A: // these are some more SSSE3+ opcodes opcode = F8; switch (opcode) { + case 0x0B: + INST_NAME("ROUNDSD Gx, Ex, Ib"); + nextop = F8; + GETGX(q0, 1); + GETEXSD(q1, 0, 1); + u8 = F8; + v1 = fpu_get_scratch(dyn); + if (u8 & 4) { + u8 = sse_setround(dyn, ninst, x1, x2); + VFRINT_D(v1, q1); + x87_restoreround(dyn, ninst, u8); + } else { + VFRINTRRD_D(v1, q1, round_round[u8 & 3]); + } + VEXTRINS_D(q0, v1, 0); + break; case 0x0F: INST_NAME("PALIGNR Gx, Ex, Ib"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c index 1fff4be3..30ce633a 100644 --- a/src/dynarec/la64/dynarec_la64_f30f.c +++ b/src/dynarec/la64/dynarec_la64_f30f.c @@ -417,6 +417,13 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int MOVGR2FR_W(q1, x2); VEXTRINS_W(v0, q1, 0); break; + case 0xE6: + INST_NAME("CVTDQ2PD Gx, Ex"); + nextop = F8; + GETEXSD(v1, 0, 0); + GETGX_empty(v0); + VFFINTL_D_W(v0, v1); + break; default: DEFAULT; } diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index d7e1af7e..86cf334b 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -1839,6 +1839,8 @@ LSX instruction starts with V, LASX instruction starts with XV. #define VPICKVE2GR_HU(rd, vj, imm3) EMIT(type_2RI3(0b0111001011110011110, imm3, vj, rd)) #define VPICKVE2GR_WU(rd, vj, imm2) EMIT(type_2RI2(0b01110010111100111110, imm2, vj, rd)) #define VPICKVE2GR_DU(rd, vj, imm1) EMIT(type_2RI1(0b011100101111001111110, imm1, vj, rd)) +#define VFRINT_D(vd, vj) EMIT(type_2R(0b0111001010011101001110, vj, vd)) +#define VFRINTRRD_D(vd, vj, imm4) EMIT(type_2RI4(0b011100101001110101, imm4, vj, vd)) //////////////////////////////////////////////////////////////////////////////// // (undocumented) LBT extension instructions |