about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-05-26 18:41:14 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-05-26 18:41:14 +0200
commit9513053f740b71316b5d69f898ce6f242386128e (patch)
treef13a474fb01f027bfd3394f2652b056dba04a8a2 /src
parentbfea73d5d8003ab48f078d64c5836b7691fc8fd3 (diff)
downloadbox64-9513053f740b71316b5d69f898ce6f242386128e.tar.gz
box64-9513053f740b71316b5d69f898ce6f242386128e.zip
[DYNAREC] Various small fixes and improvments to a few opcodes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_00.c16
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_0f.c4
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_66.c69
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_67.c8
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_helper.h2
5 files changed, 47 insertions, 52 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index b1e757cf..d7828b60 100755
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1512,7 +1512,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = F8;
                     MOV32w(x2, u8);
                     CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4);
-                    WBACK;
+                    SBACK(x1);
                     break;
                 case 3:
                     INST_NAME("RCR Ed, Ib");
@@ -1523,7 +1523,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = F8;
                     MOV32w(x2, u8);
                     CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4);
-                    WBACK;
+                    SBACK(x1);
                     break;
                 case 4:
                 case 6:
@@ -1814,7 +1814,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MOV32w(x2, 1);
                     GETEDW(x4, x1, 0);
                     CALL_(rcl32, ed, x4);
-                    WBACK;
+                    SBACK(x1);
                     break;
                 case 3:
                     INST_NAME("RCR Ed, 1");
@@ -1824,7 +1824,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MOV32w(x2, 1);
                     GETEDW(x4, x1, 0);
                     CALL_(rcr32, ed, x4);
-                    WBACK;
+                    SBACK(x1);
                     break;
                 case 4:
                 case 6:
@@ -1863,7 +1863,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     MOV64xw(x4, (rex.w?64:32));
                     SUBx_REG(x3, x4, x3);
-                    GETEDW(x4, x2, 0);
+                    GETED(0);
                     if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
                     B_NEXT(cEQ);
                     RORxw_REG(ed, ed, x3);
@@ -1887,7 +1887,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     } else {
                         ANDSw_mask(x3, xRCX, 0, 0b00100);  //mask=0x00000001f
                     }
-                    GETEDW(x4, x2, 0);
+                    GETED(0);
                     if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
                     B_NEXT(cEQ);
                     RORxw_REG(ed, ed, x3);
@@ -1918,7 +1918,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
                     B_NEXT(cEQ);
                     CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4);
-                    WBACK;
+                    SBACK(x1);
                     break;
                 case 3:
                     INST_NAME("RCR Ed, CL");
@@ -1934,7 +1934,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
                     B_NEXT(cEQ);
                     CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4);
-                    WBACK;
+                    SBACK(x1);
                     break;
                 case 4:
                 case 6:
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 2b1926b3..4a58bb70 100755
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1110,7 +1110,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             GETGD;

             MOVxw_REG(x2, gd);

             CALL_(rex.w?((void*)shld64):((void*)shld32), ed, x4);

-            WBACK;

+            SBACK(x1);

             break;

 

         case 0xAB:

@@ -1170,7 +1170,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             GETGD;

             MOVxw_REG(x2, gd);

             CALL_(rex.w?((void*)shrd64):((void*)shrd32), ed, x4);

-            WBACK;

+            SBACK(x1);

             break;

 

         case 0xAE:

diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index 1559f1a5..7b1e9fca 100755
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -301,26 +301,17 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

 

         case 0x69:

-            INST_NAME("IMUL Gw,Ew,Iw");

-            SETFLAGS(X_ALL, SF_PENDING);

-            nextop = F8;

-            UFLAG_DF(x1, d_imul16);

-            GETSEW(x1, 2);

-            i32 = F16S;

-            MOV32w(x2, i32);

-            MULw(x2, x2, x1);

-            UFLAG_RES(x2);

-            gd=x2;

-            GWBACK;

-            break;

-

         case 0x6B:

-            INST_NAME("IMUL Gw,Ew,Ib");

+            if(opcode==0x69) {

+                INST_NAME("IMUL Gw,Ew,Iw");

+            } else {

+                INST_NAME("IMUL Gw,Ew,Ib");

+            }

             SETFLAGS(X_ALL, SF_PENDING);

             nextop = F8;

             UFLAG_DF(x1, d_imul16);

-            GETSEW(x1, 1);

-            i32 = F8S;

+            GETSEW(x1, (opcode==0x69)?2:1);

+            if(opcode==0x69) i32 = F16S; else i32 = F8S;

             MOV32w(x2, i32);

             MULw(x2, x2, x1);

             UFLAG_RES(x2);

@@ -352,11 +343,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             nextop = F8;

             switch((nextop>>3)&7) {

                 case 0: //ADD

-                    if(opcode==0x81) {

-                        INST_NAME("ADD Ew, Iw");

-                    } else {

-                        INST_NAME("ADD Ew, Ib");

-                    }

+                    if(opcode==0x81) {INST_NAME("ADD Ew, Iw");} else {INST_NAME("ADD Ew, Ib");}

                     SETFLAGS(X_ALL, SF_SET_PENDING);

                     GETEW(x1, (opcode==0x81)?2:1);

                     if(opcode==0x81) i16 = F16S; else i16 = F8S;

@@ -639,7 +626,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SETFLAGS(X_ALL, SF_PENDING);

                     GETEW(x1, 1);

                     u8 = F8;

-                    MOV32w(x2, (u8&0x1f));

+                    UFLAG_IF {MOV32w(x2, (u8&0x1f));}

                     UFLAG_OP12(ed, x2)

                     LSLw_IMM(ed, ed, u8&0x1f);

                     EWBACK;

@@ -652,7 +639,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SETFLAGS(X_ALL, SF_PENDING);

                     GETEW(x1, 1);

                     u8 = F8;

-                    MOV32w(x2, (u8&0x1f));

+                    UFLAG_IF {MOV32w(x2, (u8&0x1f));}

                     UFLAG_OP12(ed, x2)

                     LSRw_IMM(ed, ed, u8&0x1f);

                     EWBACK;

@@ -663,9 +650,9 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     INST_NAME("SAR Ed, Ib");

                     SETFLAGS(X_ALL, SF_PENDING);

                     UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}

-                    GETSEW(x1, 0);

+                    GETSEW(x1, 1);

                     u8 = F8;

-                    MOV32w(x2, (u8&0x1f));

+                    UFLAG_IF {MOV32w(x2, (u8&0x1f));}

                     UFLAG_OP12(ed, x2)

                     ASRw_REG(ed, ed, x2);

                     EWBACK;

@@ -701,7 +688,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOV32w(x2, 1);

                     } else {

                         INST_NAME("ROL Ew, CL");

-                        ANDSw_mask(x2, xRCX, 0, 0b00100);

+                        ANDw_mask(x2, xRCX, 0, 0b00100);

                     }

                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     SETFLAGS(X_OF|X_CF, SF_SET);

@@ -715,7 +702,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOV32w(x2, 1);

                     } else {

                         INST_NAME("ROR Ew, CL");

-                        ANDSw_mask(x2, xRCX, 0, 0b00100);

+                        ANDw_mask(x2, xRCX, 0, 0b00100);

                     }

                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     SETFLAGS(X_OF|X_CF, SF_SET);

@@ -728,7 +715,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     READFLAGS(X_CF);

                     SETFLAGS(X_OF|X_CF, SF_SET);

-                    if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);}

+                    if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDw_mask(x2, xRCX, 0, 0b00100);}

                     GETEW(x1, 0);

                     CALL_(rcl16, x1, x3);

                     EWBACK;

@@ -738,7 +725,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MESSAGE(LOG_DUMP, "Need Optimization\n");

                     READFLAGS(X_CF);

                     SETFLAGS(X_OF|X_CF, SF_SET);

-                    if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);}

+                    if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDw_mask(x2, xRCX, 0, 0b00100);}

                     GETEW(x1, 0);

                     CALL_(rcr16, x1, x3);

                     EWBACK;

@@ -750,7 +737,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOV32w(x4, 1);

                     } else {

                         INST_NAME("SHL Ew, CL");

-                        ANDSw_mask(x4, xRCX, 0, 0b00100);

+                        ANDw_mask(x4, xRCX, 0, 0b00100);

                     }

                     UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}

                     SETFLAGS(X_ALL, SF_PENDING);

@@ -767,7 +754,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOV32w(x4, 1);

                     } else {

                         INST_NAME("SHR Ew, CL");

-                        ANDSw_mask(x4, xRCX, 0, 0b00100);

+                        ANDw_mask(x4, xRCX, 0, 0b00100);

                     }

                     UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}

                     SETFLAGS(X_ALL, SF_PENDING);

@@ -784,7 +771,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         MOV32w(x4, 1);

                     } else {

                         INST_NAME("SAR Ew, CL");

-                        ANDSw_mask(x4, xRCX, 0, 0b00100);

+                        ANDw_mask(x4, xRCX, 0, 0b00100);

                     }

                     UFLAG_IF {MESSAGE(LOG_DUMP, "Need Optimization for flags\n");}

                     SETFLAGS(X_ALL, SF_PENDING);

@@ -850,17 +837,25 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;

                 case 6:

                     INST_NAME("DIV Ew");

-                    MESSAGE(LOG_DUMP, "Need Optimization\n");

                     SETFLAGS(X_ALL, SF_SET);

                     GETEW(x1, 0);

-                    CALL(div16, -1);

+                    UXTHw(x2, xRAX);

+                    BFIw(x2, xRDX, 16, 16);

+                    UDIVw(x3, x2, ed);

+                    MSUBw(x4, x3, ed, x2);  // x4 = x2 mod ed (i.e. x2 - x3*ed)

+                    BFIx(xRAX, x3, 0, 16);

+                    BFIx(xRDX, x4, 0, 16);

                     break;

                 case 7:

                     INST_NAME("IDIV Ew");

-                    MESSAGE(LOG_DUMP, "Need Optimization\n");

                     SETFLAGS(X_ALL, SF_SET);

-                    GETEW(x1, 0);

-                    CALL(idiv16, -1);

+                    GETSEW(x1, 0);

+                    UXTHw(x2, xRAX);

+                    BFIw(x2, xRDX, 16, 16);

+                    SDIVw(x3, x2, ed);

+                    MSUBw(x4, x3, ed, x2);  // x4 = x2 mod ed (i.e. x2 - x3*ed)

+                    BFIx(xRAX, x3, 0, 16);

+                    BFIx(xRDX, x4, 0, 16);

                     break;

             }

             break;

diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c
index 7b379488..34138e82 100755
--- a/src/dynarec/arm64/dynarec_arm64_67.c
+++ b/src/dynarec/arm64/dynarec_arm64_67.c
@@ -98,7 +98,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     if(MODREG) {

                         v1 = mmx_get_reg(dyn, ninst, x1, x2, x3, nextop&7); // no rex.b on MMX

                         v0 = mmx_get_reg_empty(dyn, ninst, x1, x2, x3, gd);

-                        VMOVeD(v0, 0, v1, 0);

+                        VMOV(v0, v1);

                     } else {

                         v0 = mmx_get_reg_empty(dyn, ninst, x1, x2, x3, gd);

                         addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);

@@ -179,7 +179,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = F8;

                     MOV32w(x2, u8);

                     CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4);

-                    WBACK;

+                    SBACK(x1);

                     break;

                 case 3:

                     INST_NAME("RCR Ed, Ib");

@@ -190,7 +190,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     u8 = F8;

                     MOV32w(x2, u8);

                     CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4);

-                    WBACK;

+                    SBACK(x1);

                     break;

                 case 4:

                 case 6:

@@ -302,7 +302,7 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;

                 case 2:

                     INST_NAME("NOT Ed");

-                    GETED32(4);

+                    GETED32(0);

                     MVNxw_REG(ed, ed);

                     WBACK;

                     break;

diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 3e09bb60..c5abb1e9 100755
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -130,7 +130,7 @@
 // Write back ed in wback (if wback not 0)
 #define WBACKw      if(wback) {STRw_U12(ed, wback, fixedaddress);}
 // Send back wb to either ed or wback
-#define SBACK(wb)   if(wback) {STRxw(wb, wback, fixedaddress);} else {MOVxw_REG(ed, wb);}
+#define SBACK(wb)   if(wback) {STRxw_U12(wb, wback, fixedaddress);} else {MOVxw_REG(ed, wb);}
 //GETEDO can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
 #define GETEDO(O, D)   if(MODREG) {                     \
                     ed = xRAX+(nextop&7)+(rex.b<<3);    \