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 +