From 536c5a900a02a16ae24de68642ef72c7a7695cf6 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 1 Nov 2014 01:00:36 +0300 Subject: [PATCH] ARMv7: more opcodes + STR --- rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp | 11 ++- rpcs3/Emu/ARMv7/ARMv7DisAsm.h | 4 +- rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp | 106 ++++++++++++++++++++++--- rpcs3/Emu/ARMv7/ARMv7Interpreter.h | 4 +- rpcs3/Emu/ARMv7/ARMv7Opcodes.h | 113 +++++++++++++++++++++++++-- 5 files changed, 213 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp b/rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp index ab4f5fcc11..ccb2582cad 100644 --- a/rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7DisAsm.cpp @@ -11,6 +11,11 @@ void ARMv7DisAsm::NULL_OP(const u32 data, const ARMv7_encoding type) Write("Illegal opcode (null)"); } +void ARMv7DisAsm::HACK(const u32 data, const ARMv7_encoding type) +{ + Write(__FUNCTION__); +} + void ARMv7DisAsm::ADC_IMM(const u32 data, const ARMv7_encoding type) { Write(__FUNCTION__); @@ -881,12 +886,6 @@ void ARMv7DisAsm::SVC(const u32 data, const ARMv7_encoding type) } -void ARMv7DisAsm::SWP_(const u32 data, const ARMv7_encoding type) -{ - Write(__FUNCTION__); -} - - void ARMv7DisAsm::SXTAB(const u32 data, const ARMv7_encoding type) { Write(__FUNCTION__); diff --git a/rpcs3/Emu/ARMv7/ARMv7DisAsm.h b/rpcs3/Emu/ARMv7/ARMv7DisAsm.h index 16f0a5df67..7eb712d24c 100644 --- a/rpcs3/Emu/ARMv7/ARMv7DisAsm.h +++ b/rpcs3/Emu/ARMv7/ARMv7DisAsm.h @@ -49,6 +49,8 @@ protected: virtual void NULL_OP(const u32 data, const ARMv7_encoding type); + virtual void HACK(const u32 data, const ARMv7_encoding type); + virtual void ADC_IMM(const u32 data, const ARMv7_encoding type); virtual void ADC_REG(const u32 data, const ARMv7_encoding type); virtual void ADC_RSR(const u32 data, const ARMv7_encoding type); @@ -265,8 +267,6 @@ protected: virtual void SVC(const u32 data, const ARMv7_encoding type); - virtual void SWP_(const u32 data, const ARMv7_encoding type); - virtual void SXTAB(const u32 data, const ARMv7_encoding type); virtual void SXTAB16(const u32 data, const ARMv7_encoding type); virtual void SXTAH(const u32 data, const ARMv7_encoding type); diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index f5cf8d64a6..2f60850f59 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -17,6 +17,33 @@ void ARMv7Interpreter::NULL_OP(const u32 data, const ARMv7_encoding type) Emu.Pause(); } +void ARMv7Interpreter::HACK(const u32 data, const ARMv7_encoding type) +{ + u32 cond = CPU.ITSTATE.advance(); + u32 code = 0; + + switch (type) + { + case T1: + { + code = data & 0xffff; + break; + } + case A1: + { + cond = data >> 28; + code = (data & 0xfff00) >> 4 | (data & 0xf); + break; + } + default: throw __FUNCTION__; + } + + if (ConditionPassed(cond)) + { + // + } +} + void ARMv7Interpreter::ADC_IMM(const u32 data, const ARMv7_encoding type) { switch (type) @@ -1689,11 +1716,80 @@ void ARMv7Interpreter::STMIB(const u32 data, const ARMv7_encoding type) void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type) { + u32 cond = CPU.ITSTATE.advance(); + u32 t = 16; + u32 n = 13; + u32 imm32 = 0; + bool index = true; + bool add = true; + bool wback = false; + switch (type) { + case T1: + { + t = (data & 0x7); + n = (data & 0x38) >> 3; + imm32 = (data & 0x7c0) >> 4; + break; + } + case T2: + { + t = (data & 0x700) >> 8; + imm32 = (data & 0xff) << 2; + break; + } + case T3: + { + t = (data & 0xf000) >> 12; + n = (data & 0xf0000) >> 16; + imm32 = (data & 0xfff); + + if (n == 0xf) + { + throw "STR_IMM_T3 UNDEFINED"; + } + break; + } + case T4: + { + t = (data & 0xf000) >> 12; + n = (data & 0xf0000) >> 16; + imm32 = (data & 0xff); + index = (data & 0x400); + add = (data & 0x200); + wback = (data & 0x100); + + if (index && add && !wback) + { + throw "STRT"; + } + if (n == 13 && index && !add && wback && imm32 == 4) + { + throw "PUSH"; + } + if (n == 15 || (!index && !wback)) + { + throw "STR_IMM_T4 UNDEFINED"; + } + break; + } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } + + if (ConditionPassed(cond)) + { + const u32 offset_addr = add ? CPU.read_gpr(n) + imm32 : CPU.read_gpr(n) - imm32; + const u32 addr = index ? offset_addr : CPU.read_gpr(n); + + vm::psv::write32(addr, CPU.read_gpr(t)); + + if (wback) + { + CPU.write_gpr(n, offset_addr); + } + } } void ARMv7Interpreter::STR_REG(const u32 data, const ARMv7_encoding type) @@ -1821,16 +1917,6 @@ void ARMv7Interpreter::SVC(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SWP_(const u32 data, const ARMv7_encoding type) -{ - switch (type) - { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; - } -} - - void ARMv7Interpreter::SXTAB(const u32 data, const ARMv7_encoding type) { switch (type) diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h index da9ea99af0..ebcb66b983 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h @@ -262,6 +262,8 @@ protected: virtual void NULL_OP(const u32 data, const ARMv7_encoding type); + virtual void HACK(const u32 data, const ARMv7_encoding type); + virtual void ADC_IMM(const u32 data, const ARMv7_encoding type); virtual void ADC_REG(const u32 data, const ARMv7_encoding type); virtual void ADC_RSR(const u32 data, const ARMv7_encoding type); @@ -478,8 +480,6 @@ protected: virtual void SVC(const u32 data, const ARMv7_encoding type); - virtual void SWP_(const u32 data, const ARMv7_encoding type); - virtual void SXTAB(const u32 data, const ARMv7_encoding type); virtual void SXTAB16(const u32 data, const ARMv7_encoding type); virtual void SXTAH(const u32 data, const ARMv7_encoding type); diff --git a/rpcs3/Emu/ARMv7/ARMv7Opcodes.h b/rpcs3/Emu/ARMv7/ARMv7Opcodes.h index d391b7fcd1..963e026ef5 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Opcodes.h +++ b/rpcs3/Emu/ARMv7/ARMv7Opcodes.h @@ -49,6 +49,8 @@ public: virtual void NULL_OP(const u32 data, const ARMv7_encoding type) = 0; + virtual void HACK(const u32 data, const ARMv7_encoding type) = 0; + virtual void ADC_IMM(const u32 data, const ARMv7_encoding type) = 0; virtual void ADC_REG(const u32 data, const ARMv7_encoding type) = 0; virtual void ADC_RSR(const u32 data, const ARMv7_encoding type) = 0; @@ -265,8 +267,6 @@ public: virtual void SVC(const u32 data, const ARMv7_encoding type) = 0; - virtual void SWP_(const u32 data, const ARMv7_encoding type) = 0; - virtual void SXTAB(const u32 data, const ARMv7_encoding type) = 0; virtual void SXTAB16(const u32 data, const ARMv7_encoding type) = 0; virtual void SXTAH(const u32 data, const ARMv7_encoding type) = 0; @@ -318,7 +318,7 @@ public: virtual void UXTB16(const u32 data, const ARMv7_encoding type) = 0; virtual void UXTH(const u32 data, const ARMv7_encoding type) = 0; - // TODO: vector ops + // TODO: vector ops + something }; struct ARMv7_opcode_t @@ -340,6 +340,9 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] = { ARMv7_OP2(0xffff, 0x0000, T1, NULL_OP), // ??? + ARMv7_OP4(0xffff, 0x0000, 0xf870, 0x0000, T1, HACK), // "Undefined" Thumb opcode + ARMv7_OP4(0x0ff0, 0x00f0, 0x0070, 0x0090, A1, HACK), // "Undefined" ARM opcode + ARMv7_OP4(0xfbe0, 0x8000, 0xf140, 0x0000, T1, ADC_IMM), ARMv7_OP4(0x0fe0, 0x0000, 0x02a0, 0x0000, A1, ADC_IMM), ARMv7_OP2(0xffc0, 0x4040, T1, ADC_REG), @@ -565,7 +568,8 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] = ARMv7_OP4(0x0fe0, 0x0010, 0x0180, 0x0000, A1, ORR_REG), ARMv7_OP4(0x0fe0, 0x0090, 0x0180, 0x0010, A1, ORR_RSR), - // TODO (PKH...) + ARMv7_OP4(0xfff0, 0x8010, 0xeac0, 0x0000, T1, PKH), + ARMv7_OP4(0x0ff0, 0x0030, 0x0680, 0x0010, A1, PKH), ARMv7_OP2(0xfe00, 0xbc00, T1, POP), ARMv7_OP4(0xffff, 0x0000, 0xe8bd, 0x0000, T2, POP), @@ -581,6 +585,65 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] = // TODO (Q*...) + ARMv7_OP4(0xfff0, 0xf0f0, 0xfa90, 0xf0a0, T1, RBIT), + ARMv7_OP4(0x0fff, 0x0ff0, 0x06ff, 0x0f30, A1, RBIT), + + ARMv7_OP2(0xffc0, 0xba00, T1, REV), + ARMv7_OP4(0xfff0, 0xf0f0, 0xfa90, 0xf080, T2, REV), + ARMv7_OP4(0x0fff, 0x0ff0, 0x06bf, 0x0f30, A1, REV), + ARMv7_OP2(0xffc0, 0xba40, T1, REV16), + ARMv7_OP4(0xfff0, 0xf0f0, 0xfa90, 0xf090, T2, REV16), + ARMv7_OP4(0x0fff, 0x0ff0, 0x06bf, 0x0fb0, A1, REV16), + ARMv7_OP2(0xffc0, 0xbac0, T1, REVSH), + ARMv7_OP4(0xfff0, 0xf0f0, 0xfa90, 0xf0b0, T2, REVSH), + ARMv7_OP4(0x0fff, 0x0ff0, 0x06ff, 0x0fb0, A1, REVSH), + + ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0030, T1, ROR_IMM), + ARMv7_OP4(0x0fef, 0x0070, 0x01a0, 0x0060, A1, ROR_IMM), + ARMv7_OP2(0xffc0, 0x41c0, T1, ROR_REG), + ARMv7_OP4(0xffe0, 0xf0f0, 0xfa60, 0xf000, T2, ROR_REG), + ARMv7_OP4(0x0fef, 0x00f0, 0x01a0, 0x0070, A1, ROR_REG), + ARMv7_OP4(0xffef, 0xf0f0, 0xea4f, 0x0030, T1, RRX), + ARMv7_OP4(0x0fef, 0x0ff0, 0x01a0, 0x0060, A1, RRX), + + ARMv7_OP2(0xffc0, 0x4240, T1, RSB_IMM), + ARMv7_OP4(0xfbe0, 0x8000, 0xf1c0, 0x0000, T2, RSB_IMM), + ARMv7_OP4(0x0fe0, 0x0000, 0x0260, 0x0000, A1, RSB_IMM), + ARMv7_OP4(0xffe0, 0x8000, 0xebc0, 0x0000, T1, RSB_REG), + ARMv7_OP4(0x0fe0, 0x0010, 0x0060, 0x0000, A1, RSB_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x0060, 0x0010, A1, RSB_RSR), + + ARMv7_OP4(0x0fe0, 0x0000, 0x02e0, 0x0000, A1, RSC_IMM), + ARMv7_OP4(0x0fe0, 0x0010, 0x00e0, 0x0000, A1, RSC_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x00e0, 0x0010, A1, RSC_RSR), + + // TODO (SADD16, SADD8, SASX) + + ARMv7_OP4(0xfbe0, 0x8000, 0xf160, 0x0000, T1, SBC_IMM), + ARMv7_OP4(0x0fe0, 0x0000, 0x02c0, 0x0000, A1, SBC_IMM), + ARMv7_OP2(0xffc0, 0x4180, T1, SBC_REG), + ARMv7_OP4(0xffe0, 0x8000, 0xeb60, 0x0000, T2, SBC_REG), + ARMv7_OP4(0x0fe0, 0x0010, 0x00c0, 0x0000, A1, SBC_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x00c0, 0x0010, A1, SBC_RSR), + + ARMv7_OP4(0xfff0, 0x8020, 0xf340, 0x0000, T1, SBFX), + ARMv7_OP4(0x0fe0, 0x0070, 0x07a0, 0x0050, A1, SBFX), + + ARMv7_OP4(0xfff0, 0xf0f0, 0xfb90, 0xf0f0, T1, SDIV), // ??? + + ARMv7_OP4(0xfff0, 0xf0f0, 0xfaa0, 0xf080, T1, SEL), + ARMv7_OP4(0x0ff0, 0x0ff0, 0x0680, 0x0fb0, A1, SEL), + + // TODO (SH*, SM*, SS*) + + ARMv7_OP2(0xf800, 0xc000, T1, STM), + ARMv7_OP4(0xffd0, 0xa000, 0xe880, 0x0000, T2, STM), + ARMv7_OP4(0x0fd0, 0x0000, 0x0880, 0x0000, A1, STM), + ARMv7_OP4(0x0fd0, 0x0000, 0x0800, 0x0000, A1, STMDA), + ARMv7_OP4(0xffd0, 0xa000, 0xe900, 0x0000, T1, STMDB), + ARMv7_OP4(0x0fd0, 0x0000, 0x0900, 0x0000, A1, STMDB), + ARMv7_OP4(0x0fd0, 0x0000, 0x0980, 0x0000, A1, STMIB), + ARMv7_OP2(0xf800, 0x6000, T1, STR_IMM), ARMv7_OP2(0xf800, 0x9000, T2, STR_IMM), ARMv7_OP4(0xfff0, 0x0000, 0xf8c0, 0x0000, T3, STR_IMM), @@ -590,7 +653,25 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] = ARMv7_OP4(0xfff0, 0x0fc0, 0xf840, 0x0000, T2, STR_REG), ARMv7_OP4(0x0e50, 0x0010, 0x0600, 0x0000, A1, STR_REG), - // + ARMv7_OP2(0xf800, 0x7000, T1, STRB_IMM), + ARMv7_OP4(0xfff0, 0x0000, 0xf880, 0x0000, T2, STRB_IMM), + ARMv7_OP4(0xfff0, 0x0800, 0xf800, 0x0800, T3, STRB_IMM), + ARMv7_OP4(0x0e50, 0x0000, 0x0440, 0x0000, A1, STRB_IMM), + ARMv7_OP2(0xfe00, 0x5400, T1, STRB_REG), + ARMv7_OP4(0xfff0, 0x0fc0, 0xf800, 0x0000, T2, STRB_REG), + ARMv7_OP4(0x0e50, 0x0010, 0x0640, 0x0000, A1, STRB_REG), + + ARMv7_OP4(0xfe50, 0x0000, 0xe840, 0x0000, T1, STRD_IMM), + ARMv7_OP4(0x0e50, 0x00f0, 0x0040, 0x00f0, A1, STRD_IMM), + ARMv7_OP4(0x0e50, 0x0ff0, 0x0000, 0x00f0, A1, STRD_REG), + + ARMv7_OP2(0xf800, 0x8000, T1, STRH_IMM), + ARMv7_OP4(0xfff0, 0x0000, 0xf8a0, 0x0000, T2, STRH_IMM), + ARMv7_OP4(0xfff0, 0x0800, 0xf820, 0x0800, T3, STRH_IMM), + ARMv7_OP4(0x0e50, 0x00f0, 0x0040, 0x00b0, A1, STRH_IMM), + ARMv7_OP2(0xfe00, 0x5200, T1, STRH_REG), + ARMv7_OP4(0xfff0, 0x0fc0, 0xf820, 0x0000, T2, STRH_REG), + ARMv7_OP4(0x0e50, 0x0ff0, 0x0000, 0x00b0, A1, STRH_REG), ARMv7_OP2(0xfe00, 0x1e00, T1, SUB_IMM), ARMv7_OP2(0xf800, 0x3800, T2, SUB_IMM), @@ -607,6 +688,28 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] = ARMv7_OP4(0x0fef, 0x0000, 0x024d, 0x0000, A1, SUB_SPI), ARMv7_OP4(0xffef, 0x8000, 0xebad, 0x0000, T1, SUB_SPR), ARMv7_OP4(0x0fef, 0x0010, 0x004d, 0x0000, A1, SUB_SPR), + + ARMv7_OP2(0xff00, 0xdf00, T1, SVC), + ARMv7_OP4(0x0f00, 0x0000, 0x0f00, 0x0000, A1, SVC), + + // TODO (SX*) + + ARMv7_OP4(0xfff0, 0xffe0, 0xe8d0, 0xf000, T1, TB_), + + ARMv7_OP4(0xfbf0, 0x8f00, 0xf090, 0x0f00, T1, TEQ_IMM), + ARMv7_OP4(0x0ff0, 0xf000, 0x0330, 0x0000, A1, TEQ_IMM), + ARMv7_OP4(0xfff0, 0x8f00, 0xea90, 0x0f00, T1, TEQ_REG), + ARMv7_OP4(0x0ff0, 0xf010, 0x0130, 0x0000, A1, TEQ_REG), + ARMv7_OP4(0x0ff0, 0xf090, 0x0130, 0x0010, A1, TEQ_RSR), + + ARMv7_OP4(0xfbf0, 0x8f00, 0xf010, 0x0f00, T1, TST_IMM), + ARMv7_OP4(0x0ff0, 0xf000, 0x0310, 0x0000, A1, TST_IMM), + ARMv7_OP2(0xffc0, 0x4200, T1, TST_REG), + ARMv7_OP4(0xfff0, 0x8f00, 0xea10, 0x0f00, T2, TST_REG), + ARMv7_OP4(0x0ff0, 0xf010, 0x0110, 0x0000, A1, TST_REG), + ARMv7_OP4(0x0ff0, 0xf090, 0x0110, 0x0010, A1, TST_RSR), + + // TODO (U*, V*) }; #undef ARMv7_OP