diff options
| author | phorcys <phorcys@126.com> | 2025-08-04 19:24:50 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-04 13:24:50 +0200 |
| commit | c769330d927b61593766d85f9e9fbc0d993b7442 (patch) | |
| tree | dc653fe1f9ba3626cd7b5801a4a8d3deb92e406b /src | |
| parent | afe466b05186799938a0740604f3cea2f46befa0 (diff) | |
| download | box64-c769330d927b61593766d85f9e9fbc0d993b7442.tar.gz box64-c769330d927b61593766d85f9e9fbc0d993b7442.zip | |
[LA64_DYNAREC] Fix some la64 ops. (#2889)
Fix 0F.BA./7 BTS CF when cpuext.lbt == 1 Fix 66.0F.CF BSWAP 16bits ops. Fix VEXTRACTF128, VINSERTF128
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 5 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_660f.c | 7 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_avx_66_0f3a.c | 24 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 10 |
4 files changed, 32 insertions, 14 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index 8d247911..bf013d98 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -1782,7 +1782,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni u8 = F8; u8 &= rex.w ? 0x3f : 0x1f; BSTRPICK_D(x3, ed, u8, u8); - BSTRINS_D(xFlags, x3, 0, 0); + if (cpuext.lbt) + X64_SET_EFLAGS(x3, X_CF); + else + BSTRINS_D(xFlags, x3, 0, 0); if (u8 <= 10) { XORI(ed, ed, (1LL << u8)); } else { diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c index 47f3df30..596d26c5 100644 --- a/src/dynarec/la64/dynarec_la64_660f.c +++ b/src/dynarec/la64/dynarec_la64_660f.c @@ -2198,7 +2198,12 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int case 0xCF: INST_NAME("BSWAP Reg"); gd = TO_NAT((opcode & 7) + (rex.b << 3)); - REVBxw(gd, gd); + if(rex.w){ + REVB_D(gd, gd); + } else { + REVB_2H(x2, gd); + BSTRINS_D(gd, x2, 15, 0); + } break; case 0xD0: INST_NAME("ADDSUBPD Gx, Ex"); diff --git a/src/dynarec/la64/dynarec_la64_avx_66_0f3a.c b/src/dynarec/la64/dynarec_la64_avx_66_0f3a.c index 9a90ce0f..13a4d75b 100644 --- a/src/dynarec/la64/dynarec_la64_avx_66_0f3a.c +++ b/src/dynarec/la64/dynarec_la64_avx_66_0f3a.c @@ -466,9 +466,11 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i INST_NAME("VINSERTI128 Gx, Vx, Ex, imm8"); } nextop = F8; - GETGY_empty_VYEY_xy(q0, q1, q2, 1); + GETEYx(q2, 0, 1); + GETVYy(q1, 0); + GETGYy_empty(q0); u8 = F8; - if(q0 != q2){ + if(q0 != q2) { if(q0 != q1) XVOR_V(q0, q1, q1); XVPERMI_Q(q0, q2, ((u8 & 1) == 0) ? 0x30: 0x02); } else{ @@ -483,17 +485,25 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t i INST_NAME("VEXTRACTI128 Ex, Gx, imm8"); } nextop = F8; - GETEY_GY_xy(q1, q0, 1); - u8 = F8; + GETGYy(q0, 0); if (MODREG) { - XVPERMI_Q(q1, q0, (u8 & 1) == 0 ? XVPERMI_IMM_4_0(3, 0) : XVPERMI_IMM_4_0(3, 1)); + GETEYx_empty(q1, 1); + u8 = F8; + if((u8 & 1) == 0) { + VOR_V(q1, q0, q0); + } else { + XVPERMI_Q(q1, q0, XVPERMI_IMM_4_0(3, 1)); + } } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x4, x5, &fixedaddress, rex, NULL, 0, 1); + u8 = F8; if ((u8 & 1) == 1) { - XVPERMI_Q(q1, q0, XVPERMI_IMM_4_0(3, 1)); - VST(q1, ed, fixedaddress); + XVSTELM_D(q0, ed, 0, 2); + XVSTELM_D(q0, ed, 1, 3); } else { VST(q0, ed, fixedaddress); } + SMWRITE2(); } break; case 0x1D: diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index 85ad1fd7..44c35e05 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -41,6 +41,7 @@ #define type_2RI9(opc, imm9, rj, rd) ((opc) << 19 | ((imm9) & 0x1FF) << 10 | (rj) << 5 | (rd)) #define type_2RI10(opc, imm10, rj, rd) ((opc) << 20 | ((imm10) & 0x3FF) << 10 | (rj) << 5 | (rd)) #define type_2RI11(opc, imm11, rj, rd) ((opc) << 21 | ((imm11) & 0x7FF) << 10 | (rj) << 5 | (rd)) +#define type_2RI13(opc, imm13, rj, rd) ((opc) << 23 | ((imm13) & 0x1FFF) << 10 | (rj) << 5 | (rd)) #define type_1RI5I5(opc, imm5, imm5_2, rd) ((opc) << 15 | ((imm5) & 0x1F) << 10 | ((imm5_2) & 0x1F) << 5 | (rd)) // tmp = GR[rj][31:0] + GR[rk][31:0] @@ -1973,11 +1974,10 @@ LSX instruction starts with V, LASX instruction starts with XV. #define XVLDREPL_W(xd, rj, offset) EMIT(type_2RI10(0b001100100010, (offset >> 2), rj, xd)) #define XVLDREPL_H(xd, rj, offset) EMIT(type_2RI11(0b00110010010, (offset >> 1), rj, xd)) #define XVLDREPL_B(xd, rj, offset) EMIT(type_2RI12(0b0011001010, offset, rj, xd)) -#define XVSTELM_D(xd, rj, offset, imm2) EMIT(type_2RI10(0b001100110001, (((imm2) << 8) | (offset >>3), rj, xd)) -#define XVSTELM_W(xd, rj, offset, imm3) EMIT(type_2RI11(0b00110011001, (((imm3) << 8) | (offset >>2), rj, xd)) -#define XVSTELM_H(xd, rj, offset, imm4) EMIT(type_2RI12(0b0011001101, (((imm4) << 8) | (offset >>1), rj, xd)) -#define XVSTELM_B(xd, rj, offset, imm5) EMIT(type_2RI13(0b001100111, (((imm5) << 8) | offset, rj, xd)) - +#define XVSTELM_D(xd, rj, offset, imm2) EMIT(type_2RI10(0b001100110001, ((imm2) << 8) | (offset), rj, xd)) +#define XVSTELM_W(xd, rj, offset, imm3) EMIT(type_2RI11(0b00110011001, ((imm3) << 8) | (offset), rj, xd)) +#define XVSTELM_H(xd, rj, offset, imm4) EMIT(type_2RI12(0b0011001101, ((imm4) << 8) | (offset), rj, xd)) +#define XVSTELM_B(xd, rj, offset, imm5) EMIT(type_2RI13(0b001100111, ((imm5) << 8) | (offset), rj, xd)) #define XVHSELI_D(vd, vj, imm5) EMIT(type_2RI5(0b01110110100111111, imm5, vj, vd)) #define XVROTRI_B(vd, vj, imm3) EMIT(type_2RI3(0b0111011010100000001, imm3, vj, vd)) |