diff --git a/rpcs3/Emu/ARMv7/ARMv7Decoder.h b/rpcs3/Emu/ARMv7/ARMv7Decoder.h
index 298a23be51..923dc6a0f1 100644
--- a/rpcs3/Emu/ARMv7/ARMv7Decoder.h
+++ b/rpcs3/Emu/ARMv7/ARMv7Decoder.h
@@ -13,125 +13,22 @@ public:
{
}
- u32 branchTarget(u32 imm)
- {
- return imm << 1;
- }
-
virtual u8 DecodeMemory(const u32 address)
{
- using namespace ARMv7_opcodes;
- const u16 code0 = vm::psv::read16(address);
- const u16 code1 = vm::psv::read16(address + 2);
+ const u32 code0 = vm::psv::read16(address & ~1);
+ const u32 code1 = vm::psv::read16(address + 2 & ~1);
+ const u32 data = code0 << 16 | code1;
- switch(code0 >> 12) //15 - 12
+ for (auto& opcode : ARMv7_opcode_table)
{
- case T1_CBZ:
- switch((code0 >> 10) & 0x1)
+ if ((opcode.type >= A1) == ((address & 1) == 0) && (data & opcode.mask) == opcode.code)
{
- case 0:
- switch((code0 >> 8) & 0x1)
- {
- case 1:
- m_op.CBZ((code0 >> 11) & 0x1, branchTarget((((code0 >> 9) & 0x1) << 5) | ((code0 >> 3) & 0x1f)), code0 & 0x7, 2);
- return 2;
- }
- break;
- }
- break;
-
- case T1_B:
- m_op.B((code0 >> 8) & 0xf, branchTarget(code0 & 0xff), 2);
- return 2;
- }
-
- switch(code0 >> 11) //15 - 11
- {
- case T2_B:
- m_op.B(0xf, branchTarget(code0 & 0xfff), 2);
- return 2;
-
- case T3_B:
- {
- u8 S = (code0 >> 10) & 0x1;
- u8 J1 = (code1 >> 13) & 0x1;
- u8 J2 = (code1 >> 11) & 0x1;
- u8 I1 = 1 - (J1 ^ S);
- u8 I2 = 1 - (J2 ^ S);
- u16 imm11 = code1 & 0x7ff;
- u32 imm32 = 0;
-
- switch(code1 >> 14)
- {
- case 2: //B
- {
- u8 cond;
- switch((code1 >> 12) & 0x1)
- {
- case 0:
- {
- cond = (code0 >> 6) & 0xf;
- u32 imm6 = code0 & 0x3f;
- imm32 = sign<19, u32>((S << 19) | (I1 << 18) | (I2 << 17) | (imm6 << 11) | imm11);
- }
- break;
-
- case 1:
- cond = 0xf;
- u32 imm10 = code0 & 0x7ff;
- imm32 = sign<23, u32>((S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11);
- break;
- }
-
- m_op.B(cond, branchTarget(imm32), 4);
- }
- return 4;
-
- case 3: //BL
- switch((code1 >> 12) & 0x1)
- {
- case 0:
- break;
-
- case 1:
- u32 imm10 = code0 & 0x7ff;
- imm32 = sign<23, u32>((S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11);
- m_op.BL(branchTarget(imm32), 4);
- return 4;
- }
- break;
+ (m_op.*opcode.func)(opcode.length == 2 ? code0 : data, opcode.type);
+ return opcode.length;
}
}
- break;
- }
- switch(code0 >> 9)
- {
- case T1_PUSH:
- m_op.PUSH((((code0 >> 8) & 0x1) << 14) | (code0 & 0xff));
- return 2;
-
- case T1_POP:
- m_op.POP((((code0 >> 8) & 0x1) << 15) | (code0 & 0xff));
- return 2;
- }
-
- switch(code0)
- {
- case T2_PUSH:
- m_op.PUSH(code1);
- return 4;
-
- case T2_POP:
- m_op.POP(code1);
- return 4;
-
- case T1_NOP:
- m_op.NOP();
- return 2;
- }
-
- m_op.UNK(code0, code1);
+ m_op.UNK(data);
return 2;
}
};
diff --git a/rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp b/rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp
new file mode 100644
index 0000000000..fddba98bec
--- /dev/null
+++ b/rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp
@@ -0,0 +1,92 @@
+#include "stdafx.h"
+#include "ARMv7DisAsm.h"
+
+void ARMv7DisAsm::UNK(const u32 data)
+{
+ Write("Unknown/illegal opcode");
+}
+
+void ARMv7DisAsm::NULL_OP(const u32 data, const ARMv7_encoding type)
+{
+ Write("NULL");
+}
+
+void ARMv7DisAsm::PUSH(const u32 data, const ARMv7_encoding type)
+{
+ Write("PUSH...");
+ //Write(fmt::Format("push {%s}", GetRegsListString(regs_list).c_str()));
+}
+
+void ARMv7DisAsm::POP(const u32 data, const ARMv7_encoding type)
+{
+ Write("POP...");
+ //Write(fmt::Format("pop {%s}", GetRegsListString(regs_list).c_str()));
+}
+
+void ARMv7DisAsm::NOP(const u32 data, const ARMv7_encoding type)
+{
+ Write("NOP");
+}
+
+void ARMv7DisAsm::B(const u32 data, const ARMv7_encoding type)
+{
+ Write("B...");
+ //if ((cond & 0xe) == 0xe)
+ //{
+ // Write(fmt::Format("b 0x%x", DisAsmBranchTarget(imm) + intstr_size));
+ //}
+ //else
+ //{
+ // Write(fmt::Format("b[%s] 0x%x", g_arm_cond_name[cond], DisAsmBranchTarget(imm) + intstr_size));
+ //}
+}
+
+void ARMv7DisAsm::CBZ(const u32 data, const ARMv7_encoding type)
+{
+ Write("CBZ...");
+ //Write(fmt::Format("cbz 0x%x,%s", DisAsmBranchTarget(imm) + intstr_size, g_arm_reg_name[rn]));
+}
+
+void ARMv7DisAsm::CBNZ(const u32 data, const ARMv7_encoding type)
+{
+ Write("CBNZ...");
+ //Write(fmt::Format("cbnz 0x%x,%s", DisAsmBranchTarget(imm) + intstr_size, g_arm_reg_name[rn]));
+}
+
+void ARMv7DisAsm::BL(const u32 data, const ARMv7_encoding type)
+{
+ Write("BL...");
+ //Write(fmt::Format("bl 0x%x", DisAsmBranchTarget(imm) + intstr_size));
+}
+
+void ARMv7DisAsm::BLX(const u32 data, const ARMv7_encoding type)
+{
+ Write("BLX...");
+ //Write(fmt::Format("bl 0x%x", DisAsmBranchTarget(imm) + intstr_size));
+}
+
+void ARMv7DisAsm::SUB_IMM(const u32 data, const ARMv7_encoding type)
+{
+ Write("SUB...");
+}
+
+void ARMv7DisAsm::SUB_REG(const u32 data, const ARMv7_encoding type)
+{
+ Write("SUB...");
+}
+
+void ARMv7DisAsm::SUB_RSR(const u32 data, const ARMv7_encoding type)
+{
+ Write("SUB...");
+}
+
+void ARMv7DisAsm::SUB_SPI(const u32 data, const ARMv7_encoding type)
+{
+ Write("SUB SP...");
+}
+
+void ARMv7DisAsm::SUB_SPR(const u32 data, const ARMv7_encoding type)
+{
+ Write("SUB SP...");
+}
+
diff --git a/rpcs3/Emu/ARMv7/ARMv7DisAsm.h b/rpcs3/Emu/ARMv7/ARMv7DisAsm.h
index cf84835cd8..54067890b2 100644
--- a/rpcs3/Emu/ARMv7/ARMv7DisAsm.h
+++ b/rpcs3/Emu/ARMv7/ARMv7DisAsm.h
@@ -45,50 +45,23 @@ protected:
return regs_str;
}
- void NULL_OP()
- {
- Write("null");
- }
+ void UNK(const u32 data);
- void PUSH(u16 regs_list)
- {
- Write(fmt::Format("push {%s}", GetRegsListString(regs_list).c_str()));
- }
+ void NULL_OP(const u32 data, const ARMv7_encoding type);
+ void NOP(const u32 data, const ARMv7_encoding type);
- void POP(u16 regs_list)
- {
- Write(fmt::Format("pop {%s}", GetRegsListString(regs_list).c_str()));
- }
+ void PUSH(const u32 data, const ARMv7_encoding type);
+ void POP(const u32 data, const ARMv7_encoding type);
- void NOP()
- {
- Write("nop");
- }
+ void B(const u32 data, const ARMv7_encoding type);
+ void CBZ(const u32 data, const ARMv7_encoding type);
+ void CBNZ(const u32 data, const ARMv7_encoding type);
+ void BL(const u32 data, const ARMv7_encoding type);
+ void BLX(const u32 data, const ARMv7_encoding type);
- void B(u8 cond, u32 imm, u8 intstr_size)
- {
- if((cond & 0xe) == 0xe)
- {
- Write(fmt::Format("b 0x%x", DisAsmBranchTarget(imm) + intstr_size));
- }
- else
- {
- Write(fmt::Format("b[%s] 0x%x", g_arm_cond_name[cond], DisAsmBranchTarget(imm) + intstr_size));
- }
- }
-
- virtual void CBZ(u8 op, u32 imm, u8 rn, u8 intstr_size)
- {
- Write(fmt::Format("cb%sz 0x%x,%s", (op ? "n" : ""), DisAsmBranchTarget(imm) + intstr_size, g_arm_reg_name[rn]));
- }
-
- void BL(u32 imm, u8 intstr_size)
- {
- Write(fmt::Format("bl 0x%x", DisAsmBranchTarget(imm) + intstr_size));
- }
-
- void UNK(const u16 code0, const u16 code1)
- {
- Write(fmt::Format("Unknown/Illegal opcode! (0x%04x : 0x%04x)", code0, code1));
- }
+ void SUB_IMM(const u32 data, const ARMv7_encoding type);
+ void SUB_REG(const u32 data, const ARMv7_encoding type);
+ void SUB_RSR(const u32 data, const ARMv7_encoding type);
+ void SUB_SPI(const u32 data, const ARMv7_encoding type);
+ void SUB_SPR(const u32 data, const ARMv7_encoding type);
};
diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp
new file mode 100644
index 0000000000..e20a0dd29c
--- /dev/null
+++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp
@@ -0,0 +1,291 @@
+#include "stdafx.h"
+#include "Emu/System.h"
+#include "Emu/Memory/Memory.h"
+#include "Emu/CPU/CPUDecoder.h"
+#include "ARMv7Thread.h"
+#include "ARMv7Interpreter.h"
+
+void ARMv7Interpreter::UNK(const u32 data)
+{
+ LOG_ERROR(HLE, "Unknown/illegal opcode! (0x%04x : 0x%04x)", data >> 16, data & 0xffff);
+ Emu.Pause();
+}
+
+void ARMv7Interpreter::NULL_OP(const u32 data, const ARMv7_encoding type)
+{
+ LOG_ERROR(HLE, "Null opcode found");
+ Emu.Pause();
+}
+
+void ARMv7Interpreter::NOP(const u32 data, const ARMv7_encoding type)
+{
+ switch (type)
+ {
+ case T1: break;
+ case T2: break;
+ case A1: break;
+ default: throw __FUNCTION__;
+ }
+}
+
+void ARMv7Interpreter::PUSH(const u32 data, const ARMv7_encoding type)
+{
+ u16 reg_list = 0;
+
+ switch (type)
+ {
+ case T1:
+ {
+ reg_list = ((data & 0x100) << 6) | (data & 0xff);
+ break;
+ }
+ case T2:
+ {
+ reg_list = data & 0x5fff;
+ break;
+ }
+ case T3:
+ {
+ reg_list = 1 << (data >> 12);
+ break;
+ }
+ case A1:
+ {
+ reg_list = data & 0xffff; if (BitCount(reg_list) < 2) throw "STMDB / STMFD";
+ if (!ConditionPassed(data >> 28)) return;
+ break;
+ }
+ case A2:
+ {
+ reg_list = 1 << ((data >> 12) & 0xf);
+ if (!ConditionPassed(data >> 28)) return;
+ break;
+ }
+ default: throw __FUNCTION__;
+ }
+
+ for (u16 mask = 1 << 15, i = 15; mask; mask >>= 1, i--)
+ {
+ if (reg_list & mask)
+ {
+ CPU.SP -= 4;
+ vm::psv::write32(CPU.SP, CPU.read_gpr(i));
+ }
+ }
+}
+
+void ARMv7Interpreter::POP(const u32 data, const ARMv7_encoding type)
+{
+ u16 reg_list = 0;
+
+ switch (type)
+ {
+ case T1:
+ {
+ reg_list = ((data & 0x100) << 6) | (data & 0xff);
+ break;
+ }
+ case T2:
+ {
+ reg_list = data & 0xdfff;
+ break;
+ }
+ case T3:
+ {
+ reg_list = 1 << (data >> 12);
+ break;
+ }
+ case A1:
+ {
+ reg_list = data & 0xffff; if (BitCount(reg_list) < 2) throw "LDM / LDMIA / LDMFD";
+ if (!ConditionPassed(data >> 28)) return;
+ break;
+ }
+ case A2:
+ {
+ reg_list = 1 << ((data >> 12) & 0xf);
+ if (!ConditionPassed(data >> 28)) return;
+ break;
+ }
+ default: throw __FUNCTION__;
+ }
+
+ for (u16 mask = 1, i = 0; mask; mask <<= 1, i++)
+ {
+ if (reg_list & mask)
+ {
+ CPU.write_gpr(i, vm::psv::read32(CPU.SP));
+ CPU.SP += 4;
+ }
+ }
+}
+
+void ARMv7Interpreter::B(const u32 data, const ARMv7_encoding type)
+{
+ u8 cond = 0xf;
+ u32 jump = 0; // jump = instr_size + imm32
+
+ switch (type)
+ {
+ case T1:
+ {
+ jump = 2 + sign<9, u32>((data & 0xff) << 1);
+ cond = (data >> 8) & 0xf; if (cond == 0xf) throw "SVC";
+ break;
+ }
+ case T2:
+ {
+ jump = 2 + sign<12, u32>((data & 0x7ff) << 1);
+ break;
+ }
+ case T3:
+ {
+ u32 s = (data >> 26) & 0x1;
+ u32 j1 = (data >> 13) & 0x1;
+ u32 j2 = (data >> 11) & 0x1;
+ jump = 4 + sign<21, u32>(s << 20 | j2 << 19 | j1 << 18 | (data & 0x3f0000) >> 4 | (data & 0x7ff) << 1);
+ cond = (data >> 6) & 0xf; if (cond >= 0xe) throw "Related encodings";
+ break;
+ }
+ case T4:
+ {
+ u32 s = (data >> 26) & 0x1;
+ u32 i1 = (data >> 13) & 0x1 ^ s ^ 1;
+ u32 i2 = (data >> 11) & 0x1 ^ s ^ 1;
+ jump = 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (data & 0x3ff0000) >> 4 | (data & 0x7ff) << 1);
+ break;
+ }
+ case A1:
+ {
+ jump = 1 + 4 + sign<26, u32>((data & 0xffffff) << 2);
+ cond = (data >> 28) & 0xf;
+ break;
+ }
+ }
+
+ if (ConditionPassed(cond))
+ {
+ CPU.SetBranch(CPU.PC + jump);
+ }
+}
+
+void ARMv7Interpreter::CBZ(const u32 data, const ARMv7_encoding type)
+{
+ switch (type)
+ {
+ case T1: break;
+ default: throw __FUNCTION__;
+ }
+
+ if (CPU.GPR[data & 0x7] == 0)
+ {
+ CPU.SetBranch(CPU.PC + 2 + ((data & 0xf8) >> 2) + ((data & 0x200) >> 3));
+ }
+}
+
+void ARMv7Interpreter::CBNZ(const u32 data, const ARMv7_encoding type)
+{
+ switch (type)
+ {
+ case T1: break;
+ default: throw __FUNCTION__;
+ }
+
+ if (CPU.GPR[data & 0x7] != 0)
+ {
+ CPU.SetBranch(CPU.PC + 2 + ((data & 0xf8) >> 2) + ((data & 0x200) >> 3));
+ }
+}
+
+void ARMv7Interpreter::BL(const u32 data, const ARMv7_encoding type)
+{
+ u32 jump = 0;
+
+ switch (type)
+ {
+ case T1:
+ {
+ u32 s = (data >> 26) & 0x1;
+ u32 i1 = (data >> 13) & 0x1 ^ s ^ 1;
+ u32 i2 = (data >> 11) & 0x1 ^ s ^ 1;
+ jump = 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (data & 0x3ff0000) >> 4 | (data & 0x7ff) << 1);
+ break;
+ }
+ case A1:
+ {
+ jump = 4 + sign<26, u32>((data & 0xffffff) << 2);
+ break;
+ }
+ default: throw __FUNCTION__;
+ }
+
+ CPU.LR = (CPU.PC & 1) ? CPU.PC - 4 : CPU.PC;
+ CPU.SetBranch(CPU.PC + jump);
+}
+
+void ARMv7Interpreter::BLX(const u32 data, const ARMv7_encoding type)
+{
+ u32 target;
+
+ switch (type)
+ {
+ case T1:
+ {
+ target = CPU.GPR[(data >> 3) & 0xf];
+ break;
+ }
+ case T2:
+ {
+ u32 s = (data >> 26) & 0x1;
+ u32 i1 = (data >> 13) & 0x1 ^ s ^ 1;
+ u32 i2 = (data >> 11) & 0x1 ^ s ^ 1;
+ target = CPU.PC + 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (data & 0x3ff0000) >> 4 | (data & 0x7ff) << 1) & ~1;
+ break;
+ }
+ case A1:
+ {
+ target = CPU.GPR[data & 0xf];
+ if (!ConditionPassed(data >> 28)) return;
+ break;
+ }
+ case A2:
+ {
+ target = CPU.PC + 5 + sign<25, u32>((data & 0xffffff) << 2 | (data & 0x1000000) >> 23);
+ break;
+ }
+ default: throw __FUNCTION__;
+ }
+
+ CPU.LR = (CPU.PC & 1) ? CPU.PC - (type == T1 ? 2 : 4) : CPU.PC - 4; // ???
+ CPU.SetBranch(target);
+}
+
+void ARMv7Interpreter::SUB_IMM(const u32 data, const ARMv7_encoding type)
+{
+
+}
+
+void ARMv7Interpreter::SUB_REG(const u32 data, const ARMv7_encoding type)
+{
+
+}
+
+void ARMv7Interpreter::SUB_RSR(const u32 data, const ARMv7_encoding type)
+{
+
+}
+
+void ARMv7Interpreter::SUB_SPI(const u32 data, const ARMv7_encoding type)
+{
+ switch (type)
+ {
+ case T1: CPU.SP -= (data & 0x7f) << 2; return;
+ default: throw __FUNCTION__;
+ }
+}
+
+void ARMv7Interpreter::SUB_SPR(const u32 data, const ARMv7_encoding type)
+{
+
+}
+
diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h
index eaac69aafa..15f59f6639 100644
--- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h
+++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h
@@ -258,65 +258,23 @@ public:
}
protected:
- void NULL_OP()
- {
- LOG_ERROR(HLE, "null");
- Emu.Pause();
- }
+ void UNK(const u32 data);
- void NOP()
- {
- }
+ void NULL_OP(const u32 data, const ARMv7_encoding type);
+ void NOP(const u32 data, const ARMv7_encoding type);
- void PUSH(u16 regs_list)
- {
- for(u16 mask=0x1, i=0; mask; mask <<= 1, i++)
- {
- if(regs_list & mask)
- {
- CPU.SP -= 4;
- vm::psv::write32(CPU.SP, CPU.read_gpr(i));
- }
- }
- }
+ void PUSH(const u32 data, const ARMv7_encoding type);
+ void POP(const u32 data, const ARMv7_encoding type);
- void POP(u16 regs_list)
- {
- for(u16 mask=(0x1 << 15), i=15; mask; mask >>= 1, i--)
- {
- if(regs_list & mask)
- {
- CPU.write_gpr(i, vm::psv::read32(CPU.SP));
- CPU.SP += 4;
- }
- }
- }
+ void B(const u32 data, const ARMv7_encoding type);
+ void CBZ(const u32 data, const ARMv7_encoding type);
+ void CBNZ(const u32 data, const ARMv7_encoding type);
+ void BL(const u32 data, const ARMv7_encoding type);
+ void BLX(const u32 data, const ARMv7_encoding type);
- void B(u8 cond, u32 imm, u8 intstr_size)
- {
- if(ConditionPassed(cond))
- {
- CPU.SetBranch(CPU.PC + intstr_size + imm);
- }
- }
-
- void CBZ(u8 op, u32 imm, u8 rn, u8 intstr_size)
- {
- if((CPU.GPR[rn] == 0) ^ op)
- {
- CPU.SetBranch(CPU.PC + intstr_size + imm);
- }
- }
-
- void BL(u32 imm, u8 intstr_size)
- {
- CPU.LR = (CPU.PC + intstr_size) | 1;
- CPU.SetBranch(CPU.PC + intstr_size + imm);
- }
-
- void UNK(const u16 code0, const u16 code1)
- {
- LOG_ERROR(HLE, "Unknown/Illegal opcode! (0x%04x : 0x%04x)", code0, code1);
- Emu.Pause();
- }
+ void SUB_IMM(const u32 data, const ARMv7_encoding type);
+ void SUB_REG(const u32 data, const ARMv7_encoding type);
+ void SUB_RSR(const u32 data, const ARMv7_encoding type);
+ void SUB_SPI(const u32 data, const ARMv7_encoding type);
+ void SUB_SPR(const u32 data, const ARMv7_encoding type);
};
diff --git a/rpcs3/Emu/ARMv7/ARMv7Opcodes.h b/rpcs3/Emu/ARMv7/ARMv7Opcodes.h
index 35d3684c8e..edbe9d84f3 100644
--- a/rpcs3/Emu/ARMv7/ARMv7Opcodes.h
+++ b/rpcs3/Emu/ARMv7/ARMv7Opcodes.h
@@ -32,18 +32,88 @@ namespace ARMv7_opcodes
};
}
+enum ARMv7_encoding
+{
+ T1,
+ T2,
+ T3,
+ T4,
+ A1,
+ A2,
+};
+
class ARMv7Opcodes
{
public:
- virtual void NULL_OP() = 0;
- virtual void NOP() = 0;
+ virtual void UNK(const u32 data) = 0;
- virtual void PUSH(u16 regs_list) = 0;
- virtual void POP(u16 regs_list) = 0;
+ virtual void NULL_OP(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void NOP(const u32 data, const ARMv7_encoding type) = 0;
- virtual void B(u8 cond, u32 imm, u8 intstr_size) = 0;
- virtual void CBZ(u8 op, u32 imm, u8 rn, u8 intstr_size) = 0;
- virtual void BL(u32 imm, u8 intstr_size)=0;
-
- virtual void UNK(const u16 code0, const u16 code1) = 0;
+ virtual void PUSH(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void POP(const u32 data, const ARMv7_encoding type) = 0;
+
+ virtual void B(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void CBZ(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void CBNZ(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void BL(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void BLX(const u32 data, const ARMv7_encoding type) = 0;
+
+ virtual void SUB_IMM(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void SUB_REG(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void SUB_RSR(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void SUB_SPI(const u32 data, const ARMv7_encoding type) = 0;
+ virtual void SUB_SPR(const u32 data, const ARMv7_encoding type) = 0;
};
+
+struct ARMv7_opcode_t
+{
+ u32 mask;
+ u32 code;
+ u32 length; // 2 or 4
+ char* name;
+ ARMv7_encoding type;
+ void (ARMv7Opcodes::*func)(const u32 data, const ARMv7_encoding type);
+};
+
+// single 16-bit value
+#define ARMv7_OP2(mask, code, type, name) { (mask) << 16, (code) << 16, 2, #name, type, &ARMv7Opcodes::name }
+// two 16-bit values
+#define ARMv7_OP4(mask0, mask1, code0, code1, type, name) { ((mask0) << 16) | (mask1), ((code0) << 16) | (code1), 4, #name, type, &ARMv7Opcodes::name }
+
+static const ARMv7_opcode_t ARMv7_opcode_table[] =
+{
+ ARMv7_OP2(0xffff, 0x0000, T1, NULL_OP),
+ ARMv7_OP2(0xffff, 0xbf00, T1, NOP),
+ ARMv7_OP4(0xffff, 0xffff, 0xf3af, 0x8000, T2, NOP),
+ ARMv7_OP4(0x0fff, 0xffff, 0x0320, 0xf000, A1, NOP),
+ ARMv7_OP2(0xfe00, 0xb400, T1, PUSH),
+ ARMv7_OP4(0xffff, 0x0000, 0xe92d, 0x0000, T2, PUSH), // had an error in arch ref
+ ARMv7_OP4(0xffff, 0x0fff, 0xf84d, 0x0d04, T3, PUSH),
+ ARMv7_OP4(0x0fff, 0x0000, 0x092d, 0x0000, A1, PUSH),
+ ARMv7_OP4(0x0fff, 0x0fff, 0x052d, 0x0004, A2, PUSH),
+ ARMv7_OP2(0xfe00, 0xbc00, T1, POP),
+ ARMv7_OP4(0xffff, 0x0000, 0xe8bd, 0x0000, T2, POP),
+ ARMv7_OP4(0xffff, 0x0fff, 0xf85d, 0x0b04, T3, POP),
+ ARMv7_OP4(0x0fff, 0x0000, 0x08bd, 0x0000, A1, POP),
+ ARMv7_OP4(0x0fff, 0x0fff, 0x049d, 0x0004, A2, POP),
+ ARMv7_OP2(0xf000, 0xd000, T1, B),
+ ARMv7_OP2(0xf800, 0xe000, T2, B),
+ ARMv7_OP4(0xf800, 0xd000, 0xf000, 0x8000, T3, B),
+ ARMv7_OP4(0xf800, 0xd000, 0xf000, 0x9000, T4, B),
+ ARMv7_OP4(0x0f00, 0x0000, 0x0a00, 0x0000, A1, B),
+ ARMv7_OP2(0xfd00, 0xb100, T1, CBZ),
+ ARMv7_OP2(0xfd00, 0xb900, T1, CBNZ),
+ ARMv7_OP4(0xf800, 0xd000, 0xf000, 0xd000, T1, BL),
+ ARMv7_OP4(0x0f00, 0x0000, 0x0b00, 0x0000, A1, BL),
+ ARMv7_OP2(0xff80, 0x4780, T1, BLX),
+ ARMv7_OP4(0xf800, 0xc001, 0xf000, 0xc000, T2, BLX),
+ ARMv7_OP4(0x0fff, 0xfff0, 0x012f, 0xff30, A1, BLX),
+ ARMv7_OP4(0xfe00, 0x0000, 0xfa00, 0x0000, A2, BLX),
+
+ ARMv7_OP2(0xff80, 0xb080, T1, SUB_SPI),
+};
+
+#undef ARMv7_OP
+#undef ARMv7_OPP
+
diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp
index 3fe6595994..162f08a918 100644
--- a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp
+++ b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp
@@ -18,6 +18,7 @@ void ARMv7Thread::InitRegs()
memset(GPR, 0, sizeof(GPR[0]) * 15);
APSR.APSR = 0;
IPSR.IPSR = 0;
+ PC |= 1;
SP = m_stack_addr + m_stack_size;
}
diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj
index 007b956615..158775bfe8 100644
--- a/rpcs3/emucore.vcxproj
+++ b/rpcs3/emucore.vcxproj
@@ -54,6 +54,8 @@
+
+
diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters
index e164e1c531..e82a2cae4a 100644
--- a/rpcs3/emucore.vcxproj.filters
+++ b/rpcs3/emucore.vcxproj.filters
@@ -632,6 +632,12 @@
Source Files
+
+ Emu\ARMv7
+
+
+ Emu\ARMv7
+