about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt2
-rwxr-xr-xsrc/dynarec/arm64_emitter.h37
-rwxr-xr-xsrc/dynarec/arm64_lock.S28
-rwxr-xr-xsrc/dynarec/arm64_printer.c13
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c6
-rw-r--r--src/dynarec/dynarec_arm64_f0.c120
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h54
7 files changed, 214 insertions, 46 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8ad00493..c12f1efb 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -264,7 +264,7 @@ if(ARM_DYNAREC)
     #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_dd.c"
     #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_de.c"
     #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_df.c"
-    #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_f0.c"
+    "${BOX64_ROOT}/src/dynarec/dynarec_arm64_f0.c"
     "${BOX64_ROOT}/src/dynarec/dynarec_arm64_660f.c"
     "${BOX64_ROOT}/src/dynarec/dynarec_arm64_f20f.c"
     "${BOX64_ROOT}/src/dynarec/dynarec_arm64_f30f.c"
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index e59a9cbf..1ad5cebb 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -283,18 +283,31 @@
 #define POP1(reg)       LDRx_S9_postindex(reg, xRSP, 8)
 #define PUSH1(reg)      STRx_S9_preindex(reg, xRSP, -8)
 
+// LOAD/STORE Acquire Exclusive
+#define MEMAX_gen(size, L, Rs, Rn, Rt)      ((size)<<30 | 0b001000<<24 | (L)<<22 | (Rs)<<16 | 1<<15 | 0b11111<<10 | (Rn)<<5 | (Rt))
+#define LDAXRB(Rt, Rn)                  EMIT(MEMAX_gen(0b00, 1, 31, Rn, Rt))
+#define STLXRB(Rs, Rt, Rn)              EMIT(MEMAX_gen(0b00, 0, Rs, Rn, Rt))
+#define LDAXRH(Rt, Rn)                  EMIT(MEMAX_gen(0b01, 1, 31, Rn, Rt))
+#define STLXRH(Rs, Rt, Rn)              EMIT(MEMAX_gen(0b01, 0, Rs, Rn, Rt))
+#define LDAXRw(Rt, Rn)                  EMIT(MEMAX_gen(0b10, 1, 31, Rn, Rt))
+#define STLXRw(Rs, Rt, Rn)              EMIT(MEMAX_gen(0b10, 0, Rs, Rn, Rt))
+#define LDAXRx(Rt, Rn)                  EMIT(MEMAX_gen(0b11, 1, 31, Rn, Rt))
+#define STLXRx(Rs, Rt, Rn)              EMIT(MEMAX_gen(0b11, 0, Rs, Rn, Rt))
+#define LDAXRxw(Rt, Rn)                 EMIT(MEMAX_gen(2+rex.w, 1, 31, Rn, Rt))
+#define STLXRxw(Rs, Rt, Rn)             EMIT(MEMAX_gen(2+rex.w, 0, Rs, Rn, Rt))
+
 // LOAD/STORE Exclusive
-#define MEMX_gen(size, L, Rs, Rn, Rt)       ((size)<<30 | 0b001000<<24 | (L)<<22 | (Rs)<<16 | 1<<15 | 0b11111<<10 | (Rn)<<5 | (Rt))
-#define LDAXRB(Rt, Rn)                  EMIT(MEMX_gen(0b00, 1, 31, Rn, Rt))
-#define STLXRB(Rs, Rt, Rn)              EMIT(MEMX_gen(0b00, 0, Rs, Rn, Rt))
-#define LDAXRH(Rt, Rn)                  EMIT(MEMX_gen(0b01, 1, 31, Rn, Rt))
-#define STLXRH(Rs, Rt, Rn)              EMIT(MEMX_gen(0b01, 0, Rs, Rn, Rt))
-#define LDAXRw(Rt, Rn)                  EMIT(MEMX_gen(0b10, 1, 31, Rn, Rt))
-#define STLXRw(Rs, Rt, Rn)              EMIT(MEMX_gen(0b10, 0, Rs, Rn, Rt))
-#define LDAXRx(Rt, Rn)                  EMIT(MEMX_gen(0b11, 1, 31, Rn, Rt))
-#define STLXRx(Rs, Rt, Rn)              EMIT(MEMX_gen(0b11, 0, Rs, Rn, Rt))
-#define LDAXRxw(Rt, Rn)                 EMIT(MEMX_gen(2+rex.w, 1, 31, Rn, Rt))
-#define STLXRxw(Rs, Rt, Rn)             EMIT(MEMX_gen(2+rex.w, 0, Rs, Rn, Rt))
+#define MEMX_gen(size, L, Rs, Rn, Rt)       ((size)<<30 | 0b001000<<24 | (L)<<22 | (Rs)<<16 | 0<<15 | 0b11111<<10 | (Rn)<<5 | (Rt))
+#define LDXRB(Rt, Rn)                   EMIT(MEMX_gen(0b00, 1, 31, Rn, Rt))
+#define STXRB(Rs, Rt, Rn)               EMIT(MEMX_gen(0b00, 0, Rs, Rn, Rt))
+#define LDXRH(Rt, Rn)                   EMIT(MEMX_gen(0b01, 1, 31, Rn, Rt))
+#define STXRH(Rs, Rt, Rn)               EMIT(MEMX_gen(0b01, 0, Rs, Rn, Rt))
+#define LDXRw(Rt, Rn)                   EMIT(MEMX_gen(0b10, 1, 31, Rn, Rt))
+#define STXRw(Rs, Rt, Rn)               EMIT(MEMX_gen(0b10, 0, Rs, Rn, Rt))
+#define LDXRx(Rt, Rn)                   EMIT(MEMX_gen(0b11, 1, 31, Rn, Rt))
+#define STXRx(Rs, Rt, Rn)               EMIT(MEMX_gen(0b11, 0, Rs, Rn, Rt))
+#define LDXRxw(Rt, Rn)                  EMIT(MEMX_gen(2+rex.w, 1, 31, Rn, Rt))
+#define STXRxw(Rs, Rt, Rn)              EMIT(MEMX_gen(2+rex.w, 0, Rs, Rn, Rt))
 
 // BR and Branches
 #define BR_gen(Z, op, A, M, Rn, Rm)       (0b1101011<<25 | (Z)<<24 | (op)<<21 | 0b11111<<16 | (A)<<11 | (M)<<10 | (Rn)<<5 | (Rm))
@@ -304,8 +317,10 @@
 #define CB_gen(sf, op, imm19, Rt)       ((sf)<<31 | 0b011010<<25 | (op)<<24 | (imm19)<<5 | (Rt))
 #define CBNZx(Rt, imm19)                EMIT(CB_gen(1, 1, ((imm19)>>2)&0x7FFFF, Rt))
 #define CBNZw(Rt, imm19)                EMIT(CB_gen(0, 1, ((imm19)>>2)&0x7FFFF, Rt))
+#define CBNZxw(Rt, imm19)               EMIT(CB_gen(rex.w, 1, ((imm19)>>2)&0x7FFFF, Rt))
 #define CBZx(Rt, imm19)                 EMIT(CB_gen(1, 0, ((imm19)>>2)&0x7FFFF, Rt))
 #define CBZw(Rt, imm19)                 EMIT(CB_gen(0, 0, ((imm19)>>2)&0x7FFFF, Rt))
+#define CBZxw(Rt, imm19)                EMIT(CB_gen(rex.w, 0, ((imm19)>>2)&0x7FFFF, Rt))
 
 #define Bcond_gen(imm19, cond)          (0b0101010<<25 | (imm19)<<5 | (cond))
 #define Bcond(cond, imm19)              EMIT(Bcond_gen(((imm19)>>2)&0x7FFFF, cond))
diff --git a/src/dynarec/arm64_lock.S b/src/dynarec/arm64_lock.S
index ebe7f8ec..0eb4dff3 100755
--- a/src/dynarec/arm64_lock.S
+++ b/src/dynarec/arm64_lock.S
@@ -19,55 +19,55 @@
 
 arm64_lock_read_b:
     // address is x0, return is x0
-    ldaxrb  w0, [x0]
+    ldxrb   w0, [x0]
     ret
 
 arm64_lock_write_b:
     // address is x0, value is x1, return is x0
     mov     x2, x0
-    stlxrb  w0, w1, [x2]
+    stxrb   w0, w1, [x2]
     ret
 
 arm64_lock_read_h:
     // address is x0, return is x0
-    ldaxrh  w0, [x0]
+    ldxrh   w0, [x0]
     ret
 
 arm64_lock_write_h:
     // address is x0, value is x1, return is x0
     mov     x2, x0
-    stlxrh  w0, w1, [x2]
+    stxrh   w0, w1, [x2]
     ret
 
 arm64_lock_read_d:
     // address is x0, return is x0
-    #ldaxr   w0, [x0]
-    ldr     w0,[x0]
+    ldxr     w0, [x0]
+    #ldx     w0,[x0]
     ret
 
 arm64_lock_write_d:
     // address is x0, value is w1, return is x0
     mov     x2, x0
-    #stlxr   w0, w1, [x2]
-    str     w1, [x2]
+    stxr    w0, w1, [x2]
+    #str     w1, [x2]
     mov     w0, 0
     ret
 
 arm64_lock_read_dd:
     // address is x0, return is x0
-    ldaxr   x0, [x0]
+    ldxr    x0, [x0]
     ret
 
 arm64_lock_write_dd:
     // address is x0, value is x1, return is x0
     mov     x2, x0
-    stlxr   w0, x1, [x2]
+    stxr    w0, x1, [x2]
     ret
 
 arm64_lock_xchg:
     // address is x0, value is x1, return old value in x0
-    ldaxr   x2, [x0]
-    stlxr   w3, x1, [x0]
+    ldxr    x2, [x0]
+    stxr    w3, x1, [x0]
     cmp     w3, #1
     beq     arm64_lock_xchg
     mov     x0, x2
@@ -75,11 +75,11 @@ arm64_lock_xchg:
 
 arm64_lock_storeifnull:
     // address is x0, value is x1, x1 store to x0 only if [x0] is 0. return new [x0] value (so x1 or old value)
-    ldaxr   x2, [x0]
+    ldxr    x2, [x0]
     cmp     x2, #0
     bne     arm64_lock_storeifnull_exit
     mov     x2, x1
-    stlxr   w3, x2, [x0]
+    stxr    w3, x2, [x0]
     cmp     w3, #1
     beq     arm64_lock_storeifnull
 arm64_lock_storeifnull_exit:
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index 103e6aff..fbd1740e 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -284,6 +284,14 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         return buff;

     }

 

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

+        if(a.L)

+            snprintf(buff, sizeof(buff), "LDXR%s %s, [%s]", (sf==0)?"B":((sf==1)?"H":""), (sf==2)?Wt[Rt]:Xt[Rt], XtSp[Rn]);

+        else

+            snprintf(buff, sizeof(buff), "STXR%s %s, %s, [%s]", (sf==0)?"B":((sf==1)?"H":""), (sf==2)?Wt[Rs]:Xt[Rs], (sf==2)?Wt[Rt]:Xt[Rt], XtSp[Rn]);

+        return buff;

+    }

+

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

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

         if(!hw)

@@ -652,6 +660,11 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         snprintf(buff, sizeof(buff), "CBZ %s, #%+d\t; %p", Xt[Rt], offset, (void*)(addr + offset));

         return buff;

     }

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

+        int offset = signExtend(imm, 19)<<2;

+        snprintf(buff, sizeof(buff), "CBNZ %s, #%+d\t; %p", Xt[Rt], offset, (void*)(addr + offset));

+        return buff;

+    }

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

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

         return buff;

diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index bb51582a..938fbaf0 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -851,7 +851,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 MARKLOCK;
                 LDAXRxw(x1, ed);
                 STLXRxw(x3, gd, ed);
-                CBZx_MARKLOCK(x3);
+                CBNZx_MARKLOCK(x3);
                 B_MARK2_nocond;
                 MARK;
                 LDRxw_U12(x1, ed, 0);
@@ -1574,6 +1574,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             *ok = 0;
             break;
 
+        case 0xF0:
+            addr = dynarec64_F0(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+            break;
+
         case 0xF6:
             nextop = F8;
             switch((nextop>>3)&7) {
diff --git a/src/dynarec/dynarec_arm64_f0.c b/src/dynarec/dynarec_arm64_f0.c
new file mode 100644
index 00000000..226a2b62
--- /dev/null
+++ b/src/dynarec/dynarec_arm64_f0.c
@@ -0,0 +1,120 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "dynarec_arm64.h"
+#include "dynarec_arm64_private.h"
+#include "arm64_printer.h"
+
+#include "dynarec_arm64_helper.h"
+#include "dynarec_arm64_functions.h"
+
+
+uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
+{
+    uint8_t opcode = F8;
+    uint8_t nextop, u8;
+    uint32_t u32;
+    int32_t i32, j32;
+    int16_t i16;
+    uint16_t u16;
+    uint8_t gd, ed;
+    uint8_t wback, wb1, wb2, gb1, gb2;
+    int fixedaddress;
+    MAYUSE(u16);
+    MAYUSE(u8);
+    MAYUSE(j32);
+
+    while((opcode==0x2E) || (opcode==0x66))   // ignoring CS: or multiple 0x66
+        opcode = F8;
+
+    while((opcode==0xF2) || (opcode==0xF3)) {
+        rep = opcode-0xF1;
+        opcode = F8;
+    }
+    // REX prefix before the F0 are ignored
+    rex.rex = 0;
+    while(opcode>=0x40 && opcode<=0x4f) {
+        rex.rex = opcode;
+        opcode = F8;
+    }
+
+    switch(opcode) {
+
+        case 0x0F:
+            nextop = F8;
+            switch(nextop) {
+
+                case 0xB1:
+                    INST_NAME("LOCK CMPXCHG Ed, Gd");
+                    SETFLAGS(X_ALL, SF_SET);
+                    nextop = F8;
+                    GETGD;
+                    if(MODREG) {
+                        ed = xRAX+(nextop&7)+(rex.b<<3);
+                        wback = 0;
+                        CMPSxw_REG(xRAX, ed);
+                        B_MARK(cNE);
+                        UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, ed, x3, x4, x5);}
+                        MOVxw_REG(ed, gd);
+                        B_MARK_nocond;
+                    } else {
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, 0);
+                        TSTx_mask(wback, 1, 0, 1+rex.w);    // mask=3 or 7
+                        B_MARK3(cNE);
+                        // Aligned version
+                        MARKLOCK;
+                        LDXRxw(x1, wback);
+                        ed = x1;
+                        CMPSxw_REG(xRAX, ed);
+                        B_MARK(cNE);
+                        // EAX == Ed
+                        STXRxw(x4, gd, wback);
+                        CBNZx_MARKLOCK(x4);
+                        UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, ed, x3, x4, x5);}
+                        // done
+                        B_MARK_nocond;
+                        // Unaligned version
+                        MARK3;
+                        LDRxw_U12(x1, wback, 0);
+                        LDXRB(x3, wback); // dummy read, to arm the write...
+                        ed = x1;
+                        CMPSxw_REG(xRAX, ed);
+                        B_MARK(cNE);
+                        // EAX == Ed
+                        STXRB(x4, gd, wback);
+                        CBNZx_MARK3(x4);
+                        STRxw_U12(gd, wback, 0);
+                        UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, ed, x3, x4, x5);}
+                        B_MARK_nocond;
+                    }
+                    MARK;
+                    // EAX != Ed
+                    UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, ed, x3, x4, x5);}
+                    MOVxw_REG(xRAX, ed);
+                    break;
+
+                default:
+                    DEFAULT;
+            }
+            break;
+                    
+        default:
+            DEFAULT;
+    }
+    return addr;
+}
+
diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h
index 91bc4f83..e7c8e6ca 100755
--- a/src/dynarec/dynarec_arm64_helper.h
+++ b/src/dynarec/dynarec_arm64_helper.h
@@ -254,25 +254,41 @@
 #define GETMARKLOCK ((dyn->insts)?dyn->insts[ninst].marklock:(dyn->arm_size+4))
 
 // Branch to MARK if cond (use j32)
-#define B_MARK(cond)    \
-    j32 = GETMARK-(dyn->arm_size);    \
+#define B_MARK(cond)                \
+    j32 = GETMARK-(dyn->arm_size);  \
     Bcond(cond, j32)
+// Branch to MARK unconditionnal (use j32)
+#define B_MARK_nocond               \
+    j32 = GETMARK-(dyn->arm_size);  \
+    B(j32)
 // Branch to MARK2 if cond (use j32)
-#define B_MARK2(cond)    \
-    j32 = GETMARK2-(dyn->arm_size);   \
+#define B_MARK2(cond)               \
+    j32 = GETMARK2-(dyn->arm_size); \
     Bcond(cond, j32)
 // Branch to MARK2 unconditionnal (use j32)
-#define B_MARK2_nocond    \
-    j32 = GETMARK2-(dyn->arm_size);   \
+#define B_MARK2_nocond              \
+    j32 = GETMARK2-(dyn->arm_size); \
     B(j32)
 // Branch to MARK3 if cond (use j32)
-#define B_MARK3(cond)    \
-    j32 = GETMARK3-(dyn->arm_size);   \
+#define B_MARK3(cond)               \
+    j32 = GETMARK3-(dyn->arm_size); \
     Bcond(cond, j32)
+// Branch to MARK3 unconditionnal (use j32)
+#define B_MARK3_nocond              \
+    j32 = GETMARK3-(dyn->arm_size); \
+    B(j32)
+// Branch to MARK3 if reg is not 0 (use j32)
+#define CBNZx_MARK3(reg)            \
+    j32 = GETMARK3-(dyn->arm_size); \
+    CBNZx(reg, j32)
 // Branch to next instruction if cond (use j32)
 #define B_NEXT(cond)     \
     j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)):0; \
     Bcond(cond, j32)
+// Branch to next instruction unconditionnal (use j32)
+#define B_NEXT_nocond                                               \
+    j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)):0;\
+    B(j32)
 // Branch to next instruction if reg is 0 (use j32)
 #define CBZw_NEXT(reg)    \
     j32 =  (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)):0; \
@@ -294,8 +310,8 @@
     j32 = GETMARKLOCK-(dyn->arm_size);   \
     Bcond(cond, j32)
 // Branch to MARKLOCK if reg is not 0 (use j32)
-#define CBZx_MARKLOCK(reg)    \
-    j32 = GETMARKLOCK-(dyn->arm_size);   \
+#define CBNZx_MARKLOCK(reg)             \
+    j32 = GETMARKLOCK-(dyn->arm_size);  \
     CBNZx(reg, j32)
 
 #define IFX(A)  if(dyn->insts && (dyn->insts[ninst].x64.need_flags&(A)))
@@ -775,15 +791,15 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 //uintptr_t dynarec64_GS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog);
 uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
-//uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
-//uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
-//uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
-//uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
-//uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
-//uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
-//uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
-//uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
-//uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog);
+//uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+//uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+//uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+//uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+//uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+//uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+//uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+//uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);