aboutsummaryrefslogtreecommitdiff
path: root/emulators/libretro-reicast/files/patch-libswirl_hw_arm7_arm7__jit__virt__x86.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'emulators/libretro-reicast/files/patch-libswirl_hw_arm7_arm7__jit__virt__x86.cpp')
-rw-r--r--emulators/libretro-reicast/files/patch-libswirl_hw_arm7_arm7__jit__virt__x86.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/emulators/libretro-reicast/files/patch-libswirl_hw_arm7_arm7__jit__virt__x86.cpp b/emulators/libretro-reicast/files/patch-libswirl_hw_arm7_arm7__jit__virt__x86.cpp
new file mode 100644
index 000000000000..f2c04dd29ffa
--- /dev/null
+++ b/emulators/libretro-reicast/files/patch-libswirl_hw_arm7_arm7__jit__virt__x86.cpp
@@ -0,0 +1,109 @@
+--- libswirl/hw/arm7/arm7_jit_virt_x86.cpp.orig 2020-10-18 11:22:48 UTC
++++ libswirl/hw/arm7/arm7_jit_virt_x86.cpp
+@@ -13,6 +13,99 @@
+
+ #if HOST_OS == OS_LINUX || HOST_OS == OS_DARWIN
+ #include <sys/mman.h>
++
++#define DP_R_ROFC (OP_READ_FLAGS_S|OP_READ_REG_1) //Reads reg1, op2, flags if S
++#define DP_R_ROF (OP_READ_FLAGS|OP_READ_REG_1) //Reads reg1, op2, flags (ADC & co)
++#define DP_R_OFC (OP_READ_FLAGS_S) //Reads op2, flags if S
++
++#define DP_W_RFC (OP_WRITE_FLAGS_S|OP_WRITE_REG) //Writes reg, and flags if S
++#define DP_W_F (OP_WRITE_FLAGS) //Writes only flags, always (S=1)
++
++struct ArmDPOP {
++ u32 key;
++ u32 mask;
++ u32 flags;
++};
++
++vector<ArmDPOP> ops;
++
++void AddDPOP(u32 subcd, u32 rflags, u32 wflags) {
++ ArmDPOP op;
++
++ u32 key = subcd << 21;
++ u32 mask = (15 << 21) | (7 << 25);
++
++ op.flags = rflags | wflags;
++
++ if (wflags == DP_W_F) {
++ //also match S bit for opcodes that must write to flags (CMP & co)
++ mask |= 1 << 20;
++ key |= 1 << 20;
++ }
++
++ //ISR form (bit 25=0, bit 4 = 0)
++ op.key = key;
++ op.mask = mask | (1 << 4);
++ ops.push_back(op);
++
++ //RSR form (bit 25=0, bit 4 = 1, bit 7=0)
++ op.key = key | (1 << 4);
++ op.mask = mask | (1 << 4) | (1 << 7);
++ ops.push_back(op);
++
++ //imm8r4 form (bit 25=1)
++ op.key = key | (1 << 25);
++ op.mask = mask;
++ ops.push_back(op);
++}
++
++void InitHash() {
++ /*
++ COND | 00 I OP1 S Rn Rd OPER2 -- Data opcode, PSR xfer
++ Data processing opcodes
++ */
++
++ //AND 0000 Rn, OPER2, {Flags} Rd, {Flags}
++ //EOR 0001 Rn, OPER2, {Flags} Rd, {Flags}
++ //SUB 0010 Rn, OPER2, {Flags} Rd, {Flags}
++ //RSB 0011 Rn, OPER2, {Flags} Rd, {Flags}
++ //ADD 0100 Rn, OPER2, {Flags} Rd, {Flags}
++ //ORR 1100 Rn, OPER2, {Flags} Rd, {Flags}
++ //BIC 1110 Rn, OPER2, {Flags} Rd, {Flags}
++ AddDPOP(0, DP_R_ROFC, DP_W_RFC);
++ AddDPOP(1, DP_R_ROFC, DP_W_RFC);
++ AddDPOP(2, DP_R_ROFC, DP_W_RFC);
++ AddDPOP(3, DP_R_ROFC, DP_W_RFC);
++ AddDPOP(4, DP_R_ROFC, DP_W_RFC);
++ AddDPOP(12, DP_R_ROFC, DP_W_RFC);
++ AddDPOP(14, DP_R_ROFC, DP_W_RFC);
++
++ //ADC 0101 Rn, OPER2, Flags Rd, {Flags}
++ //SBC 0110 Rn, OPER2, Flags Rd, {Flags}
++ //RSC 0111 Rn, OPER2, Flags Rd, {Flags}
++ AddDPOP(5, DP_R_ROF, DP_W_RFC);
++ AddDPOP(6, DP_R_ROF, DP_W_RFC);
++ AddDPOP(7, DP_R_ROF, DP_W_RFC);
++
++ //TST 1000 S=1 Rn, OPER2, Flags Flags
++ //TEQ 1001 S=1 Rn, OPER2, Flags Flags
++ AddDPOP(8, DP_R_ROF, DP_W_F);
++ AddDPOP(9, DP_R_ROF, DP_W_F);
++
++ //CMP 1010 S=1 Rn, OPER2 Flags
++ //CMN 1011 S=1 Rn, OPER2 Flags
++ AddDPOP(10, DP_R_ROF, DP_W_F);
++ AddDPOP(11, DP_R_ROF, DP_W_F);
++
++ //MOV 1101 OPER2, {Flags} Rd, {Flags}
++ //MVN 1111 OPER2, {Flags} Rd, {Flags}
++ AddDPOP(13, DP_R_OFC, DP_W_RFC);
++ AddDPOP(15, DP_R_OFC, DP_W_RFC);
++}
++
++void armt_init() {
++ InitHash();
++}
+ #endif
+ #if HOST_OS == OS_WINDOWS
+ #include <Windows.h>
+@@ -455,4 +548,4 @@ struct Arm7VirtBackendX86 : Arm7VirtBackend {
+ Arm7VirtBackend* Arm7VirtBackend::Create(ARM7Backend* arm, Arm7Context* ctx) {
+ return new Arm7VirtBackendX86(arm, ctx);
+ }
+-#endif
+\ No newline at end of file
++#endif