about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-21 22:08:58 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-21 22:08:58 +0100
commit8bd81dffcfa97a0014ec64efdbfc411fa144524f (patch)
tree04f6f2e97333dcb222874975dbba526f10b18145 /src/dynarec
parent79ca411d6a5d35e66842b3886d2c6077ef85b58a (diff)
downloadbox64-8bd81dffcfa97a0014ec64efdbfc411fa144524f.tar.gz
box64-8bd81dffcfa97a0014ec64efdbfc411fa144524f.zip
[DYNAREC] Complete 81/833 opcodes, plus various bugfixes
Diffstat (limited to 'src/dynarec')
-rwxr-xr-xsrc/dynarec/arm64_printer.c39
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c30
-rwxr-xr-xsrc/dynarec/dynarec_arm64_0f.c6
-rwxr-xr-xsrc/dynarec/dynarec_arm64_660f.c2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_f30f.c4
5 files changed, 68 insertions, 13 deletions
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index 46e1feae..b068b9d8 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -265,7 +265,17 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         else

             snprintf(buff, sizeof(buff), "STR%c %s, [%s]", size?'H':'B', Xt[Rt], XtSp[Rn]);

         return buff;

-    }    // --- MOV (REGS: see Logic MOV==ORR, MVN==ORN)

+    }    

+    if(isMask(opcode, "1011100110iiiiiiiiiiiinnnnnttttt", &a)) {

+        int offset = imm<<2;

+        if(!offset)

+            snprintf(buff, sizeof(buff), "LDRSW %s, [%s]", Xt[Rt], XtSp[Rn]);

+        else

+            snprintf(buff, sizeof(buff), "LDRSW %s, [%s, #%d]", Xt[Rt], XtSp[Rn], offset);

+        return buff;

+    }

+

+    // --- MOV (REGS: see Logic MOV==ORR, MVN==ORN)

     if(isMask(opcode, "f10100101wwiiiiiiiiiiiiiiiiddddd", &a)) {

         if(!hw)

             snprintf(buff, sizeof(buff), "MOVZ %s, 0x%x", sf?Xt[Rd]:Wt[Rd], imm);

@@ -582,6 +592,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         return buff;

     }

 

+    if(isMask(opcode, "f0011010110mmmmm001011nnnnnddddd", &a)) {

+        snprintf(buff, sizeof(buff), "ROR %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm]);

+        return buff;

+    }

+

     if(isMask(opcode, "f0011010110mmmmm001001nnnnnddddd", &a)) {

         snprintf(buff, sizeof(buff), "LSR %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm]);

         return buff;

@@ -893,6 +908,28 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         return buff;

     }

 

+    // FMOV

+    if(isMask(opcode, "00011110pp100000010000nnnnnddddd", &a)) {

+        int type = a.p;

+        char s = (type==0)?'S':((type==1)?'D':'?');

+        snprintf(buff, sizeof(buff), "FMOV %c%d, %c%d", s, Rd, s, Rn);

+        return buff;

+    }

+    if(isMask(opcode, "f0011110pp10x11c000000nnnnnddddd", &a)) {

+        int type = a.p;

+        int rmode = a.x;

+        int opcd = 6+a.c;

+             if(sf==0 && type==0 && rmode==0 && opcd==7) {snprintf(buff, sizeof(buff), "FMOV S%d, %s", Rd, Wt[Rn]);}

+        else if(sf==0 && type==0 && rmode==0 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, S%d", Wt[Rn], Rd);}

+        else if(sf==1 && type==1 && rmode==0 && opcd==7) {snprintf(buff, sizeof(buff), "FMOV D%d, %s", Rd, Xt[Rn]);}

+        else if(sf==1 && type==2 && rmode==1 && opcd==7) {snprintf(buff, sizeof(buff), "FMOV V%d.D[1], %s", Rd, Xt[Rn]);}

+        else if(sf==1 && type==1 && rmode==0 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, S%d", Xt[Rn], Rd);}

+        else if(sf==1 && type==2 && rmode==1 && opcd==6) {snprintf(buff, sizeof(buff), "FMOV %s, V%d.D[1]", Xt[Rn], Rd);}

+        else snprintf(buff, sizeof(buff), "FMOV ????");

+        return buff;

+    }

+

+

 

     snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(opcode));

     return buff;

diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index 2b9cc55b..9ad7516b 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -531,14 +531,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 if(MODREG) {   // reg <= reg
                     SXTWx(gd, xRAX+(nextop&7)+(rex.b<<3));
                 } else {                    // mem <= reg
-                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<2, 3, rex, 0, 0);
                     LDRSW_U12(gd, ed, fixedaddress);
                 }
             } else {
                 if(MODREG) {   // reg <= reg
                     MOVw_REG(gd, xRAX+(nextop&7)+(rex.b<<3));
                 } else {                    // mem <= reg
-                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<2, 3, rex, 0, 0);
                     LDRw_U12(gd, ed, fixedaddress);
                 }
             }
@@ -756,7 +756,26 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     emit_or32c(dyn, ninst, rex, ed, i64, x3, x4);
                     WBACK;
                     break;
-
+                case 2: //ADC
+                    if(opcode==0x81) {INST_NAME("ADC Ed, Id");} else {INST_NAME("ADC Ed, Ib");}
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_ALL, SF_SET);
+                    GETED((opcode==0x81)?4:1);
+                    if(opcode==0x81) i64 = F32S; else i64 = F8S;
+                    MOV64xw(x5, i64);
+                    emit_adc32(dyn, ninst, rex, ed, x5, x3, x4);
+                    WBACK;
+                    break;
+                case 3: //SBB
+                    if(opcode==0x81) {INST_NAME("SBB Ed, Id");} else {INST_NAME("SBB Ed, Ib");}
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_ALL, SF_SET);
+                    GETED((opcode==0x81)?4:1);
+                    if(opcode==0x81) i64 = F32S; else i64 = F8S;
+                    MOV64xw(x5, i64);
+                    emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4);
+                    WBACK;
+                    break;
                 case 4: //AND
                     if(opcode==0x81) {INST_NAME("AND Ed, Id");} else {INST_NAME("AND Ed, Ib");}
                     SETFLAGS(X_ALL, SF_SET);
@@ -792,9 +811,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     } else
                         emit_cmp32_0(dyn, ninst, rex, ed, x3, x4);
                     break;
-
-                default:
-                    DEFAULT;
             }
             break;
         case 0x84:
@@ -880,6 +896,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 addr = geted(dyn, addr, ninst, nextop, &ed, gd, &fixedaddress, 0, 0, rex, 0, 0);
                 if(gd!=ed) {    // it's sometimes used as a 3 bytes NOP
                     MOVxw_REG(gd, ed);
+                } else if(ed>=xRAX && !rex.w) {
+                    MOVw(gd, gd);   //truncate the higher 32bits as asked
                 }
             }
             break;
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c
index 9ce1951f..6e65208e 100755
--- a/src/dynarec/dynarec_arm64_0f.c
+++ b/src/dynarec/dynarec_arm64_0f.c
@@ -165,12 +165,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             nextop = F8;

             GETGX(v0);

             if(MODREG) {

-                s0 = sse_get_reg(dyn, ninst, x1, nextop&7);

+                s0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3));

             } else {

-                parity = getedparity(dyn, ninst, addr, nextop, 2, 0);

+                parity = getedparity(dyn, ninst, addr, nextop, 3, 0);

                 s0 = fpu_get_scratch(dyn);

                 if(parity) {

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

+                    addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<2, 3, rex, 0, 0);

                     VLDR32_U12(s0, ed, fixedaddress);

                 } else {

                     GETED(0);

diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c
index ee6fa45d..a55e89c8 100755
--- a/src/dynarec/dynarec_arm64_660f.c
+++ b/src/dynarec/dynarec_arm64_660f.c
@@ -122,7 +122,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             if(MODREG) {                            \

                 ed = xRAX+(nextop&7)+(rex.b<<3);    \

             } else {                                \

-                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); \

+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<1, 1, rex, 0, 0); \

                 LDRH_U12(x1, ed, fixedaddress);     \

                 ed = x1;                            \

             }                                       \

diff --git a/src/dynarec/dynarec_arm64_f30f.c b/src/dynarec/dynarec_arm64_f30f.c
index 21b3531e..16937842 100755
--- a/src/dynarec/dynarec_arm64_f30f.c
+++ b/src/dynarec/dynarec_arm64_f30f.c
@@ -77,7 +77,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 VMOVeS(v0, 0, q0, 0);

             } else {

                 v0 = sse_get_reg_empty(dyn, ninst, x1, gd);

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

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

                 LDRw_U12(x2, ed, fixedaddress);   // to avoid bus errors

                 VEORQ(v0, v0, v0);

                 VMOVQSfrom(v0, 0, x2);

@@ -93,7 +93,7 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 VMOVeS(q0, 0, v0, 0);

             } else {

                 VMOVSto(x2, v0, 0);

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

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

                 STRw_U12(x2, ed, fixedaddress);

             }

             break;