about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-19 16:50:21 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-19 16:50:27 +0100
commit10088c6566f4ecb4b1405c977a395fa75d2f72a0 (patch)
treebc60f490954f6167269a82d62efa519bcce61122 /src
parenta2abb4e8b161cd049aa5196e09a63ca2eb5c1f44 (diff)
downloadbox64-10088c6566f4ecb4b1405c977a395fa75d2f72a0.tar.gz
box64-10088c6566f4ecb4b1405c977a395fa75d2f72a0.zip
[DYNAREC] Added 0F 80..8F Jcc Id opcodes (and factorised GOCOND macro)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c90
-rwxr-xr-xsrc/dynarec/dynarec_arm64_0f.c111
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h90
3 files changed, 115 insertions, 176 deletions
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index 01901c10..0646a630 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -293,94 +293,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 }   \
             }
 
-        case 0x70:
-            INST_NAME("JO ib");
-            GO( TSTw_mask(xFlags, 0b010101, 0)
-                , cEQ, cNE, X_OF)
-            break;
-        case 0x71:
-            INST_NAME("JNO ib");
-            GO( TSTw_mask(xFlags, 0b010101, 0)
-                , cNE, cEQ, X_OF)
-            break;
-        case 0x72:
-            INST_NAME("JC ib");
-            GO( TSTw_mask(xFlags, 0, 0)
-                , cEQ, cNE, X_CF)
-            break;
-        case 0x73:
-            INST_NAME("JNC ib");
-            GO( TSTw_mask(xFlags, 0, 0)
-                , cNE, cEQ, X_CF)
-            break;
-        case 0x74:
-            INST_NAME("JZ ib");
-            GO( TSTw_mask(xFlags, 0b011010, 0)
-                , cEQ, cNE, X_ZF)
-            break;
-        case 0x75:
-            INST_NAME("JNZ ib");
-            GO( TSTw_mask(xFlags, 0b011010, 0)
-                , cNE, cEQ, X_ZF)
-            break;
-        case 0x76:
-            INST_NAME("JBE ib");
-            GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF));
-                TSTw_REG(xFlags, x1)
-                , cEQ, cNE, X_CF|X_ZF)
-            break;
-        case 0x77:
-            INST_NAME("JNBE ib");
-            GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF));
-                TSTw_REG(xFlags, x1)
-                , cNE, cEQ, X_CF|X_ZF)
-            break;
-        case 0x78:
-            INST_NAME("JS ib");
-            GO( TSTw_mask(xFlags, 0b011001, 0)  // 0X80
-                , cEQ, cNE, X_SF)
-            break;
-        case 0x79:
-            INST_NAME("JNS ib");
-            GO( TSTw_mask(xFlags, 0b011001, 0)
-                , cNE, cEQ, X_SF)
-            break;
-        case 0x7A:
-            INST_NAME("JP ib");
-            GO( TSTw_mask(xFlags, 0b011110, 0)
-                , cEQ, cNE, X_PF)
-            break;
-        case 0x7B:
-            INST_NAME("JNP ib");
-            GO( TSTw_mask(xFlags, 0b011110, 0)
-                , cNE, cEQ, X_PF)
-            break;
-        case 0x7C:
-            INST_NAME("JL ib");
-            GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);
-                TSTw_mask(x1, 0b010101, 0)
-                , cEQ, cNE, X_SF|X_OF)
-            break;
-        case 0x7D:
-            INST_NAME("JGE ib");
-            GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);
-                TSTw_mask(x1, 0b010101, 0)
-                , cNE, cEQ, X_SF|X_OF)
-            break;
-        case 0x7E:
-            INST_NAME("JLE ib");
-            GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);
-                ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF);
-                TSTw_mask(x1, 0b010101, 0)
-                , cEQ, cNE, X_SF|X_OF|X_ZF)
-            break;
-        case 0x7F:
-            INST_NAME("JG ib");
-            GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);
-                ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF);
-                TSTw_mask(x1, 0b010101, 0)
-                , cNE, cEQ, X_SF|X_OF|X_ZF)
-            break;
+        GOCOND(0x70, "J", "ib");
+
         #undef GO
         
         case 0x80:
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c
index 5270d981..afc0ce34 100755
--- a/src/dynarec/dynarec_arm64_0f.c
+++ b/src/dynarec/dynarec_arm64_0f.c
@@ -104,96 +104,31 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 if(!rex.w) {MOVw_REG(gd, gd);}      \

             }

 

-        case 0x40:

-            INST_NAME("CMOVO Gd, Ed");

-            GO( TSTw_mask(xFlags, 0b010101, 0)

-                , cEQ, cNE, X_OF)

-            break;

-        case 0x41:

-            INST_NAME("CMOVNO Gd, Ed");

-            GO( TSTw_mask(xFlags, 0b010101, 0)

-                , cNE, cEQ, X_OF)

-            break;

-        case 0x42:

-            INST_NAME("CMOVC Gd, Ed");

-            GO( TSTw_mask(xFlags, 0, 0)

-                , cEQ, cNE, X_CF)

-            break;

-        case 0x43:

-            INST_NAME("CMOVNC Gd, Ed");

-            GO( TSTw_mask(xFlags, 0, 0)

-                , cNE, cEQ, X_CF)

-            break;

-        case 0x44:

-            INST_NAME("CMOVZ Gd, Ed");

-            GO( TSTw_mask(xFlags, 0b011010, 0)

-                , cEQ, cNE, X_ZF)

-            break;

-        case 0x45:

-            INST_NAME("CMOVNZ Gd, Ed");

-            GO( TSTw_mask(xFlags, 0b011010, 0)

-                , cNE, cEQ, X_ZF)

-            break;

-        case 0x46:

-            INST_NAME("CMOVBE Gd, Ed");

-            GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF));

-                TSTw_REG(xFlags, x1)

-                , cEQ, cNE, X_CF|X_ZF)

-            break;

-        case 0x47:

-            INST_NAME("CMOVNBE Gd, Ed");

-            GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF));

-                TSTw_REG(xFlags, x1)

-                , cNE, cEQ, X_CF|X_ZF)

-            break;

-        case 0x48:

-            INST_NAME("CMOVS Gd, Ed");

-            GO( TSTw_mask(xFlags, 0b011001, 0)  // 0X80

-                , cEQ, cNE, X_SF)

-            break;

-        case 0x49:

-            INST_NAME("CMOVNS Gd, Ed");

-            GO( TSTw_mask(xFlags, 0b011001, 0)

-                , cNE, cEQ, X_SF)

-            break;

-        case 0x4A:

-            INST_NAME("CMOVP Gd, Ed");

-            GO( TSTw_mask(xFlags, 0b011110, 0)

-                , cEQ, cNE, X_PF)

-            break;

-        case 0x4B:

-            INST_NAME("CMOVNP Gd, Ed");

-            GO( TSTw_mask(xFlags, 0b011110, 0)

-                , cNE, cEQ, X_PF)

-            break;

-        case 0x4C:

-            INST_NAME("CMOVL Gd, Ed");

-            GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);

-                TSTw_mask(x1, 0b010101, 0)

-                , cEQ, cNE, X_SF|X_OF)

-            break;

-        case 0x4D:

-            INST_NAME("CMOVGE Gd, Ed");

-            GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);

-                TSTw_mask(x1, 0b010101, 0)

-                , cNE, cEQ, X_SF|X_OF)

-            break;

-        case 0x4E:

-            INST_NAME("CMOVLE Gd, Ed");

-            GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);

-                ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF);

-                TSTw_mask(x1, 0b010101, 0)

-                , cEQ, cNE, X_SF|X_OF|X_ZF)

-            break;

-        case 0x4F:

-            INST_NAME("CMOVG Gd, Ed");

-            GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);

-                ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF);

-                TSTw_mask(x1, 0b010101, 0)

-                , cNE, cEQ, X_SF|X_OF|X_ZF)

-            break;

+        GOCOND(0x40, "CMOV", "Gd, Ed");

         #undef GO

         

+        #define GO(GETFLAGS, NO, YES, F)   \

+            READFLAGS(F);   \

+            i32_ = F32S;    \

+            BARRIER(2);     \

+            JUMP(addr+i32_);\

+            GETFLAGS;   \

+            if(dyn->insts) {    \

+                if(dyn->insts[ninst].x64.jmp_insts==-1) {   \

+                    /* out of the block */                  \

+                    i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \

+                    Bcond(NO, i32);     \

+                    jump_to_next(dyn, addr+i32_, 0, ninst); \

+                } else {    \

+                    /* inside the block */  \

+                    i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size);    \

+                    Bcond(YES, i32);    \

+                }   \

+            }

+

+        GOCOND(0x80, "J", "Id");

+        #undef GO

+            

         case 0xBB:

             INST_NAME("BTC Ed, Gd");

             SETFLAGS(X_CF, SF_SET);

diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 69f48f1a..b7ef4a6a 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -781,4 +781,94 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 #define MAYUSE(A)   
 #endif
 
+#define GOCOND(B, T1, T2)                                   \
+    case B+0x0:                                             \
+        INST_NAME(T1 "O " T2);                              \
+        GO( TSTw_mask(xFlags, 0b010101, 0)                  \
+            , cEQ, cNE, X_OF)                               \
+        break;                                              \
+    case B+0x1:                                             \
+        INST_NAME(T1 "NO " T2);                             \
+        GO( TSTw_mask(xFlags, 0b010101, 0)                  \
+            , cNE, cEQ, X_OF)                               \
+        break;                                              \
+    case B+0x2:                                             \
+        INST_NAME(T1 "C " T2);                              \
+        GO( TSTw_mask(xFlags, 0, 0)                         \
+            , cEQ, cNE, X_CF)                               \
+        break;                                              \
+    case B+0x3:                                             \
+        INST_NAME(T1 "NC " T2);                             \
+        GO( TSTw_mask(xFlags, 0, 0)                         \
+            , cNE, cEQ, X_CF)                               \
+        break;                                              \
+    case B+0x4:                                             \
+        INST_NAME(T1 "Z " T2);                              \
+        GO( TSTw_mask(xFlags, 0b011010, 0)                  \
+            , cEQ, cNE, X_ZF)                               \
+        break;                                              \
+    case B+0x5:                                             \
+        INST_NAME(T1 "NZ " T2);                             \
+        GO( TSTw_mask(xFlags, 0b011010, 0)                  \
+            , cNE, cEQ, X_ZF)                               \
+        break;                                              \
+    case B+0x6:                                             \
+        INST_NAME(T1 "BE " T2);                             \
+        GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF));                \
+            TSTw_REG(xFlags, x1)                            \
+            , cEQ, cNE, X_CF|X_ZF)                          \
+        break;                                              \
+    case B+0x7:                                             \
+        INST_NAME(T1 "NBE " T2);                            \
+        GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF));                \
+            TSTw_REG(xFlags, x1)                            \
+            , cNE, cEQ, X_CF|X_ZF)                          \
+        break;                                              \
+    case B+0x8:                                             \
+        INST_NAME(T1 "S " T2);                              \
+        GO( TSTw_mask(xFlags, 0b011001, 0)                  \
+            , cEQ, cNE, X_SF)                               \
+        break;                                              \
+    case B+0x9:                                             \
+        INST_NAME(T1 "NS " T2);                             \
+        GO( TSTw_mask(xFlags, 0b011001, 0)                  \
+            , cNE, cEQ, X_SF)                               \
+        break;                                              \
+    case B+0xA:                                             \
+        INST_NAME(T1 "P " T2);                              \
+        GO( TSTw_mask(xFlags, 0b011110, 0)                  \
+            , cEQ, cNE, X_PF)                               \
+        break;                                              \
+    case B+0xB:                                             \
+        INST_NAME(T1 "NP " T2);                             \
+        GO( TSTw_mask(xFlags, 0b011110, 0)                  \
+            , cNE, cEQ, X_PF)                               \
+        break;                                              \
+    case B+0xC:                                             \
+        INST_NAME(T1 "L " T2);                              \
+        GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);    \
+            TSTw_mask(x1, 0b010101, 0)                      \
+            , cEQ, cNE, X_SF|X_OF)                          \
+        break;                                              \
+    case B+0xD:                                             \
+        INST_NAME(T1 "GE " T2);                             \
+        GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);    \
+            TSTw_mask(x1, 0b010101, 0)                      \
+            , cNE, cEQ, X_SF|X_OF)                          \
+        break;                                              \
+    case B+0xE:                                             \
+        INST_NAME(T1 "LE " T2);                             \
+        GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);    \
+            ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF);        \
+            TSTw_mask(x1, 0b010101, 0)                      \
+            , cEQ, cNE, X_SF|X_OF|X_ZF)                     \
+        break;                                              \
+    case B+0xF:                                             \
+        INST_NAME(T1 "G " T2);                              \
+        GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF);    \
+            ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF);        \
+            TSTw_mask(x1, 0b010101, 0)                      \
+            , cNE, cEQ, X_SF|X_OF|X_ZF)                     \
+        break
+
 #endif //__DYNAREC_ARM64_HELPER_H__
\ No newline at end of file