about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorphorcys <phorcys@126.com>2025-08-04 19:24:50 +0800
committerGitHub <noreply@github.com>2025-08-04 13:24:50 +0200
commitc769330d927b61593766d85f9e9fbc0d993b7442 (patch)
treedc653fe1f9ba3626cd7b5801a4a8d3deb92e406b /src
parentafe466b05186799938a0740604f3cea2f46befa0 (diff)
downloadbox64-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.c5
-rw-r--r--src/dynarec/la64/dynarec_la64_660f.c7
-rw-r--r--src/dynarec/la64/dynarec_la64_avx_66_0f3a.c24
-rw-r--r--src/dynarec/la64/la64_emitter.h10
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))