about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-03-16 15:39:40 +0000
committerptitSeb <sebastien.chev@gmail.com>2023-03-16 15:39:40 +0000
commitdbd1b977fc5bae2dea51e62399228cfe7c271ac0 (patch)
tree8c8b3798f67ba24daeda8517b0895bff961dbf17 /src
parent5d14667536418889607a97310f966ce3cb32727b (diff)
downloadbox64-dbd1b977fc5bae2dea51e62399228cfe7c271ac0.tar.gz
box64-dbd1b977fc5bae2dea51e62399228cfe7c271ac0.zip
[ARM64_DYNAREC] Added FF /2 CALL, /4 JMP and /6 PUSH opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00.c64
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h18
2 files changed, 82 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c
index 76202092..e6bea413 100644
--- a/src/dynarec/rv64/dynarec_rv64_00.c
+++ b/src/dynarec/rv64/dynarec_rv64_00.c
@@ -665,6 +665,70 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             *ok = 0;
             break;
 
+        case 0xFF:
+            nextop = F8;
+            switch((nextop>>3)&7) {
+                case 0: // INC Ed
+                    DEFAULT;
+                    break;
+                case 1: //DEC Ed
+                    DEFAULT;
+                    break;
+                case 2: // CALL Ed
+                    INST_NAME("CALL Ed");
+                    PASS2IF((box64_dynarec_safeflags>1) || 
+                        ((ninst && dyn->insts[ninst-1].x64.set_flags)
+                        || ((ninst>1) && dyn->insts[ninst-2].x64.set_flags)), 1)
+                    {
+                        READFLAGS(X_PEND);          // that's suspicious
+                    } else {
+                        SETFLAGS(X_ALL, SF_SET);    //Hack to put flag in "don't care" state
+                    }
+                    GETEDx(0);
+                    if(box64_dynarec_callret && box64_dynarec_bigblock>1) {
+                        BARRIER(BARRIER_FULL);
+                    } else {
+                        BARRIER(BARRIER_FLOAT);
+                        *need_epilog = 0;
+                        *ok = 0;
+                    }
+                    GETIP_(addr);
+                    // TODO: Add suport for CALLRET optim
+                    /*if(box64_dynarec_callret) {
+                        // Push actual return address
+                        if(addr < (dyn->start+dyn->isize)) {
+                            // there is a next...
+                            j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0;
+                            ADR_S20(x4, j64);
+                        } else {
+                            j64 = getJumpTableAddress64(addr);
+                            TABLE64(x4, j64);
+                            LDRx_U12(x4, x4, 0);
+                        }
+                        STPx_S7_preindex(x4, xRIP, xSP, -16);
+                    }*/
+                    PUSH1(xRIP);
+                    jump_to_next(dyn, 0, ed, ninst);
+                    break;
+                case 4: // JMP Ed
+                    INST_NAME("JMP Ed");
+                    READFLAGS(X_PEND);
+                    BARRIER(BARRIER_FLOAT);
+                    GETEDx(0);
+                    jump_to_next(dyn, 0, ed, ninst);
+                    *need_epilog = 0;
+                    *ok = 0;
+                    break;
+                case 6: // Push Ed
+                    INST_NAME("PUSH Ed");
+                    GETEDx(0);
+                    PUSH1(ed);
+                    break;
+
+                default:
+                    DEFAULT;
+            }
+            break;
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 83e9c8cc..47f59fb7 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -73,6 +73,17 @@
                     ed = x1;                            \
                 }
 
+// GETEDx can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI
+#define GETEDx(D) if(MODREG) {                          \
+                    ed = xRAX+(nextop&7)+(rex.b<<3);    \
+                    wback = 0;                          \
+                } else {                                \
+                    SMREAD()                            \
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \
+                    LD(x1, wback, fixedaddress);        \
+                    ed = x1;                            \
+                }
+
 // FAKEED like GETED, but doesn't get anything
 #define FAKEED  if(!MODREG) {   \
                     addr = fakeed(dyn, addr, ninst, nextop); \
@@ -330,6 +341,13 @@
 #endif
 #define CLEARIP()   dyn->last_ip=0
 
+#if STEP < 2
+#define PASS2IF(A, B) if(A)
+#elif STEP == 2
+#define PASS2IF(A, B) if(A) dyn->insts[ninst].pass2choice = B; if(dyn->insts[ninst].pass2choice == B)
+#else
+#define PASS2IF(A, B) if(dyn->insts[ninst].pass2choice == B)
+#endif
 
 #define MODREG  ((nextop&0xC0)==0xC0)