From c3696f7897e423efdb13bd01e6606e2c758488a3 Mon Sep 17 00:00:00 2001 From: Oil Date: Mon, 1 Dec 2014 23:20:27 +0400 Subject: [PATCH] ARMv7 decoder reworked (needs more testing / fixes / optimisations). TODO: implement new ARMv7 disassembler (currently ARMv7DisAsm fully disabled), add 0x0 opcodes group. --- rpcs3/Emu/ARMv7/ARMv7Decoder.h | 41 +- rpcs3/Emu/ARMv7/ARMv7DisAsm.h | 3 +- rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp | 1408 ++++++++------ rpcs3/Emu/ARMv7/ARMv7Interpreter.h | 1206 +++++++----- rpcs3/Emu/ARMv7/ARMv7Opcodes.h | 2686 +++++++++++++++++++------- rpcs3/Emu/ARMv7/ARMv7Thread.cpp | 8 +- rpcs3/Emu/ARMv7/ARMv7Thread.h | 27 +- rpcs3/Gui/InterpreterDisAsm.cpp | 9 +- rpcs3/Loader/Loader.cpp | 9 +- rpcs3/Loader/Loader.h | 36 +- 10 files changed, 3628 insertions(+), 1805 deletions(-) diff --git a/rpcs3/Emu/ARMv7/ARMv7Decoder.h b/rpcs3/Emu/ARMv7/ARMv7Decoder.h index 81b58e9939..e25e9c8e25 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Decoder.h +++ b/rpcs3/Emu/ARMv7/ARMv7Decoder.h @@ -1,35 +1,48 @@ #pragma once -#include "Emu/CPU/CPUDecoder.h" -#include "ARMv7Opcodes.h" +#include "Emu/CPU/CPUDecoder.h" +#include "ARMv7Thread.h" +#include "ARMv7Interpreter.h" +#include "ARMv7Opcodes.h" +#include "Utilities/Log.h" class ARMv7Decoder : public CPUDecoder { - ARMv7Opcodes& m_op; - u8 m_last_instr_size; + ARMv7Thread& m_thr; public: - ARMv7Decoder(ARMv7Opcodes& op) : m_op(op) + ARMv7Decoder(ARMv7Thread& thr) : m_thr(thr) { } virtual u8 DecodeMemory(const u32 address) { - const u32 code0 = vm::psv::read16(address & ~1); - const u32 code1 = vm::psv::read16(address + 2 & ~1); - const u32 data = code0 << 16 | code1; - const u32 arg = address & 1 ? code1 << 16 | code0 : data; + m_thr.update_code(address & ~1); + // LOG_NOTICE(GENERAL, "code0 = 0x%04x, code1 = 0x%04x, data = 0x%08x", m_thr.code.code0, m_thr.code.code1, m_thr.code.data); + // LOG_NOTICE(GENERAL, "arg = 0x%08x", m_thr.m_arg); + // Emu.Pause(); + + // old decoding algorithm + /* for (auto& opcode : ARMv7_opcode_table) { - if ((opcode.type < A1) == ((address & 1) == 0) && (arg & opcode.mask) == opcode.code) + if ((opcode.type < A1) == ((address & 0x1) == 0) && (m_thr.m_arg & opcode.mask) == opcode.code) { - (m_op.*opcode.func)(opcode.length == 2 ? code0 : arg, opcode.type); + m_thr.code.data = opcode.length == 2 ? m_thr.code.code0 : m_thr.m_arg; + (*opcode.func)(&m_thr, opcode.type); + // LOG_NOTICE(GENERAL, "%s, %d \n\n", opcode.name, opcode.length); return opcode.length; } } - m_op.UNK(data); - return address & 1 ? 4 : 2; + ARMv7_instrs::UNK(&m_thr); + return address & 0x1 ? 4 : 2; + */ + + execute_main_group(&m_thr); + LOG_NOTICE(GENERAL, "%s, %d \n\n", m_thr.m_last_instr_name, m_thr.m_last_instr_size); + m_thr.m_last_instr_name = "Unknown"; + return m_thr.m_last_instr_size; } -}; +}; \ No newline at end of file diff --git a/rpcs3/Emu/ARMv7/ARMv7DisAsm.h b/rpcs3/Emu/ARMv7/ARMv7DisAsm.h index 7eb712d24c..05375dc167 100644 --- a/rpcs3/Emu/ARMv7/ARMv7DisAsm.h +++ b/rpcs3/Emu/ARMv7/ARMv7DisAsm.h @@ -12,10 +12,9 @@ static const char* g_arm_cond_name[16] = class ARMv7DisAsm : public CPUDisAsm - , public ARMv7Opcodes { public: - ARMv7DisAsm(CPUDisAsmMode mode) : CPUDisAsm(mode) + ARMv7DisAsm() : CPUDisAsm(CPUDisAsm_InterpreterMode) { } diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index 87d33e05c6..fb56e1a8eb 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -6,46 +6,292 @@ #include "PSVFuncList.h" #include "ARMv7Interpreter.h" -void ARMv7Interpreter::UNK(const u32 data) +template +u8 ARMv7_instrs::BitCount(T x, u8 len) { - LOG_ERROR(HLE, "Unknown/illegal opcode! (0x%04x : 0x%04x)", data >> 16, data & 0xffff); + u8 result = 0; + + for (u8 mask = 1 << (len - 1); mask; mask >>= 1) + { + if (x & mask) result++; + } + + return result; +} + +template +s8 ARMv7_instrs::LowestSetBit(T x, u8 len) +{ + if (!x) return len; + + u8 result = 0; + + for (T mask = 1, i = 0; i +s8 ARMv7_instrs::HighestSetBit(T x, u8 len) +{ + if (!x) return -1; + + u8 result = len; + + for (T mask = T(1) << (len - 1); (x & mask) == 0; mask >>= 1) + { + result--; + } + + return result; +} + +template +s8 ARMv7_instrs::CountLeadingZeroBits(T x, u8 len) +{ + return len - 1 - HighestSetBit(x, len); +} + +SRType ARMv7_instrs::DecodeImmShift(u32 type, u32 imm5, u32* shift_n) +{ + SRType shift_t = SRType_None; + + switch (type) + { + case 0: shift_t = SRType_LSL; if (shift_n) *shift_n = imm5; break; + case 1: shift_t = SRType_LSR; if (shift_n) *shift_n = imm5 == 0 ? 32 : imm5; break; + case 2: shift_t = SRType_ASR; if (shift_n) *shift_n = imm5 == 0 ? 32 : imm5; break; + case 3: + if (imm5 == 0) + { + shift_t = SRType_RRX; if (shift_n) *shift_n = 1; + } + else + { + shift_t = SRType_ROR; if (shift_n) *shift_n = imm5; + } + break; + } + + return shift_t; +} + +SRType ARMv7_instrs::DecodeRegShift(u8 type) +{ + SRType shift_t = SRType_None; + + switch (type) + { + case 0: shift_t = SRType_LSL; break; + case 1: shift_t = SRType_LSR; break; + case 2: shift_t = SRType_ASR; break; + case 3: shift_t = SRType_ROR; break; + } + + return shift_t; +} + +u32 ARMv7_instrs::LSL_C(u32 x, s32 shift, bool& carry_out) +{ + assert(shift > 0); + carry_out = shift <= 32 ? x & (1 << (32 - shift)) : false; + return shift < 32 ? x << shift : 0; +} + +u32 ARMv7_instrs::LSL(u32 x, s32 shift) +{ + assert(shift >= 0); + return shift < 32 ? x << shift : 0; +} + +u32 ARMv7_instrs::LSR_C(u32 x, s32 shift, bool& carry_out) +{ + assert(shift > 0); + carry_out = shift <= 32 ? x & (1 << (shift - 1)) : false; + return shift < 32 ? x >> shift : 0; +} + +u32 ARMv7_instrs::LSR(u32 x, s32 shift) +{ + assert(shift >= 0); + return shift < 32 ? x >> shift : 0; +} + +s32 ARMv7_instrs::ASR_C(s32 x, s32 shift, bool& carry_out) +{ + assert(shift > 0); + carry_out = shift <= 32 ? x & (1 << (shift - 1)) : false; + return shift < 32 ? x >> shift : x >> 31; +} + +s32 ARMv7_instrs::ASR(s32 x, s32 shift) +{ + assert(shift >= 0); + return shift < 32 ? x >> shift : x >> 31; +} + +u32 ARMv7_instrs::ROR_C(u32 x, s32 shift, bool& carry_out) +{ + assert(shift); + carry_out = x & (1 << (shift - 1)); + return x >> shift | x << (32 - shift); +} + +u32 ARMv7_instrs::ROR(u32 x, s32 shift) +{ + return x >> shift | x << (32 - shift); +} + +u32 ARMv7_instrs::RRX_C(u32 x, bool carry_in, bool& carry_out) +{ + carry_out = x & 0x1; + return ((u32)carry_in << 31) | (x >> 1); +} + +u32 ARMv7_instrs::RRX(u32 x, bool carry_in) +{ + return ((u32)carry_in << 31) | (x >> 1); +} + +template T ARMv7_instrs::Shift_C(T value, SRType type, s32 amount, bool carry_in, bool& carry_out) +{ + assert(type != SRType_RRX || amount == 1); + + if (amount) + { + switch (type) + { + case SRType_LSL: return LSL_C(value, amount, carry_out); + case SRType_LSR: return LSR_C(value, amount, carry_out); + case SRType_ASR: return ASR_C(value, amount, carry_out); + case SRType_ROR: return ROR_C(value, amount, carry_out); + case SRType_RRX: return RRX_C(value, carry_in, carry_out); + } + } + + carry_out = carry_in; + return value; +} + +template T ARMv7_instrs::Shift(T value, SRType type, s32 amount, bool carry_in) +{ + bool carry_out; + return Shift_C(value, type, amount, carry_in, carry_out); +} + +template T ARMv7_instrs::AddWithCarry(T x, T y, bool carry_in, bool& carry_out, bool& overflow) +{ + const T sign_mask = (T)1 << (sizeof(T) - 1); + + T result = x + y; + carry_out = ((x & y) | ((x ^ y) & ~result)) & sign_mask; + overflow = (x ^ result) & (y ^ result) & sign_mask; + if (carry_in) + { + result += 1; + carry_out ^= (result == 0); + overflow ^= (result == sign_mask); + } + return result; +} + +u32 ARMv7_instrs::ThumbExpandImm_C(u32 imm12, bool carry_in, bool& carry_out) +{ + if ((imm12 & 0xc00) >> 10) + { + u32 unrotated_value = (imm12 & 0x7f) | 0x80; + + return ROR_C(unrotated_value, (imm12 & 0xf80) >> 7, carry_out); + } + else + { + carry_out = carry_in; + + u32 imm8 = imm12 & 0xff; + switch ((imm12 & 0x300) >> 8) + { + case 0: return imm8; + case 1: return imm8 << 16 | imm8; + case 2: return imm8 << 24 | imm8 << 8; + default: return imm8 << 24 | imm8 << 16 | imm8 << 8 | imm8; + } + } +} + +u32 ARMv7_instrs::ThumbExpandImm(ARMv7Thread* CPU, u32 imm12) +{ + bool carry = CPU->APSR.C; + return ThumbExpandImm_C(imm12, carry, carry); +} + +bool ARMv7_instrs::ConditionPassed(ARMv7Thread* CPU, u32 cond) +{ + bool result = false; + + switch (cond >> 1) + { + case 0: result = CPU->APSR.Z == 1; break; + case 1: result = CPU->APSR.C == 1; break; + case 2: result = CPU->APSR.N == 1; break; + case 3: result = CPU->APSR.V == 1; break; + case 4: result = CPU->APSR.C == 1 && CPU->APSR.Z == 0; break; + case 5: result = CPU->APSR.N == CPU->APSR.V; break; + case 6: result = CPU->APSR.N == CPU->APSR.V && CPU->APSR.Z == 0; break; + case 7: return true; + } + + if (cond & 0x1) + { + return !result; + } + + return result; +} + +// instructions +void ARMv7_instrs::UNK(ARMv7Thread* thr) +{ + LOG_ERROR(HLE, "Unknown/illegal opcode! (0x%04x : 0x%04x)", thr->code.data >> 16, thr->code.data & 0xffff); Emu.Pause(); } -void ARMv7Interpreter::NULL_OP(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::NULL_OP(ARMv7Thread* thr, const ARMv7_encoding type) { - LOG_ERROR(HLE, "Null opcode found"); + LOG_ERROR(HLE, "Null opcode found: data = 0x%x", thr->m_arg); Emu.Pause(); } -void ARMv7Interpreter::HACK(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::HACK(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 code = 0; switch (type) { case T1: { - code = data & 0xffff; + code = thr->code.data & 0xffff; break; } case A1: { - cond = data >> 28; - code = (data & 0xfff00) >> 4 | (data & 0xf); + cond = thr->code.data >> 28; + code = (thr->code.data & 0xfff00) >> 4 | (thr->code.data & 0xf); break; } default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - execute_psv_func_by_index(CPU, code); + execute_psv_func_by_index(*thr, code); } } -void ARMv7Interpreter::ADC_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ADC_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -54,7 +300,7 @@ void ARMv7Interpreter::ADC_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::ADC_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ADC_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -63,7 +309,7 @@ void ARMv7Interpreter::ADC_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::ADC_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ADC_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -73,10 +319,10 @@ void ARMv7Interpreter::ADC_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::ADD_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ADD_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { - bool set_flags = !CPU.ITSTATE; - u32 cond = CPU.ITSTATE.advance(); + bool set_flags = !thr->ITSTATE; + u32 cond = thr->ITSTATE.advance(); u32 d = 0; u32 n = 0; u32 imm32 = 0; @@ -85,23 +331,23 @@ void ARMv7Interpreter::ADD_IMM(const u32 data, const ARMv7_encoding type) { case T1: { - d = (data & 0x7); - n = (data & 0x38) >> 3; - imm32 = (data & 0x1c0) >> 6; + d = (thr->code.data & 0x7); + n = (thr->code.data & 0x38) >> 3; + imm32 = (thr->code.data & 0x1c0) >> 6; break; } case T2: { - d = n = (data & 0x700) >> 8; - imm32 = (data & 0xff); + d = n = (thr->code.data & 0x700) >> 8; + imm32 = (thr->code.data & 0xff); break; } case T3: { - d = (data & 0xf00) >> 8; - n = (data & 0xf0000) >> 16; - set_flags = (data & 0x100000); - imm32 = ThumbExpandImm((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff)); + d = (thr->code.data & 0xf00) >> 8; + n = (thr->code.data & 0xf0000) >> 16; + set_flags = (thr->code.data & 0x100000); + imm32 = ThumbExpandImm(thr, (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff)); if (d == 15 && set_flags) { @@ -115,10 +361,10 @@ void ARMv7Interpreter::ADD_IMM(const u32 data, const ARMv7_encoding type) } case T4: { - d = (data & 0xf00) >> 8; - n = (data & 0xf0000) >> 16; + d = (thr->code.data & 0xf00) >> 8; + n = (thr->code.data & 0xf0000) >> 16; set_flags = false; - imm32 = (data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff); + imm32 = (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff); if (n == 15) { @@ -134,29 +380,29 @@ void ARMv7Interpreter::ADD_IMM(const u32 data, const ARMv7_encoding type) default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { if (set_flags) { bool carry, overflow; - const u32 res = AddWithCarry(CPU.read_gpr(n), imm32, false, carry, overflow); - CPU.write_gpr(d, res); - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; - CPU.APSR.V = overflow; + const u32 res = AddWithCarry(thr->read_gpr(n), imm32, false, carry, overflow); + thr->write_gpr(d, res); + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; + thr->APSR.V = overflow; } else { - CPU.write_gpr(d, CPU.read_gpr(n) + imm32); + thr->write_gpr(d, thr->read_gpr(n) + imm32); } } } -void ARMv7Interpreter::ADD_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ADD_REG(ARMv7Thread* thr, const ARMv7_encoding type) { - bool set_flags = !CPU.ITSTATE; - u32 cond = CPU.ITSTATE.advance(); + bool set_flags = !thr->ITSTATE; + u32 cond = thr->ITSTATE.advance(); u32 d = 0; u32 n = 0; u32 m = 0; @@ -167,15 +413,15 @@ void ARMv7Interpreter::ADD_REG(const u32 data, const ARMv7_encoding type) { case T1: { - d = (data & 0x7); - n = (data & 0x38) >> 3; - m = (data & 0x1c0) >> 6; + d = (thr->code.data & 0x7); + n = (thr->code.data & 0x38) >> 3; + m = (thr->code.data & 0x1c0) >> 6; break; } case T2: { - n = d = (data & 0x80) >> 4 | (data & 0x7); - m = (data & 0x78) >> 3; + n = d = (thr->code.data & 0x80) >> 4 | (thr->code.data & 0x7); + m = (thr->code.data & 0x78) >> 3; set_flags = false; if (n == 13 || m == 13) @@ -186,11 +432,11 @@ void ARMv7Interpreter::ADD_REG(const u32 data, const ARMv7_encoding type) } case T3: { - d = (data & 0xf00) >> 8; - n = (data & 0xf0000) >> 16; - m = (data & 0xf); - set_flags = (data & 0x100000); - shift_t = DecodeImmShift((data & 0x30) >> 4, (data & 0x7000) >> 10 | (data & 0xc0) >> 6, &shift_n); + d = (thr->code.data & 0xf00) >> 8; + n = (thr->code.data & 0xf0000) >> 16; + m = (thr->code.data & 0xf); + set_flags = (thr->code.data & 0x100000); + shift_t = DecodeImmShift((thr->code.data & 0x30) >> 4, (thr->code.data & 0x7000) >> 10 | (thr->code.data & 0xc0) >> 6, &shift_n); if (d == 15 && set_flags) { @@ -206,27 +452,27 @@ void ARMv7Interpreter::ADD_REG(const u32 data, const ARMv7_encoding type) default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - const u32 shifted = Shift(CPU.read_gpr(m), shift_t, shift_n, true); + const u32 shifted = Shift(thr->read_gpr(m), shift_t, shift_n, true); if (set_flags) { bool carry, overflow; - const u32 res = AddWithCarry(CPU.read_gpr(n), shifted, false, carry, overflow); - CPU.write_gpr(d, res); - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; - CPU.APSR.V = overflow; + const u32 res = AddWithCarry(thr->read_gpr(n), shifted, false, carry, overflow); + thr->write_gpr(d, res); + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; + thr->APSR.V = overflow; } else { - CPU.write_gpr(d, CPU.read_gpr(n) + shifted); + thr->write_gpr(d, thr->read_gpr(n) + shifted); } } } -void ARMv7Interpreter::ADD_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ADD_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -235,9 +481,9 @@ void ARMv7Interpreter::ADD_RSR(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::ADD_SPI(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ADD_SPI(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 d = 13; bool set_flags = false; u32 imm32 = 0; @@ -246,20 +492,20 @@ void ARMv7Interpreter::ADD_SPI(const u32 data, const ARMv7_encoding type) { case T1: { - d = (data & 0x700) >> 8; - imm32 = (data & 0xff) << 2; + d = (thr->code.data & 0x700) >> 8; + imm32 = (thr->code.data & 0xff) << 2; break; } case T2: { - imm32 = (data & 0x7f) << 2; + imm32 = (thr->code.data & 0x7f) << 2; break; } case T3: { - d = (data & 0xf00) >> 8; - set_flags = (data & 0x100000); - imm32 = ThumbExpandImm((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff)); + d = (thr->code.data & 0xf00) >> 8; + set_flags = (thr->code.data & 0x100000); + imm32 = ThumbExpandImm(thr, (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff)); if (d == 15 && set_flags) { @@ -269,37 +515,37 @@ void ARMv7Interpreter::ADD_SPI(const u32 data, const ARMv7_encoding type) } case T4: { - d = (data & 0xf00) >> 8; + d = (thr->code.data & 0xf00) >> 8; set_flags = false; - imm32 = (data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff); + imm32 = (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff); break; } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { if (set_flags) { bool carry, overflow; - const u32 res = AddWithCarry(CPU.SP, imm32, false, carry, overflow); - CPU.write_gpr(d, res); - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; - CPU.APSR.V = overflow; + const u32 res = AddWithCarry(thr->SP, imm32, false, carry, overflow); + thr->write_gpr(d, res); + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; + thr->APSR.V = overflow; } else { - CPU.write_gpr(d, CPU.SP + imm32); + thr->write_gpr(d, thr->SP + imm32); } } } -void ARMv7Interpreter::ADD_SPR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ADD_SPR(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 d = 13; u32 m = 0; bool set_flags = false; @@ -310,12 +556,12 @@ void ARMv7Interpreter::ADD_SPR(const u32 data, const ARMv7_encoding type) { case T1: { - m = d = (data & 0x80) >> 4 | (data & 0x7); + m = d = (thr->code.data & 0x80) >> 4 | (thr->code.data & 0x7); break; } case T2: { - m = (data & 0x78) >> 3; + m = (thr->code.data & 0x78) >> 3; if (m == 13) { @@ -325,38 +571,38 @@ void ARMv7Interpreter::ADD_SPR(const u32 data, const ARMv7_encoding type) } case T3: { - d = (data & 0xf00) >> 8; - m = (data & 0xf); - set_flags = (data & 0x100000); - shift_t = DecodeImmShift((data & 0x30) >> 4, (data & 0x7000) >> 10 | (data & 0xc0) >> 6, &shift_n); + d = (thr->code.data & 0xf00) >> 8; + m = (thr->code.data & 0xf); + set_flags = (thr->code.data & 0x100000); + shift_t = DecodeImmShift((thr->code.data & 0x30) >> 4, (thr->code.data & 0x7000) >> 10 | (thr->code.data & 0xc0) >> 6, &shift_n); break; } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - const u32 shifted = Shift(CPU.read_gpr(m), shift_t, shift_n, CPU.APSR.C); + const u32 shifted = Shift(thr->read_gpr(m), shift_t, shift_n, thr->APSR.C); if (set_flags) { bool carry, overflow; - const u32 res = AddWithCarry(CPU.SP, shifted, false, carry, overflow); - CPU.write_gpr(d, res); - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; - CPU.APSR.V = overflow; + const u32 res = AddWithCarry(thr->SP, shifted, false, carry, overflow); + thr->write_gpr(d, res); + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; + thr->APSR.V = overflow; } else { - CPU.write_gpr(d, CPU.SP + CPU.read_gpr(m)); + thr->write_gpr(d, thr->SP + thr->read_gpr(m)); } } } -void ARMv7Interpreter::ADR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ADR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -366,7 +612,7 @@ void ARMv7Interpreter::ADR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::AND_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::AND_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -375,7 +621,7 @@ void ARMv7Interpreter::AND_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::AND_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::AND_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -384,7 +630,7 @@ void ARMv7Interpreter::AND_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::AND_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::AND_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -394,7 +640,7 @@ void ARMv7Interpreter::AND_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::ASR_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ASR_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -403,7 +649,7 @@ void ARMv7Interpreter::ASR_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::ASR_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ASR_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -413,67 +659,67 @@ void ARMv7Interpreter::ASR_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::B(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::B(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 jump = 0; // jump = instr_size + imm32 ??? switch (type) { case T1: { - cond = (data >> 8) & 0xf; + cond = (thr->code.data >> 8) & 0xf; if (cond == 0xf) { throw "SVC"; } - jump = 4 + sign<9, u32>((data & 0xff) << 1); + jump = 4 + sign<9, u32>((thr->code.data & 0xff) << 1); break; } case T2: { - jump = 4 + sign<12, u32>((data & 0x7ff) << 1); + jump = 4 + sign<12, u32>((thr->code.data & 0x7ff) << 1); break; } case T3: { - cond = (data >> 6) & 0xf; + cond = (thr->code.data >> 6) & 0xf; if (cond >= 0xe) { throw "B_T3: Related encodings"; } - 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); + u32 s = (thr->code.data >> 26) & 0x1; + u32 j1 = (thr->code.data >> 13) & 0x1; + u32 j2 = (thr->code.data >> 11) & 0x1; + jump = 4 + sign<21, u32>(s << 20 | j2 << 19 | j1 << 18 | (thr->code.data & 0x3f0000) >> 4 | (thr->code.data & 0x7ff) << 1); 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); + u32 s = (thr->code.data >> 26) & 0x1; + u32 i1 = (thr->code.data >> 13) & 0x1 ^ s ^ 1; + u32 i2 = (thr->code.data >> 11) & 0x1 ^ s ^ 1; + jump = 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (thr->code.data & 0x3ff0000) >> 4 | (thr->code.data & 0x7ff) << 1); break; } case A1: { - cond = data >> 28; - jump = 1 + 4 + sign<26, u32>((data & 0xffffff) << 2); + cond = thr->code.data >> 28; + jump = 1 + 4 + sign<26, u32>((thr->code.data & 0xffffff) << 2); break; } } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - CPU.SetBranch(CPU.PC + jump); + thr->SetBranch(thr->PC + jump); } } -void ARMv7Interpreter::BFC(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::BFC(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -482,7 +728,7 @@ void ARMv7Interpreter::BFC(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::BFI(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::BFI(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -492,7 +738,7 @@ void ARMv7Interpreter::BFI(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::BIC_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::BIC_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -501,7 +747,7 @@ void ARMv7Interpreter::BIC_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::BIC_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::BIC_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -510,7 +756,7 @@ void ARMv7Interpreter::BIC_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::BIC_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::BIC_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -520,7 +766,7 @@ void ARMv7Interpreter::BIC_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::BKPT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::BKPT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -530,132 +776,132 @@ void ARMv7Interpreter::BKPT(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::BL(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::BL(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); - u32 newLR = CPU.PC; + u32 cond = thr->ITSTATE.advance(); + u32 newLR = thr->PC; u32 imm32 = 0; switch (type) { case T1: { - u32 s = (data >> 26) & 0x1; - u32 i1 = (data >> 13) & 0x1 ^ s ^ 1; - u32 i2 = (data >> 11) & 0x1 ^ s ^ 1; - imm32 = 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (data & 0x3ff0000) >> 4 | (data & 0x7ff) << 1); - newLR = (CPU.PC + 4) | 1; + u32 s = (thr->code.data >> 26) & 0x1; + u32 i1 = (thr->code.data >> 13) & 0x1 ^ s ^ 1; + u32 i2 = (thr->code.data >> 11) & 0x1 ^ s ^ 1; + imm32 = 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (thr->code.data & 0x3ff0000) >> 4 | (thr->code.data & 0x7ff) << 1); + newLR = (thr->PC + 4) | 1; break; } case A1: { - cond = data >> 28; - imm32 = 4 + sign<26, u32>((data & 0xffffff) << 2); - newLR = (CPU.PC + 4) - 4; + cond = thr->code.data >> 28; + imm32 = 4 + sign<26, u32>((thr->code.data & 0xffffff) << 2); + newLR = (thr->PC + 4) - 4; break; } default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - CPU.LR = newLR; - CPU.SetBranch(CPU.PC + imm32); + thr->LR = newLR; + thr->SetBranch(thr->PC + imm32); } } -void ARMv7Interpreter::BLX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::BLX(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); - u32 newLR = CPU.PC; + u32 cond = thr->ITSTATE.advance(); + u32 newLR = thr->PC; u32 target = 0; switch (type) { case T1: { - target = CPU.read_gpr((data >> 3) & 0xf); - newLR = (CPU.PC + 2) | 1; // ??? + target = thr->read_gpr((thr->code.data >> 3) & 0xf); + newLR = (thr->PC + 2) | 1; // ??? 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 & ~3) + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (data & 0x3ff0000) >> 4 | (data & 0x7ff) << 1); - newLR = (CPU.PC + 4) | 1; + u32 s = (thr->code.data >> 26) & 0x1; + u32 i1 = (thr->code.data >> 13) & 0x1 ^ s ^ 1; + u32 i2 = (thr->code.data >> 11) & 0x1 ^ s ^ 1; + target = (thr->PC + 4 & ~3) + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (thr->code.data & 0x3ff0000) >> 4 | (thr->code.data & 0x7ff) << 1); + newLR = (thr->PC + 4) | 1; break; } case A1: { - cond = data >> 28; - target = CPU.read_gpr(data & 0xf); - newLR = (CPU.PC + 4) - 4; + cond = thr->code.data >> 28; + target = thr->read_gpr(thr->code.data & 0xf); + newLR = (thr->PC + 4) - 4; break; } case A2: { - target = (CPU.PC + 4 | 1) + sign<25, u32>((data & 0xffffff) << 2 | (data & 0x1000000) >> 23); - newLR = (CPU.PC + 4) - 4; + target = (thr->PC + 4 | 1) + sign<25, u32>((thr->code.data & 0xffffff) << 2 | (thr->code.data & 0x1000000) >> 23); + newLR = (thr->PC + 4) - 4; break; } default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - CPU.LR = newLR; + thr->LR = newLR; if (target & 1) { - CPU.ISET = Thumb; - CPU.SetBranch(target & ~1); + thr->ISET = Thumb; + thr->SetBranch(target & ~1); } else { - CPU.ISET = ARM; - CPU.SetBranch(target); + thr->ISET = ARM; + thr->SetBranch(target); } } } -void ARMv7Interpreter::BX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::BX(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 target = 0; switch (type) { case T1: { - target = CPU.read_gpr((data >> 3) & 0xf); + target = thr->read_gpr((thr->code.data >> 3) & 0xf); break; } case A1: { - cond = data >> 28; - target = CPU.read_gpr(data & 0xf); + cond = thr->code.data >> 28; + target = thr->read_gpr(thr->code.data & 0xf); } default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { if (target & 1) { - CPU.ISET = Thumb; - CPU.SetBranch(target & ~1); + thr->ISET = Thumb; + thr->SetBranch(target & ~1); } else { - CPU.ISET = ARM; - CPU.SetBranch(target); + thr->ISET = ARM; + thr->SetBranch(target); } } } -void ARMv7Interpreter::CB_Z(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::CB_Z(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -663,14 +909,14 @@ void ARMv7Interpreter::CB_Z(const u32 data, const ARMv7_encoding type) default: throw __FUNCTION__; } - if ((CPU.read_gpr(data & 0x7) == 0) ^ ((data & 0x800) != 0)) + if ((thr->read_gpr(thr->code.data & 0x7) == 0) ^ ((thr->code.data & 0x800) != 0)) { - CPU.SetBranch(CPU.PC + 2 + ((data & 0xf8) >> 2) + ((data & 0x200) >> 3)); + thr->SetBranch(thr->PC + 2 + ((thr->code.data & 0xf8) >> 2) + ((thr->code.data & 0x200) >> 3)); } } -void ARMv7Interpreter::CLZ(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::CLZ(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -680,7 +926,7 @@ void ARMv7Interpreter::CLZ(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::CMN_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::CMN_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -689,7 +935,7 @@ void ARMv7Interpreter::CMN_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::CMN_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::CMN_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -698,7 +944,7 @@ void ARMv7Interpreter::CMN_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::CMN_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::CMN_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -708,9 +954,9 @@ void ARMv7Interpreter::CMN_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::CMP_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::CMP_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 n = 0; u32 imm32 = 0; @@ -718,34 +964,34 @@ void ARMv7Interpreter::CMP_IMM(const u32 data, const ARMv7_encoding type) { case T1: { - n = (data & 0x700) >> 8; - imm32 = (data & 0xff); + n = (thr->code.data & 0x700) >> 8; + imm32 = (thr->code.data & 0xff); break; } case T2: { - n = (data & 0xf0000) >> 16; - imm32 = ThumbExpandImm((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff)); + n = (thr->code.data & 0xf0000) >> 16; + imm32 = ThumbExpandImm(thr, (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff)); break; } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { bool carry, overflow; - const u32 res = AddWithCarry(CPU.read_gpr(n), ~imm32, true, carry, overflow); - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; - CPU.APSR.V = overflow; + const u32 res = AddWithCarry(thr->read_gpr(n), ~imm32, true, carry, overflow); + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; + thr->APSR.V = overflow; } } -void ARMv7Interpreter::CMP_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::CMP_REG(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 n = 0; u32 m = 0; auto shift_t = SRType_LSL; @@ -755,40 +1001,40 @@ void ARMv7Interpreter::CMP_REG(const u32 data, const ARMv7_encoding type) { case T1: { - n = (data & 0x7); - m = (data & 0x38) >> 3; + n = (thr->code.data & 0x7); + m = (thr->code.data & 0x38) >> 3; break; } case T2: { - n = (data & 0x80) >> 4 | (data & 0x7); - m = (data & 0x78) >> 3; + n = (thr->code.data & 0x80) >> 4 | (thr->code.data & 0x7); + m = (thr->code.data & 0x78) >> 3; break; } case T3: { - n = (data & 0xf0000) >> 16; - m = (data & 0xf); - shift_t = DecodeImmShift((data & 0x30) >> 4, (data & 0x7000) >> 10 | (data & 0xc0) >> 6, &shift_n); + n = (thr->code.data & 0xf0000) >> 16; + m = (thr->code.data & 0xf); + shift_t = DecodeImmShift((thr->code.data & 0x30) >> 4, (thr->code.data & 0x7000) >> 10 | (thr->code.data & 0xc0) >> 6, &shift_n); break; } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { bool carry, overflow; - const u32 shifted = Shift(CPU.read_gpr(m), shift_t, shift_n, true); - const u32 res = AddWithCarry(CPU.read_gpr(n), ~shifted, true, carry, overflow); - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; - CPU.APSR.V = overflow; + const u32 shifted = Shift(thr->read_gpr(m), shift_t, shift_n, true); + const u32 res = AddWithCarry(thr->read_gpr(n), ~shifted, true, carry, overflow); + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; + thr->APSR.V = overflow; } } -void ARMv7Interpreter::CMP_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::CMP_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -798,7 +1044,7 @@ void ARMv7Interpreter::CMP_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::EOR_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::EOR_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -807,7 +1053,7 @@ void ARMv7Interpreter::EOR_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::EOR_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::EOR_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -816,7 +1062,7 @@ void ARMv7Interpreter::EOR_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::EOR_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::EOR_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -826,18 +1072,18 @@ void ARMv7Interpreter::EOR_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::IT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::IT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { case T1: { - if ((data & 0xf) == 0) + if ((thr->code.data & 0xf) == 0) { throw "IT_T1: Related encodings"; } - CPU.ITSTATE.IT = data & 0xff; + thr->ITSTATE.IT = thr->code.data & 0xff; return; } default: throw __FUNCTION__; @@ -845,7 +1091,7 @@ void ARMv7Interpreter::IT(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::LDM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -854,7 +1100,7 @@ void ARMv7Interpreter::LDM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDMDA(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDMDA(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -863,7 +1109,7 @@ void ARMv7Interpreter::LDMDA(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDMDB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDMDB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -872,7 +1118,7 @@ void ARMv7Interpreter::LDMDB(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDMIB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDMIB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -882,9 +1128,9 @@ void ARMv7Interpreter::LDMIB(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::LDR_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDR_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 t = 0; u32 n = 13; u32 imm32 = 0; @@ -896,22 +1142,22 @@ void ARMv7Interpreter::LDR_IMM(const u32 data, const ARMv7_encoding type) { case T1: { - t = (data & 0x7); - n = (data & 0x38) >> 3; - imm32 = (data & 0x7c0) >> 4; + t = (thr->code.data & 0x7); + n = (thr->code.data & 0x38) >> 3; + imm32 = (thr->code.data & 0x7c0) >> 4; break; } case T2: { - t = (data & 0x700) >> 8; - imm32 = (data & 0xff) << 2; + t = (thr->code.data & 0x700) >> 8; + imm32 = (thr->code.data & 0xff) << 2; break; } case T3: { - t = (data & 0xf000) >> 12; - n = (data & 0xf0000) >> 16; - imm32 = (data & 0xfff); + t = (thr->code.data & 0xf000) >> 12; + n = (thr->code.data & 0xf0000) >> 16; + imm32 = (thr->code.data & 0xfff); if (n == 15) { @@ -921,12 +1167,12 @@ void ARMv7Interpreter::LDR_IMM(const u32 data, const ARMv7_encoding type) } case T4: { - t = (data & 0xf000) >> 12; - n = (data & 0xf0000) >> 16; - imm32 = (data & 0xff); - index = (data & 0x400); - add = (data & 0x200); - wback = (data & 0x100); + t = (thr->code.data & 0xf000) >> 12; + n = (thr->code.data & 0xf0000) >> 16; + imm32 = (thr->code.data & 0xff); + index = (thr->code.data & 0x400); + add = (thr->code.data & 0x200); + wback = (thr->code.data & 0x100); if (n == 15) { @@ -949,21 +1195,21 @@ void ARMv7Interpreter::LDR_IMM(const u32 data, const ARMv7_encoding type) default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, 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); + const u32 offset_addr = add ? thr->read_gpr(n) + imm32 : thr->read_gpr(n) - imm32; + const u32 addr = index ? offset_addr : thr->read_gpr(n); if (wback) { - CPU.write_gpr(n, offset_addr); + thr->write_gpr(n, offset_addr); } - CPU.write_gpr(t, vm::psv::read32(addr)); + thr->write_gpr(t, vm::psv::read32(addr)); } } -void ARMv7Interpreter::LDR_LIT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDR_LIT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -972,7 +1218,7 @@ void ARMv7Interpreter::LDR_LIT(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDR_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDR_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -982,7 +1228,7 @@ void ARMv7Interpreter::LDR_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::LDRB_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRB_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -991,7 +1237,7 @@ void ARMv7Interpreter::LDRB_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRB_LIT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRB_LIT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1000,7 +1246,7 @@ void ARMv7Interpreter::LDRB_LIT(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRB_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRB_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1010,7 +1256,7 @@ void ARMv7Interpreter::LDRB_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::LDRD_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRD_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1019,7 +1265,7 @@ void ARMv7Interpreter::LDRD_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRD_LIT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRD_LIT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1028,7 +1274,7 @@ void ARMv7Interpreter::LDRD_LIT(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRD_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRD_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1038,7 +1284,7 @@ void ARMv7Interpreter::LDRD_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::LDRH_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRH_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1047,7 +1293,7 @@ void ARMv7Interpreter::LDRH_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRH_LIT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRH_LIT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1056,7 +1302,7 @@ void ARMv7Interpreter::LDRH_LIT(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRH_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRH_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1066,7 +1312,7 @@ void ARMv7Interpreter::LDRH_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::LDRSB_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRSB_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1075,7 +1321,7 @@ void ARMv7Interpreter::LDRSB_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRSB_LIT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRSB_LIT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1084,7 +1330,7 @@ void ARMv7Interpreter::LDRSB_LIT(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRSB_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRSB_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1094,7 +1340,7 @@ void ARMv7Interpreter::LDRSB_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::LDRSH_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRSH_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1103,7 +1349,7 @@ void ARMv7Interpreter::LDRSH_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRSH_LIT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRSH_LIT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1112,7 +1358,7 @@ void ARMv7Interpreter::LDRSH_LIT(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LDRSH_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LDRSH_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1122,10 +1368,10 @@ void ARMv7Interpreter::LDRSH_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::LSL_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LSL_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { - bool set_flags = !CPU.ITSTATE; - u32 cond = CPU.ITSTATE.advance(); + bool set_flags = !thr->ITSTATE; + u32 cond = thr->ITSTATE.advance(); u32 d = 0; u32 m = 0; u32 shift_n = 0; @@ -1134,9 +1380,9 @@ void ARMv7Interpreter::LSL_IMM(const u32 data, const ARMv7_encoding type) { case T1: { - d = (data & 0x7); - m = (data & 0x38) >> 3; - shift_n = (data & 0x7c0) >> 6; + d = (thr->code.data & 0x7); + m = (thr->code.data & 0x38) >> 3; + shift_n = (thr->code.data & 0x7c0) >> 6; if (!shift_n) { @@ -1146,10 +1392,10 @@ void ARMv7Interpreter::LSL_IMM(const u32 data, const ARMv7_encoding type) } case T2: { - d = (data & 0xf00) >> 8; - m = (data & 0xf); - set_flags = (data & 0x100000); - shift_n = (data & 0x7000) >> 10 | (data & 0xc0) >> 6; + d = (thr->code.data & 0xf00) >> 8; + m = (thr->code.data & 0xf); + set_flags = (thr->code.data & 0x100000); + shift_n = (thr->code.data & 0x7000) >> 10 | (thr->code.data & 0xc0) >> 6; if (!shift_n) { @@ -1161,24 +1407,24 @@ void ARMv7Interpreter::LSL_IMM(const u32 data, const ARMv7_encoding type) default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { bool carry; - const u32 res = Shift_C(CPU.read_gpr(m), SRType_LSL, shift_n, CPU.APSR.C, carry); - CPU.write_gpr(d, res); + const u32 res = Shift_C(thr->read_gpr(m), SRType_LSL, shift_n, thr->APSR.C, carry); + thr->write_gpr(d, res); if (set_flags) { - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; } } } -void ARMv7Interpreter::LSL_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LSL_REG(ARMv7Thread* thr, const ARMv7_encoding type) { - bool set_flags = !CPU.ITSTATE; - u32 cond = CPU.ITSTATE.advance(); + bool set_flags = !thr->ITSTATE; + u32 cond = thr->ITSTATE.advance(); u32 d = 0; u32 n = 0; u32 m = 0; @@ -1187,38 +1433,38 @@ void ARMv7Interpreter::LSL_REG(const u32 data, const ARMv7_encoding type) { case T1: { - d = n = (data & 0x7); - m = (data & 0x38) >> 3; + d = n = (thr->code.data & 0x7); + m = (thr->code.data & 0x38) >> 3; break; } case T2: { - d = (data & 0xf00) >> 8; - n = (data & 0xf0000) >> 16; - m = (data & 0xf); - set_flags = (data & 0x100000); + d = (thr->code.data & 0xf00) >> 8; + n = (thr->code.data & 0xf0000) >> 16; + m = (thr->code.data & 0xf); + set_flags = (thr->code.data & 0x100000); break; } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { bool carry; - const u32 res = Shift_C(CPU.read_gpr(n), SRType_LSL, (CPU.read_gpr(m) & 0xff), CPU.APSR.C, carry); - CPU.write_gpr(d, res); + const u32 res = Shift_C(thr->read_gpr(n), SRType_LSL, (thr->read_gpr(m) & 0xff), thr->APSR.C, carry); + thr->write_gpr(d, res); if (set_flags) { - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; } } } -void ARMv7Interpreter::LSR_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LSR_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1227,7 +1473,7 @@ void ARMv7Interpreter::LSR_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::LSR_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::LSR_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1237,7 +1483,7 @@ void ARMv7Interpreter::LSR_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::MLA(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MLA(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1246,7 +1492,7 @@ void ARMv7Interpreter::MLA(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::MLS(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MLS(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1256,11 +1502,11 @@ void ARMv7Interpreter::MLS(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::MOV_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MOV_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { - bool set_flags = !CPU.ITSTATE; - bool carry = CPU.APSR.C; - u32 cond = CPU.ITSTATE.advance(); + bool set_flags = !thr->ITSTATE; + bool carry = thr->APSR.C; + u32 cond = thr->ITSTATE.advance(); u32 d = 0; u32 imm32 = 0; @@ -1268,42 +1514,42 @@ void ARMv7Interpreter::MOV_IMM(const u32 data, const ARMv7_encoding type) { case T1: { - d = (data >> 8) & 0x7; - imm32 = sign<8, u32>(data & 0xff); + d = (thr->code.data >> 8) & 0x7; + imm32 = sign<8, u32>(thr->code.data & 0xff); break; } case T2: { - set_flags = data & 0x100000; - d = (data >> 8) & 0xf; - imm32 = ThumbExpandImm_C((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff), carry, carry); + set_flags = thr->code.data & 0x100000; + d = (thr->code.data >> 8) & 0xf; + imm32 = ThumbExpandImm_C((thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff), carry, carry); break; } case T3: { set_flags = false; - d = (data >> 8) & 0xf; - imm32 = (data & 0xf0000) >> 4 | (data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff); + d = (thr->code.data >> 8) & 0xf; + imm32 = (thr->code.data & 0xf0000) >> 4 | (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff); break; } default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - CPU.write_gpr(d, imm32); + thr->write_gpr(d, imm32); if (set_flags) { - CPU.APSR.N = imm32 >> 31; - CPU.APSR.Z = imm32 == 0; - CPU.APSR.C = carry; + thr->APSR.N = imm32 >> 31; + thr->APSR.Z = imm32 == 0; + thr->APSR.C = carry; } } } -void ARMv7Interpreter::MOV_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MOV_REG(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 d = 0; u32 m = 0; bool set_flags = false; @@ -1312,44 +1558,44 @@ void ARMv7Interpreter::MOV_REG(const u32 data, const ARMv7_encoding type) { case T1: { - d = (data & 0x80) >> 4 | (data & 0x7); - m = (data & 0x78) >> 3; + d = (thr->code.data & 0x80) >> 4 | (thr->code.data & 0x7); + m = (thr->code.data & 0x78) >> 3; break; } case T2: { - d = (data & 0x7); - m = (data & 0x38) >> 3; + d = (thr->code.data & 0x7); + m = (thr->code.data & 0x38) >> 3; set_flags = true; break; } case T3: { - d = (data & 0xf00) >> 8; - m = (data & 0xf); - set_flags = (data & 0x100000); + d = (thr->code.data & 0xf00) >> 8; + m = (thr->code.data & 0xf); + set_flags = (thr->code.data & 0x100000); break; } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - const u32 res = CPU.read_gpr(m); - CPU.write_gpr(d, res); + const u32 res = thr->read_gpr(m); + thr->write_gpr(d, res); if (set_flags) { - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - //CPU.APSR.C = ? + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + //thr->APSR.C = ? } } } -void ARMv7Interpreter::MOVT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MOVT(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 d = 0; u32 imm16 = 0; @@ -1357,22 +1603,22 @@ void ARMv7Interpreter::MOVT(const u32 data, const ARMv7_encoding type) { case T1: { - d = (data & 0xf00) >> 8; - imm16 = (data & 0xf0000) >> 4 | (data & 0x4000000) >> 14 | (data & 0x7000) >> 4 | (data & 0xff); + d = (thr->code.data & 0xf00) >> 8; + imm16 = (thr->code.data & 0xf0000) >> 4 | (thr->code.data & 0x4000000) >> 14 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff); break; } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - CPU.write_gpr(d, (CPU.read_gpr(d) & 0xffff) | (imm16 << 16)); + thr->write_gpr(d, (thr->read_gpr(d) & 0xffff) | (imm16 << 16)); } } -void ARMv7Interpreter::MRS(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MRS(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1381,7 +1627,7 @@ void ARMv7Interpreter::MRS(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::MSR_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MSR_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1390,7 +1636,7 @@ void ARMv7Interpreter::MSR_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::MSR_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MSR_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1400,7 +1646,7 @@ void ARMv7Interpreter::MSR_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::MUL(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MUL(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1410,7 +1656,7 @@ void ARMv7Interpreter::MUL(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::MVN_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MVN_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1419,7 +1665,7 @@ void ARMv7Interpreter::MVN_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::MVN_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MVN_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1428,7 +1674,7 @@ void ARMv7Interpreter::MVN_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::MVN_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::MVN_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1438,9 +1684,9 @@ void ARMv7Interpreter::MVN_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::NOP(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::NOP(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); switch (type) { @@ -1454,19 +1700,19 @@ void ARMv7Interpreter::NOP(const u32 data, const ARMv7_encoding type) } case A1: { - cond = data >> 28; + cond = thr->code.data >> 28; break; } default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { } } -void ARMv7Interpreter::ORN_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ORN_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1475,7 +1721,7 @@ void ARMv7Interpreter::ORN_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::ORN_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ORN_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1485,7 +1731,7 @@ void ARMv7Interpreter::ORN_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::ORR_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ORR_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1494,7 +1740,7 @@ void ARMv7Interpreter::ORR_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::ORR_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ORR_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1503,7 +1749,7 @@ void ARMv7Interpreter::ORR_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::ORR_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ORR_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1513,7 +1759,7 @@ void ARMv7Interpreter::ORR_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::PKH(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::PKH(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1523,32 +1769,32 @@ void ARMv7Interpreter::PKH(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::POP(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::POP(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u16 reg_list = 0; switch (type) { case T1: { - reg_list = ((data & 0x100) << 7) | (data & 0xff); + reg_list = ((thr->code.data & 0x100) << 7) | (thr->code.data & 0xff); break; } case T2: { - reg_list = data & 0xdfff; + reg_list = thr->code.data & 0xdfff; break; } case T3: { - reg_list = 1 << (data >> 12); + reg_list = 1 << (thr->code.data >> 12); break; } case A1: { - cond = data >> 28; - reg_list = data & 0xffff; + cond = thr->code.data >> 28; + reg_list = thr->code.data & 0xffff; if (BitCount(reg_list) < 2) { throw "LDM / LDMIA / LDMFD"; @@ -1557,52 +1803,52 @@ void ARMv7Interpreter::POP(const u32 data, const ARMv7_encoding type) } case A2: { - cond = data >> 28; - reg_list = 1 << ((data >> 12) & 0xf); + cond = thr->code.data >> 28; + reg_list = 1 << ((thr->code.data >> 12) & 0xf); break; } default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { 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; + thr->write_gpr(i, vm::psv::read32(thr->SP)); + thr->SP += 4; } } } } -void ARMv7Interpreter::PUSH(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::PUSH(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u16 reg_list = 0; switch (type) { case T1: { - reg_list = ((data & 0x100) << 6) | (data & 0xff); + reg_list = ((thr->code.data & 0x100) << 6) | (thr->code.data & 0xff); break; } case T2: { - reg_list = data & 0x5fff; + reg_list = thr->code.data & 0x5fff; break; } case T3: { - reg_list = 1 << (data >> 12); + reg_list = 1 << (thr->code.data >> 12); break; } case A1: { - cond = data >> 28; - reg_list = data & 0xffff; + cond = thr->code.data >> 28; + reg_list = thr->code.data & 0xffff; if (BitCount(reg_list) < 2) { throw "STMDB / STMFD"; @@ -1611,28 +1857,28 @@ void ARMv7Interpreter::PUSH(const u32 data, const ARMv7_encoding type) } case A2: { - cond = data >> 28; - reg_list = 1 << ((data >> 12) & 0xf); + cond = thr->code.data >> 28; + reg_list = 1 << ((thr->code.data >> 12) & 0xf); break; } default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { 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)); + thr->SP -= 4; + vm::psv::write32(thr->SP, thr->read_gpr(i)); } } } } -void ARMv7Interpreter::QADD(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QADD(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1641,7 +1887,7 @@ void ARMv7Interpreter::QADD(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::QADD16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QADD16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1650,7 +1896,7 @@ void ARMv7Interpreter::QADD16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::QADD8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QADD8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1659,7 +1905,7 @@ void ARMv7Interpreter::QADD8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::QASX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QASX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1668,7 +1914,7 @@ void ARMv7Interpreter::QASX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::QDADD(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QDADD(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1677,7 +1923,7 @@ void ARMv7Interpreter::QDADD(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::QDSUB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QDSUB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1686,7 +1932,7 @@ void ARMv7Interpreter::QDSUB(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::QSAX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QSAX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1695,7 +1941,7 @@ void ARMv7Interpreter::QSAX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::QSUB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QSUB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1704,7 +1950,7 @@ void ARMv7Interpreter::QSUB(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::QSUB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QSUB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1713,7 +1959,7 @@ void ARMv7Interpreter::QSUB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::QSUB8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::QSUB8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1723,7 +1969,7 @@ void ARMv7Interpreter::QSUB8(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::RBIT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::RBIT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1732,7 +1978,7 @@ void ARMv7Interpreter::RBIT(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::REV(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::REV(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1741,7 +1987,7 @@ void ARMv7Interpreter::REV(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::REV16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::REV16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1750,7 +1996,7 @@ void ARMv7Interpreter::REV16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::REVSH(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::REVSH(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1760,7 +2006,7 @@ void ARMv7Interpreter::REVSH(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::ROR_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ROR_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1769,7 +2015,7 @@ void ARMv7Interpreter::ROR_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::ROR_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::ROR_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1779,7 +2025,7 @@ void ARMv7Interpreter::ROR_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::RRX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::RRX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1789,7 +2035,7 @@ void ARMv7Interpreter::RRX(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::RSB_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::RSB_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1798,7 +2044,7 @@ void ARMv7Interpreter::RSB_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::RSB_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::RSB_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1807,7 +2053,7 @@ void ARMv7Interpreter::RSB_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::RSB_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::RSB_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1817,7 +2063,7 @@ void ARMv7Interpreter::RSB_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::RSC_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::RSC_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1826,7 +2072,7 @@ void ARMv7Interpreter::RSC_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::RSC_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::RSC_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1835,7 +2081,7 @@ void ARMv7Interpreter::RSC_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::RSC_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::RSC_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1845,7 +2091,7 @@ void ARMv7Interpreter::RSC_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SADD16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SADD16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1854,7 +2100,7 @@ void ARMv7Interpreter::SADD16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SADD8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SADD8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1863,7 +2109,7 @@ void ARMv7Interpreter::SADD8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SASX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SASX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1873,7 +2119,7 @@ void ARMv7Interpreter::SASX(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SBC_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SBC_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1882,7 +2128,7 @@ void ARMv7Interpreter::SBC_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SBC_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SBC_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1891,7 +2137,7 @@ void ARMv7Interpreter::SBC_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SBC_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SBC_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1901,7 +2147,7 @@ void ARMv7Interpreter::SBC_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SBFX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SBFX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1911,7 +2157,7 @@ void ARMv7Interpreter::SBFX(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SDIV(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SDIV(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1921,7 +2167,7 @@ void ARMv7Interpreter::SDIV(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SEL(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SEL(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1931,7 +2177,7 @@ void ARMv7Interpreter::SEL(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SHADD16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SHADD16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1940,7 +2186,7 @@ void ARMv7Interpreter::SHADD16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SHADD8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SHADD8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1949,7 +2195,7 @@ void ARMv7Interpreter::SHADD8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SHASX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SHASX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1958,7 +2204,7 @@ void ARMv7Interpreter::SHASX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SHSAX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SHSAX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1967,7 +2213,7 @@ void ARMv7Interpreter::SHSAX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SHSUB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SHSUB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1976,7 +2222,7 @@ void ARMv7Interpreter::SHSUB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SHSUB8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SHSUB8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1986,7 +2232,7 @@ void ARMv7Interpreter::SHSUB8(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SMLA__(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMLA__(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -1995,7 +2241,7 @@ void ARMv7Interpreter::SMLA__(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMLAD(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMLAD(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2004,7 +2250,7 @@ void ARMv7Interpreter::SMLAD(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMLAL(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMLAL(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2013,7 +2259,7 @@ void ARMv7Interpreter::SMLAL(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMLAL__(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMLAL__(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2022,7 +2268,7 @@ void ARMv7Interpreter::SMLAL__(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMLALD(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMLALD(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2031,7 +2277,7 @@ void ARMv7Interpreter::SMLALD(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMLAW_(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMLAW_(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2040,7 +2286,7 @@ void ARMv7Interpreter::SMLAW_(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMLSD(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMLSD(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2049,7 +2295,7 @@ void ARMv7Interpreter::SMLSD(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMLSLD(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMLSLD(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2058,7 +2304,7 @@ void ARMv7Interpreter::SMLSLD(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMMLA(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMMLA(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2067,7 +2313,7 @@ void ARMv7Interpreter::SMMLA(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMMLS(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMMLS(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2076,7 +2322,7 @@ void ARMv7Interpreter::SMMLS(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMMUL(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMMUL(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2085,7 +2331,7 @@ void ARMv7Interpreter::SMMUL(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMUAD(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMUAD(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2094,7 +2340,7 @@ void ARMv7Interpreter::SMUAD(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMUL__(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMUL__(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2103,7 +2349,7 @@ void ARMv7Interpreter::SMUL__(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMULL(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMULL(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2112,7 +2358,7 @@ void ARMv7Interpreter::SMULL(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMULW_(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMULW_(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2121,7 +2367,7 @@ void ARMv7Interpreter::SMULW_(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SMUSD(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SMUSD(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2131,7 +2377,7 @@ void ARMv7Interpreter::SMUSD(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SSAT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SSAT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2140,7 +2386,7 @@ void ARMv7Interpreter::SSAT(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SSAT16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SSAT16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2149,7 +2395,7 @@ void ARMv7Interpreter::SSAT16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SSAX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SSAX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2158,7 +2404,7 @@ void ARMv7Interpreter::SSAX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SSUB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SSUB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2167,7 +2413,7 @@ void ARMv7Interpreter::SSUB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SSUB8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SSUB8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2177,7 +2423,7 @@ void ARMv7Interpreter::SSUB8(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::STM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2186,7 +2432,7 @@ void ARMv7Interpreter::STM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::STMDA(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STMDA(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2195,7 +2441,7 @@ void ARMv7Interpreter::STMDA(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::STMDB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STMDB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2204,7 +2450,7 @@ void ARMv7Interpreter::STMDB(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::STMIB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STMIB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2214,9 +2460,9 @@ void ARMv7Interpreter::STMIB(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STR_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 t = 16; u32 n = 13; u32 imm32 = 0; @@ -2228,22 +2474,22 @@ void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type) { case T1: { - t = (data & 0x7); - n = (data & 0x38) >> 3; - imm32 = (data & 0x7c0) >> 4; + t = (thr->code.data & 0x7); + n = (thr->code.data & 0x38) >> 3; + imm32 = (thr->code.data & 0x7c0) >> 4; break; } case T2: { - t = (data & 0x700) >> 8; - imm32 = (data & 0xff) << 2; + t = (thr->code.data & 0x700) >> 8; + imm32 = (thr->code.data & 0xff) << 2; break; } case T3: { - t = (data & 0xf000) >> 12; - n = (data & 0xf0000) >> 16; - imm32 = (data & 0xfff); + t = (thr->code.data & 0xf000) >> 12; + n = (thr->code.data & 0xf0000) >> 16; + imm32 = (thr->code.data & 0xfff); if (n == 0xf) { @@ -2253,12 +2499,12 @@ void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type) } case T4: { - t = (data & 0xf000) >> 12; - n = (data & 0xf0000) >> 16; - imm32 = (data & 0xff); - index = (data & 0x400); - add = (data & 0x200); - wback = (data & 0x100); + t = (thr->code.data & 0xf000) >> 12; + n = (thr->code.data & 0xf0000) >> 16; + imm32 = (thr->code.data & 0xff); + index = (thr->code.data & 0x400); + add = (thr->code.data & 0x200); + wback = (thr->code.data & 0x100); if (index && add && !wback) { @@ -2278,23 +2524,23 @@ void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type) default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, 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); + const u32 offset_addr = add ? thr->read_gpr(n) + imm32 : thr->read_gpr(n) - imm32; + const u32 addr = index ? offset_addr : thr->read_gpr(n); - vm::psv::write32(addr, CPU.read_gpr(t)); + vm::psv::write32(addr, thr->read_gpr(t)); if (wback) { - CPU.write_gpr(n, offset_addr); + thr->write_gpr(n, offset_addr); } } } -void ARMv7Interpreter::STR_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STR_REG(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 t = 0; u32 n = 0; u32 m = 0; @@ -2308,17 +2554,17 @@ void ARMv7Interpreter::STR_REG(const u32 data, const ARMv7_encoding type) { case T1: { - t = (data & 0x7); - n = (data & 0x38) >> 3; - m = (data & 0x1c0) >> 6; + t = (thr->code.data & 0x7); + n = (thr->code.data & 0x38) >> 3; + m = (thr->code.data & 0x1c0) >> 6; break; } case T2: { - t = (data & 0xf000) >> 12; - n = (data & 0xf0000) >> 16; - m = (data & 0xf); - shift_n = (data & 0x30) >> 4; + t = (thr->code.data & 0xf000) >> 12; + n = (thr->code.data & 0xf0000) >> 16; + m = (thr->code.data & 0xf); + shift_n = (thr->code.data & 0x30) >> 4; if (n == 15) { @@ -2330,23 +2576,23 @@ void ARMv7Interpreter::STR_REG(const u32 data, const ARMv7_encoding type) default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - const u32 offset = Shift(CPU.read_gpr(m), shift_t, shift_n, CPU.APSR.C); - const u32 offset_addr = add ? CPU.read_gpr(n) + offset : CPU.read_gpr(n) - offset; - const u32 addr = index ? offset_addr : CPU.read_gpr(n); + const u32 offset = Shift(thr->read_gpr(m), shift_t, shift_n, thr->APSR.C); + const u32 offset_addr = add ? thr->read_gpr(n) + offset : thr->read_gpr(n) - offset; + const u32 addr = index ? offset_addr : thr->read_gpr(n); - vm::psv::write32(addr, CPU.read_gpr(t)); + vm::psv::write32(addr, thr->read_gpr(t)); if (wback) { - CPU.write_gpr(n, offset_addr); + thr->write_gpr(n, offset_addr); } } } -void ARMv7Interpreter::STRB_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STRB_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2355,7 +2601,7 @@ void ARMv7Interpreter::STRB_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::STRB_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STRB_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2365,7 +2611,7 @@ void ARMv7Interpreter::STRB_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::STRD_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STRD_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2374,7 +2620,7 @@ void ARMv7Interpreter::STRD_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::STRD_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STRD_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2384,7 +2630,7 @@ void ARMv7Interpreter::STRD_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::STRH_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STRH_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2393,7 +2639,7 @@ void ARMv7Interpreter::STRH_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::STRH_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::STRH_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2403,10 +2649,10 @@ void ARMv7Interpreter::STRH_REG(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SUB_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SUB_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { - bool set_flags = !CPU.ITSTATE; - u32 cond = CPU.ITSTATE.advance(); + bool set_flags = !thr->ITSTATE; + u32 cond = thr->ITSTATE.advance(); u32 d = 0; u32 n = 0; u32 imm32 = 0; @@ -2415,23 +2661,23 @@ void ARMv7Interpreter::SUB_IMM(const u32 data, const ARMv7_encoding type) { case T1: { - d = (data & 0x7); - n = (data & 0x38) >> 3; - imm32 = (data & 0x1c) >> 6; + d = (thr->code.data & 0x7); + n = (thr->code.data & 0x38) >> 3; + imm32 = (thr->code.data & 0x1c) >> 6; break; } case T2: { - d = n = (data & 0x700) >> 8; - imm32 = (data & 0xff); + d = n = (thr->code.data & 0x700) >> 8; + imm32 = (thr->code.data & 0xff); break; } case T3: { - d = (data & 0xf00) >> 8; - n = (data & 0xf0000) >> 16; - set_flags = (data & 0x100000); - imm32 = ThumbExpandImm((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff)); + d = (thr->code.data & 0xf00) >> 8; + n = (thr->code.data & 0xf0000) >> 16; + set_flags = (thr->code.data & 0x100000); + imm32 = ThumbExpandImm(thr, (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff)); if (d == 15 && set_flags) { @@ -2445,10 +2691,10 @@ void ARMv7Interpreter::SUB_IMM(const u32 data, const ARMv7_encoding type) } case T4: { - d = (data & 0xf00) >> 8; - n = (data & 0xf0000) >> 16; + d = (thr->code.data & 0xf00) >> 8; + n = (thr->code.data & 0xf0000) >> 16; set_flags = false; - imm32 = (data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff); + imm32 = (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff); if (d == 15) { @@ -2464,29 +2710,29 @@ void ARMv7Interpreter::SUB_IMM(const u32 data, const ARMv7_encoding type) default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { if (set_flags) { bool carry, overflow; - const u32 res = AddWithCarry(CPU.read_gpr(n), ~imm32, true, carry, overflow); - CPU.write_gpr(d, res); - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; - CPU.APSR.V = overflow; + const u32 res = AddWithCarry(thr->read_gpr(n), ~imm32, true, carry, overflow); + thr->write_gpr(d, res); + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; + thr->APSR.V = overflow; } else { - CPU.write_gpr(d, CPU.read_gpr(n) - imm32); + thr->write_gpr(d, thr->read_gpr(n) - imm32); } } } -void ARMv7Interpreter::SUB_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SUB_REG(ARMv7Thread* thr, const ARMv7_encoding type) { - bool set_flags = !CPU.ITSTATE; - u32 cond = CPU.ITSTATE.advance(); + bool set_flags = !thr->ITSTATE; + u32 cond = thr->ITSTATE.advance(); u32 d = 0; u32 n = 0; u32 m = 0; @@ -2497,18 +2743,18 @@ void ARMv7Interpreter::SUB_REG(const u32 data, const ARMv7_encoding type) { case T1: { - d = (data & 0x7); - n = (data & 0x38) >> 3; - m = (data & 0x1c0) >> 6; + d = (thr->code.data & 0x7); + n = (thr->code.data & 0x38) >> 3; + m = (thr->code.data & 0x1c0) >> 6; break; } case T2: { - d = (data & 0xf00) >> 8; - n = (data & 0xf0000) >> 16; - m = (data & 0xf); - set_flags = (data & 0x100000); - shift_t = DecodeImmShift((data & 0x30) >> 4, (data & 0x7000) >> 10 | (data & 0xc0) >> 6, &shift_n); + d = (thr->code.data & 0xf00) >> 8; + n = (thr->code.data & 0xf0000) >> 16; + m = (thr->code.data & 0xf); + set_flags = (thr->code.data & 0x100000); + shift_t = DecodeImmShift((thr->code.data & 0x30) >> 4, (thr->code.data & 0x7000) >> 10 | (thr->code.data & 0xc0) >> 6, &shift_n); if (d == 15 && set_flags) { @@ -2524,27 +2770,27 @@ void ARMv7Interpreter::SUB_REG(const u32 data, const ARMv7_encoding type) default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { - const u32 shifted = Shift(CPU.read_gpr(m), shift_t, shift_n, CPU.APSR.C); + const u32 shifted = Shift(thr->read_gpr(m), shift_t, shift_n, thr->APSR.C); if (set_flags) { bool carry, overflow; - const u32 res = AddWithCarry(CPU.read_gpr(n), ~shifted, true, carry, overflow); - CPU.write_gpr(d, res); - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; - CPU.APSR.V = overflow; + const u32 res = AddWithCarry(thr->read_gpr(n), ~shifted, true, carry, overflow); + thr->write_gpr(d, res); + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; + thr->APSR.V = overflow; } else { - CPU.write_gpr(d, CPU.read_gpr(n) - shifted); + thr->write_gpr(d, thr->read_gpr(n) - shifted); } } } -void ARMv7Interpreter::SUB_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SUB_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2553,9 +2799,9 @@ void ARMv7Interpreter::SUB_RSR(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SUB_SPI(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SUB_SPI(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 cond = CPU.ITSTATE.advance(); + u32 cond = thr->ITSTATE.advance(); u32 d = 13; bool set_flags = false; u32 imm32 = 0; @@ -2564,14 +2810,14 @@ void ARMv7Interpreter::SUB_SPI(const u32 data, const ARMv7_encoding type) { case T1: { - imm32 = (data & 0x7f) << 2; + imm32 = (thr->code.data & 0x7f) << 2; break; } case T2: { - d = (data & 0xf00) >> 8; - set_flags = (data & 0x100000); - imm32 = ThumbExpandImm((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff)); + d = (thr->code.data & 0xf00) >> 8; + set_flags = (thr->code.data & 0x100000); + imm32 = ThumbExpandImm(thr, (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff)); if (d == 15 && set_flags) { @@ -2581,35 +2827,35 @@ void ARMv7Interpreter::SUB_SPI(const u32 data, const ARMv7_encoding type) } case T3: { - d = (data & 0xf00) >> 8; + d = (thr->code.data & 0xf00) >> 8; set_flags = false; - imm32 = (data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff); + imm32 = (thr->code.data & 0x4000000) >> 15 | (thr->code.data & 0x7000) >> 4 | (thr->code.data & 0xff); break; } case A1: throw __FUNCTION__; default: throw __FUNCTION__; } - if (ConditionPassed(cond)) + if (ConditionPassed(thr, cond)) { if (set_flags) { bool carry, overflow; - const u32 res = AddWithCarry(CPU.SP, ~imm32, true, carry, overflow); - CPU.write_gpr(d, res); - CPU.APSR.N = res >> 31; - CPU.APSR.Z = res == 0; - CPU.APSR.C = carry; - CPU.APSR.V = overflow; + const u32 res = AddWithCarry(thr->SP, ~imm32, true, carry, overflow); + thr->write_gpr(d, res); + thr->APSR.N = res >> 31; + thr->APSR.Z = res == 0; + thr->APSR.C = carry; + thr->APSR.V = overflow; } else { - CPU.write_gpr(d, CPU.SP - imm32); + thr->write_gpr(d, thr->SP - imm32); } } } -void ARMv7Interpreter::SUB_SPR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SUB_SPR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2619,7 +2865,7 @@ void ARMv7Interpreter::SUB_SPR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SVC(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SVC(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2629,7 +2875,7 @@ void ARMv7Interpreter::SVC(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::SXTAB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SXTAB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2638,7 +2884,7 @@ void ARMv7Interpreter::SXTAB(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SXTAB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SXTAB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2647,7 +2893,7 @@ void ARMv7Interpreter::SXTAB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SXTAH(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SXTAH(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2656,7 +2902,7 @@ void ARMv7Interpreter::SXTAH(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SXTB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SXTB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2665,7 +2911,7 @@ void ARMv7Interpreter::SXTB(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SXTB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SXTB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2674,7 +2920,7 @@ void ARMv7Interpreter::SXTB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::SXTH(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::SXTH(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2684,7 +2930,7 @@ void ARMv7Interpreter::SXTH(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::TB_(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::TB_(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2694,7 +2940,7 @@ void ARMv7Interpreter::TB_(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::TEQ_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::TEQ_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2703,7 +2949,7 @@ void ARMv7Interpreter::TEQ_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::TEQ_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::TEQ_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2712,7 +2958,7 @@ void ARMv7Interpreter::TEQ_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::TEQ_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::TEQ_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2722,7 +2968,7 @@ void ARMv7Interpreter::TEQ_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::TST_IMM(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::TST_IMM(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2731,7 +2977,7 @@ void ARMv7Interpreter::TST_IMM(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::TST_REG(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::TST_REG(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2740,7 +2986,7 @@ void ARMv7Interpreter::TST_REG(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::TST_RSR(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::TST_RSR(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2750,7 +2996,7 @@ void ARMv7Interpreter::TST_RSR(const u32 data, const ARMv7_encoding type) } -void ARMv7Interpreter::UADD16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UADD16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2759,7 +3005,7 @@ void ARMv7Interpreter::UADD16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UADD8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UADD8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2768,7 +3014,7 @@ void ARMv7Interpreter::UADD8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UASX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UASX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2777,7 +3023,7 @@ void ARMv7Interpreter::UASX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UBFX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UBFX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2786,7 +3032,7 @@ void ARMv7Interpreter::UBFX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UDIV(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UDIV(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2795,7 +3041,7 @@ void ARMv7Interpreter::UDIV(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UHADD16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UHADD16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2804,7 +3050,7 @@ void ARMv7Interpreter::UHADD16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UHADD8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UHADD8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2813,7 +3059,7 @@ void ARMv7Interpreter::UHADD8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UHASX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UHASX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2822,7 +3068,7 @@ void ARMv7Interpreter::UHASX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UHSAX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UHSAX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2831,7 +3077,7 @@ void ARMv7Interpreter::UHSAX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UHSUB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UHSUB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2840,7 +3086,7 @@ void ARMv7Interpreter::UHSUB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UHSUB8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UHSUB8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2849,7 +3095,7 @@ void ARMv7Interpreter::UHSUB8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UMAAL(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UMAAL(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2858,7 +3104,7 @@ void ARMv7Interpreter::UMAAL(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UMLAL(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UMLAL(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2867,7 +3113,7 @@ void ARMv7Interpreter::UMLAL(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UMULL(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UMULL(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2876,7 +3122,7 @@ void ARMv7Interpreter::UMULL(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UQADD16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UQADD16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2885,7 +3131,7 @@ void ARMv7Interpreter::UQADD16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UQADD8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UQADD8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2894,7 +3140,7 @@ void ARMv7Interpreter::UQADD8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UQASX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UQASX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2903,7 +3149,7 @@ void ARMv7Interpreter::UQASX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UQSAX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UQSAX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2912,7 +3158,7 @@ void ARMv7Interpreter::UQSAX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UQSUB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UQSUB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2921,7 +3167,7 @@ void ARMv7Interpreter::UQSUB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UQSUB8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UQSUB8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2930,7 +3176,7 @@ void ARMv7Interpreter::UQSUB8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::USAD8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::USAD8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2939,7 +3185,7 @@ void ARMv7Interpreter::USAD8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::USADA8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::USADA8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2948,7 +3194,7 @@ void ARMv7Interpreter::USADA8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::USAT(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::USAT(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2957,7 +3203,7 @@ void ARMv7Interpreter::USAT(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::USAT16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::USAT16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2966,7 +3212,7 @@ void ARMv7Interpreter::USAT16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::USAX(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::USAX(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2975,7 +3221,7 @@ void ARMv7Interpreter::USAX(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::USUB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::USUB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2984,7 +3230,7 @@ void ARMv7Interpreter::USUB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::USUB8(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::USUB8(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -2993,7 +3239,7 @@ void ARMv7Interpreter::USUB8(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UXTAB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UXTAB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -3002,7 +3248,7 @@ void ARMv7Interpreter::UXTAB(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UXTAB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UXTAB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -3011,7 +3257,7 @@ void ARMv7Interpreter::UXTAB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UXTAH(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UXTAH(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -3020,7 +3266,7 @@ void ARMv7Interpreter::UXTAH(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UXTB(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UXTB(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -3029,7 +3275,7 @@ void ARMv7Interpreter::UXTB(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UXTB16(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UXTB16(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { @@ -3038,11 +3284,11 @@ void ARMv7Interpreter::UXTB16(const u32 data, const ARMv7_encoding type) } } -void ARMv7Interpreter::UXTH(const u32 data, const ARMv7_encoding type) +void ARMv7_instrs::UXTH(ARMv7Thread* thr, const ARMv7_encoding type) { switch (type) { case A1: throw __FUNCTION__; default: throw __FUNCTION__; } -} +} \ No newline at end of file diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h index bb8d71b1fc..6713dbc2c9 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.h +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.h @@ -1,565 +1,759 @@ #pragma once -#include "Emu/ARMv7/ARMv7Opcodes.h" -class ARMv7Interpreter : public ARMv7Opcodes +#include "Emu/ARMv7/ARMv7Thread.h" +#include "Emu/System.h" +#include "Utilities/Log.h" + +static enum ARMv7_encoding { - ARMv7Thread& CPU; + T1, T2, T3, T4, A1, A2 +}; -public: - ARMv7Interpreter(ARMv7Thread& cpu) : CPU(cpu) - { - } - - enum SRType : u32 - { - SRType_None, - SRType_LSL, - SRType_LSR, - SRType_ASR, - SRType_ROR, - SRType_RRX, - }; +static enum SRType : u32 +{ + SRType_None, + SRType_LSL, + SRType_LSR, + SRType_ASR, + SRType_ROR, + SRType_RRX +}; +namespace ARMv7_instrs +{ template - bool IsZero(T x) + static bool IsZero(T x) { return x == T(0); } template - bool IsOnes(T x) + static bool IsOnes(T x) { return x == ~T(0); } template - u8 IsZeroBit(T x) + static u8 IsZeroBit(T x) { return IsZero(x) ? 1 : 0; } template - bool IsOnesBit(T x, u8 len = sizeof(T) * 8) + static bool IsOnesBit(T x, u8 len = sizeof(T) * 8) { return IsOnes(x) ? 1 : 0; } template - u8 BitCount(T x, u8 len = sizeof(T) * 8) - { - u8 result = 0; - - for(u8 mask=1 << (len - 1); mask; mask >>= 1) - { - if(x & mask) result++; - } - - return result; - } + u8 BitCount(T x, u8 len = sizeof(T) * 8); template - s8 LowestSetBit(T x, u8 len = sizeof(T) * 8) - { - if(!x) return len; - - u8 result = 0; - - for(T mask=1, i=0; i - s8 HighestSetBit(T x, u8 len = sizeof(T) * 8) - { - if(!x) return -1; - - u8 result = len; - - for(T mask=T(1) << (len - 1); (x & mask) == 0; mask >>= 1) - { - result--; - } - - return result; - } + s8 HighestSetBit(T x, u8 len = sizeof(T) * 8); template - s8 CountLeadingZeroBits(T x, u8 len = sizeof(T) * 8) - { - return len - 1 - HighestSetBit(x, len); - } - - SRType DecodeImmShift(u32 type, u32 imm5, u32* shift_n) - { - SRType shift_t = SRType_None; - - switch(type) - { - case 0: shift_t = SRType_LSL; if(shift_n) *shift_n = imm5; break; - case 1: shift_t = SRType_LSR; if(shift_n) *shift_n = imm5 == 0 ? 32 : imm5; break; - case 2: shift_t = SRType_ASR; if(shift_n) *shift_n = imm5 == 0 ? 32 : imm5; break; - case 3: - if(imm5 == 0) - { - shift_t = SRType_RRX; if(shift_n) *shift_n = 1; - } - else - { - shift_t = SRType_ROR; if(shift_n) *shift_n = imm5; - } - break; - } - - return shift_t; - } - - SRType DecodeRegShift(u8 type) - { - SRType shift_t = SRType_None; - - switch(type) - { - case 0: shift_t = SRType_LSL; break; - case 1: shift_t = SRType_LSR; break; - case 2: shift_t = SRType_ASR; break; - case 3: shift_t = SRType_ROR; break; - } - - return shift_t; - } - - u32 LSL_C(u32 x, s32 shift, bool& carry_out) - { - assert(shift > 0); - carry_out = shift <= 32 ? x & (1 << (32 - shift)) : false; - return shift < 32 ? x << shift : 0; - } - - u32 LSL(u32 x, s32 shift) - { - assert(shift >= 0); - return shift < 32 ? x << shift : 0; - } - - u32 LSR_C(u32 x, s32 shift, bool& carry_out) - { - assert(shift > 0); - carry_out = shift <= 32 ? x & (1 << (shift - 1)) : false; - return shift < 32 ? x >> shift : 0; - } - - u32 LSR(u32 x, s32 shift) - { - assert(shift >= 0); - return shift < 32 ? x >> shift : 0; - } - - s32 ASR_C(s32 x, s32 shift, bool& carry_out) - { - assert(shift > 0); - carry_out = shift <= 32 ? x & (1 << (shift - 1)) : false; - return shift < 32 ? x >> shift : x >> 31; - } - - s32 ASR(s32 x, s32 shift) - { - assert(shift >= 0); - return shift < 32 ? x >> shift : x >> 31; - } - - u32 ROR_C(u32 x, s32 shift, bool& carry_out) - { - assert(shift); - carry_out = x & (1 << (shift - 1)); - return x >> shift | x << (32 - shift); - } - - u32 ROR(u32 x, s32 shift) - { - return x >> shift | x << (32 - shift); - } - - u32 RRX_C(u32 x, bool carry_in, bool& carry_out) - { - carry_out = x & 0x1; - return ((u32)carry_in << 31) | (x >> 1); - } - - u32 RRX(u32 x, bool carry_in) - { - return ((u32)carry_in << 31) | (x >> 1); - } - - template T Shift_C(T value, SRType type, s32 amount, bool carry_in, bool& carry_out) - { - assert(type != SRType_RRX || amount == 1); - - if(amount) - { - switch(type) - { - case SRType_LSL: return LSL_C(value, amount, carry_out); - case SRType_LSR: return LSR_C(value, amount, carry_out); - case SRType_ASR: return ASR_C(value, amount, carry_out); - case SRType_ROR: return ROR_C(value, amount, carry_out); - case SRType_RRX: return RRX_C(value, carry_in, carry_out); - } - } - - carry_out = carry_in; - return value; - } - - template T Shift(T value, SRType type, s32 amount, bool carry_in) - { - bool carry_out; - return Shift_C(value, type, amount, carry_in, carry_out); - } - - template T AddWithCarry(T x, T y, bool carry_in, bool& carry_out, bool& overflow) - { - const T sign_mask = (T)1 << (sizeof(T) - 1); - - T result = x + y; - carry_out = ((x & y) | ((x ^ y) & ~result)) & sign_mask; - overflow = (x ^ result) & (y ^ result) & sign_mask; - if (carry_in) - { - result += 1; - carry_out ^= (result == 0); - overflow ^= (result == sign_mask); - } - return result; - } - - u32 ThumbExpandImm_C(u32 imm12, bool carry_in, bool& carry_out) - { - if ((imm12 & 0xc00) >> 10) - { - u32 unrotated_value = (imm12 & 0x7f) | 0x80; - - return ROR_C(unrotated_value, (imm12 & 0xf80) >> 7, carry_out); - } - else - { - carry_out = carry_in; - - u32 imm8 = imm12 & 0xff; - switch ((imm12 & 0x300) >> 8) - { - case 0: return imm8; - case 1: return imm8 << 16 | imm8; - case 2: return imm8 << 24 | imm8 << 8; - default: return imm8 << 24 | imm8 << 16 | imm8 << 8 | imm8; - } - } - } - - u32 ThumbExpandImm(u32 imm12) - { - bool carry = CPU.APSR.C; - return ThumbExpandImm_C(imm12, carry, carry); - } - - bool ConditionPassed(u32 cond) const - { - bool result = false; - - switch(cond >> 1) - { - case 0: result = CPU.APSR.Z == 1; break; - case 1: result = CPU.APSR.C == 1; break; - case 2: result = CPU.APSR.N == 1; break; - case 3: result = CPU.APSR.V == 1; break; - case 4: result = CPU.APSR.C == 1 && CPU.APSR.Z == 0; break; - case 5: result = CPU.APSR.N == CPU.APSR.V; break; - case 6: result = CPU.APSR.N == CPU.APSR.V && CPU.APSR.Z == 0; break; - case 7: return true; - } - - if(cond & 0x1) - { - return !result; - } - - return result; - } - -protected: - virtual void UNK(const u32 data); - - 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); - - virtual void ADD_IMM(const u32 data, const ARMv7_encoding type); - virtual void ADD_REG(const u32 data, const ARMv7_encoding type); - virtual void ADD_RSR(const u32 data, const ARMv7_encoding type); - virtual void ADD_SPI(const u32 data, const ARMv7_encoding type); - virtual void ADD_SPR(const u32 data, const ARMv7_encoding type); - - virtual void ADR(const u32 data, const ARMv7_encoding type); - - virtual void AND_IMM(const u32 data, const ARMv7_encoding type); - virtual void AND_REG(const u32 data, const ARMv7_encoding type); - virtual void AND_RSR(const u32 data, const ARMv7_encoding type); - - virtual void ASR_IMM(const u32 data, const ARMv7_encoding type); - virtual void ASR_REG(const u32 data, const ARMv7_encoding type); - - virtual void B(const u32 data, const ARMv7_encoding type); - - virtual void BFC(const u32 data, const ARMv7_encoding type); - virtual void BFI(const u32 data, const ARMv7_encoding type); - - virtual void BIC_IMM(const u32 data, const ARMv7_encoding type); - virtual void BIC_REG(const u32 data, const ARMv7_encoding type); - virtual void BIC_RSR(const u32 data, const ARMv7_encoding type); - - virtual void BKPT(const u32 data, const ARMv7_encoding type); - - virtual void BL(const u32 data, const ARMv7_encoding type); - virtual void BLX(const u32 data, const ARMv7_encoding type); - virtual void BX(const u32 data, const ARMv7_encoding type); - - virtual void CB_Z(const u32 data, const ARMv7_encoding type); - - virtual void CLZ(const u32 data, const ARMv7_encoding type); + s8 CountLeadingZeroBits(T x, u8 len = sizeof(T) * 8); - virtual void CMN_IMM(const u32 data, const ARMv7_encoding type); - virtual void CMN_REG(const u32 data, const ARMv7_encoding type); - virtual void CMN_RSR(const u32 data, const ARMv7_encoding type); + SRType DecodeImmShift(u32 type, u32 imm5, u32* shift_n); + SRType DecodeRegShift(u8 type); - virtual void CMP_IMM(const u32 data, const ARMv7_encoding type); - virtual void CMP_REG(const u32 data, const ARMv7_encoding type); - virtual void CMP_RSR(const u32 data, const ARMv7_encoding type); + u32 LSL_C(u32 x, s32 shift, bool& carry_out); + u32 LSL(u32 x, s32 shift); + u32 LSR_C(u32 x, s32 shift, bool& carry_out); + u32 LSR(u32 x, s32 shift); - virtual void EOR_IMM(const u32 data, const ARMv7_encoding type); - virtual void EOR_REG(const u32 data, const ARMv7_encoding type); - virtual void EOR_RSR(const u32 data, const ARMv7_encoding type); + s32 ASR_C(s32 x, s32 shift, bool& carry_out); + s32 ASR(s32 x, s32 shift); - virtual void IT(const u32 data, const ARMv7_encoding type); + u32 ROR_C(u32 x, s32 shift, bool& carry_out); + u32 ROR(u32 x, s32 shift); - virtual void LDM(const u32 data, const ARMv7_encoding type); - virtual void LDMDA(const u32 data, const ARMv7_encoding type); - virtual void LDMDB(const u32 data, const ARMv7_encoding type); - virtual void LDMIB(const u32 data, const ARMv7_encoding type); + u32 RRX_C(u32 x, bool carry_in, bool& carry_out); + u32 RRX(u32 x, bool carry_in); - virtual void LDR_IMM(const u32 data, const ARMv7_encoding type); - virtual void LDR_LIT(const u32 data, const ARMv7_encoding type); - virtual void LDR_REG(const u32 data, const ARMv7_encoding type); + template T Shift_C(T value, SRType type, s32 amount, bool carry_in, bool& carry_out); - virtual void LDRB_IMM(const u32 data, const ARMv7_encoding type); - virtual void LDRB_LIT(const u32 data, const ARMv7_encoding type); - virtual void LDRB_REG(const u32 data, const ARMv7_encoding type); + template T Shift(T value, SRType type, s32 amount, bool carry_in); - virtual void LDRD_IMM(const u32 data, const ARMv7_encoding type); - virtual void LDRD_LIT(const u32 data, const ARMv7_encoding type); - virtual void LDRD_REG(const u32 data, const ARMv7_encoding type); + template T AddWithCarry(T x, T y, bool carry_in, bool& carry_out, bool& overflow); - virtual void LDRH_IMM(const u32 data, const ARMv7_encoding type); - virtual void LDRH_LIT(const u32 data, const ARMv7_encoding type); - virtual void LDRH_REG(const u32 data, const ARMv7_encoding type); + u32 ThumbExpandImm_C(u32 imm12, bool carry_in, bool& carry_out); + u32 ThumbExpandImm(ARMv7Thread* CPU, u32 imm12); - virtual void LDRSB_IMM(const u32 data, const ARMv7_encoding type); - virtual void LDRSB_LIT(const u32 data, const ARMv7_encoding type); - virtual void LDRSB_REG(const u32 data, const ARMv7_encoding type); + bool ConditionPassed(ARMv7Thread* CPU, u32 cond); - virtual void LDRSH_IMM(const u32 data, const ARMv7_encoding type); - virtual void LDRSH_LIT(const u32 data, const ARMv7_encoding type); - virtual void LDRSH_REG(const u32 data, const ARMv7_encoding type); + // instructions + void UNK(ARMv7Thread* thr); - virtual void LSL_IMM(const u32 data, const ARMv7_encoding type); - virtual void LSL_REG(const u32 data, const ARMv7_encoding type); + void NULL_OP(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void LSR_IMM(const u32 data, const ARMv7_encoding type); - virtual void LSR_REG(const u32 data, const ARMv7_encoding type); + void HACK(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void MLA(const u32 data, const ARMv7_encoding type); - virtual void MLS(const u32 data, const ARMv7_encoding type); + void ADC_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void ADC_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void ADC_RSR(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void MOV_IMM(const u32 data, const ARMv7_encoding type); - virtual void MOV_REG(const u32 data, const ARMv7_encoding type); - virtual void MOVT(const u32 data, const ARMv7_encoding type); + void ADD_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void ADD_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void ADD_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + void ADD_SPI(ARMv7Thread* thr, const ARMv7_encoding type); + void ADD_SPR(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void MRS(const u32 data, const ARMv7_encoding type); - virtual void MSR_IMM(const u32 data, const ARMv7_encoding type); - virtual void MSR_REG(const u32 data, const ARMv7_encoding type); + void ADR(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void MUL(const u32 data, const ARMv7_encoding type); + void AND_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void AND_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void AND_RSR(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void MVN_IMM(const u32 data, const ARMv7_encoding type); - virtual void MVN_REG(const u32 data, const ARMv7_encoding type); - virtual void MVN_RSR(const u32 data, const ARMv7_encoding type); + void ASR_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void ASR_REG(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void NOP(const u32 data, const ARMv7_encoding type); + void B(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void ORN_IMM(const u32 data, const ARMv7_encoding type); - virtual void ORN_REG(const u32 data, const ARMv7_encoding type); + void BFC(ARMv7Thread* thr, const ARMv7_encoding type); + void BFI(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void ORR_IMM(const u32 data, const ARMv7_encoding type); - virtual void ORR_REG(const u32 data, const ARMv7_encoding type); - virtual void ORR_RSR(const u32 data, const ARMv7_encoding type); + void BIC_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void BIC_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void BIC_RSR(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void PKH(const u32 data, const ARMv7_encoding type); + void BKPT(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void POP(const u32 data, const ARMv7_encoding type); - virtual void PUSH(const u32 data, const ARMv7_encoding type); + void BL(ARMv7Thread* thr, const ARMv7_encoding type); + void BLX(ARMv7Thread* thr, const ARMv7_encoding type); + void BX(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void QADD(const u32 data, const ARMv7_encoding type); - virtual void QADD16(const u32 data, const ARMv7_encoding type); - virtual void QADD8(const u32 data, const ARMv7_encoding type); - virtual void QASX(const u32 data, const ARMv7_encoding type); - virtual void QDADD(const u32 data, const ARMv7_encoding type); - virtual void QDSUB(const u32 data, const ARMv7_encoding type); - virtual void QSAX(const u32 data, const ARMv7_encoding type); - virtual void QSUB(const u32 data, const ARMv7_encoding type); - virtual void QSUB16(const u32 data, const ARMv7_encoding type); - virtual void QSUB8(const u32 data, const ARMv7_encoding type); + void CB_Z(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void RBIT(const u32 data, const ARMv7_encoding type); - virtual void REV(const u32 data, const ARMv7_encoding type); - virtual void REV16(const u32 data, const ARMv7_encoding type); - virtual void REVSH(const u32 data, const ARMv7_encoding type); + void CLZ(ARMv7Thread* thr, const ARMv7_encoding type); - virtual void ROR_IMM(const u32 data, const ARMv7_encoding type); - virtual void ROR_REG(const u32 data, const ARMv7_encoding type); - - virtual void RRX(const u32 data, const ARMv7_encoding type); - - virtual void RSB_IMM(const u32 data, const ARMv7_encoding type); - virtual void RSB_REG(const u32 data, const ARMv7_encoding type); - virtual void RSB_RSR(const u32 data, const ARMv7_encoding type); - - virtual void RSC_IMM(const u32 data, const ARMv7_encoding type); - virtual void RSC_REG(const u32 data, const ARMv7_encoding type); - virtual void RSC_RSR(const u32 data, const ARMv7_encoding type); - - virtual void SADD16(const u32 data, const ARMv7_encoding type); - virtual void SADD8(const u32 data, const ARMv7_encoding type); - virtual void SASX(const u32 data, const ARMv7_encoding type); - - virtual void SBC_IMM(const u32 data, const ARMv7_encoding type); - virtual void SBC_REG(const u32 data, const ARMv7_encoding type); - virtual void SBC_RSR(const u32 data, const ARMv7_encoding type); - - virtual void SBFX(const u32 data, const ARMv7_encoding type); - - virtual void SDIV(const u32 data, const ARMv7_encoding type); - - virtual void SEL(const u32 data, const ARMv7_encoding type); - - virtual void SHADD16(const u32 data, const ARMv7_encoding type); - virtual void SHADD8(const u32 data, const ARMv7_encoding type); - virtual void SHASX(const u32 data, const ARMv7_encoding type); - virtual void SHSAX(const u32 data, const ARMv7_encoding type); - virtual void SHSUB16(const u32 data, const ARMv7_encoding type); - virtual void SHSUB8(const u32 data, const ARMv7_encoding type); - - virtual void SMLA__(const u32 data, const ARMv7_encoding type); - virtual void SMLAD(const u32 data, const ARMv7_encoding type); - virtual void SMLAL(const u32 data, const ARMv7_encoding type); - virtual void SMLAL__(const u32 data, const ARMv7_encoding type); - virtual void SMLALD(const u32 data, const ARMv7_encoding type); - virtual void SMLAW_(const u32 data, const ARMv7_encoding type); - virtual void SMLSD(const u32 data, const ARMv7_encoding type); - virtual void SMLSLD(const u32 data, const ARMv7_encoding type); - virtual void SMMLA(const u32 data, const ARMv7_encoding type); - virtual void SMMLS(const u32 data, const ARMv7_encoding type); - virtual void SMMUL(const u32 data, const ARMv7_encoding type); - virtual void SMUAD(const u32 data, const ARMv7_encoding type); - virtual void SMUL__(const u32 data, const ARMv7_encoding type); - virtual void SMULL(const u32 data, const ARMv7_encoding type); - virtual void SMULW_(const u32 data, const ARMv7_encoding type); - virtual void SMUSD(const u32 data, const ARMv7_encoding type); - - virtual void SSAT(const u32 data, const ARMv7_encoding type); - virtual void SSAT16(const u32 data, const ARMv7_encoding type); - virtual void SSAX(const u32 data, const ARMv7_encoding type); - virtual void SSUB16(const u32 data, const ARMv7_encoding type); - virtual void SSUB8(const u32 data, const ARMv7_encoding type); - - virtual void STM(const u32 data, const ARMv7_encoding type); - virtual void STMDA(const u32 data, const ARMv7_encoding type); - virtual void STMDB(const u32 data, const ARMv7_encoding type); - virtual void STMIB(const u32 data, const ARMv7_encoding type); - - virtual void STR_IMM(const u32 data, const ARMv7_encoding type); - virtual void STR_REG(const u32 data, const ARMv7_encoding type); - - virtual void STRB_IMM(const u32 data, const ARMv7_encoding type); - virtual void STRB_REG(const u32 data, const ARMv7_encoding type); - - virtual void STRD_IMM(const u32 data, const ARMv7_encoding type); - virtual void STRD_REG(const u32 data, const ARMv7_encoding type); - - virtual void STRH_IMM(const u32 data, const ARMv7_encoding type); - virtual void STRH_REG(const u32 data, const ARMv7_encoding type); - - virtual void SUB_IMM(const u32 data, const ARMv7_encoding type); - virtual void SUB_REG(const u32 data, const ARMv7_encoding type); - virtual void SUB_RSR(const u32 data, const ARMv7_encoding type); - virtual void SUB_SPI(const u32 data, const ARMv7_encoding type); - virtual void SUB_SPR(const u32 data, const ARMv7_encoding type); - - virtual void SVC(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); - virtual void SXTB(const u32 data, const ARMv7_encoding type); - virtual void SXTB16(const u32 data, const ARMv7_encoding type); - virtual void SXTH(const u32 data, const ARMv7_encoding type); - - virtual void TB_(const u32 data, const ARMv7_encoding type); - - virtual void TEQ_IMM(const u32 data, const ARMv7_encoding type); - virtual void TEQ_REG(const u32 data, const ARMv7_encoding type); - virtual void TEQ_RSR(const u32 data, const ARMv7_encoding type); - - virtual void TST_IMM(const u32 data, const ARMv7_encoding type); - virtual void TST_REG(const u32 data, const ARMv7_encoding type); - virtual void TST_RSR(const u32 data, const ARMv7_encoding type); - - virtual void UADD16(const u32 data, const ARMv7_encoding type); - virtual void UADD8(const u32 data, const ARMv7_encoding type); - virtual void UASX(const u32 data, const ARMv7_encoding type); - virtual void UBFX(const u32 data, const ARMv7_encoding type); - virtual void UDIV(const u32 data, const ARMv7_encoding type); - virtual void UHADD16(const u32 data, const ARMv7_encoding type); - virtual void UHADD8(const u32 data, const ARMv7_encoding type); - virtual void UHASX(const u32 data, const ARMv7_encoding type); - virtual void UHSAX(const u32 data, const ARMv7_encoding type); - virtual void UHSUB16(const u32 data, const ARMv7_encoding type); - virtual void UHSUB8(const u32 data, const ARMv7_encoding type); - virtual void UMAAL(const u32 data, const ARMv7_encoding type); - virtual void UMLAL(const u32 data, const ARMv7_encoding type); - virtual void UMULL(const u32 data, const ARMv7_encoding type); - virtual void UQADD16(const u32 data, const ARMv7_encoding type); - virtual void UQADD8(const u32 data, const ARMv7_encoding type); - virtual void UQASX(const u32 data, const ARMv7_encoding type); - virtual void UQSAX(const u32 data, const ARMv7_encoding type); - virtual void UQSUB16(const u32 data, const ARMv7_encoding type); - virtual void UQSUB8(const u32 data, const ARMv7_encoding type); - virtual void USAD8(const u32 data, const ARMv7_encoding type); - virtual void USADA8(const u32 data, const ARMv7_encoding type); - virtual void USAT(const u32 data, const ARMv7_encoding type); - virtual void USAT16(const u32 data, const ARMv7_encoding type); - virtual void USAX(const u32 data, const ARMv7_encoding type); - virtual void USUB16(const u32 data, const ARMv7_encoding type); - virtual void USUB8(const u32 data, const ARMv7_encoding type); - virtual void UXTAB(const u32 data, const ARMv7_encoding type); - virtual void UXTAB16(const u32 data, const ARMv7_encoding type); - virtual void UXTAH(const u32 data, const ARMv7_encoding type); - virtual void UXTB(const u32 data, const ARMv7_encoding type); - virtual void UXTB16(const u32 data, const ARMv7_encoding type); - virtual void UXTH(const u32 data, const ARMv7_encoding type); + void CMN_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void CMN_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void CMN_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void CMP_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void CMP_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void CMP_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void EOR_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void EOR_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void EOR_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void IT(ARMv7Thread* thr, const ARMv7_encoding type); + + void LDM(ARMv7Thread* thr, const ARMv7_encoding type); + void LDMDA(ARMv7Thread* thr, const ARMv7_encoding type); + void LDMDB(ARMv7Thread* thr, const ARMv7_encoding type); + void LDMIB(ARMv7Thread* thr, const ARMv7_encoding type); + + void LDR_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void LDR_LIT(ARMv7Thread* thr, const ARMv7_encoding type); + void LDR_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void LDRB_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRB_LIT(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRB_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void LDRD_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRD_LIT(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRD_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void LDRH_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRH_LIT(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRH_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void LDRSB_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRSB_LIT(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRSB_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void LDRSH_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRSH_LIT(ARMv7Thread* thr, const ARMv7_encoding type); + void LDRSH_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void LSL_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void LSL_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void LSR_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void LSR_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void MLA(ARMv7Thread* thr, const ARMv7_encoding type); + void MLS(ARMv7Thread* thr, const ARMv7_encoding type); + + void MOV_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void MOV_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void MOVT(ARMv7Thread* thr, const ARMv7_encoding type); + + void MRS(ARMv7Thread* thr, const ARMv7_encoding type); + void MSR_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void MSR_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void MUL(ARMv7Thread* thr, const ARMv7_encoding type); + + void MVN_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void MVN_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void MVN_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void NOP(ARMv7Thread* thr, const ARMv7_encoding type); + + void ORN_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void ORN_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void ORR_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void ORR_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void ORR_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void PKH(ARMv7Thread* thr, const ARMv7_encoding type); + + void POP(ARMv7Thread* thr, const ARMv7_encoding type); + void PUSH(ARMv7Thread* thr, const ARMv7_encoding type); + + void QADD(ARMv7Thread* thr, const ARMv7_encoding type); + void QADD16(ARMv7Thread* thr, const ARMv7_encoding type); + void QADD8(ARMv7Thread* thr, const ARMv7_encoding type); + void QASX(ARMv7Thread* thr, const ARMv7_encoding type); + void QDADD(ARMv7Thread* thr, const ARMv7_encoding type); + void QDSUB(ARMv7Thread* thr, const ARMv7_encoding type); + void QSAX(ARMv7Thread* thr, const ARMv7_encoding type); + void QSUB(ARMv7Thread* thr, const ARMv7_encoding type); + void QSUB16(ARMv7Thread* thr, const ARMv7_encoding type); + void QSUB8(ARMv7Thread* thr, const ARMv7_encoding type); + + void RBIT(ARMv7Thread* thr, const ARMv7_encoding type); + void REV(ARMv7Thread* thr, const ARMv7_encoding type); + void REV16(ARMv7Thread* thr, const ARMv7_encoding type); + void REVSH(ARMv7Thread* thr, const ARMv7_encoding type); + + void ROR_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void ROR_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void RRX(ARMv7Thread* thr, const ARMv7_encoding type); + + void RSB_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void RSB_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void RSB_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void RSC_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void RSC_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void RSC_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void SADD16(ARMv7Thread* thr, const ARMv7_encoding type); + void SADD8(ARMv7Thread* thr, const ARMv7_encoding type); + void SASX(ARMv7Thread* thr, const ARMv7_encoding type); + + void SBC_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void SBC_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void SBC_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void SBFX(ARMv7Thread* thr, const ARMv7_encoding type); + + void SDIV(ARMv7Thread* thr, const ARMv7_encoding type); + + void SEL(ARMv7Thread* thr, const ARMv7_encoding type); + + void SHADD16(ARMv7Thread* thr, const ARMv7_encoding type); + void SHADD8(ARMv7Thread* thr, const ARMv7_encoding type); + void SHASX(ARMv7Thread* thr, const ARMv7_encoding type); + void SHSAX(ARMv7Thread* thr, const ARMv7_encoding type); + void SHSUB16(ARMv7Thread* thr, const ARMv7_encoding type); + void SHSUB8(ARMv7Thread* thr, const ARMv7_encoding type); + + void SMLA__(ARMv7Thread* thr, const ARMv7_encoding type); + void SMLAD(ARMv7Thread* thr, const ARMv7_encoding type); + void SMLAL(ARMv7Thread* thr, const ARMv7_encoding type); + void SMLAL__(ARMv7Thread* thr, const ARMv7_encoding type); + void SMLALD(ARMv7Thread* thr, const ARMv7_encoding type); + void SMLAW_(ARMv7Thread* thr, const ARMv7_encoding type); + void SMLSD(ARMv7Thread* thr, const ARMv7_encoding type); + void SMLSLD(ARMv7Thread* thr, const ARMv7_encoding type); + void SMMLA(ARMv7Thread* thr, const ARMv7_encoding type); + void SMMLS(ARMv7Thread* thr, const ARMv7_encoding type); + void SMMUL(ARMv7Thread* thr, const ARMv7_encoding type); + void SMUAD(ARMv7Thread* thr, const ARMv7_encoding type); + void SMUL__(ARMv7Thread* thr, const ARMv7_encoding type); + void SMULL(ARMv7Thread* thr, const ARMv7_encoding type); + void SMULW_(ARMv7Thread* thr, const ARMv7_encoding type); + void SMUSD(ARMv7Thread* thr, const ARMv7_encoding type); + + void SSAT(ARMv7Thread* thr, const ARMv7_encoding type); + void SSAT16(ARMv7Thread* thr, const ARMv7_encoding type); + void SSAX(ARMv7Thread* thr, const ARMv7_encoding type); + void SSUB16(ARMv7Thread* thr, const ARMv7_encoding type); + void SSUB8(ARMv7Thread* thr, const ARMv7_encoding type); + + void STM(ARMv7Thread* thr, const ARMv7_encoding type); + void STMDA(ARMv7Thread* thr, const ARMv7_encoding type); + void STMDB(ARMv7Thread* thr, const ARMv7_encoding type); + void STMIB(ARMv7Thread* thr, const ARMv7_encoding type); + + void STR_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void STR_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void STRB_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void STRB_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void STRD_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void STRD_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void STRH_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void STRH_REG(ARMv7Thread* thr, const ARMv7_encoding type); + + void SUB_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void SUB_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void SUB_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + void SUB_SPI(ARMv7Thread* thr, const ARMv7_encoding type); + void SUB_SPR(ARMv7Thread* thr, const ARMv7_encoding type); + + void SVC(ARMv7Thread* thr, const ARMv7_encoding type); + + void SXTAB(ARMv7Thread* thr, const ARMv7_encoding type); + void SXTAB16(ARMv7Thread* thr, const ARMv7_encoding type); + void SXTAH(ARMv7Thread* thr, const ARMv7_encoding type); + void SXTB(ARMv7Thread* thr, const ARMv7_encoding type); + void SXTB16(ARMv7Thread* thr, const ARMv7_encoding type); + void SXTH(ARMv7Thread* thr, const ARMv7_encoding type); + + void TB_(ARMv7Thread* thr, const ARMv7_encoding type); + + void TEQ_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void TEQ_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void TEQ_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void TST_IMM(ARMv7Thread* thr, const ARMv7_encoding type); + void TST_REG(ARMv7Thread* thr, const ARMv7_encoding type); + void TST_RSR(ARMv7Thread* thr, const ARMv7_encoding type); + + void UADD16(ARMv7Thread* thr, const ARMv7_encoding type); + void UADD8(ARMv7Thread* thr, const ARMv7_encoding type); + void UASX(ARMv7Thread* thr, const ARMv7_encoding type); + void UBFX(ARMv7Thread* thr, const ARMv7_encoding type); + void UDIV(ARMv7Thread* thr, const ARMv7_encoding type); + void UHADD16(ARMv7Thread* thr, const ARMv7_encoding type); + void UHADD8(ARMv7Thread* thr, const ARMv7_encoding type); + void UHASX(ARMv7Thread* thr, const ARMv7_encoding type); + void UHSAX(ARMv7Thread* thr, const ARMv7_encoding type); + void UHSUB16(ARMv7Thread* thr, const ARMv7_encoding type); + void UHSUB8(ARMv7Thread* thr, const ARMv7_encoding type); + void UMAAL(ARMv7Thread* thr, const ARMv7_encoding type); + void UMLAL(ARMv7Thread* thr, const ARMv7_encoding type); + void UMULL(ARMv7Thread* thr, const ARMv7_encoding type); + void UQADD16(ARMv7Thread* thr, const ARMv7_encoding type); + void UQADD8(ARMv7Thread* thr, const ARMv7_encoding type); + void UQASX(ARMv7Thread* thr, const ARMv7_encoding type); + void UQSAX(ARMv7Thread* thr, const ARMv7_encoding type); + void UQSUB16(ARMv7Thread* thr, const ARMv7_encoding type); + void UQSUB8(ARMv7Thread* thr, const ARMv7_encoding type); + void USAD8(ARMv7Thread* thr, const ARMv7_encoding type); + void USADA8(ARMv7Thread* thr, const ARMv7_encoding type); + void USAT(ARMv7Thread* thr, const ARMv7_encoding type); + void USAT16(ARMv7Thread* thr, const ARMv7_encoding type); + void USAX(ARMv7Thread* thr, const ARMv7_encoding type); + void USUB16(ARMv7Thread* thr, const ARMv7_encoding type); + void USUB8(ARMv7Thread* thr, const ARMv7_encoding type); + void UXTAB(ARMv7Thread* thr, const ARMv7_encoding type); + void UXTAB16(ARMv7Thread* thr, const ARMv7_encoding type); + void UXTAH(ARMv7Thread* thr, const ARMv7_encoding type); + void UXTB(ARMv7Thread* thr, const ARMv7_encoding type); + void UXTB16(ARMv7Thread* thr, const ARMv7_encoding type); + void UXTH(ARMv7Thread* thr, const ARMv7_encoding type); }; + + +// old instructions table for debugging and information, delete this later +using namespace ARMv7_instrs; + +struct ARMv7_opcode_t +{ + u32 mask; + u32 code; + u32 length; // 2 or 4 + const char* name; + ARMv7_encoding type; + void(*func)(ARMv7Thread* thr, const ARMv7_encoding type); +}; + +// single 16-bit value +#define ARMv7_OP2(mask, code, type, name) { (u32)((mask) << 16), (u32)((code) << 16), 2, #name "_" #type, type, name } +// two 16-bit values +#define ARMv7_OP4(mask0, mask1, code0, code1, type, name) { (u32)((mask0) << 16) | (mask1), (u32)((code0) << 16) | (code1), 4, #name "_" #type, type, name } + +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), + ARMv7_OP4(0xffe0, 0x8000, 0xeb40, 0x0000, T2, ADC_REG), + ARMv7_OP4(0x0fe0, 0x0010, 0x00a0, 0x0000, A1, ADC_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x00a0, 0x0010, A1, ADC_RSR), + + ARMv7_OP2(0xf800, 0xa800, T1, ADD_SPI), + ARMv7_OP2(0xff80, 0xb000, T2, ADD_SPI), + ARMv7_OP4(0xfbef, 0x8000, 0xf10d, 0x0000, T3, ADD_SPI), + ARMv7_OP4(0xfbff, 0x8000, 0xf20d, 0x0000, T4, ADD_SPI), + ARMv7_OP4(0x0fef, 0x0000, 0x028d, 0x0000, A1, ADD_SPI), + ARMv7_OP2(0xff78, 0x4468, T1, ADD_SPR), + ARMv7_OP2(0xff87, 0x4485, T2, ADD_SPR), + ARMv7_OP4(0xffef, 0x8000, 0xeb0d, 0x0000, T3, ADD_SPR), + ARMv7_OP4(0x0fef, 0x0010, 0x008d, 0x0000, A1, ADD_SPR), + ARMv7_OP2(0xfe00, 0x1c00, T1, ADD_IMM), + ARMv7_OP2(0xf800, 0x3000, T2, ADD_IMM), + ARMv7_OP4(0xfbe0, 0x8000, 0xf100, 0x0000, T3, ADD_IMM), + ARMv7_OP4(0xfbf0, 0x8000, 0xf200, 0x0000, T4, ADD_IMM), + ARMv7_OP4(0x0fe0, 0x0000, 0x0280, 0x0000, A1, ADD_IMM), + ARMv7_OP2(0xfe00, 0x1800, T1, ADD_REG), + ARMv7_OP2(0xff00, 0x4400, T2, ADD_REG), + ARMv7_OP4(0xffe0, 0x8000, 0xeb00, 0x0000, T3, ADD_REG), + ARMv7_OP4(0x0fe0, 0x0010, 0x0080, 0x0000, A1, ADD_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x0080, 0x0010, A1, ADD_RSR), + + ARMv7_OP2(0xf800, 0xa000, T1, ADR), + ARMv7_OP4(0xfbff, 0x8000, 0xf2af, 0x0000, T2, ADR), + ARMv7_OP4(0xfbff, 0x8000, 0xf20f, 0x0000, T3, ADR), + ARMv7_OP4(0x0fff, 0x0000, 0x028f, 0x0000, A1, ADR), + ARMv7_OP4(0x0fff, 0x0000, 0x024f, 0x0000, A2, ADR), + + ARMv7_OP4(0xfbe0, 0x8000, 0xf000, 0x0000, T1, AND_IMM), + ARMv7_OP4(0x0fe0, 0x0000, 0x0200, 0x0000, A1, AND_IMM), + ARMv7_OP2(0xffc0, 0x4000, T1, AND_REG), + ARMv7_OP4(0xffe0, 0x8000, 0xea00, 0x0000, T2, AND_REG), + ARMv7_OP4(0x0fe0, 0x0010, 0x0000, 0x0000, A1, AND_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x0000, 0x0010, A1, AND_RSR), + + ARMv7_OP2(0xf800, 0x1000, T1, ASR_IMM), + ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0020, T2, ASR_IMM), + ARMv7_OP4(0x0fef, 0x0070, 0x01a0, 0x0040, A1, ASR_IMM), + ARMv7_OP2(0xffc0, 0x4100, T1, ASR_REG), + ARMv7_OP4(0xffe0, 0xf0f0, 0xfa40, 0xf000, T2, ASR_REG), + ARMv7_OP4(0x0fef, 0x00f0, 0x01a0, 0x0050, A1, ASR_REG), + + 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_OP4(0xffff, 0x8020, 0xf36f, 0x0000, T1, BFC), + ARMv7_OP4(0x0fe0, 0x007f, 0x07c0, 0x001f, A1, BFC), + ARMv7_OP4(0xfff0, 0x8020, 0xf360, 0x0000, T1, BFI), + ARMv7_OP4(0x0fe0, 0x0070, 0x07c0, 0x0010, A1, BFI), + + ARMv7_OP4(0xfbe0, 0x8000, 0xf020, 0x0000, T1, BIC_IMM), + ARMv7_OP4(0x0fe0, 0x0000, 0x03c0, 0x0000, A1, BIC_IMM), + ARMv7_OP2(0xffc0, 0x4380, T1, BIC_REG), + ARMv7_OP4(0xffe0, 0x8000, 0xea20, 0x0000, T2, BIC_REG), + ARMv7_OP4(0x0fe0, 0x0010, 0x01c0, 0x0000, A1, BIC_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x01c0, 0x0010, A1, BIC_RSR), + + ARMv7_OP2(0xff00, 0xbe00, T1, BKPT), + ARMv7_OP4(0x0ff0, 0x00f0, 0x0120, 0x0070, A1, BKPT), + + 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(0xff87, 0x4700, T1, BX), + ARMv7_OP4(0x0fff, 0xfff0, 0x012f, 0xff10, A1, BX), + + ARMv7_OP2(0xf500, 0xb100, T1, CB_Z), + + ARMv7_OP4(0xfff0, 0xf0f0, 0xfab0, 0xf080, T1, CLZ), + ARMv7_OP4(0x0fff, 0x0ff0, 0x016f, 0x0f10, A1, CLZ), + + ARMv7_OP4(0xfbf0, 0x8f00, 0xf110, 0x0f00, T1, CMN_IMM), + ARMv7_OP4(0x0ff0, 0xf000, 0x0370, 0x0000, A1, CMN_IMM), + ARMv7_OP2(0xffc0, 0x42c0, T1, CMN_REG), + ARMv7_OP4(0xfff0, 0x8f00, 0xeb10, 0x0f00, T2, CMN_REG), + ARMv7_OP4(0x0ff0, 0xf010, 0x0170, 0x0000, A1, CMN_REG), + ARMv7_OP4(0x0ff0, 0xf090, 0x0170, 0x0010, A1, CMN_RSR), + + ARMv7_OP2(0xf800, 0x2800, T1, CMP_IMM), + ARMv7_OP4(0xfbf0, 0x8f00, 0xf1b0, 0x0f00, T2, CMP_IMM), + ARMv7_OP4(0x0ff0, 0xf000, 0x0350, 0x0000, A1, CMP_IMM), + ARMv7_OP2(0xffc0, 0x4280, T1, CMP_REG), + ARMv7_OP2(0xff00, 0x4500, T2, CMP_REG), + ARMv7_OP4(0xfff0, 0x8f00, 0xebb0, 0x0f00, T3, CMP_REG), + ARMv7_OP4(0x0ff0, 0xf010, 0x0150, 0x0000, A1, CMP_REG), + ARMv7_OP4(0x0ff0, 0xf090, 0x0150, 0x0010, A1, CMP_RSR), + + ARMv7_OP4(0xfbe0, 0x8000, 0xf080, 0x0000, T1, EOR_IMM), + ARMv7_OP4(0x0fe0, 0x0000, 0x0220, 0x0000, A1, EOR_IMM), + ARMv7_OP2(0xffc0, 0x4040, T1, EOR_REG), + ARMv7_OP4(0xffe0, 0x8000, 0xea80, 0x0000, T2, EOR_REG), + ARMv7_OP4(0x0fe0, 0x0010, 0x0020, 0x0000, A1, EOR_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x0020, 0x0010, A1, EOR_RSR), + + ARMv7_OP2(0xff00, 0xbf00, T1, IT), + + ARMv7_OP2(0xf800, 0xc800, T1, LDM), + ARMv7_OP4(0xffd0, 0x2000, 0xe890, 0x0000, T2, LDM), + ARMv7_OP4(0x0fd0, 0x0000, 0x0890, 0x0000, A1, LDM), + ARMv7_OP4(0x0fd0, 0x0000, 0x0810, 0x0000, A1, LDMDA), + ARMv7_OP4(0xffd0, 0x2000, 0xe910, 0x0000, T1, LDMDB), + ARMv7_OP4(0x0fd0, 0x0000, 0x0910, 0x0000, A1, LDMDB), + ARMv7_OP4(0x0fd0, 0x0000, 0x0990, 0x0000, A1, LDMIB), + + ARMv7_OP2(0xf800, 0x6800, T1, LDR_IMM), + ARMv7_OP2(0xf800, 0x9800, T2, LDR_IMM), + ARMv7_OP4(0xfff0, 0x0000, 0xf8d0, 0x0000, T3, LDR_IMM), + ARMv7_OP4(0xfff0, 0x0800, 0xf850, 0x0800, T4, LDR_IMM), + ARMv7_OP4(0x0e50, 0x0000, 0x0410, 0x0000, A1, LDR_IMM), + ARMv7_OP2(0xf800, 0x4800, T1, LDR_LIT), + ARMv7_OP4(0xff7f, 0x0000, 0xf85f, 0x0000, T2, LDR_LIT), + ARMv7_OP4(0x0f7f, 0x0000, 0x051f, 0x0000, A1, LDR_LIT), + ARMv7_OP2(0xfe00, 0x5800, T1, LDR_REG), + ARMv7_OP4(0xfff0, 0x0fc0, 0xf850, 0x0000, T2, LDR_REG), + ARMv7_OP4(0x0e50, 0x0010, 0x0610, 0x0000, A1, LDR_REG), + + ARMv7_OP2(0xf800, 0x7800, T1, LDRB_IMM), + ARMv7_OP4(0xfff0, 0x0000, 0xf890, 0x0000, T2, LDRB_IMM), + ARMv7_OP4(0xfff0, 0x0800, 0xf810, 0x0800, T3, LDRB_IMM), + ARMv7_OP4(0x0e50, 0x0000, 0x0450, 0x0000, A1, LDRB_IMM), + ARMv7_OP4(0xff7f, 0x0000, 0xf81f, 0x0000, T1, LDRB_LIT), + ARMv7_OP4(0x0f7f, 0x0000, 0x055f, 0x0000, A1, LDRB_LIT), + ARMv7_OP2(0xfe00, 0x5c00, T1, LDRB_REG), + ARMv7_OP4(0xfff0, 0x0fc0, 0xf810, 0x0000, T2, LDRB_REG), + ARMv7_OP4(0x0e50, 0x0010, 0x0650, 0x0000, A1, LDRB_REG), + + ARMv7_OP4(0xfe50, 0x0000, 0xe850, 0x0000, T1, LDRD_IMM), + ARMv7_OP4(0x0e50, 0x00f0, 0x0040, 0x00d0, A1, LDRD_IMM), + ARMv7_OP4(0xfe7f, 0x0000, 0xe85f, 0x0000, T1, LDRD_LIT), + ARMv7_OP4(0x0f7f, 0x00f0, 0x014f, 0x00d0, A1, LDRD_LIT), + ARMv7_OP4(0x0e50, 0x0ff0, 0x0000, 0x00d0, A1, LDRD_REG), + + ARMv7_OP4(0xfff0, 0x0000, 0xf990, 0x0000, T1, LDRSB_IMM), + ARMv7_OP4(0xfff0, 0x0800, 0xf910, 0x0800, T2, LDRSB_IMM), + ARMv7_OP4(0x0e50, 0x00f0, 0x0050, 0x00d0, A1, LDRSB_IMM), + ARMv7_OP4(0xff7f, 0x0000, 0xf91f, 0x0000, T1, LDRSB_LIT), + ARMv7_OP4(0x0f7f, 0x00f0, 0x015f, 0x00d0, A1, LDRSB_LIT), + ARMv7_OP2(0xfe00, 0x5600, T1, LDRSB_REG), + ARMv7_OP4(0xfff0, 0x0fc0, 0xf910, 0x0000, T2, LDRSB_REG), + ARMv7_OP4(0x0e50, 0x0ff0, 0x0010, 0x00d0, A1, LDRSB_REG), + + ARMv7_OP4(0xfff0, 0x0000, 0xf9b0, 0x0000, T1, LDRSH_IMM), + ARMv7_OP4(0xfff0, 0x0800, 0xf930, 0x0800, T2, LDRSH_IMM), + ARMv7_OP4(0x0e50, 0x00f0, 0x0050, 0x00f0, A1, LDRSH_IMM), + ARMv7_OP4(0xff7f, 0x0000, 0xf93f, 0x0000, T1, LDRSH_LIT), + ARMv7_OP4(0x0f7f, 0x00f0, 0x015f, 0x00f0, A1, LDRSH_LIT), + ARMv7_OP2(0xfe00, 0x5e00, T1, LDRSH_REG), + ARMv7_OP4(0xfff0, 0x0fc0, 0xf930, 0x0000, T2, LDRSH_REG), + ARMv7_OP4(0x0e50, 0x0ff0, 0x0010, 0x00f0, A1, LDRSH_REG), + + ARMv7_OP2(0xf800, 0x0000, T1, LSL_IMM), + ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0000, T2, LSL_IMM), + ARMv7_OP4(0x0fef, 0x0070, 0x01a0, 0x0000, A1, LSL_IMM), + ARMv7_OP2(0xffc0, 0x4080, T1, LSL_REG), + ARMv7_OP4(0xffe0, 0xf0f0, 0xfa00, 0xf000, T2, LSL_REG), + ARMv7_OP4(0x0fef, 0x00f0, 0x01a0, 0x0010, A1, LSL_REG), + + ARMv7_OP2(0xf800, 0x0800, T1, LSR_IMM), + ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0010, T2, LSR_IMM), + ARMv7_OP4(0x0fef, 0x0030, 0x01a0, 0x0020, A1, LSR_IMM), + ARMv7_OP2(0xffc0, 0x40c0, T1, LSR_REG), + ARMv7_OP4(0xffe0, 0xf0f0, 0xfa20, 0xf000, T2, LSR_REG), + ARMv7_OP4(0x0fef, 0x00f0, 0x01a0, 0x0030, A1, LSR_REG), + + ARMv7_OP4(0xfff0, 0x00f0, 0xfb00, 0x0000, T1, MLA), + ARMv7_OP4(0x0fe0, 0x00f0, 0x0020, 0x0090, A1, MLA), + + ARMv7_OP4(0xfff0, 0x00f0, 0xfb00, 0x0010, T1, MLS), + ARMv7_OP4(0x0ff0, 0x00f0, 0x0060, 0x0090, A1, MLS), + + ARMv7_OP2(0xf800, 0x2000, T1, MOV_IMM), + ARMv7_OP4(0xfbef, 0x8000, 0xf04f, 0x0000, T2, MOV_IMM), + ARMv7_OP4(0xfbf0, 0x8000, 0xf240, 0x0000, T3, MOV_IMM), + ARMv7_OP4(0x0fef, 0x0000, 0x03a0, 0x0000, A1, MOV_IMM), + ARMv7_OP4(0x0ff0, 0x0000, 0x0300, 0x0000, A2, MOV_IMM), + ARMv7_OP2(0xff00, 0x4600, T1, MOV_REG), + ARMv7_OP2(0xffc0, 0x0000, T2, MOV_REG), + ARMv7_OP4(0xffef, 0xf0f0, 0xea4f, 0x0000, T3, MOV_REG), + ARMv7_OP4(0x0fef, 0x0ff0, 0x01a0, 0x0000, A1, MOV_REG), + ARMv7_OP4(0xfbf0, 0x8000, 0xf2c0, 0x0000, T1, MOVT), + ARMv7_OP4(0x0ff0, 0x0000, 0x0340, 0x0000, A1, MOVT), + + ARMv7_OP4(0xffff, 0xf0ff, 0xf3ef, 0x8000, T1, MRS), + ARMv7_OP4(0x0fff, 0x0fff, 0x010f, 0x0000, A1, MRS), + ARMv7_OP4(0x0ff3, 0xf000, 0x0320, 0xf000, A1, MSR_IMM), + ARMv7_OP4(0xfff0, 0xf3ff, 0xf380, 0x8000, T1, MSR_REG), + ARMv7_OP4(0x0ff3, 0xfff0, 0x0120, 0xf000, A1, MSR_REG), + + ARMv7_OP2(0xffc0, 0x4340, T1, MUL), + ARMv7_OP4(0xfff0, 0xf0f0, 0xfb00, 0xf000, T2, MUL), + ARMv7_OP4(0x0fe0, 0xf0f0, 0x0000, 0x0090, A1, MUL), + + ARMv7_OP4(0xfbef, 0x8000, 0xf06f, 0x0000, T1, MVN_IMM), + ARMv7_OP4(0x0fef, 0x0000, 0x03e0, 0x0000, A1, MVN_IMM), + ARMv7_OP2(0xffc0, 0x43c0, T1, MVN_REG), + ARMv7_OP4(0xffef, 0x8000, 0xea6f, 0x0000, T2, MVN_REG), + ARMv7_OP4(0xffef, 0x0010, 0x01e0, 0x0000, A1, MVN_REG), + ARMv7_OP4(0x0fef, 0x0090, 0x01e0, 0x0010, A1, MVN_RSR), + + ARMv7_OP2(0xffff, 0xbf00, T1, NOP), + ARMv7_OP4(0xffff, 0xffff, 0xf3af, 0x8000, T2, NOP), + ARMv7_OP4(0x0fff, 0xffff, 0x0320, 0xf000, A1, NOP), + + ARMv7_OP4(0xfbe0, 0x8000, 0xf060, 0x0000, T1, ORN_IMM), + ARMv7_OP4(0xffe0, 0x8000, 0xea60, 0x0000, T1, ORN_REG), + + ARMv7_OP4(0xfbe0, 0x8000, 0xf040, 0x0000, T1, ORR_IMM), + ARMv7_OP4(0x0fe0, 0x0000, 0x0380, 0x0000, A1, ORR_IMM), + ARMv7_OP2(0xffc0, 0x4300, T1, ORR_REG), + ARMv7_OP4(0xffe0, 0x8000, 0xea40, 0x0000, T2, ORR_REG), + ARMv7_OP4(0x0fe0, 0x0010, 0x0180, 0x0000, A1, ORR_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x0180, 0x0010, A1, ORR_RSR), + + 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), + 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(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), + + // 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), + ARMv7_OP4(0xfff0, 0x0800, 0xf840, 0x0800, T4, STR_IMM), + ARMv7_OP4(0x0e50, 0x0000, 0x0400, 0x0000, A1, STR_IMM), + ARMv7_OP2(0xfe00, 0x5000, T1, STR_REG), + 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(0xff80, 0xb080, T1, SUB_SPI), + ARMv7_OP4(0xfbef, 0x8000, 0xf1ad, 0x0000, T2, SUB_SPI), + ARMv7_OP4(0xfbff, 0x8000, 0xf2ad, 0x0000, T3, SUB_SPI), + 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(0xfe00, 0x1e00, T1, SUB_IMM), + ARMv7_OP2(0xf800, 0x3800, T2, SUB_IMM), + ARMv7_OP4(0xfbe0, 0x8000, 0xf1a0, 0x0000, T3, SUB_IMM), + ARMv7_OP4(0xfbf0, 0x8000, 0xf2a0, 0x0000, T4, SUB_IMM), + ARMv7_OP4(0x0fe0, 0x0000, 0x0240, 0x0000, A1, SUB_IMM), + ARMv7_OP2(0xfe00, 0x1a00, T1, SUB_REG), + ARMv7_OP4(0xffe0, 0x8000, 0xeba0, 0x0000, T2, SUB_REG), + ARMv7_OP4(0x0fe0, 0x0010, 0x0040, 0x0000, A1, SUB_REG), + ARMv7_OP4(0x0fe0, 0x0090, 0x0040, 0x0010, A1, SUB_RSR), + + 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_OP2 +#undef ARMv7_OP4 diff --git a/rpcs3/Emu/ARMv7/ARMv7Opcodes.h b/rpcs3/Emu/ARMv7/ARMv7Opcodes.h index ddd6962885..2d079aa6f9 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Opcodes.h +++ b/rpcs3/Emu/ARMv7/ARMv7Opcodes.h @@ -1,5 +1,10 @@ #pragma once +#include "Emu/ARMv7/ARMv7Thread.h" +#include "Emu/ARMv7/ARMv7Interpreter.h" +#include "Emu/System.h" +#include "Utilities/Log.h" + static const char* g_arm_reg_name[16] = { "r0", "r1", "r2", "r3", @@ -8,710 +13,2013 @@ static const char* g_arm_reg_name[16] = "r12", "sp", "lr", "pc", }; -namespace ARMv7_opcodes +using namespace ARMv7_instrs; + +struct ARMv7_Instruction { - enum ARMv7_T1Opcodes - { - T1_CBZ = 0xb, - T1_B = 0xd, - T1_PUSH = 0x1d, - T1_POP = 0x5e, - T1_NOP = 0xBF00, - }; + void(*func)(ARMv7Thread* thr, const ARMv7_encoding type); + u8 size; + ARMv7_encoding type; + const char* name; +}; - enum ARMv7_T2Opcodes - { - T2_B = 0x1c, - T2_PUSH = 0xe92d, - T2_POP = 0xe8bd, - }; - enum ARMv7_T3Opcodes - { - T3_B = 0x1e, - }; +#define ARMv7_OP_2(func, type) { func, 2, type, #func "_" #type } +#define ARMv7_OP_4(func, type) { func, 4, type, #func "_" #type } +#define ARMv7_NULL_OP { NULL_OP, 2, T1, "NULL_OP" } + + +// 0x1... +static void group_0x1(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0x1_main[] = +{ + ARMv7_OP_2(ASR_IMM, T1), // 0 0xf800 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(ADD_REG, T1), // 8 0xfe00 + ARMv7_NULL_OP, // 9 + ARMv7_OP_2(SUB_REG, T1), // A 0xfe00 + ARMv7_NULL_OP, // B + ARMv7_OP_2(ADD_IMM, T1), // C 0xfe00 + ARMv7_NULL_OP, // D + ARMv7_OP_2(SUB_IMM, T1) // E 0xfe00 +}; + +static const ARMv7_Instruction g_table_0x1[] = +{ + { group_0x1 } +}; + +static void group_0x1(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x0e00) >> 8; + + if ((thr->code.code0 & 0xf800) == 0x1000) index = 0x0; + + thr->m_last_instr_name = g_table_0x1_main[index].name; + thr->m_last_instr_size = g_table_0x1_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x1_main[index].func(thr, g_table_0x1_main[index].type); } -enum ARMv7_encoding +// 0x2... +static void group_0x2(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0x2_main[] = { - T1, - T2, - T3, - T4, - A1, - A2, + ARMv7_OP_2(MOV_IMM, T1), // 0 0xf800 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(CMP_IMM, T1) // 8 0xf800 }; -class ARMv7Opcodes +static const ARMv7_Instruction g_table_0x2[] = { -public: - virtual void UNK(const u32 data) = 0; - - 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; - - virtual void ADD_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void ADD_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void ADD_RSR(const u32 data, const ARMv7_encoding type) = 0; - virtual void ADD_SPI(const u32 data, const ARMv7_encoding type) = 0; - virtual void ADD_SPR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void ADR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void AND_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void AND_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void AND_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void ASR_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void ASR_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void B(const u32 data, const ARMv7_encoding type) = 0; - - virtual void BFC(const u32 data, const ARMv7_encoding type) = 0; - virtual void BFI(const u32 data, const ARMv7_encoding type) = 0; - - virtual void BIC_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void BIC_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void BIC_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void BKPT(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 BX(const u32 data, const ARMv7_encoding type) = 0; - - virtual void CB_Z(const u32 data, const ARMv7_encoding type) = 0; - - virtual void CLZ(const u32 data, const ARMv7_encoding type) = 0; - - virtual void CMN_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void CMN_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void CMN_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void CMP_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void CMP_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void CMP_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void EOR_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void EOR_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void EOR_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void IT(const u32 data, const ARMv7_encoding type) = 0; - - virtual void LDM(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDMDA(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDMDB(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDMIB(const u32 data, const ARMv7_encoding type) = 0; - - virtual void LDR_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDR_LIT(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDR_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void LDRB_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRB_LIT(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRB_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void LDRD_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRD_LIT(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRD_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void LDRH_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRH_LIT(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRH_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void LDRSB_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRSB_LIT(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRSB_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void LDRSH_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRSH_LIT(const u32 data, const ARMv7_encoding type) = 0; - virtual void LDRSH_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void LSL_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void LSL_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void LSR_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void LSR_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void MLA(const u32 data, const ARMv7_encoding type) = 0; - virtual void MLS(const u32 data, const ARMv7_encoding type) = 0; - - virtual void MOV_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void MOV_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void MOVT(const u32 data, const ARMv7_encoding type) = 0; - - virtual void MRS(const u32 data, const ARMv7_encoding type) = 0; - virtual void MSR_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void MSR_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void MUL(const u32 data, const ARMv7_encoding type) = 0; - - virtual void MVN_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void MVN_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void MVN_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void NOP(const u32 data, const ARMv7_encoding type) = 0; - - virtual void ORN_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void ORN_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void ORR_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void ORR_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void ORR_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void PKH(const u32 data, const ARMv7_encoding type) = 0; - - virtual void POP(const u32 data, const ARMv7_encoding type) = 0; - virtual void PUSH(const u32 data, const ARMv7_encoding type) = 0; - - virtual void QADD(const u32 data, const ARMv7_encoding type) = 0; - virtual void QADD16(const u32 data, const ARMv7_encoding type) = 0; - virtual void QADD8(const u32 data, const ARMv7_encoding type) = 0; - virtual void QASX(const u32 data, const ARMv7_encoding type) = 0; - virtual void QDADD(const u32 data, const ARMv7_encoding type) = 0; - virtual void QDSUB(const u32 data, const ARMv7_encoding type) = 0; - virtual void QSAX(const u32 data, const ARMv7_encoding type) = 0; - virtual void QSUB(const u32 data, const ARMv7_encoding type) = 0; - virtual void QSUB16(const u32 data, const ARMv7_encoding type) = 0; - virtual void QSUB8(const u32 data, const ARMv7_encoding type) = 0; - - virtual void RBIT(const u32 data, const ARMv7_encoding type) = 0; - virtual void REV(const u32 data, const ARMv7_encoding type) = 0; - virtual void REV16(const u32 data, const ARMv7_encoding type) = 0; - virtual void REVSH(const u32 data, const ARMv7_encoding type) = 0; - - virtual void ROR_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void ROR_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void RRX(const u32 data, const ARMv7_encoding type) = 0; - - virtual void RSB_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void RSB_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void RSB_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void RSC_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void RSC_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void RSC_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void SADD16(const u32 data, const ARMv7_encoding type) = 0; - virtual void SADD8(const u32 data, const ARMv7_encoding type) = 0; - virtual void SASX(const u32 data, const ARMv7_encoding type) = 0; - - virtual void SBC_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void SBC_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void SBC_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void SBFX(const u32 data, const ARMv7_encoding type) = 0; - - virtual void SDIV(const u32 data, const ARMv7_encoding type) = 0; - - virtual void SEL(const u32 data, const ARMv7_encoding type) = 0; - - virtual void SHADD16(const u32 data, const ARMv7_encoding type) = 0; - virtual void SHADD8(const u32 data, const ARMv7_encoding type) = 0; - virtual void SHASX(const u32 data, const ARMv7_encoding type) = 0; - virtual void SHSAX(const u32 data, const ARMv7_encoding type) = 0; - virtual void SHSUB16(const u32 data, const ARMv7_encoding type) = 0; - virtual void SHSUB8(const u32 data, const ARMv7_encoding type) = 0; - - virtual void SMLA__(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMLAD(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMLAL(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMLAL__(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMLALD(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMLAW_(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMLSD(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMLSLD(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMMLA(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMMLS(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMMUL(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMUAD(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMUL__(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMULL(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMULW_(const u32 data, const ARMv7_encoding type) = 0; - virtual void SMUSD(const u32 data, const ARMv7_encoding type) = 0; - - virtual void SSAT(const u32 data, const ARMv7_encoding type) = 0; - virtual void SSAT16(const u32 data, const ARMv7_encoding type) = 0; - virtual void SSAX(const u32 data, const ARMv7_encoding type) = 0; - virtual void SSUB16(const u32 data, const ARMv7_encoding type) = 0; - virtual void SSUB8(const u32 data, const ARMv7_encoding type) = 0; - - virtual void STM(const u32 data, const ARMv7_encoding type) = 0; - virtual void STMDA(const u32 data, const ARMv7_encoding type) = 0; - virtual void STMDB(const u32 data, const ARMv7_encoding type) = 0; - virtual void STMIB(const u32 data, const ARMv7_encoding type) = 0; - - virtual void STR_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void STR_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void STRB_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void STRB_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void STRD_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void STRD_REG(const u32 data, const ARMv7_encoding type) = 0; - - virtual void STRH_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void STRH_REG(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; - - virtual void SVC(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; - virtual void SXTB(const u32 data, const ARMv7_encoding type) = 0; - virtual void SXTB16(const u32 data, const ARMv7_encoding type) = 0; - virtual void SXTH(const u32 data, const ARMv7_encoding type) = 0; - - virtual void TB_(const u32 data, const ARMv7_encoding type) = 0; - - virtual void TEQ_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void TEQ_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void TEQ_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void TST_IMM(const u32 data, const ARMv7_encoding type) = 0; - virtual void TST_REG(const u32 data, const ARMv7_encoding type) = 0; - virtual void TST_RSR(const u32 data, const ARMv7_encoding type) = 0; - - virtual void UADD16(const u32 data, const ARMv7_encoding type) = 0; - virtual void UADD8(const u32 data, const ARMv7_encoding type) = 0; - virtual void UASX(const u32 data, const ARMv7_encoding type) = 0; - virtual void UBFX(const u32 data, const ARMv7_encoding type) = 0; - virtual void UDIV(const u32 data, const ARMv7_encoding type) = 0; - virtual void UHADD16(const u32 data, const ARMv7_encoding type) = 0; - virtual void UHADD8(const u32 data, const ARMv7_encoding type) = 0; - virtual void UHASX(const u32 data, const ARMv7_encoding type) = 0; - virtual void UHSAX(const u32 data, const ARMv7_encoding type) = 0; - virtual void UHSUB16(const u32 data, const ARMv7_encoding type) = 0; - virtual void UHSUB8(const u32 data, const ARMv7_encoding type) = 0; - virtual void UMAAL(const u32 data, const ARMv7_encoding type) = 0; - virtual void UMLAL(const u32 data, const ARMv7_encoding type) = 0; - virtual void UMULL(const u32 data, const ARMv7_encoding type) = 0; - virtual void UQADD16(const u32 data, const ARMv7_encoding type) = 0; - virtual void UQADD8(const u32 data, const ARMv7_encoding type) = 0; - virtual void UQASX(const u32 data, const ARMv7_encoding type) = 0; - virtual void UQSAX(const u32 data, const ARMv7_encoding type) = 0; - virtual void UQSUB16(const u32 data, const ARMv7_encoding type) = 0; - virtual void UQSUB8(const u32 data, const ARMv7_encoding type) = 0; - virtual void USAD8(const u32 data, const ARMv7_encoding type) = 0; - virtual void USADA8(const u32 data, const ARMv7_encoding type) = 0; - virtual void USAT(const u32 data, const ARMv7_encoding type) = 0; - virtual void USAT16(const u32 data, const ARMv7_encoding type) = 0; - virtual void USAX(const u32 data, const ARMv7_encoding type) = 0; - virtual void USUB16(const u32 data, const ARMv7_encoding type) = 0; - virtual void USUB8(const u32 data, const ARMv7_encoding type) = 0; - virtual void UXTAB(const u32 data, const ARMv7_encoding type) = 0; - virtual void UXTAB16(const u32 data, const ARMv7_encoding type) = 0; - virtual void UXTAH(const u32 data, const ARMv7_encoding type) = 0; - virtual void UXTB(const u32 data, const ARMv7_encoding type) = 0; - 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 + something + { group_0x2 } }; -struct ARMv7_opcode_t +static void group_0x2(ARMv7Thread* thr, const ARMv7_encoding type) { - u32 mask; - u32 code; - u32 length; // 2 or 4 - const char* name; - ARMv7_encoding type; - void (ARMv7Opcodes::*func)(const u32 data, const ARMv7_encoding type); + const u32 index = (thr->code.code0 & 0x0800) >> 8; + thr->m_last_instr_name = g_table_0x2_main[index].name; + thr->m_last_instr_size = g_table_0x2_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x2_main[index].func(thr, g_table_0x2_main[index].type); +} + +// 0x3... +static void group_0x3(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0x3_main[] = +{ + ARMv7_OP_2(ADD_IMM, T2), // 0 0xf800 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(SUB_IMM, T2) // 8 0xf800 }; -// single 16-bit value -#define ARMv7_OP2(mask, code, type, name) { (u32)((mask) << 16), (u32)((code) << 16), 2, #name "_" #type, type, &ARMv7Opcodes::name } -// two 16-bit values -#define ARMv7_OP4(mask0, mask1, code0, code1, type, name) { (u32)((mask0) << 16) | (mask1), (u32)((code0) << 16) | (code1), 4, #name "_" #type, type, &ARMv7Opcodes::name } - -static const ARMv7_opcode_t ARMv7_opcode_table[] = +static const ARMv7_Instruction g_table_0x3[] = { - 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), - ARMv7_OP4(0xffe0, 0x8000, 0xeb40, 0x0000, T2, ADC_REG), - ARMv7_OP4(0x0fe0, 0x0010, 0x00a0, 0x0000, A1, ADC_REG), - ARMv7_OP4(0x0fe0, 0x0090, 0x00a0, 0x0010, A1, ADC_RSR), - - ARMv7_OP2(0xf800, 0xa800, T1, ADD_SPI), - ARMv7_OP2(0xff80, 0xb000, T2, ADD_SPI), - ARMv7_OP4(0xfbef, 0x8000, 0xf10d, 0x0000, T3, ADD_SPI), - ARMv7_OP4(0xfbff, 0x8000, 0xf20d, 0x0000, T4, ADD_SPI), - ARMv7_OP4(0x0fef, 0x0000, 0x028d, 0x0000, A1, ADD_SPI), - ARMv7_OP2(0xff78, 0x4468, T1, ADD_SPR), - ARMv7_OP2(0xff87, 0x4485, T2, ADD_SPR), - ARMv7_OP4(0xffef, 0x8000, 0xeb0d, 0x0000, T3, ADD_SPR), - ARMv7_OP4(0x0fef, 0x0010, 0x008d, 0x0000, A1, ADD_SPR), - ARMv7_OP2(0xfe00, 0x1c00, T1, ADD_IMM), - ARMv7_OP2(0xf800, 0x3000, T2, ADD_IMM), - ARMv7_OP4(0xfbe0, 0x8000, 0xf100, 0x0000, T3, ADD_IMM), - ARMv7_OP4(0xfbf0, 0x8000, 0xf200, 0x0000, T4, ADD_IMM), - ARMv7_OP4(0x0fe0, 0x0000, 0x0280, 0x0000, A1, ADD_IMM), - ARMv7_OP2(0xfe00, 0x1800, T1, ADD_REG), - ARMv7_OP2(0xff00, 0x4400, T2, ADD_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xeb00, 0x0000, T3, ADD_REG), - ARMv7_OP4(0x0fe0, 0x0010, 0x0080, 0x0000, A1, ADD_REG), - ARMv7_OP4(0x0fe0, 0x0090, 0x0080, 0x0010, A1, ADD_RSR), - - ARMv7_OP2(0xf800, 0xa000, T1, ADR), - ARMv7_OP4(0xfbff, 0x8000, 0xf2af, 0x0000, T2, ADR), - ARMv7_OP4(0xfbff, 0x8000, 0xf20f, 0x0000, T3, ADR), - ARMv7_OP4(0x0fff, 0x0000, 0x028f, 0x0000, A1, ADR), - ARMv7_OP4(0x0fff, 0x0000, 0x024f, 0x0000, A2, ADR), - - ARMv7_OP4(0xfbe0, 0x8000, 0xf000, 0x0000, T1, AND_IMM), - ARMv7_OP4(0x0fe0, 0x0000, 0x0200, 0x0000, A1, AND_IMM), - ARMv7_OP2(0xffc0, 0x4000, T1, AND_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xea00, 0x0000, T2, AND_REG), - ARMv7_OP4(0x0fe0, 0x0010, 0x0000, 0x0000, A1, AND_REG), - ARMv7_OP4(0x0fe0, 0x0090, 0x0000, 0x0010, A1, AND_RSR), - - ARMv7_OP2(0xf800, 0x1000, T1, ASR_IMM), - ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0020, T2, ASR_IMM), - ARMv7_OP4(0x0fef, 0x0070, 0x01a0, 0x0040, A1, ASR_IMM), - ARMv7_OP2(0xffc0, 0x4100, T1, ASR_REG), - ARMv7_OP4(0xffe0, 0xf0f0, 0xfa40, 0xf000, T2, ASR_REG), - ARMv7_OP4(0x0fef, 0x00f0, 0x01a0, 0x0050, A1, ASR_REG), - - 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_OP4(0xffff, 0x8020, 0xf36f, 0x0000, T1, BFC), - ARMv7_OP4(0x0fe0, 0x007f, 0x07c0, 0x001f, A1, BFC), - ARMv7_OP4(0xfff0, 0x8020, 0xf360, 0x0000, T1, BFI), - ARMv7_OP4(0x0fe0, 0x0070, 0x07c0, 0x0010, A1, BFI), - - ARMv7_OP4(0xfbe0, 0x8000, 0xf020, 0x0000, T1, BIC_IMM), - ARMv7_OP4(0x0fe0, 0x0000, 0x03c0, 0x0000, A1, BIC_IMM), - ARMv7_OP2(0xffc0, 0x4380, T1, BIC_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xea20, 0x0000, T2, BIC_REG), - ARMv7_OP4(0x0fe0, 0x0010, 0x01c0, 0x0000, A1, BIC_REG), - ARMv7_OP4(0x0fe0, 0x0090, 0x01c0, 0x0010, A1, BIC_RSR), - - ARMv7_OP2(0xff00, 0xbe00, T1, BKPT), - ARMv7_OP4(0x0ff0, 0x00f0, 0x0120, 0x0070, A1, BKPT), - - 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(0xff87, 0x4700, T1, BX), - ARMv7_OP4(0x0fff, 0xfff0, 0x012f, 0xff10, A1, BX), - - ARMv7_OP2(0xf500, 0xb100, T1, CB_Z), - - ARMv7_OP4(0xfff0, 0xf0f0, 0xfab0, 0xf080, T1, CLZ), - ARMv7_OP4(0x0fff, 0x0ff0, 0x016f, 0x0f10, A1, CLZ), - - ARMv7_OP4(0xfbf0, 0x8f00, 0xf110, 0x0f00, T1, CMN_IMM), - ARMv7_OP4(0x0ff0, 0xf000, 0x0370, 0x0000, A1, CMN_IMM), - ARMv7_OP2(0xffc0, 0x42c0, T1, CMN_REG), - ARMv7_OP4(0xfff0, 0x8f00, 0xeb10, 0x0f00, T2, CMN_REG), - ARMv7_OP4(0x0ff0, 0xf010, 0x0170, 0x0000, A1, CMN_REG), - ARMv7_OP4(0x0ff0, 0xf090, 0x0170, 0x0010, A1, CMN_RSR), - - ARMv7_OP2(0xf800, 0x2800, T1, CMP_IMM), - ARMv7_OP4(0xfbf0, 0x8f00, 0xf1b0, 0x0f00, T2, CMP_IMM), - ARMv7_OP4(0x0ff0, 0xf000, 0x0350, 0x0000, A1, CMP_IMM), - ARMv7_OP2(0xffc0, 0x4280, T1, CMP_REG), - ARMv7_OP2(0xff00, 0x4500, T2, CMP_REG), - ARMv7_OP4(0xfff0, 0x8f00, 0xebb0, 0x0f00, T3, CMP_REG), - ARMv7_OP4(0x0ff0, 0xf010, 0x0150, 0x0000, A1, CMP_REG), - ARMv7_OP4(0x0ff0, 0xf090, 0x0150, 0x0010, A1, CMP_RSR), - - ARMv7_OP4(0xfbe0, 0x8000, 0xf080, 0x0000, T1, EOR_IMM), - ARMv7_OP4(0x0fe0, 0x0000, 0x0220, 0x0000, A1, EOR_IMM), - ARMv7_OP2(0xffc0, 0x4040, T1, EOR_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xea80, 0x0000, T2, EOR_REG), - ARMv7_OP4(0x0fe0, 0x0010, 0x0020, 0x0000, A1, EOR_REG), - ARMv7_OP4(0x0fe0, 0x0090, 0x0020, 0x0010, A1, EOR_RSR), - - ARMv7_OP2(0xff00, 0xbf00, T1, IT), - - ARMv7_OP2(0xf800, 0xc800, T1, LDM), - ARMv7_OP4(0xffd0, 0x2000, 0xe890, 0x0000, T2, LDM), - ARMv7_OP4(0x0fd0, 0x0000, 0x0890, 0x0000, A1, LDM), - ARMv7_OP4(0x0fd0, 0x0000, 0x0810, 0x0000, A1, LDMDA), - ARMv7_OP4(0xffd0, 0x2000, 0xe910, 0x0000, T1, LDMDB), - ARMv7_OP4(0x0fd0, 0x0000, 0x0910, 0x0000, A1, LDMDB), - ARMv7_OP4(0x0fd0, 0x0000, 0x0990, 0x0000, A1, LDMIB), - - ARMv7_OP2(0xf800, 0x6800, T1, LDR_IMM), - ARMv7_OP2(0xf800, 0x9800, T2, LDR_IMM), - ARMv7_OP4(0xfff0, 0x0000, 0xf8d0, 0x0000, T3, LDR_IMM), - ARMv7_OP4(0xfff0, 0x0800, 0xf850, 0x0800, T4, LDR_IMM), - ARMv7_OP4(0x0e50, 0x0000, 0x0410, 0x0000, A1, LDR_IMM), - ARMv7_OP2(0xf800, 0x4800, T1, LDR_LIT), - ARMv7_OP4(0xff7f, 0x0000, 0xf85f, 0x0000, T2, LDR_LIT), - ARMv7_OP4(0x0f7f, 0x0000, 0x051f, 0x0000, A1, LDR_LIT), - ARMv7_OP2(0xfe00, 0x5800, T1, LDR_REG), - ARMv7_OP4(0xfff0, 0x0fc0, 0xf850, 0x0000, T2, LDR_REG), - ARMv7_OP4(0x0e50, 0x0010, 0x0610, 0x0000, A1, LDR_REG), - - ARMv7_OP2(0xf800, 0x7800, T1, LDRB_IMM), - ARMv7_OP4(0xfff0, 0x0000, 0xf890, 0x0000, T2, LDRB_IMM), - ARMv7_OP4(0xfff0, 0x0800, 0xf810, 0x0800, T3, LDRB_IMM), - ARMv7_OP4(0x0e50, 0x0000, 0x0450, 0x0000, A1, LDRB_IMM), - ARMv7_OP4(0xff7f, 0x0000, 0xf81f, 0x0000, T1, LDRB_LIT), - ARMv7_OP4(0x0f7f, 0x0000, 0x055f, 0x0000, A1, LDRB_LIT), - ARMv7_OP2(0xfe00, 0x5c00, T1, LDRB_REG), - ARMv7_OP4(0xfff0, 0x0fc0, 0xf810, 0x0000, T2, LDRB_REG), - ARMv7_OP4(0x0e50, 0x0010, 0x0650, 0x0000, A1, LDRB_REG), - - ARMv7_OP4(0xfe50, 0x0000, 0xe850, 0x0000, T1, LDRD_IMM), - ARMv7_OP4(0x0e50, 0x00f0, 0x0040, 0x00d0, A1, LDRD_IMM), - ARMv7_OP4(0xfe7f, 0x0000, 0xe85f, 0x0000, T1, LDRD_LIT), - ARMv7_OP4(0x0f7f, 0x00f0, 0x014f, 0x00d0, A1, LDRD_LIT), - ARMv7_OP4(0x0e50, 0x0ff0, 0x0000, 0x00d0, A1, LDRD_REG), - - ARMv7_OP4(0xfff0, 0x0000, 0xf990, 0x0000, T1, LDRSB_IMM), - ARMv7_OP4(0xfff0, 0x0800, 0xf910, 0x0800, T2, LDRSB_IMM), - ARMv7_OP4(0x0e50, 0x00f0, 0x0050, 0x00d0, A1, LDRSB_IMM), - ARMv7_OP4(0xff7f, 0x0000, 0xf91f, 0x0000, T1, LDRSB_LIT), - ARMv7_OP4(0x0f7f, 0x00f0, 0x015f, 0x00d0, A1, LDRSB_LIT), - ARMv7_OP2(0xfe00, 0x5600, T1, LDRSB_REG), - ARMv7_OP4(0xfff0, 0x0fc0, 0xf910, 0x0000, T2, LDRSB_REG), - ARMv7_OP4(0x0e50, 0x0ff0, 0x0010, 0x00d0, A1, LDRSB_REG), - - ARMv7_OP4(0xfff0, 0x0000, 0xf9b0, 0x0000, T1, LDRSH_IMM), - ARMv7_OP4(0xfff0, 0x0800, 0xf930, 0x0800, T2, LDRSH_IMM), - ARMv7_OP4(0x0e50, 0x00f0, 0x0050, 0x00f0, A1, LDRSH_IMM), - ARMv7_OP4(0xff7f, 0x0000, 0xf93f, 0x0000, T1, LDRSH_LIT), - ARMv7_OP4(0x0f7f, 0x00f0, 0x015f, 0x00f0, A1, LDRSH_LIT), - ARMv7_OP2(0xfe00, 0x5e00, T1, LDRSH_REG), - ARMv7_OP4(0xfff0, 0x0fc0, 0xf930, 0x0000, T2, LDRSH_REG), - ARMv7_OP4(0x0e50, 0x0ff0, 0x0010, 0x00f0, A1, LDRSH_REG), - - ARMv7_OP2(0xf800, 0x0000, T1, LSL_IMM), - ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0000, T2, LSL_IMM), - ARMv7_OP4(0x0fef, 0x0070, 0x01a0, 0x0000, A1, LSL_IMM), - ARMv7_OP2(0xffc0, 0x4080, T1, LSL_REG), - ARMv7_OP4(0xffe0, 0xf0f0, 0xfa00, 0xf000, T2, LSL_REG), - ARMv7_OP4(0x0fef, 0x00f0, 0x01a0, 0x0010, A1, LSL_REG), - - ARMv7_OP2(0xf800, 0x0800, T1, LSR_IMM), - ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0010, T2, LSR_IMM), - ARMv7_OP4(0x0fef, 0x0030, 0x01a0, 0x0020, A1, LSR_IMM), - ARMv7_OP2(0xffc0, 0x40c0, T1, LSR_REG), - ARMv7_OP4(0xffe0, 0xf0f0, 0xfa20, 0xf000, T2, LSR_REG), - ARMv7_OP4(0x0fef, 0x00f0, 0x01a0, 0x0030, A1, LSR_REG), - - ARMv7_OP4(0xfff0, 0x00f0, 0xfb00, 0x0000, T1, MLA), - ARMv7_OP4(0x0fe0, 0x00f0, 0x0020, 0x0090, A1, MLA), - - ARMv7_OP4(0xfff0, 0x00f0, 0xfb00, 0x0010, T1, MLS), - ARMv7_OP4(0x0ff0, 0x00f0, 0x0060, 0x0090, A1, MLS), - - ARMv7_OP2(0xf800, 0x2000, T1, MOV_IMM), - ARMv7_OP4(0xfbef, 0x8000, 0xf04f, 0x0000, T2, MOV_IMM), - ARMv7_OP4(0xfbf0, 0x8000, 0xf240, 0x0000, T3, MOV_IMM), - ARMv7_OP4(0x0fef, 0x0000, 0x03a0, 0x0000, A1, MOV_IMM), - ARMv7_OP4(0x0ff0, 0x0000, 0x0300, 0x0000, A2, MOV_IMM), - ARMv7_OP2(0xff00, 0x4600, T1, MOV_REG), - ARMv7_OP2(0xffc0, 0x0000, T2, MOV_REG), - ARMv7_OP4(0xffef, 0xf0f0, 0xea4f, 0x0000, T3, MOV_REG), - ARMv7_OP4(0x0fef, 0x0ff0, 0x01a0, 0x0000, A1, MOV_REG), - ARMv7_OP4(0xfbf0, 0x8000, 0xf2c0, 0x0000, T1, MOVT), - ARMv7_OP4(0x0ff0, 0x0000, 0x0340, 0x0000, A1, MOVT), - - ARMv7_OP4(0xffff, 0xf0ff, 0xf3ef, 0x8000, T1, MRS), - ARMv7_OP4(0x0fff, 0x0fff, 0x010f, 0x0000, A1, MRS), - ARMv7_OP4(0x0ff3, 0xf000, 0x0320, 0xf000, A1, MSR_IMM), - ARMv7_OP4(0xfff0, 0xf3ff, 0xf380, 0x8000, T1, MSR_REG), - ARMv7_OP4(0x0ff3, 0xfff0, 0x0120, 0xf000, A1, MSR_REG), - - ARMv7_OP2(0xffc0, 0x4340, T1, MUL), - ARMv7_OP4(0xfff0, 0xf0f0, 0xfb00, 0xf000, T2, MUL), - ARMv7_OP4(0x0fe0, 0xf0f0, 0x0000, 0x0090, A1, MUL), - - ARMv7_OP4(0xfbef, 0x8000, 0xf06f, 0x0000, T1, MVN_IMM), - ARMv7_OP4(0x0fef, 0x0000, 0x03e0, 0x0000, A1, MVN_IMM), - ARMv7_OP2(0xffc0, 0x43c0, T1, MVN_REG), - ARMv7_OP4(0xffef, 0x8000, 0xea6f, 0x0000, T2, MVN_REG), - ARMv7_OP4(0xffef, 0x0010, 0x01e0, 0x0000, A1, MVN_REG), - ARMv7_OP4(0x0fef, 0x0090, 0x01e0, 0x0010, A1, MVN_RSR), - - ARMv7_OP2(0xffff, 0xbf00, T1, NOP), - ARMv7_OP4(0xffff, 0xffff, 0xf3af, 0x8000, T2, NOP), - ARMv7_OP4(0x0fff, 0xffff, 0x0320, 0xf000, A1, NOP), - - ARMv7_OP4(0xfbe0, 0x8000, 0xf060, 0x0000, T1, ORN_IMM), - ARMv7_OP4(0xffe0, 0x8000, 0xea60, 0x0000, T1, ORN_REG), - - ARMv7_OP4(0xfbe0, 0x8000, 0xf040, 0x0000, T1, ORR_IMM), - ARMv7_OP4(0x0fe0, 0x0000, 0x0380, 0x0000, A1, ORR_IMM), - ARMv7_OP2(0xffc0, 0x4300, T1, ORR_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xea40, 0x0000, T2, ORR_REG), - ARMv7_OP4(0x0fe0, 0x0010, 0x0180, 0x0000, A1, ORR_REG), - ARMv7_OP4(0x0fe0, 0x0090, 0x0180, 0x0010, A1, ORR_RSR), - - 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), - 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(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), - - // 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), - ARMv7_OP4(0xfff0, 0x0800, 0xf840, 0x0800, T4, STR_IMM), - ARMv7_OP4(0x0e50, 0x0000, 0x0400, 0x0000, A1, STR_IMM), - ARMv7_OP2(0xfe00, 0x5000, T1, STR_REG), - 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(0xff80, 0xb080, T1, SUB_SPI), - ARMv7_OP4(0xfbef, 0x8000, 0xf1ad, 0x0000, T2, SUB_SPI), - ARMv7_OP4(0xfbff, 0x8000, 0xf2ad, 0x0000, T3, SUB_SPI), - 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(0xfe00, 0x1e00, T1, SUB_IMM), - ARMv7_OP2(0xf800, 0x3800, T2, SUB_IMM), - ARMv7_OP4(0xfbe0, 0x8000, 0xf1a0, 0x0000, T3, SUB_IMM), - ARMv7_OP4(0xfbf0, 0x8000, 0xf2a0, 0x0000, T4, SUB_IMM), - ARMv7_OP4(0x0fe0, 0x0000, 0x0240, 0x0000, A1, SUB_IMM), - ARMv7_OP2(0xfe00, 0x1a00, T1, SUB_REG), - ARMv7_OP4(0xffe0, 0x8000, 0xeba0, 0x0000, T2, SUB_REG), - ARMv7_OP4(0x0fe0, 0x0010, 0x0040, 0x0000, A1, SUB_REG), - ARMv7_OP4(0x0fe0, 0x0090, 0x0040, 0x0010, A1, SUB_RSR), - - 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*) + { group_0x3 } }; -#undef ARMv7_OP -#undef ARMv7_OPP +static void group_0x3(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x0800) >> 8; + thr->m_last_instr_name = g_table_0x3_main[index].name; + thr->m_last_instr_size = g_table_0x3_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x3_main[index].func(thr, g_table_0x3_main[index].type); +} +// 0x4... +static void group_0x4(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0x40(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0x41(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0x42(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0x43(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0x44(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0x47(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0x4[] = +{ + { group_0x4 } +}; + +static const ARMv7_Instruction g_table_0x40[] = +{ + ARMv7_OP_2(AND_REG, T1), // 0 0xffc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_2(ADC_REG, T1), // 4 0xffc0 + // ARMv7_OP_2(EOR_REG, T1), // 4 0xffc0 code(ADC_REG, T1) == code(EOR_REG, T1) ??? + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(LSL_REG, T1), // 8 0xffc0 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_OP_2(LSR_REG, T1) // C 0xffc0 +}; + +static void group_0x40(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x00c0) >> 4; + thr->m_last_instr_name = g_table_0x40[index].name; + thr->m_last_instr_size = g_table_0x40[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x40[index].func(thr, g_table_0x40[index].type); +} + +static const ARMv7_Instruction g_table_0x41[] = +{ + ARMv7_OP_2(ASR_REG, T1), // 0 0xffc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(SBC_REG, T1), // 8 0xffc0 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_OP_2(ROR_REG, T1) // C 0xffc0 +}; + +static void group_0x41(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x00c0) >> 4; + thr->m_last_instr_name = g_table_0x41[index].name; + thr->m_last_instr_size = g_table_0x41[index].size; + g_table_0x41[index].func(thr, g_table_0x41[index].type); +} + +static const ARMv7_Instruction g_table_0x42[] = +{ + ARMv7_OP_2(TST_REG, T1), // 0 0xffc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_2(RSB_IMM, T1), // 4 0xffc0 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(CMP_REG, T1), // 8 0xffc0 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_OP_2(CMN_REG, T1) // C 0xffc0 +}; + +static void group_0x42(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x00c0) >> 4; + thr->m_last_instr_name = g_table_0x42[index].name; + thr->m_last_instr_size = g_table_0x42[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x42[index].func(thr, g_table_0x42[index].type); +} + +static const ARMv7_Instruction g_table_0x43[] = +{ + ARMv7_OP_2(ORR_REG, T1), // 0 0xffc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_2(MUL, T1), // 4 0xffc0 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(BIC_REG, T1), // 8 0xffc0 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_OP_2(MVN_REG, T1) // C 0xffc0 +}; + +static void group_0x43(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x00c0) >> 4; + thr->m_last_instr_name = g_table_0x43[index].name; + thr->m_last_instr_size = g_table_0x43[index].size; + g_table_0x43[index].func(thr, g_table_0x43[index].type); +} + +static const ARMv7_Instruction g_table_0x44[] = +{ + ARMv7_OP_2(ADD_REG, T2), // 0 0xff00 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_OP_2(ADD_SPR, T1), // 6 0xff78 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(ADD_SPR, T2) // 8 0xff87 +}; + +static void group_0x44(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x0080) >> 4; + + if ((thr->code.code0 & 0xff00) == 0x4400) index = 0x0; + if ((thr->code.code0 & 0xff78) == 0x4468) index = 0x6; + + thr->m_last_instr_name = g_table_0x44[index].name; + thr->m_last_instr_size = g_table_0x44[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x44[index].func(thr, g_table_0x44[index].type); +} + +static const ARMv7_Instruction g_table_0x47[] = +{ + ARMv7_OP_2(BX, T1), // 0 0xff87 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(BLX, T1) // 8 0xff80 +}; + +static void group_0x47(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x0080) >> 4; + thr->m_last_instr_name = g_table_0x47[index].name; + thr->m_last_instr_size = g_table_0x47[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x47[index].func(thr, g_table_0x47[index].type); +} + +static const ARMv7_Instruction g_table_0x4_main[] = +{ + { group_0x40 }, // 0 + { group_0x41 }, // 1 + { group_0x42 }, // 2 + { group_0x43 }, // 3 + { group_0x44 }, // 4 + ARMv7_OP_2(CMP_REG, T2), // 5 0xff00 + ARMv7_OP_2(MOV_REG, T1), // 6 0xff00 + { group_0x47 }, // 7 + ARMv7_OP_2(LDR_LIT, T1) // 8 0xf800 +}; + +static void group_0x4(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x0f00) >> 8; + + if ((index & 0xf800) == 0x4800) index = 0x8; + + thr->m_last_instr_name = g_table_0x4_main[index].name; + thr->m_last_instr_size = g_table_0x4_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x4_main[index].func(thr, g_table_0x4_main[index].type); +} + +// 0x5... +static void group_0x5(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0x5_main[] = +{ + ARMv7_OP_2(STR_REG, T1), // 0 0xfe00 + ARMv7_NULL_OP, // 1 + ARMv7_OP_2(STRH_REG, T1), // 2 0xfe00 + ARMv7_NULL_OP, // 3 + ARMv7_OP_2(STRB_REG, T1), // 4 0xfe00 + ARMv7_NULL_OP, // 5 + ARMv7_OP_2(LDRSB_REG, T1), // 6 0xfe00 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(LDR_REG, T1), // 8 0xfe00 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_OP_2(LDRB_REG, T1), // C 0xfe00 + ARMv7_NULL_OP, // D + ARMv7_OP_2(LDRSH_REG, T1) // E 0xfe00 +}; + +static const ARMv7_Instruction g_table_0x5[] = +{ + { group_0x5 } +}; + +static void group_0x5(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x0e00) >> 8; + thr->m_last_instr_name = g_table_0x5_main[index].name; + thr->m_last_instr_size = g_table_0x5_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x5_main[index].func(thr, g_table_0x5_main[index].type); +} + +// 0x6... +static void group_0x6(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0x6_main[] = +{ + ARMv7_OP_2(STR_IMM, T1), // 0 0xf800 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(LDR_IMM, T1) // 8 0xf800 +}; + +static const ARMv7_Instruction g_table_0x6[] = +{ + { group_0x6 } +}; + +static void group_0x6(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x0800) >> 8; + thr->m_last_instr_name = g_table_0x6_main[index].name; + thr->m_last_instr_size = g_table_0x6_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x6_main[index].func(thr, g_table_0x6_main[index].type); +} + +// 0x7... +static void group_0x7(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0x7_main[] = +{ + ARMv7_OP_2(STRB_IMM, T1), // 0 0xf800 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(LDRB_IMM, T1) // 8 0xf800 +}; + +static const ARMv7_Instruction g_table_0x7[] = +{ + { group_0x7 } +}; + +static void group_0x7(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x0800) >> 8; + thr->m_last_instr_name = g_table_0x7_main[index].name; + thr->m_last_instr_size = g_table_0x7_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x7_main[index].func(thr, g_table_0x7_main[index].type); +} + +// 0x8... +static void group_0x8(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0x8_main[] = +{ + ARMv7_OP_2(STRH_IMM, T1) // 0 0xf800 +}; + +static const ARMv7_Instruction g_table_0x8[] = +{ + { group_0x8 } +}; + +static void group_0x8(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x0800) >> 8; + thr->m_last_instr_name = g_table_0x8_main[index].name; + thr->m_last_instr_size = g_table_0x8_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x8_main[index].func(thr, g_table_0x8_main[index].type); +} + +// 0x9... +static void group_0x9(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0x9_main[] = +{ + ARMv7_OP_2(STR_IMM, T2), // 0 0xf800 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(LDR_IMM, T2) // 8 0xf800 +}; + +static const ARMv7_Instruction g_table_0x9[] = +{ + { group_0x9 } +}; + +static void group_0x9(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x0800) >> 8; + thr->m_last_instr_name = g_table_0x9_main[index].name; + thr->m_last_instr_size = g_table_0x9_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0x9_main[index].func(thr, g_table_0x9_main[index].type); +} + +// 0xa... +static void group_0xa(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0xa_main[] = +{ + ARMv7_OP_2(ADR, T1), // 0 0xf800 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(ADD_SPI, T1) // 8 0xf800 +}; + +static const ARMv7_Instruction g_table_0xa[] = +{ + { group_0xa } +}; + +static void group_0xa(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x0800) >> 8; + thr->m_last_instr_name = g_table_0xa_main[index].name; + thr->m_last_instr_size = g_table_0xa_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xa_main[index].func(thr, g_table_0xa_main[index].type); +} + +// 0xb... +static void group_0xb(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xb0(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xba(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0xb0[] = +{ + ARMv7_OP_2(ADD_SPI, T2), // 0 0xff80 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(SUB_SPI, T1) // 8 0xff80 +}; + +static void group_0xb0(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x0080) >> 4; + thr->m_last_instr_name = g_table_0xb0[index].name; + thr->m_last_instr_size = g_table_0xb0[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xb0[index].func(thr, g_table_0xb0[index].type); +} + +static const ARMv7_Instruction g_table_0xba[] = +{ + ARMv7_OP_2(REV, T1), // 0 0xffc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_2(REV16, T1), // 4 0xffc0 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_OP_2(REVSH, T1) // C 0xffc0 +}; + +static void group_0xba(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x00c0) >> 4; // mask 0xffc0 + thr->m_last_instr_name = g_table_0xba[index].name; + thr->m_last_instr_size = g_table_0xba[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xba[index].func(thr, g_table_0xba[index].type); +} + +static const ARMv7_Instruction g_table_0xb_main[] = +{ + { group_0xb0 }, // 0 + ARMv7_OP_2(CB_Z, T1), // 1 0xf500 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_2(PUSH, T1), // 4 0xfe00 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + { group_0xba }, // A + ARMv7_NULL_OP, // B + ARMv7_OP_2(POP, T1), // C 0xfe00 + ARMv7_NULL_OP, // D + ARMv7_OP_2(BKPT, T1), // E 0xff00 + ARMv7_OP_2(NOP, T1), // F 0xffff + ARMv7_OP_2(IT, T1), // 10 0xff00 +}; + +static const ARMv7_Instruction g_table_0xb[] = +{ + { group_0xb } +}; + +static void group_0xb(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x0e00) >> 8; + + if ((thr->code.code0 & 0xf500) == 0xb100) index = 0x1; // CB_Z, T1 + if ((thr->code.code0 & 0xff00) == 0xbe00) index = 0xe; // BKPT, T1 + if ((thr->code.code0 & 0xffff) == 0xbf00) index = 0xf; // NOP, T1 + if ((thr->code.code0 & 0xff00) == 0xbf00) index = 0x10; // IT, T1 + + thr->m_last_instr_name = g_table_0xb_main[index].name; + thr->m_last_instr_size = g_table_0xb_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xb_main[index].func(thr, g_table_0xb_main[index].type); +} + +// 0xc... +static void group_0xc(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0xc_main[] = +{ + ARMv7_OP_2(STM, T1), // 0 0xf800 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_2(LDM, T1) // 8 0xf800 +}; + +static const ARMv7_Instruction g_table_0xc[] = +{ + { group_0xc } +}; + +static void group_0xc(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x0800) >> 8; + thr->m_last_instr_name = g_table_0xc_main[index].name; + thr->m_last_instr_size = g_table_0xc_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xc_main[index].func(thr, g_table_0xc_main[index].type); +} + +// 0xd... +static void group_0xd(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0xd_main[] = +{ + ARMv7_OP_2(B, T1), // 0 0xf000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // E + ARMv7_OP_2(SVC, T1) // F 0xff00 +}; + +static const ARMv7_Instruction g_table_0xd[] = +{ + { group_0xd } +}; + +static void group_0xd(ARMv7Thread* thr, const ARMv7_encoding type) +{ + //u32 index = (thr->code.code0 & 0x0f00) >> 8; + //if ((thr->code.code0 & 0xf000) == 0xd000) index = 0; + + const u32 index = (thr->code.code0 & 0xff00) == 0xdf00 ? 0xf : 0x0; // check me + thr->m_last_instr_name = g_table_0xd_main[index].name; + thr->m_last_instr_size = g_table_0xd_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xd_main[index].func(thr, g_table_0xd_main[index].type); +} + +// 0xe... +static void group_0xe(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xe85(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xe8(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xe9(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xea(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xea4(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xea4f(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xea4f0000(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xea4f0030(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xea6(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xeb(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xeb0(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xeba(ARMv7Thread* thr, const ARMv7_encoding type); + + +static const ARMv7_Instruction g_table_0xe85[] = +{ + ARMv7_OP_4(LDRD_IMM, T1), // 0 0xfe50, 0x0000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // E + ARMv7_OP_4(LDRD_LIT, T1) // F 0xfe7f, 0x0000 +}; + +static void group_0xe85(ARMv7Thread* thr, const ARMv7_encoding type) +{ + //u32 index = thr->code.code0 & 0x000f; + //if ((thr->code.code0 & 0xfe50) == 0xe850) index = 0x0; + + const u32 index = (thr->code.code0 & 0xfe7f) == 0xe85f ? 0xf : 0x0; // check me + thr->m_last_instr_name = g_table_0xe85[index].name; + thr->m_last_instr_size = g_table_0xe85[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xe85[index].func(thr, g_table_0xe85[index].type); +}; + +static const ARMv7_Instruction g_table_0xe8[] = +{ + ARMv7_NULL_OP, // 0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_4(STRD_IMM, T1), // 4 0xfe50, 0x0000 + { group_0xe85 }, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(STM, T2), // 8 0xffd0, 0xa000 + ARMv7_OP_4(LDM, T2), // 9 0xffd0, 0x2000 + ARMv7_NULL_OP, // A + ARMv7_OP_4(POP, T2), // B 0xffff, 0x0000 + ARMv7_NULL_OP, // C + ARMv7_OP_4(TB_, T1) // D 0xfff0, 0xffe0 +}; + +static void group_0xe8(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x00f0) >> 4; + + if ((thr->code.code0 & 0xfe50) == 0xe840) index = 0x4; + if ((thr->code.code0 & 0xffd0) == 0xe880) index = 0x8; + if ((thr->code.code0 & 0xffd0) == 0xe890) index = 0x9; + + thr->m_last_instr_name = g_table_0xe8[index].name; + thr->m_last_instr_size = g_table_0xe8[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xe8[index].func(thr, g_table_0xe8[index].type); +} + +static const ARMv7_Instruction g_table_0xe9[] = +{ + ARMv7_OP_4(STMDB, T1), // 0 0xffd0, 0xa000 + ARMv7_OP_4(LDMDB, T1), // 1 0xffd0, 0x2000 + ARMv7_OP_4(PUSH, T2) // 2 0xffff, 0x0000 +}; + +static void group_0xe9(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x00d0) >> 4; + + if ((thr->code.code0 & 0xffff) == 0xe92d) index = 0x2; + + thr->m_last_instr_name = g_table_0xe9[index].name; + thr->m_last_instr_size = g_table_0xe9[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xe9[index].func(thr, g_table_0xe9[index].type); +} + +static const ARMv7_Instruction g_table_0xea4[] = +{ + ARMv7_OP_4(ORR_REG, T2), // 0 0xffe0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // E + { group_0xea4f } // F +}; + +static void group_0xea4(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = 0x0; + if ((thr->code.code0 & 0xffef) == 0xea4f) index = 0xf; // check me + + thr->m_last_instr_name = g_table_0xea4[index].name; + thr->m_last_instr_size = g_table_0xea4[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xea4[index].func(thr, g_table_0xea4[index].type); +} + +static const ARMv7_Instruction g_table_0xea4f[] = +{ + { group_0xea4f0000 }, // 0 + ARMv7_OP_4(ASR_IMM, T2), // 1 0xffef, 0x8030 + ARMv7_OP_4(ASR_IMM, T2), // 2 0xffef, 0x8030 + { group_0xea4f0030 } // 3 +}; + +static void group_0xea4f(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code1 & 0x0030) >> 4; + thr->m_last_instr_name = g_table_0xea4f[index].name; + thr->m_last_instr_size = g_table_0xea4f[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xea4f[index].func(thr, g_table_0xea4f[index].type); +} + +static const ARMv7_Instruction g_table_0xea4f0000[] = +{ + ARMv7_OP_4(MOV_REG, T3), // 0 0xffef, 0xf0f0 + ARMv7_OP_4(LSL_IMM, T2) // 1 0xffef, 0x8030 +}; + +static void group_0xea4f0000(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = thr->code.code1 & 0x8030 ? 0x0 : 0x1; + thr->m_last_instr_name = g_table_0xea4f0000[index].name; + thr->m_last_instr_size = g_table_0xea4f0000[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xea4f0000[index].func(thr, g_table_0xea4f0000[index].type); +} + +static const ARMv7_Instruction g_table_0xea4f0030[] = +{ + ARMv7_OP_4(RRX, T1), // 1 0xffef, 0xf0f0 + ARMv7_OP_4(ROR_IMM, T1) // 2 0xffef, 0x8030 +}; + +static void group_0xea4f0030(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = thr->code.code1 & 0x8030 ? 0x0 : 0x1; + thr->m_last_instr_name = g_table_0xea4f0030[index].name; + thr->m_last_instr_size = g_table_0xea4f0030[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xea4f0030[index].func(thr, g_table_0xea4f0030[index].type); +} + +static const ARMv7_Instruction g_table_0xea6[] = +{ + ARMv7_OP_4(ORN_REG, T1), // 0 0xffe0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // E + ARMv7_OP_4(MVN_REG, T2) // F 0xffef, 0x8000 +}; + +static void group_0xea6(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xffe08000) == 0xea600000) index = 0x0; + + thr->m_last_instr_name = g_table_0xea6[index].name; + thr->m_last_instr_size = g_table_0xea6[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xea6[index].func(thr, g_table_0xea6[index].type); +} + +static const ARMv7_Instruction g_table_0xea[] = +{ + ARMv7_OP_4(AND_REG, T2), // 0 0xffe0, 0x8000 + ARMv7_OP_4(TST_REG, T2), // 1 0xfff0, 0x8f00 + ARMv7_OP_4(BIC_REG, T2), // 2 0xffe0, 0x8000 + ARMv7_NULL_OP, // 3 + { group_0xea4 }, // 4 + ARMv7_NULL_OP, // 5 + { group_0xea6 }, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(EOR_REG, T2), // 8 0xffe0, 0x8000 + ARMv7_OP_4(TEQ_REG, T1), // 9 0xfff0, 0x8f00 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_OP_4(PKH, T1) // C 0xfff0, 0x8010 +}; + +static void group_0xea(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x00e0) >> 4; + + if ((thr->m_arg & 0xfff08f00) == 0xea100f00) index = 0x1; + if ((thr->m_arg & 0xfff08f00) == 0xea900f00) index = 0x9; + if ((thr->m_arg & 0xfff08010) == 0xeac00000) index = 0xc; + + thr->m_last_instr_name = g_table_0xea[index].name; + thr->m_last_instr_size = g_table_0xea[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xea[index].func(thr, g_table_0xea[index].type); +} + +static const ARMv7_Instruction g_table_0xeb0[] = +{ + ARMv7_OP_4(ADD_REG, T3), // 0 0xffe0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_OP_4(ADD_SPR, T3) // D 0xffef, 0x8000 +}; + +static void group_0xeb0(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xffe08000) == 0xeb000000) index = 0x0; + + thr->m_last_instr_name = g_table_0xeb0[index].name; + thr->m_last_instr_size = g_table_0xeb0[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xeb0[index].func(thr, g_table_0xeb0[index].type); +} + +static const ARMv7_Instruction g_table_0xeba[] = +{ + ARMv7_OP_4(SUB_REG, T2), // 0 0xffe0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_OP_4(SUB_SPR, T1) // D 0xffef, 0x8000 +}; + +static void group_0xeba(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xffe08000) == 0xeba00000) index = 0x0; + + thr->m_last_instr_name = g_table_0xeba[index].name; + thr->m_last_instr_size = g_table_0xeba[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xeba[index].func(thr, g_table_0xeba[index].type); +} + +static const ARMv7_Instruction g_table_0xeb[] = +{ + { group_0xeb0 }, // 0 0xffe0 + ARMv7_OP_4(CMN_REG, T2), // 1 0xfff0, 0x8f00 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_4(ADC_REG, T2), // 4 0xffe0, 0x8000 + ARMv7_NULL_OP, // 5 + ARMv7_OP_4(SBC_REG, T2), // 6 0xffe0, 0x8000 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + { group_0xeba }, // A 0xffe0 + ARMv7_OP_4(CMP_REG, T3), // B 0xfff0, 0x8f00 + ARMv7_OP_4(RSB_REG, T1) // C 0xffe0, 0x8000 +}; + +static void group_0xeb(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x00e0) >> 4; + + if ((thr->m_arg & 0xfff08f00) == 0xeb100f00) index = 0x1; + if ((thr->m_arg & 0xfff08f00) == 0xebb00f00) index = 0xb; + + thr->m_last_instr_name = g_table_0xeb[index].name; + thr->m_last_instr_size = g_table_0xeb[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xeb[index].func(thr, g_table_0xeb[index].type); +} + +static const ARMv7_Instruction g_table_0xe_main[] = +{ + ARMv7_OP_2(B, T2), // 0 0xf800 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + { group_0xe8 }, // 8 + { group_0xe9 }, // 9 + { group_0xea }, // A + { group_0xeb }, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // E + ARMv7_NULL_OP, // F +}; + +static const ARMv7_Instruction g_table_0xe[] = +{ + { group_0xe } +}; + +static void group_0xe(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x0f00) >> 8; + + if ((thr->code.code0 & 0xf800) == 0xe000) index = 0x0; + + thr->m_last_instr_name = g_table_0xe_main[index].name; + thr->m_last_instr_size = g_table_0xe_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xe_main[index].func(thr, g_table_0xe_main[index].type); +} + +// 0xf... +static void group_0xf(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf000(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf04(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf06(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf0(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf1(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf1a(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf10(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf20(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf2a(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf2(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf36(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf3(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf810(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf800(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf81(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf820(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf840(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf84(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf850(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf85(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf8(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf910(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf91(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf930(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf93(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xf9(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xfa00(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xfa90(ARMv7Thread* thr, const ARMv7_encoding type); +static void group_0xfa(ARMv7Thread* thr, const ARMv7_encoding type); + +static const ARMv7_Instruction g_table_0xf000[] = +{ + ARMv7_OP_4(AND_IMM, T1), // 0 0xfbe0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(B, T3), // 8 0xf800, 0xd000 + ARMv7_OP_4(B, T4), // 9 0xf800, 0xd000 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_OP_4(BLX, T2), // C 0xf800, 0xc001 + ARMv7_OP_4(BL, T1) // D 0xf800, 0xd000 +}; + +static void group_0xf000(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code1 & 0xd000) >> 12; + + if ((thr->code.code1 & 0x8000) == 0x0000) index = 0x0; + if ((thr->code.code1 & 0xc001) == 0xc000) index = 0xc; + + thr->m_last_instr_size = g_table_0xf000[index].size; + thr->m_last_instr_name = g_table_0xf000[index].name; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf000[index].func(thr, g_table_0xf000[index].type); +} + +static const ARMv7_Instruction g_table_0xf04[] = +{ + ARMv7_OP_4(ORR_IMM, T1), // 0 0xfbe0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // E + ARMv7_OP_4(MOV_IMM, T2) // F 0xfbef, 0x8000 +}; + +static void group_0xf04(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xfbe08000) == 0xf0400000) index = 0x0; + + thr->m_last_instr_size = g_table_0xf04[index].size; + thr->m_last_instr_name = g_table_0xf04[index].name; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf04[index].func(thr, g_table_0xf04[index].type); +} + +static const ARMv7_Instruction g_table_0xf06[] = +{ + ARMv7_OP_4(ORN_IMM, T1), // 0 0xfbe0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // E + ARMv7_OP_4(MVN_IMM, T1) // F 0xfbef, 0x8000 +}; + +static void group_0xf06(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xfbe08000) == 0xf0600000) index = 0x0; + + thr->m_last_instr_size = g_table_0xf06[index].size; + thr->m_last_instr_name = g_table_0xf06[index].name; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf06[index].func(thr, g_table_0xf06[index].type); +} + +static const ARMv7_Instruction g_table_0xf0[] = +{ + /* + { group_0xf000 }, // 0 0xfbe0 + ARMv7_OP_4(TST_IMM, T1), // 1 0xfbf0, 0x8f00 + ARMv7_OP_4(BIC_IMM, T1), // 2 0xfbe0, 0x8000 + ARMv7_NULL_OP, // 3 + { group_0xf04 }, // 4 0xfbef + ARMv7_NULL_OP, // 5 + { group_0xf06 }, // 6 0xfbef + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(EOR_IMM, T1), // 8 0xfbe0, 0x8000 + ARMv7_OP_4(TEQ_IMM, T1) // 9 0xfbf0, 0x8f00 + */ + + ARMv7_OP_4(AND_IMM, T1), // f0 000 // 0 + ARMv7_OP_4(B, T3), // f0 008 // 1 + ARMv7_OP_4(B, T4), // f0 009 // 2 + ARMv7_OP_4(BLX, T2), // f0 00C // 3 + ARMv7_OP_4(BL, T1), // f0 00D // 4 + + ARMv7_OP_4(TST_IMM, T1), // f0 1 // 5 + ARMv7_OP_4(BIC_IMM, T1), // f0 2 // 6 + ARMv7_NULL_OP, // f0 3 // 7 + + + ARMv7_OP_4(ORR_IMM, T1), // f0 40 // 8 + ARMv7_OP_4(MOV_IMM, T2), // f0 4F // 9 + + ARMv7_NULL_OP, // f0 5 // A + + ARMv7_OP_4(ORN_IMM, T1), // f0 60 // B + ARMv7_OP_4(MVN_IMM, T1), // f0 6F // C + + ARMv7_NULL_OP, // f0 7 // D + ARMv7_OP_4(EOR_IMM, T1), // f0 8 // E + ARMv7_OP_4(TEQ_IMM, T1) // f0 9 // F + +}; + +static void group_0xf0(ARMv7Thread* thr, const ARMv7_encoding type) // TODO: optimize this group +{ + u32 index = 0; + if ((thr->m_arg & 0xfbe08000) == 0xf0000000) index = 0x0; + if ((thr->m_arg & 0xf800d000) == 0xf0008000) index = 0x1; + if ((thr->m_arg & 0xf800d000) == 0xf0009000) index = 0x2; + if ((thr->m_arg & 0xf800c001) == 0xf000c000) index = 0x3; + if ((thr->m_arg & 0xf800d000) == 0xf000d000) index = 0x4; + if ((thr->m_arg & 0xfbf08f00) == 0xf0100f00) index = 0x5; + if ((thr->m_arg & 0xfbe08000) == 0xf0200000) index = 0x6; + if ((thr->m_arg & 0xfbe08000) == 0xf0400000) index = 0x8; + if ((thr->m_arg & 0xfbef8000) == 0xf04f0000) index = 0x9; + if ((thr->m_arg & 0xfbe08000) == 0xf0600000) index = 0xb; + if ((thr->m_arg & 0xfbef8000) == 0xf06f0000) index = 0xc; + if ((thr->m_arg & 0xfbe08000) == 0xf0800000) index = 0xe; + if ((thr->m_arg & 0xfbf08f00) == 0xf0900f00) index = 0xf; + + /* + u32 index = (thr->code.code0 & 0x00e0) >> 4; // 0xfbef + + if ((thr->code.code0 & 0xfbf0) == 0xf010) index = 0x1; + if ((thr->code.code0 & 0xfbf0) == 0xf090) index = 0x9; + */ + + thr->m_last_instr_size = g_table_0xf0[index].size; + thr->m_last_instr_name = g_table_0xf0[index].name; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf0[index].func(thr, g_table_0xf0[index].type); +} + +static const ARMv7_Instruction g_table_0xf10[] = +{ + ARMv7_OP_4(ADD_IMM, T3), // 0 0xfbe0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_OP_4(ADD_SPI, T3) // D 0xfbef, 0x8000 +}; + +static void group_0xf10(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xfbe08000) == 0xf1000000) index = 0x0; + + thr->m_last_instr_name = g_table_0xf10[index].name; + thr->m_last_instr_size = g_table_0xf10[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf10[index].func(thr, g_table_0xf10[index].type); +} + +static const ARMv7_Instruction g_table_0xf1a[] = +{ + ARMv7_OP_4(SUB_IMM, T3), // 0 0xfbe0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_OP_4(SUB_SPI, T2) // D 0xfbef, 0x8000 +}; + +static void group_0xf1a(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xfbe08000) == 0xf1a00000) index = 0x0; + + thr->m_last_instr_name = g_table_0xf1a[index].name; + thr->m_last_instr_size = g_table_0xf1a[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf1a[index].func(thr, g_table_0xf1a[index].type); +} + +static const ARMv7_Instruction g_table_0xf1[] = +{ + { group_0xf10 }, // 0 + ARMv7_OP_4(CMN_IMM, T1), // 1 0xfbf0, 0x8f00 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_4(ADC_IMM, T1), // 4 0xfbe0, 0x8000 + ARMv7_NULL_OP, // 5 + ARMv7_OP_4(SBC_IMM, T1), // 6 0xfbe0, 0x8000 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + { group_0xf1a }, // A + ARMv7_OP_4(CMP_IMM, T2), // B 0xfbf0, 0x8f00 + ARMv7_OP_4(RSB_IMM, T2) // C 0xfbe0, 0x8000 +}; + +static void group_0xf1(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x00e0) >> 4; + + if ((thr->m_arg & 0xfbf08f00) == 0xf1100f00) index = 0x1; + if ((thr->m_arg & 0xfbf08f00) == 0xf1b00f00) index = 0xb; + + thr->m_last_instr_name = g_table_0xf1[index].name; + thr->m_last_instr_size = g_table_0xf1[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf1[index].func(thr, g_table_0xf1[index].type); +} + +static const ARMv7_Instruction g_table_0xf20[] = +{ + ARMv7_OP_4(ADD_IMM, T4), // 0 0xfbf0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_OP_4(ADD_SPI, T4), // D 0xfbff, 0x8000 + ARMv7_NULL_OP, // E + ARMv7_OP_4(ADR, T3) // F 0xfbff, 0x8000 +}; + +static void group_0xf20(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xfbf08000) == 0xf2000000) index = 0x0; + + thr->m_last_instr_name = g_table_0xf20[index].name; + thr->m_last_instr_size = g_table_0xf20[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf20[index].func(thr, g_table_0xf20[index].type); +} + +static const ARMv7_Instruction g_table_0xf2a[] = +{ + ARMv7_OP_4(SUB_IMM, T4), // 0 0xfbf0, 0x8000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_OP_4(SUB_SPI, T3), // D 0xfbff, 0x8000 + ARMv7_NULL_OP, // E + ARMv7_OP_4(ADR, T2) // F 0xfbff, 0x8000 +}; + +static void group_0xf2a(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xfbf08000) == 0xf2a00000) index = 0x0; + + thr->m_last_instr_name = g_table_0xf2a[index].name; + thr->m_last_instr_size = g_table_0xf2a[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf2a[index].func(thr, g_table_0xf2a[index].type); +} + +static const ARMv7_Instruction g_table_0xf2[] = +{ + { group_0xf20 }, // 0 0xfbff + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_4(MOV_IMM, T3), // 4 0xfbf0, 0x8000 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + { group_0xf2a }, // A 0xfbff + ARMv7_NULL_OP, // B + ARMv7_OP_4(MOVT, T1) // C 0xfbf0, 0x8000 +}; + +static void group_0xf2(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x00f0) >> 4; // mask 0xfbf0 + thr->m_last_instr_name = g_table_0xf2[index].name; + thr->m_last_instr_size = g_table_0xf2[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf2[index].func(thr, g_table_0xf2[index].type); +} + +static const ARMv7_Instruction g_table_0xf36[] = +{ + ARMv7_OP_4(BFI, T1), // 0 0xfff0, 0x8020 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // E + ARMv7_OP_4(BFC, T1) // F 0xffff, 0x8020 +}; + +static void group_0xf36(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if ((thr->m_arg & 0xfff08020) == 0xf3600000) index = 0x0; + + thr->m_last_instr_name = g_table_0xf36[index].name; + thr->m_last_instr_size = g_table_0xf36[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf36[index].func(thr, g_table_0xf36[index].type); +} + +static const ARMv7_Instruction g_table_0xf3[] = +{ + ARMv7_NULL_OP, // 0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_OP_4(SBFX, T1), // 4 0xfff0, 0x8020 + ARMv7_NULL_OP, // 5 + { group_0xf36 }, // 6 0xffff + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(MSR_REG, T1), // 8 0xfff0, 0xf3ff + ARMv7_NULL_OP, // 9 + ARMv7_OP_4(NOP, T2), // A 0xffff, 0xffff + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_OP_4(MRS, T1), // E 0xffff, 0xf0ff +}; + +static void group_0xf3(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x00f0) >> 4; + thr->m_last_instr_name = g_table_0xf3[index].name; + thr->m_last_instr_size = g_table_0xf3[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf3[index].func(thr, g_table_0xf3[index].type); +} + +static const ARMv7_Instruction g_table_0xf800[] = +{ + ARMv7_OP_4(STRB_REG, T2), // 0 0xfff0, 0x0fc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(STRB_IMM, T3) // 8 0xfff0, 0x0800 +}; + +static void group_0xf800(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code1 & 0x0f00) >> 8; + + if ((thr->code.code1 & 0x0800) == 0x0800) index = 0x8; + + thr->m_last_instr_name = g_table_0xf800[index].name; + thr->m_last_instr_size = g_table_0xf800[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf800[index].func(thr, g_table_0xf800[index].type); +} + +static const ARMv7_Instruction g_table_0xf810[] = +{ + ARMv7_OP_4(LDRB_REG, T2), // 0 0xfff0, 0x0fc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(LDRB_IMM, T3) // 8 0xfff0, 0x0800 +}; + +static void group_0xf810(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code1 & 0x0f00) >> 8; + + if ((thr->code.code1 & 0x0800) == 0x0800) index = 0x8; + + thr->m_last_instr_name = g_table_0xf810[index].name; + thr->m_last_instr_size = g_table_0xf810[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf810[index].func(thr, g_table_0xf810[index].type); +} + +static const ARMv7_Instruction g_table_0xf81[] = +{ + { group_0xf810 }, // 0 0xfff0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // E + ARMv7_OP_4(LDRB_LIT, T1) // F 0xff7f, 0x0000 +}; + +static void group_0xf81(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if (((thr->m_arg & 0xfff00fc0) == 0xf8100000) || ((thr->m_arg & 0xfff00800) == 0xf8100800)) index = 0x0; + + thr->m_last_instr_name = g_table_0xf81[index].name; + thr->m_last_instr_size = g_table_0xf81[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf81[index].func(thr, g_table_0xf81[index].type); +} + +static const ARMv7_Instruction g_table_0xf820[] = +{ + ARMv7_OP_4(STRH_REG, T2), // 0 0xfff0, 0x0fc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(STRH_IMM, T3) // 8 0xfff0, 0x0800 +}; + +static void group_0xf820(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code1 & 0x0f00) >> 8; + + if ((thr->code.code1 & 0x0800) == 0x0800) index = 0x8; + + thr->m_last_instr_name = g_table_0xf820[index].name; + thr->m_last_instr_size = g_table_0xf820[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf820[index].func(thr, g_table_0xf820[index].type); +} + +static const ARMv7_Instruction g_table_0xf840[] = +{ + ARMv7_OP_4(STR_REG, T2), // 0 0xfff0, 0x0fc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(STR_IMM, T4) // 8 0xfff0, 0x0800 +}; + +static void group_0xf840(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code1 & 0x0f00) >> 8; + + if ((thr->code.code1 & 0x0800) == 0x0800) index = 0x8; + + thr->m_last_instr_name = g_table_0xf840[index].name; + thr->m_last_instr_size = g_table_0xf840[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf840[index].func(thr, g_table_0xf840[index].type); +} + +static const ARMv7_Instruction g_table_0xf84[] = +{ + { group_0xf840 }, // 0 0xfff0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_OP_4(PUSH, T3) // D 0xffff, 0x0fff +}; + +static void group_0xf84(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if (((thr->m_arg & 0xfff00fc0) == 0xf8400000) || ((thr->m_arg & 0xfff00800) == 0xf8400800)) index = 0x0; + + thr->m_last_instr_name = g_table_0xf84[index].name; + thr->m_last_instr_size = g_table_0xf84[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf84[index].func(thr, g_table_0xf84[index].type); +} + +static const ARMv7_Instruction g_table_0xf850[] = +{ + ARMv7_OP_4(LDR_REG, T2), // 0 0xfff0, 0x0fc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(LDR_IMM, T4) // 8 0xfff0, 0x0800 +}; + +static void group_0xf850(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code1 & 0x0f00) >> 8; + + if ((thr->code.code1 & 0x0800) == 0x0800) index = 0x8; + + thr->m_last_instr_name = g_table_0xf850[index].name; + thr->m_last_instr_size = g_table_0xf850[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf850[index].func(thr, g_table_0xf850[index].type); +} + +static const ARMv7_Instruction g_table_0xf85[] = +{ + { group_0xf850 }, // 0 0xfff0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_OP_4(POP, T3), // D 0xffff, 0x0fff + ARMv7_NULL_OP, // C + ARMv7_OP_4(LDR_LIT, T2) // F 0xff7f, 0x0000 +}; + +static void group_0xf85(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if (((thr->m_arg & 0xfff00fc0) == 0xf8500000) || ((thr->m_arg & 0xfff00800) == 0xf8500800)) index = 0x0; + + thr->m_last_instr_name = g_table_0xf85[index].name; + thr->m_last_instr_size = g_table_0xf85[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf85[index].func(thr, g_table_0xf85[index].type); +} + +static const ARMv7_Instruction g_table_0xf8[] = +{ + { group_0xf800 }, // 0 0xfff0 + { group_0xf81 }, // 1 0xfff0 + { group_0xf820 }, // 2 0xfff0 + ARMv7_NULL_OP, // 3 + { group_0xf84 }, // 4 0xfff0 + { group_0xf85 }, // 5 0xfff0 + ARMv7_NULL_OP, // 6 + ARMv7_OP_4(HACK, T1), // 7 0xffff, 0x0000 + ARMv7_OP_4(STRB_IMM, T2), // 8 0xfff0, 0x0000 + ARMv7_OP_4(LDRB_IMM, T2), // 9 0xfff0, 0x0000 + ARMv7_OP_4(STRH_IMM, T2), // A 0xfff0, 0x0000 + ARMv7_NULL_OP, // B + ARMv7_OP_4(STR_IMM, T3), // C 0xfff0, 0x0000 + ARMv7_OP_4(LDR_IMM, T3) // D 0xfff0, 0x0000 +}; + +static void group_0xf8(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code0 & 0x00f0) >> 4; + thr->m_last_instr_name = g_table_0xf8[index].name; + thr->m_last_instr_size = g_table_0xf8[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf8[index].func(thr, g_table_0xf8[index].type); +} + +static const ARMv7_Instruction g_table_0xf910[] = +{ + ARMv7_OP_4(LDRSB_REG, T2), // 0 0xfff0, 0x0fc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(LDRSB_IMM, T2) // 8 0xfff0, 0x0800 +}; + +static void group_0xf910(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code1 & 0x0f00) >> 8; + + if ((thr->code.code1 & 0x0800) == 0x0800) index = 0x8; + + thr->m_last_instr_name = g_table_0xf910[index].name; + thr->m_last_instr_size = g_table_0xf910[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf910[index].func(thr, g_table_0xf910[index].type); +} + +static const ARMv7_Instruction g_table_0xf91[] = +{ + { group_0xf910 }, // 0 0xfff0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // C + ARMv7_OP_4(LDRSB_LIT, T1) // F 0xff7f, 0x0000 +}; + +static void group_0xf91(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if (((thr->m_arg & 0xfff00fc0) == 0xf9100000) || ((thr->m_arg & 0xfff00800) == 0xf9100800)) index = 0x0; + + thr->m_last_instr_name = g_table_0xf91[index].name; + thr->m_last_instr_size = g_table_0xf91[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf91[index].func(thr, g_table_0xf91[index].type); +} + +static const ARMv7_Instruction g_table_0xf930[] = +{ + ARMv7_OP_4(LDRSH_REG, T2), // 0 0xfff0, 0x0fc0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(LDRSH_IMM, T2) // 8 0xfff0, 0x0800 +}; + +static void group_0xf930(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code1 & 0x0f00) >> 8; + + if ((thr->code.code1 & 0x0800) == 0x0800) index = 0x8; + + thr->m_last_instr_name = g_table_0xf930[index].name; + thr->m_last_instr_size = g_table_0xf930[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf930[index].func(thr, g_table_0xf930[index].type); +} + +static const ARMv7_Instruction g_table_0xf93[] = +{ + { group_0xf930 }, // 0 0xfff0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // C + ARMv7_OP_4(LDRSH_LIT, T1) // F 0xff7f, 0x0000 +}; + +static void group_0xf93(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = thr->code.code0 & 0x000f; + + if (((thr->m_arg & 0xfff00fc0) == 0xf9300000) || ((thr->m_arg & 0xfff00800) == 0xf9300800)) index = 0x0; + + thr->m_last_instr_name = g_table_0xf93[index].name; + thr->m_last_instr_size = g_table_0xf93[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf93[index].func(thr, g_table_0xf93[index].type); +} + +static const ARMv7_Instruction g_table_0xf9[] = +{ + ARMv7_NULL_OP, // 0 + { group_0xf91 }, // 1 0xff7f + ARMv7_NULL_OP, // 2 + { group_0xf93 }, // 3 0xff7f + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_OP_4(LDRSB_IMM, T1), // 9 0xfff0, 0x0000 + ARMv7_NULL_OP, // A + ARMv7_OP_4(LDRSH_IMM, T1), // B 0xfff0, 0x0000 +}; + +static void group_0xf9(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x00f0) >> 4; + + if ((thr->code.code0 & 0xff7) == 0xf91) index = 0x1; // check me + if ((thr->code.code0 & 0xff7) == 0xf93) index = 0x3; + + thr->m_last_instr_name = g_table_0xf9[index].name; + thr->m_last_instr_size = g_table_0xf9[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf9[index].func(thr, g_table_0xf9[index].type); +} + +static const ARMv7_Instruction g_table_0xfa00[] = +{ + ARMv7_OP_4(BLX, A2), // 0 0xfe00, 0x0000 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + ARMv7_NULL_OP, // 9 + ARMv7_NULL_OP, // A + ARMv7_NULL_OP, // B + ARMv7_NULL_OP, // C + ARMv7_NULL_OP, // D + ARMv7_NULL_OP, // E + ARMv7_OP_4(LSL_REG, T2) // F 0xffe0, 0xf0f0 +}; + +static void group_0xfa00(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code1 & 0xf0f0) == 0xf000 ? 0xf : 0x0; + thr->m_last_instr_name = g_table_0xfa00[index].name; + thr->m_last_instr_size = g_table_0xfa00[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xfa00[index].func(thr, g_table_0xfa00[index].type); +} + +static const ARMv7_Instruction g_table_0xfa90[] = +{ + ARMv7_NULL_OP, // 0 + ARMv7_NULL_OP, // 1 + ARMv7_NULL_OP, // 2 + ARMv7_NULL_OP, // 3 + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + ARMv7_OP_4(REV, T2), // 8 0xfff0, 0xf0f0 + ARMv7_OP_4(REV16, T2), // 9 0xfff0, 0xf0f0 + ARMv7_OP_4(RBIT, T1), // A 0xfff0, 0xf0f0 + ARMv7_OP_4(REVSH, T2) // B 0xfff0, 0xf0f0 +}; + +static void group_0xfa90(ARMv7Thread* thr, const ARMv7_encoding type) +{ + const u32 index = (thr->code.code1 & 0x00f0) >> 4; + thr->m_last_instr_name = g_table_0xfa90[index].name; + thr->m_last_instr_size = g_table_0xfa90[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xfa90[index].func(thr, g_table_0xfa90[index].type); +} + +static const ARMv7_Instruction g_table_0xfa[] = +{ + { group_0xfa00 }, // 0 0xffe0 + ARMv7_NULL_OP, // 1 + ARMv7_OP_4(LSR_REG, T2), // 2 0xffe0, 0xf0f0 + ARMv7_NULL_OP, // 3 + ARMv7_OP_4(ASR_REG, T2), // 4 0xffe0, 0xf0f0 + ARMv7_NULL_OP, // 5 + ARMv7_OP_4(ROR_REG, T2), // 6 0xffe0, 0xf0f0 + ARMv7_NULL_OP, // 7 + ARMv7_NULL_OP, // 8 + { group_0xfa90 }, // 9 0xfff0 + ARMv7_OP_4(SEL, T1), // A 0xfff0, 0xf0f0 + ARMv7_OP_4(CLZ, T1) // B 0xfff0, 0xf0f0 +}; + +static void group_0xfa(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x00e0) >> 4; + + switch ((thr->code.code0 & 0x00f0) >> 4) + { + case 0x9: index = 0x9; break; + case 0xa: index = 0xa; break; + case 0xb: index = 0xb; break; + + default: break; + } + + thr->m_last_instr_name = g_table_0xfa[index].name; + thr->m_last_instr_size = g_table_0xfa[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xfa[index].func(thr, g_table_0xfa[index].type); +} + +static const ARMv7_Instruction g_table_0xf_main[] = +{ + { group_0xf0 }, // 0 0xfbef + { group_0xf1 }, // 1 0xfbef + { group_0xf2 }, // 2 0xfbff + { group_0xf3 }, // 3 0xffff + ARMv7_NULL_OP, // 4 + ARMv7_NULL_OP, // 5 + ARMv7_NULL_OP, // 6 + ARMv7_NULL_OP, // 7 + { group_0xf8 }, // 8 0xfff0 + { group_0xf9 }, // 9 0xfff0 + { group_0xfa }, // A 0xfff0 + +}; + +static void group_0xf(ARMv7Thread* thr, const ARMv7_encoding type) +{ + u32 index = (thr->code.code0 & 0x0b00) >> 8; + + switch ((thr->m_arg & 0x0800d000) >> 12) + { + case 0x8: // B, T3 + case 0x9: // B, T4 + case 0xd: index = 0x0; break; // BL, T1 + + default: break; + } + + if ((thr->m_arg & 0xf800c001) == 0xf000c000) index = 0x0; // BLX, T2 + + switch ((thr->code.code0 & 0x0f00) >> 8) + { + case 0x3: index = 0x3; break; + case 0x8: index = 0x8; break; + case 0x9: index = 0x9; break; + case 0xa: index = 0xa; break; + + default: break; + } + + thr->m_last_instr_name = g_table_0xf_main[index].name; + thr->m_last_instr_size = g_table_0xf_main[index].size; + thr->code.data = thr->m_last_instr_size == 2 ? thr->code.code0 : thr->m_arg; + g_table_0xf_main[index].func(thr, g_table_0xf_main[index].type); +} + +static const ARMv7_Instruction g_table_0xf[] = +{ + { group_0xf } +}; + + +static void execute_main_group(ARMv7Thread* thr) +{ + switch ((thr->code.code0 & 0xf000) >> 12) + { + //case 0x0: (*g_table_0x0).func(thr, (*g_table_0x0).type); break; // TODO + case 0x1: (*g_table_0x1).func(thr, (*g_table_0x1).type); break; + case 0x2: (*g_table_0x2).func(thr, (*g_table_0x2).type); break; + case 0x3: (*g_table_0x3).func(thr, (*g_table_0x3).type); break; + case 0x4: (*g_table_0x4).func(thr, (*g_table_0x4).type); break; + case 0x5: (*g_table_0x5).func(thr, (*g_table_0x5).type); break; + case 0x6: (*g_table_0x6).func(thr, (*g_table_0x6).type); break; + case 0x7: (*g_table_0x7).func(thr, (*g_table_0x7).type); break; + case 0x8: (*g_table_0x8).func(thr, (*g_table_0x8).type); break; + case 0x9: (*g_table_0x9).func(thr, (*g_table_0x9).type); break; + case 0xa: (*g_table_0xa).func(thr, (*g_table_0xa).type); break; + case 0xb: (*g_table_0xb).func(thr, (*g_table_0xb).type); break; + case 0xc: (*g_table_0xc).func(thr, (*g_table_0xc).type); break; + case 0xd: (*g_table_0xd).func(thr, (*g_table_0xd).type); break; + case 0xe: (*g_table_0xe).func(thr, (*g_table_0xe).type); break; + case 0xf: (*g_table_0xf).func(thr, (*g_table_0xf).type); break; + + default: LOG_ERROR(GENERAL, "ARMv7Decoder: unknown group 0x%x", (thr->code.code0 & 0xf000) >> 12); Emu.Pause(); break; + } +} + +#undef ARMv7_OP_2 +#undef ARMv7_OP_4 +#undef ARMv7_NULL_OP diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp index 40423d511d..c8a9e7c4b5 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp @@ -10,7 +10,11 @@ #include "ARMv7DisAsm.h" #include "ARMv7Interpreter.h" -ARMv7Thread::ARMv7Thread() : CPUThread(CPU_THREAD_ARMv7) +ARMv7Thread::ARMv7Thread() + : CPUThread(CPU_THREAD_ARMv7) + , m_arg(0) + , m_last_instr_size(0) + , m_last_instr_name("UNK") { } @@ -81,7 +85,7 @@ void ARMv7Thread::DoRun() case 1: case 2: - m_dec = new ARMv7Decoder(*new ARMv7Interpreter(*this)); + m_dec = new ARMv7Decoder(*this); break; } } diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.h b/rpcs3/Emu/ARMv7/ARMv7Thread.h index 543b19cf0c..ce63376273 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.h +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.h @@ -1,17 +1,23 @@ #pragma once + #include "Emu/CPU/CPUThread.h" +#include "Emu/Memory/Memory.h" enum ARMv7InstructionSet { ARM, Thumb, Jazelle, - ThumbEE, + ThumbEE }; class ARMv7Thread : public CPUThread { public: + u32 m_arg; + u8 m_last_instr_size; + const char* m_last_instr_name; + ARMv7Thread(); union @@ -61,6 +67,18 @@ public: } IPSR; + union + { + struct + { + u32 code1 : 16; + u32 code0 : 16; + }; + + u32 data; + + } code; + ARMv7InstructionSet ISET; union @@ -119,6 +137,13 @@ public: return PC; } + void update_code(const u32 address) + { + code.code0 = vm::psv::read16(address & ~1); + code.code1 = vm::psv::read16(address + 2 & ~1); + m_arg = address & 0x1 ? code.code1 << 16 | code.code0 : code.data; + } + public: virtual void InitRegs(); virtual void InitStack(); diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index 4957a393bd..7750fc5c9d 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -112,7 +112,8 @@ void InterpreterDisAsmFrame::UpdateUnitList() for(uint i=0; iAppend(thrs[i]->GetFName(), thrs[i]); + if (thrs[i]->GetType() != CPU_THREAD_ARMv7) + m_choice_units->Append(thrs[i]->GetFName(), thrs[i]); } m_choice_units->Thaw(); @@ -150,9 +151,9 @@ void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event) case CPU_THREAD_ARMv7: { - ARMv7DisAsm& dis_asm = *new ARMv7DisAsm(CPUDisAsm_InterpreterMode); - decoder = new ARMv7Decoder(dis_asm); - disasm = &dis_asm; + //ARMv7DisAsm& dis_asm = *new ARMv7DisAsm(CPUDisAsm_InterpreterMode); + //decoder = new ARMv7Decoder(dis_asm); + //disasm = &dis_asm; } break; } diff --git a/rpcs3/Loader/Loader.cpp b/rpcs3/Loader/Loader.cpp index e2567a60f0..e86b1d58e3 100644 --- a/rpcs3/Loader/Loader.cpp +++ b/rpcs3/Loader/Loader.cpp @@ -10,14 +10,19 @@ namespace loader { for (auto i : m_handlers) { - if (i->init(stream) == handler::ok) + i->set_status(i->init(stream)); + if (i->get_status() == handler::ok) { - if (i->load() == handler::ok) + i->set_status(i->load()); + if (i->get_status() == handler::ok) { return true; } + + LOG_ERROR(LOADER, "loader::load() failed: %s", i->get_error_code().c_str()); } + LOG_ERROR(LOADER, "loader::init() failed: %s", i->get_error_code().c_str()); stream.Seek(i->get_stream_offset()); } diff --git a/rpcs3/Loader/Loader.h b/rpcs3/Loader/Loader.h index 3e6fbf925a..9ff96b0dc5 100644 --- a/rpcs3/Loader/Loader.h +++ b/rpcs3/Loader/Loader.h @@ -15,7 +15,7 @@ enum Elf_Machine MACHINE_MIPS = 0x08, MACHINE_PPC64 = 0x15, MACHINE_SPU = 0x17, - MACHINE_ARM = 0x28, + MACHINE_ARM = 0x28 }; enum ShdrType @@ -31,7 +31,7 @@ enum ShdrType SHT_NOBITS, SHT_REL, SHT_SHLIB, - SHT_DYNSYM, + SHT_DYNSYM }; enum ShdrFlag @@ -39,7 +39,7 @@ enum ShdrFlag SHF_WRITE = 0x1, SHF_ALLOC = 0x2, SHF_EXECINSTR = 0x4, - SHF_MASKPROC = 0xf0000000, + SHF_MASKPROC = 0xf0000000 }; const std::string Ehdr_DataToString(const u8 data); @@ -117,7 +117,7 @@ namespace loader broken_file = -3, loading_error = -4, bad_relocation_type = -5, - ok = 0, + ok = 0 }; virtual ~handler() = default; @@ -128,6 +128,34 @@ namespace loader { return m_stream_offset; } + + void set_status(const error_code& code) + { + m_status = code; + } + + error_code get_status() const + { + return m_status; + } + + const std::string get_error_code() const + { + switch (m_status) + { + case bad_version: return "Bad version"; + case bad_file: return "Bad file"; + case broken_file: return "Broken file"; + case loading_error: return "Loading error"; + case bad_relocation_type: return "Bad relocation type"; + case ok: return "Ok"; + + default: return "Unknown error code"; + } + } + + protected: + error_code m_status; }; class loader