summaryrefslogtreecommitdiffstats
path: root/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/dyncom/arm_dyncom_interpreter.cpp')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp6289
1 files changed, 3300 insertions, 2989 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index c8d45c6db..211d49edb 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -11,29 +11,29 @@
#include "common/logging/log.h"
#include "common/microprofile.h"
-#include "core/memory.h"
-#include "core/hle/svc.h"
#include "core/arm/disassembler/arm_disasm.h"
#include "core/arm/dyncom/arm_dyncom_dec.h"
#include "core/arm/dyncom/arm_dyncom_interpreter.h"
+#include "core/arm/dyncom/arm_dyncom_run.h"
#include "core/arm/dyncom/arm_dyncom_thumb.h"
#include "core/arm/dyncom/arm_dyncom_trans.h"
-#include "core/arm/dyncom/arm_dyncom_run.h"
#include "core/arm/skyeye_common/armstate.h"
#include "core/arm/skyeye_common/armsupp.h"
#include "core/arm/skyeye_common/vfp/vfp.h"
+#include "core/hle/svc.h"
+#include "core/memory.h"
#include "core/gdbstub/gdbstub.h"
-#define RM BITS(sht_oper, 0, 3)
-#define RS BITS(sht_oper, 8, 11)
+#define RM BITS(sht_oper, 0, 3)
+#define RS BITS(sht_oper, 8, 11)
-#define glue(x, y) x ## y
-#define DPO(s) glue(DataProcessingOperands, s)
+#define glue(x, y) x##y
+#define DPO(s) glue(DataProcessingOperands, s)
#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i))
-#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
+#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
-#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
+#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
static bool CondPassed(const ARMul_State* cpu, unsigned int cond) {
const bool n_flag = cpu->NFlag != 0;
@@ -232,17 +232,19 @@ static unsigned int DPO(RotateRightByRegister)(ARMul_State* cpu, unsigned int sh
return shifter_operand;
}
-#define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0)
+#define DEBUG_MSG \
+ LOG_DEBUG(Core_ARM11, "inst is %x", inst); \
+ CITRA_IGNORE_EXIT(0)
-#define LnSWoUB(s) glue(LnSWoUB, s)
-#define MLnS(s) glue(MLnS, s)
-#define LdnStM(s) glue(LdnStM, s)
+#define LnSWoUB(s) glue(LnSWoUB, s)
+#define MLnS(s) glue(MLnS, s)
+#define LdnStM(s) glue(LdnStM, s)
-#define W_BIT BIT(inst, 21)
-#define U_BIT BIT(inst, 23)
-#define I_BIT BIT(inst, 25)
-#define P_BIT BIT(inst, 24)
-#define OFFSET_12 BITS(inst, 0, 11)
+#define W_BIT BIT(inst, 21)
+#define U_BIT BIT(inst, 23)
+#define I_BIT BIT(inst, 25)
+#define P_BIT BIT(inst, 24)
+#define OFFSET_12 BITS(inst, 0, 11)
static void LnSWoUB(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
unsigned int Rn = BITS(inst, 16, 19);
@@ -271,7 +273,8 @@ static void LnSWoUB(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigne
virt_addr = addr;
}
-static void LnSWoUB(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
+static void LnSWoUB(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
unsigned int Rn = BITS(inst, 16, 19);
unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
@@ -283,7 +286,8 @@ static void LnSWoUB(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, u
virt_addr = addr;
}
-static void LnSWoUB(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
+static void LnSWoUB(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
unsigned int Rn = BITS(inst, 16, 19);
unsigned int addr;
@@ -301,7 +305,7 @@ static void LnSWoUB(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, un
static void MLnS(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
unsigned int addr;
unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int Rm = BITS(inst, 0, 3);
unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
@@ -316,7 +320,8 @@ static void MLnS(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsign
cpu->Reg[Rn] = addr;
}
-static void LnSWoUB(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
+static void LnSWoUB(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
unsigned int Rn = BITS(inst, 16, 19);
unsigned int Rm = BITS(inst, 0, 3);
unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
@@ -335,7 +340,8 @@ static void LnSWoUB(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, uns
}
}
-static void LnSWoUB(ScaledRegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
+static void LnSWoUB(ScaledRegisterPreIndexed)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
unsigned int shift = BITS(inst, 5, 6);
unsigned int shift_imm = BITS(inst, 7, 11);
unsigned int Rn = BITS(inst, 16, 19);
@@ -386,7 +392,8 @@ static void LnSWoUB(ScaledRegisterPreIndexed)(ARMul_State* cpu, unsigned int ins
cpu->Reg[Rn] = addr;
}
-static void LnSWoUB(ScaledRegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
+static void LnSWoUB(ScaledRegisterPostIndexed)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
unsigned int shift = BITS(inst, 5, 6);
unsigned int shift_imm = BITS(inst, 7, 11);
unsigned int Rn = BITS(inst, 16, 19);
@@ -435,9 +442,10 @@ static void LnSWoUB(ScaledRegisterPostIndexed)(ARMul_State* cpu, unsigned int in
}
}
-static void LnSWoUB(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
+static void LnSWoUB(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int Rm = BITS(inst, 0, 3);
unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
@@ -454,7 +462,7 @@ static void LnSWoUB(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, un
static void MLnS(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
unsigned int immedL = BITS(inst, 0, 3);
unsigned int immedH = BITS(inst, 8, 11);
- unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int Rn = BITS(inst, 16, 19);
unsigned int addr;
unsigned int offset_8 = (immedH << 4) | immedL;
@@ -470,7 +478,7 @@ static void MLnS(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned
static void MLnS(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
unsigned int addr;
unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int Rm = BITS(inst, 0, 3);
unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
@@ -482,10 +490,11 @@ static void MLnS(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned i
virt_addr = addr;
}
-static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int immedL = BITS(inst, 0, 3);
+static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int immedH = BITS(inst, 8, 11);
+ unsigned int immedL = BITS(inst, 0, 3);
unsigned int addr;
unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
unsigned int offset_8 = (immedH << 4) | immedL;
@@ -501,10 +510,11 @@ static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsig
cpu->Reg[Rn] = addr;
}
-static void MLnS(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int immedH = BITS(inst, 8, 11);
- unsigned int immedL = BITS(inst, 0, 3);
+static void MLnS(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int immedH = BITS(inst, 8, 11);
+ unsigned int immedL = BITS(inst, 0, 3);
unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
virt_addr = rn;
@@ -520,9 +530,10 @@ static void MLnS(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, unsi
}
}
-static void MLnS(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
+static void MLnS(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
unsigned int Rn = BITS(inst, 16, 19);
- unsigned int Rm = BITS(inst, 0, 3);
+ unsigned int Rm = BITS(inst, 0, 3);
unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
virt_addr = CHECK_READ_REG15_WA(cpu, Rn);
@@ -541,7 +552,8 @@ static void LdnStM(DecrementBefore)(ARMul_State* cpu, unsigned int inst, unsigne
int count = 0;
while (i) {
- if (i & 1) count++;
+ if (i & 1)
+ count++;
i = i >> 1;
}
@@ -557,7 +569,8 @@ static void LdnStM(IncrementBefore)(ARMul_State* cpu, unsigned int inst, unsigne
int count = 0;
while (i) {
- if (i & 1) count++;
+ if (i & 1)
+ count++;
i = i >> 1;
}
@@ -572,8 +585,9 @@ static void LdnStM(IncrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned
unsigned int i = BITS(inst, 0, 15);
int count = 0;
- while(i) {
- if (i & 1) count++;
+ while (i) {
+ if (i & 1)
+ count++;
i = i >> 1;
}
@@ -587,8 +601,9 @@ static void LdnStM(DecrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned
unsigned int Rn = BITS(inst, 16, 19);
unsigned int i = BITS(inst, 0, 15);
int count = 0;
- while(i) {
- if(i & 1) count++;
+ while (i) {
+ if (i & 1)
+ count++;
i = i >> 1;
}
unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
@@ -601,7 +616,8 @@ static void LdnStM(DecrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned
}
}
-static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) {
+static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst,
+ unsigned int& virt_addr) {
unsigned int shift = BITS(inst, 5, 6);
unsigned int shift_imm = BITS(inst, 7, 11);
unsigned int Rn = BITS(inst, 16, 19);
@@ -693,17 +709,23 @@ get_addr_fp_t GetAddressingOp(unsigned int inst) {
return LnSWoUB(RegisterPostIndexed);
} else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
return LnSWoUB(ScaledRegisterPostIndexed);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 &&
+ BIT(inst, 4) == 1) {
return MLnS(ImmediateOffset);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 &&
+ BIT(inst, 4) == 1) {
return MLnS(RegisterOffset);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 &&
+ BIT(inst, 4) == 1) {
return MLnS(ImmediatePreIndexed);
- } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 &&
+ BIT(inst, 4) == 1) {
return MLnS(RegisterPreIndexed);
- } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 &&
+ BIT(inst, 4) == 1) {
return MLnS(ImmediatePostIndexed);
- } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
+ } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 &&
+ BIT(inst, 4) == 1) {
return MLnS(RegisterPostIndexed);
} else if (BITS(inst, 23, 27) == 0x11) {
return LdnStM(IncrementAfter);
@@ -732,14 +754,12 @@ get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst) {
return nullptr;
}
-enum {
- FETCH_SUCCESS,
- FETCH_FAILURE
-};
+enum { FETCH_SUCCESS, FETCH_FAILURE };
-static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) {
+static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size,
+ ARM_INST_PTR* ptr_inst_base) {
// Check if in Thumb mode
- ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size);
+ ThumbDecodeStatus ret = TranslateThumbInstruction(addr, inst, arm_inst, inst_size);
if (ret == ThumbDecodeStatus::BRANCH) {
int inst_index;
int table_length = arm_instruction_trans_len;
@@ -748,7 +768,7 @@ static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_ins
switch ((tinstr & 0xF800) >> 11) {
case 26:
case 27:
- if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
+ if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)) {
inst_index = table_length - 4;
*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
} else {
@@ -785,21 +805,21 @@ static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_ins
return ret;
}
-enum {
- KEEP_GOING,
- FETCH_EXCEPTION
-};
+enum { KEEP_GOING, FETCH_EXCEPTION };
MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64));
-static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr, ARM_INST_PTR& inst_base) {
+static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr,
+ ARM_INST_PTR& inst_base) {
unsigned int inst_size = 4;
unsigned int inst = Memory::Read32(phys_addr & 0xFFFFFFFC);
- // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction
+ // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM
+ // instruction
if (cpu->TFlag) {
u32 arm_inst;
- ThumbDecodeStatus state = DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
+ ThumbDecodeStatus state =
+ DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
// We have translated the Thumb branch instruction in the Thumb decoder
if (state == ThumbDecodeStatus::BRANCH) {
@@ -811,8 +831,10 @@ static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, cons
int idx;
if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) {
std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst);
- LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst);
- LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
+ LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr,
+ disasm.c_str(), inst);
+ LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag,
+ cpu->Reg[15]);
CITRA_IGNORE_EXIT(-1);
}
inst_base = arm_instruction_trans[idx](inst, idx);
@@ -875,12 +897,25 @@ static int InterpreterTranslateSingle(ARMul_State* cpu, int& bb_start, u32 addr)
static int clz(unsigned int x) {
int n;
- if (x == 0) return (32);
+ if (x == 0)
+ return (32);
n = 1;
- if ((x >> 16) == 0) { n = n + 16; x = x << 16;}
- if ((x >> 24) == 0) { n = n + 8; x = x << 8;}
- if ((x >> 28) == 0) { n = n + 4; x = x << 4;}
- if ((x >> 30) == 0) { n = n + 2; x = x << 2;}
+ if ((x >> 16) == 0) {
+ n = n + 16;
+ x = x << 16;
+ }
+ if ((x >> 24) == 0) {
+ n = n + 8;
+ x = x << 8;
+ }
+ if ((x >> 28) == 0) {
+ n = n + 4;
+ x = x << 4;
+ }
+ if ((x >> 30) == 0) {
+ n = n + 2;
+ x = x << 2;
+ }
n = n - (x >> 31);
return n;
}
@@ -892,310 +927,698 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
GDBStub::BreakpointAddress breakpoint_data;
- #undef RM
- #undef RS
-
- #define CRn inst_cream->crn
- #define OPCODE_1 inst_cream->opcode_1
- #define OPCODE_2 inst_cream->opcode_2
- #define CRm inst_cream->crm
- #define RD cpu->Reg[inst_cream->Rd]
- #define RD2 cpu->Reg[inst_cream->Rd + 1]
- #define RN cpu->Reg[inst_cream->Rn]
- #define RM cpu->Reg[inst_cream->Rm]
- #define RS cpu->Reg[inst_cream->Rs]
- #define RDHI cpu->Reg[inst_cream->RdHi]
- #define RDLO cpu->Reg[inst_cream->RdLo]
- #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
- #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
- #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
-
- #define FETCH_INST if (inst_base->br != TransExtData::NON_BRANCH) goto DISPATCH; \
- inst_base = (arm_inst *)&trans_cache_buf[ptr]
-
- #define INC_PC(l) ptr += sizeof(arm_inst) + l
- #define INC_PC_STUB ptr += sizeof(arm_inst)
-
-#define GDB_BP_CHECK \
- cpu->Cpsr &= ~(1 << 5); \
- cpu->Cpsr |= cpu->TFlag << 5; \
- if (GDBStub::g_server_enabled) { \
- if (GDBStub::IsMemoryBreak() || (breakpoint_data.type != GDBStub::BreakpointType::None && PC == breakpoint_data.address)) { \
- GDBStub::Break(); \
- goto END; \
- } \
+#undef RM
+#undef RS
+
+#define CRn inst_cream->crn
+#define OPCODE_1 inst_cream->opcode_1
+#define OPCODE_2 inst_cream->opcode_2
+#define CRm inst_cream->crm
+#define RD cpu->Reg[inst_cream->Rd]
+#define RD2 cpu->Reg[inst_cream->Rd + 1]
+#define RN cpu->Reg[inst_cream->Rn]
+#define RM cpu->Reg[inst_cream->Rm]
+#define RS cpu->Reg[inst_cream->Rs]
+#define RDHI cpu->Reg[inst_cream->RdHi]
+#define RDLO cpu->Reg[inst_cream->RdLo]
+#define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
+#define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
+#define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
+
+#define FETCH_INST \
+ if (inst_base->br != TransExtData::NON_BRANCH) \
+ goto DISPATCH; \
+ inst_base = (arm_inst*)&trans_cache_buf[ptr]
+
+#define INC_PC(l) ptr += sizeof(arm_inst) + l
+#define INC_PC_STUB ptr += sizeof(arm_inst)
+
+#define GDB_BP_CHECK \
+ cpu->Cpsr &= ~(1 << 5); \
+ cpu->Cpsr |= cpu->TFlag << 5; \
+ if (GDBStub::g_server_enabled) { \
+ if (GDBStub::IsMemoryBreak() || (breakpoint_data.type != GDBStub::BreakpointType::None && \
+ PC == breakpoint_data.address)) { \
+ GDBStub::Break(); \
+ goto END; \
+ } \
}
// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
// clunky switch statement.
#if defined __GNUC__ || defined __clang__
-#define GOTO_NEXT_INST \
- GDB_BP_CHECK; \
- if (num_instrs >= cpu->NumInstrsToExecute) goto END; \
- num_instrs++; \
- goto *InstLabel[inst_base->idx]
+#define GOTO_NEXT_INST \
+ GDB_BP_CHECK; \
+ if (num_instrs >= cpu->NumInstrsToExecute) \
+ goto END; \
+ num_instrs++; \
+ goto* InstLabel[inst_base->idx]
#else
-#define GOTO_NEXT_INST \
- GDB_BP_CHECK; \
- if (num_instrs >= cpu->NumInstrsToExecute) goto END; \
- num_instrs++; \
- switch(inst_base->idx) { \
- case 0: goto VMLA_INST; \
- case 1: goto VMLS_INST; \
- case 2: goto VNMLA_INST; \
- case 3: goto VNMLS_INST; \
- case 4: goto VNMUL_INST; \
- case 5: goto VMUL_INST; \
- case 6: goto VADD_INST; \
- case 7: goto VSUB_INST; \
- case 8: goto VDIV_INST; \
- case 9: goto VMOVI_INST; \
- case 10: goto VMOVR_INST; \
- case 11: goto VABS_INST; \
- case 12: goto VNEG_INST; \
- case 13: goto VSQRT_INST; \
- case 14: goto VCMP_INST; \
- case 15: goto VCMP2_INST; \
- case 16: goto VCVTBDS_INST; \
- case 17: goto VCVTBFF_INST; \
- case 18: goto VCVTBFI_INST; \
- case 19: goto VMOVBRS_INST; \
- case 20: goto VMSR_INST; \
- case 21: goto VMOVBRC_INST; \
- case 22: goto VMRS_INST; \
- case 23: goto VMOVBCR_INST; \
- case 24: goto VMOVBRRSS_INST; \
- case 25: goto VMOVBRRD_INST; \
- case 26: goto VSTR_INST; \
- case 27: goto VPUSH_INST; \
- case 28: goto VSTM_INST; \
- case 29: goto VPOP_INST; \
- case 30: goto VLDR_INST; \
- case 31: goto VLDM_INST ; \
- case 32: goto SRS_INST; \
- case 33: goto RFE_INST; \
- case 34: goto BKPT_INST; \
- case 35: goto BLX_INST; \
- case 36: goto CPS_INST; \
- case 37: goto PLD_INST; \
- case 38: goto SETEND_INST; \
- case 39: goto CLREX_INST; \
- case 40: goto REV16_INST; \
- case 41: goto USAD8_INST; \
- case 42: goto SXTB_INST; \
- case 43: goto UXTB_INST; \
- case 44: goto SXTH_INST; \
- case 45: goto SXTB16_INST; \
- case 46: goto UXTH_INST; \
- case 47: goto UXTB16_INST; \
- case 48: goto CPY_INST; \
- case 49: goto UXTAB_INST; \
- case 50: goto SSUB8_INST; \
- case 51: goto SHSUB8_INST; \
- case 52: goto SSUBADDX_INST; \
- case 53: goto STREX_INST; \
- case 54: goto STREXB_INST; \
- case 55: goto SWP_INST; \
- case 56: goto SWPB_INST; \
- case 57: goto SSUB16_INST; \
- case 58: goto SSAT16_INST; \
- case 59: goto SHSUBADDX_INST; \
- case 60: goto QSUBADDX_INST; \
- case 61: goto SHADDSUBX_INST; \
- case 62: goto SHADD8_INST; \
- case 63: goto SHADD16_INST; \
- case 64: goto SEL_INST; \
- case 65: goto SADDSUBX_INST; \
- case 66: goto SADD8_INST; \
- case 67: goto SADD16_INST; \
- case 68: goto SHSUB16_INST; \
- case 69: goto UMAAL_INST; \
- case 70: goto UXTAB16_INST; \
- case 71: goto USUBADDX_INST; \
- case 72: goto USUB8_INST; \
- case 73: goto USUB16_INST; \
- case 74: goto USAT16_INST; \
- case 75: goto USADA8_INST; \
- case 76: goto UQSUBADDX_INST; \
- case 77: goto UQSUB8_INST; \
- case 78: goto UQSUB16_INST; \
- case 79: goto UQADDSUBX_INST; \
- case 80: goto UQADD8_INST; \
- case 81: goto UQADD16_INST; \
- case 82: goto SXTAB_INST; \
- case 83: goto UHSUBADDX_INST; \
- case 84: goto UHSUB8_INST; \
- case 85: goto UHSUB16_INST; \
- case 86: goto UHADDSUBX_INST; \
- case 87: goto UHADD8_INST; \
- case 88: goto UHADD16_INST; \
- case 89: goto UADDSUBX_INST; \
- case 90: goto UADD8_INST; \
- case 91: goto UADD16_INST; \
- case 92: goto SXTAH_INST; \
- case 93: goto SXTAB16_INST; \
- case 94: goto QADD8_INST; \
- case 95: goto BXJ_INST; \
- case 96: goto CLZ_INST; \
- case 97: goto UXTAH_INST; \
- case 98: goto BX_INST; \
- case 99: goto REV_INST; \
- case 100: goto BLX_INST; \
- case 101: goto REVSH_INST; \
- case 102: goto QADD_INST; \
- case 103: goto QADD16_INST; \
- case 104: goto QADDSUBX_INST; \
- case 105: goto LDREX_INST; \
- case 106: goto QDADD_INST; \
- case 107: goto QDSUB_INST; \
- case 108: goto QSUB_INST; \
- case 109: goto LDREXB_INST; \
- case 110: goto QSUB8_INST; \
- case 111: goto QSUB16_INST; \
- case 112: goto SMUAD_INST; \
- case 113: goto SMMUL_INST; \
- case 114: goto SMUSD_INST; \
- case 115: goto SMLSD_INST; \
- case 116: goto SMLSLD_INST; \
- case 117: goto SMMLA_INST; \
- case 118: goto SMMLS_INST; \
- case 119: goto SMLALD_INST; \
- case 120: goto SMLAD_INST; \
- case 121: goto SMLAW_INST; \
- case 122: goto SMULW_INST; \
- case 123: goto PKHTB_INST; \
- case 124: goto PKHBT_INST; \
- case 125: goto SMUL_INST; \
- case 126: goto SMLALXY_INST; \
- case 127: goto SMLA_INST; \
- case 128: goto MCRR_INST; \
- case 129: goto MRRC_INST; \
- case 130: goto CMP_INST; \
- case 131: goto TST_INST; \
- case 132: goto TEQ_INST; \
- case 133: goto CMN_INST; \
- case 134: goto SMULL_INST; \
- case 135: goto UMULL_INST; \
- case 136: goto UMLAL_INST; \
- case 137: goto SMLAL_INST; \
- case 138: goto MUL_INST; \
- case 139: goto MLA_INST; \
- case 140: goto SSAT_INST; \
- case 141: goto USAT_INST; \
- case 142: goto MRS_INST; \
- case 143: goto MSR_INST; \
- case 144: goto AND_INST; \
- case 145: goto BIC_INST; \
- case 146: goto LDM_INST; \
- case 147: goto EOR_INST; \
- case 148: goto ADD_INST; \
- case 149: goto RSB_INST; \
- case 150: goto RSC_INST; \
- case 151: goto SBC_INST; \
- case 152: goto ADC_INST; \
- case 153: goto SUB_INST; \
- case 154: goto ORR_INST; \
- case 155: goto MVN_INST; \
- case 156: goto MOV_INST; \
- case 157: goto STM_INST; \
- case 158: goto LDM_INST; \
- case 159: goto LDRSH_INST; \
- case 160: goto STM_INST; \
- case 161: goto LDM_INST; \
- case 162: goto LDRSB_INST; \
- case 163: goto STRD_INST; \
- case 164: goto LDRH_INST; \
- case 165: goto STRH_INST; \
- case 166: goto LDRD_INST; \
- case 167: goto STRT_INST; \
- case 168: goto STRBT_INST; \
- case 169: goto LDRBT_INST; \
- case 170: goto LDRT_INST; \
- case 171: goto MRC_INST; \
- case 172: goto MCR_INST; \
- case 173: goto MSR_INST; \
- case 174: goto MSR_INST; \
- case 175: goto MSR_INST; \
- case 176: goto MSR_INST; \
- case 177: goto MSR_INST; \
- case 178: goto LDRB_INST; \
- case 179: goto STRB_INST; \
- case 180: goto LDR_INST; \
- case 181: goto LDRCOND_INST ; \
- case 182: goto STR_INST; \
- case 183: goto CDP_INST; \
- case 184: goto STC_INST; \
- case 185: goto LDC_INST; \
- case 186: goto LDREXD_INST; \
- case 187: goto STREXD_INST; \
- case 188: goto LDREXH_INST; \
- case 189: goto STREXH_INST; \
- case 190: goto NOP_INST; \
- case 191: goto YIELD_INST; \
- case 192: goto WFE_INST; \
- case 193: goto WFI_INST; \
- case 194: goto SEV_INST; \
- case 195: goto SWI_INST; \
- case 196: goto BBL_INST; \
- case 197: goto B_2_THUMB ; \
- case 198: goto B_COND_THUMB ; \
- case 199: goto BL_1_THUMB ; \
- case 200: goto BL_2_THUMB ; \
- case 201: goto BLX_1_THUMB ; \
- case 202: goto DISPATCH; \
- case 203: goto INIT_INST_LENGTH; \
- case 204: goto END; \
+#define GOTO_NEXT_INST \
+ GDB_BP_CHECK; \
+ if (num_instrs >= cpu->NumInstrsToExecute) \
+ goto END; \
+ num_instrs++; \
+ switch (inst_base->idx) { \
+ case 0: \
+ goto VMLA_INST; \
+ case 1: \
+ goto VMLS_INST; \
+ case 2: \
+ goto VNMLA_INST; \
+ case 3: \
+ goto VNMLS_INST; \
+ case 4: \
+ goto VNMUL_INST; \
+ case 5: \
+ goto VMUL_INST; \
+ case 6: \
+ goto VADD_INST; \
+ case 7: \
+ goto VSUB_INST; \
+ case 8: \
+ goto VDIV_INST; \
+ case 9: \
+ goto VMOVI_INST; \
+ case 10: \
+ goto VMOVR_INST; \
+ case 11: \
+ goto VABS_INST; \
+ case 12: \
+ goto VNEG_INST; \
+ case 13: \
+ goto VSQRT_INST; \
+ case 14: \
+ goto VCMP_INST; \
+ case 15: \
+ goto VCMP2_INST; \
+ case 16: \
+ goto VCVTBDS_INST; \
+ case 17: \
+ goto VCVTBFF_INST; \
+ case 18: \
+ goto VCVTBFI_INST; \
+ case 19: \
+ goto VMOVBRS_INST; \
+ case 20: \
+ goto VMSR_INST; \
+ case 21: \
+ goto VMOVBRC_INST; \
+ case 22: \
+ goto VMRS_INST; \
+ case 23: \
+ goto VMOVBCR_INST; \
+ case 24: \
+ goto VMOVBRRSS_INST; \
+ case 25: \
+ goto VMOVBRRD_INST; \
+ case 26: \
+ goto VSTR_INST; \
+ case 27: \
+ goto VPUSH_INST; \
+ case 28: \
+ goto VSTM_INST; \
+ case 29: \
+ goto VPOP_INST; \
+ case 30: \
+ goto VLDR_INST; \
+ case 31: \
+ goto VLDM_INST; \
+ case 32: \
+ goto SRS_INST; \
+ case 33: \
+ goto RFE_INST; \
+ case 34: \
+ goto BKPT_INST; \
+ case 35: \
+ goto BLX_INST; \
+ case 36: \
+ goto CPS_INST; \
+ case 37: \
+ goto PLD_INST; \
+ case 38: \
+ goto SETEND_INST; \
+ case 39: \
+ goto CLREX_INST; \
+ case 40: \
+ goto REV16_INST; \
+ case 41: \
+ goto USAD8_INST; \
+ case 42: \
+ goto SXTB_INST; \
+ case 43: \
+ goto UXTB_INST; \
+ case 44: \
+ goto SXTH_INST; \
+ case 45: \
+ goto SXTB16_INST; \
+ case 46: \
+ goto UXTH_INST; \
+ case 47: \
+ goto UXTB16_INST; \
+ case 48: \
+ goto CPY_INST; \
+ case 49: \
+ goto UXTAB_INST; \
+ case 50: \
+ goto SSUB8_INST; \
+ case 51: \
+ goto SHSUB8_INST; \
+ case 52: \
+ goto SSUBADDX_INST; \
+ case 53: \
+ goto STREX_INST; \
+ case 54: \
+ goto STREXB_INST; \
+ case 55: \
+ goto SWP_INST; \
+ case 56: \
+ goto SWPB_INST; \
+ case 57: \
+ goto SSUB16_INST; \
+ case 58: \
+ goto SSAT16_INST; \
+ case 59: \
+ goto SHSUBADDX_INST; \
+ case 60: \
+ goto QSUBADDX_INST; \
+ case 61: \
+ goto SHADDSUBX_INST; \
+ case 62: \
+ goto SHADD8_INST; \
+ case 63: \
+ goto SHADD16_INST; \
+ case 64: \
+ goto SEL_INST; \
+ case 65: \
+ goto SADDSUBX_INST; \
+ case 66: \
+ goto SADD8_INST; \
+ case 67: \
+ goto SADD16_INST; \
+ case 68: \
+ goto SHSUB16_INST; \
+ case 69: \
+ goto UMAAL_INST; \
+ case 70: \
+ goto UXTAB16_INST; \
+ case 71: \
+ goto USUBADDX_INST; \
+ case 72: \
+ goto USUB8_INST; \
+ case 73: \
+ goto USUB16_INST; \
+ case 74: \
+ goto USAT16_INST; \
+ case 75: \
+ goto USADA8_INST; \
+ case 76: \
+ goto UQSUBADDX_INST; \
+ case 77: \
+ goto UQSUB8_INST; \
+ case 78: \
+ goto UQSUB16_INST; \
+ case 79: \
+ goto UQADDSUBX_INST; \
+ case 80: \
+ goto UQADD8_INST; \
+ case 81: \
+ goto UQADD16_INST; \
+ case 82: \
+ goto SXTAB_INST; \
+ case 83: \
+ goto UHSUBADDX_INST; \
+ case 84: \
+ goto UHSUB8_INST; \
+ case 85: \
+ goto UHSUB16_INST; \
+ case 86: \
+ goto UHADDSUBX_INST; \
+ case 87: \
+ goto UHADD8_INST; \
+ case 88: \
+ goto UHADD16_INST; \
+ case 89: \
+ goto UADDSUBX_INST; \
+ case 90: \
+ goto UADD8_INST; \
+ case 91: \
+ goto UADD16_INST; \
+ case 92: \
+ goto SXTAH_INST; \
+ case 93: \
+ goto SXTAB16_INST; \
+ case 94: \
+ goto QADD8_INST; \
+ case 95: \
+ goto BXJ_INST; \
+ case 96: \
+ goto CLZ_INST; \
+ case 97: \
+ goto UXTAH_INST; \
+ case 98: \
+ goto BX_INST; \
+ case 99: \
+ goto REV_INST; \
+ case 100: \
+ goto BLX_INST; \
+ case 101: \
+ goto REVSH_INST; \
+ case 102: \
+ goto QADD_INST; \
+ case 103: \
+ goto QADD16_INST; \
+ case 104: \
+ goto QADDSUBX_INST; \
+ case 105: \
+ goto LDREX_INST; \
+ case 106: \
+ goto QDADD_INST; \
+ case 107: \
+ goto QDSUB_INST; \
+ case 108: \
+ goto QSUB_INST; \
+ case 109: \
+ goto LDREXB_INST; \
+ case 110: \
+ goto QSUB8_INST; \
+ case 111: \
+ goto QSUB16_INST; \
+ case 112: \
+ goto SMUAD_INST; \
+ case 113: \
+ goto SMMUL_INST; \
+ case 114: \
+ goto SMUSD_INST; \
+ case 115: \
+ goto SMLSD_INST; \
+ case 116: \
+ goto SMLSLD_INST; \
+ case 117: \
+ goto SMMLA_INST; \
+ case 118: \
+ goto SMMLS_INST; \
+ case 119: \
+ goto SMLALD_INST; \
+ case 120: \
+ goto SMLAD_INST; \
+ case 121: \
+ goto SMLAW_INST; \
+ case 122: \
+ goto SMULW_INST; \
+ case 123: \
+ goto PKHTB_INST; \
+ case 124: \
+ goto PKHBT_INST; \
+ case 125: \
+ goto SMUL_INST; \
+ case 126: \
+ goto SMLALXY_INST; \
+ case 127: \
+ goto SMLA_INST; \
+ case 128: \
+ goto MCRR_INST; \
+ case 129: \
+ goto MRRC_INST; \
+ case 130: \
+ goto CMP_INST; \
+ case 131: \
+ goto TST_INST; \
+ case 132: \
+ goto TEQ_INST; \
+ case 133: \
+ goto CMN_INST; \
+ case 134: \
+ goto SMULL_INST; \
+ case 135: \
+ goto UMULL_INST; \
+ case 136: \
+ goto UMLAL_INST; \
+ case 137: \
+ goto SMLAL_INST; \
+ case 138: \
+ goto MUL_INST; \
+ case 139: \
+ goto MLA_INST; \
+ case 140: \
+ goto SSAT_INST; \
+ case 141: \
+ goto USAT_INST; \
+ case 142: \
+ goto MRS_INST; \
+ case 143: \
+ goto MSR_INST; \
+ case 144: \
+ goto AND_INST; \
+ case 145: \
+ goto BIC_INST; \
+ case 146: \
+ goto LDM_INST; \
+ case 147: \
+ goto EOR_INST; \
+ case 148: \
+ goto ADD_INST; \
+ case 149: \
+ goto RSB_INST; \
+ case 150: \
+ goto RSC_INST; \
+ case 151: \
+ goto SBC_INST; \
+ case 152: \
+ goto ADC_INST; \
+ case 153: \
+ goto SUB_INST; \
+ case 154: \
+ goto ORR_INST; \
+ case 155: \
+ goto MVN_INST; \
+ case 156: \
+ goto MOV_INST; \
+ case 157: \
+ goto STM_INST; \
+ case 158: \
+ goto LDM_INST; \
+ case 159: \
+ goto LDRSH_INST; \
+ case 160: \
+ goto STM_INST; \
+ case 161: \
+ goto LDM_INST; \
+ case 162: \
+ goto LDRSB_INST; \
+ case 163: \
+ goto STRD_INST; \
+ case 164: \
+ goto LDRH_INST; \
+ case 165: \
+ goto STRH_INST; \
+ case 166: \
+ goto LDRD_INST; \
+ case 167: \
+ goto STRT_INST; \
+ case 168: \
+ goto STRBT_INST; \
+ case 169: \
+ goto LDRBT_INST; \
+ case 170: \
+ goto LDRT_INST; \
+ case 171: \
+ goto MRC_INST; \
+ case 172: \
+ goto MCR_INST; \
+ case 173: \
+ goto MSR_INST; \
+ case 174: \
+ goto MSR_INST; \
+ case 175: \
+ goto MSR_INST; \
+ case 176: \
+ goto MSR_INST; \
+ case 177: \
+ goto MSR_INST; \
+ case 178: \
+ goto LDRB_INST; \
+ case 179: \
+ goto STRB_INST; \
+ case 180: \
+ goto LDR_INST; \
+ case 181: \
+ goto LDRCOND_INST; \
+ case 182: \
+ goto STR_INST; \
+ case 183: \
+ goto CDP_INST; \
+ case 184: \
+ goto STC_INST; \
+ case 185: \
+ goto LDC_INST; \
+ case 186: \
+ goto LDREXD_INST; \
+ case 187: \
+ goto STREXD_INST; \
+ case 188: \
+ goto LDREXH_INST; \
+ case 189: \
+ goto STREXH_INST; \
+ case 190: \
+ goto NOP_INST; \
+ case 191: \
+ goto YIELD_INST; \
+ case 192: \
+ goto WFE_INST; \
+ case 193: \
+ goto WFI_INST; \
+ case 194: \
+ goto SEV_INST; \
+ case 195: \
+ goto SWI_INST; \
+ case 196: \
+ goto BBL_INST; \
+ case 197: \
+ goto B_2_THUMB; \
+ case 198: \
+ goto B_COND_THUMB; \
+ case 199: \
+ goto BL_1_THUMB; \
+ case 200: \
+ goto BL_2_THUMB; \
+ case 201: \
+ goto BLX_1_THUMB; \
+ case 202: \
+ goto DISPATCH; \
+ case 203: \
+ goto INIT_INST_LENGTH; \
+ case 204: \
+ goto END; \
}
#endif
- #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
- #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
- #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out)
-
- #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \
- (cpu->NFlag << 31) | \
- (cpu->ZFlag << 30) | \
- (cpu->CFlag << 29) | \
- (cpu->VFlag << 28) | \
- (cpu->TFlag << 5)
- #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \
- cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
- cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
- cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
- cpu->TFlag = (cpu->Cpsr >> 5) & 1;
-
- #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
- #define PC (cpu->Reg[15])
-
- // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
- // to a clunky switch statement.
+#define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
+#define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
+#define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out)
+
+#define SAVE_NZCVT \
+ cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | (cpu->NFlag << 31) | (cpu->ZFlag << 30) | \
+ (cpu->CFlag << 29) | (cpu->VFlag << 28) | (cpu->TFlag << 5)
+#define LOAD_NZCVT \
+ cpu->NFlag = (cpu->Cpsr >> 31); \
+ cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
+ cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
+ cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
+ cpu->TFlag = (cpu->Cpsr >> 5) & 1;
+
+#define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
+#define PC (cpu->Reg[15])
+
+// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
+// to a clunky switch statement.
#if defined __GNUC__ || defined __clang__
- void *InstLabel[] = {
- &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST,
- &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST,
- &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST,
- &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST,
-
- &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
- &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
- &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
- &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST,
- &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST,
- &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST,
- &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST,
- &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST,
- &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST,
- &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST,
- &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST,
- &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
- &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
- &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,
- &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST,
- &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST, &&LDREXD_INST,
- &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST, &&NOP_INST, &&YIELD_INST, &&WFE_INST, &&WFI_INST, &&SEV_INST, &&SWI_INST,&&BBL_INST,
- &&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,
- &&INIT_INST_LENGTH,&&END
- };
+ void* InstLabel[] = {&&VMLA_INST,
+ &&VMLS_INST,
+ &&VNMLA_INST,
+ &&VNMLS_INST,
+ &&VNMUL_INST,
+ &&VMUL_INST,
+ &&VADD_INST,
+ &&VSUB_INST,
+ &&VDIV_INST,
+ &&VMOVI_INST,
+ &&VMOVR_INST,
+ &&VABS_INST,
+ &&VNEG_INST,
+ &&VSQRT_INST,
+ &&VCMP_INST,
+ &&VCMP2_INST,
+ &&VCVTBDS_INST,
+ &&VCVTBFF_INST,
+ &&VCVTBFI_INST,
+ &&VMOVBRS_INST,
+ &&VMSR_INST,
+ &&VMOVBRC_INST,
+ &&VMRS_INST,
+ &&VMOVBCR_INST,
+ &&VMOVBRRSS_INST,
+ &&VMOVBRRD_INST,
+ &&VSTR_INST,
+ &&VPUSH_INST,
+ &&VSTM_INST,
+ &&VPOP_INST,
+ &&VLDR_INST,
+ &&VLDM_INST,
+
+ &&SRS_INST,
+ &&RFE_INST,
+ &&BKPT_INST,
+ &&BLX_INST,
+ &&CPS_INST,
+ &&PLD_INST,
+ &&SETEND_INST,
+ &&CLREX_INST,
+ &&REV16_INST,
+ &&USAD8_INST,
+ &&SXTB_INST,
+ &&UXTB_INST,
+ &&SXTH_INST,
+ &&SXTB16_INST,
+ &&UXTH_INST,
+ &&UXTB16_INST,
+ &&CPY_INST,
+ &&UXTAB_INST,
+ &&SSUB8_INST,
+ &&SHSUB8_INST,
+ &&SSUBADDX_INST,
+ &&STREX_INST,
+ &&STREXB_INST,
+ &&SWP_INST,
+ &&SWPB_INST,
+ &&SSUB16_INST,
+ &&SSAT16_INST,
+ &&SHSUBADDX_INST,
+ &&QSUBADDX_INST,
+ &&SHADDSUBX_INST,
+ &&SHADD8_INST,
+ &&SHADD16_INST,
+ &&SEL_INST,
+ &&SADDSUBX_INST,
+ &&SADD8_INST,
+ &&SADD16_INST,
+ &&SHSUB16_INST,
+ &&UMAAL_INST,
+ &&UXTAB16_INST,
+ &&USUBADDX_INST,
+ &&USUB8_INST,
+ &&USUB16_INST,
+ &&USAT16_INST,
+ &&USADA8_INST,
+ &&UQSUBADDX_INST,
+ &&UQSUB8_INST,
+ &&UQSUB16_INST,
+ &&UQADDSUBX_INST,
+ &&UQADD8_INST,
+ &&UQADD16_INST,
+ &&SXTAB_INST,
+ &&UHSUBADDX_INST,
+ &&UHSUB8_INST,
+ &&UHSUB16_INST,
+ &&UHADDSUBX_INST,
+ &&UHADD8_INST,
+ &&UHADD16_INST,
+ &&UADDSUBX_INST,
+ &&UADD8_INST,
+ &&UADD16_INST,
+ &&SXTAH_INST,
+ &&SXTAB16_INST,
+ &&QADD8_INST,
+ &&BXJ_INST,
+ &&CLZ_INST,
+ &&UXTAH_INST,
+ &&BX_INST,
+ &&REV_INST,
+ &&BLX_INST,
+ &&REVSH_INST,
+ &&QADD_INST,
+ &&QADD16_INST,
+ &&QADDSUBX_INST,
+ &&LDREX_INST,
+ &&QDADD_INST,
+ &&QDSUB_INST,
+ &&QSUB_INST,
+ &&LDREXB_INST,
+ &&QSUB8_INST,
+ &&QSUB16_INST,
+ &&SMUAD_INST,
+ &&SMMUL_INST,
+ &&SMUSD_INST,
+ &&SMLSD_INST,
+ &&SMLSLD_INST,
+ &&SMMLA_INST,
+ &&SMMLS_INST,
+ &&SMLALD_INST,
+ &&SMLAD_INST,
+ &&SMLAW_INST,
+ &&SMULW_INST,
+ &&PKHTB_INST,
+ &&PKHBT_INST,
+ &&SMUL_INST,
+ &&SMLALXY_INST,
+ &&SMLA_INST,
+ &&MCRR_INST,
+ &&MRRC_INST,
+ &&CMP_INST,
+ &&TST_INST,
+ &&TEQ_INST,
+ &&CMN_INST,
+ &&SMULL_INST,
+ &&UMULL_INST,
+ &&UMLAL_INST,
+ &&SMLAL_INST,
+ &&MUL_INST,
+ &&MLA_INST,
+ &&SSAT_INST,
+ &&USAT_INST,
+ &&MRS_INST,
+ &&MSR_INST,
+ &&AND_INST,
+ &&BIC_INST,
+ &&LDM_INST,
+ &&EOR_INST,
+ &&ADD_INST,
+ &&RSB_INST,
+ &&RSC_INST,
+ &&SBC_INST,
+ &&ADC_INST,
+ &&SUB_INST,
+ &&ORR_INST,
+ &&MVN_INST,
+ &&MOV_INST,
+ &&STM_INST,
+ &&LDM_INST,
+ &&LDRSH_INST,
+ &&STM_INST,
+ &&LDM_INST,
+ &&LDRSB_INST,
+ &&STRD_INST,
+ &&LDRH_INST,
+ &&STRH_INST,
+ &&LDRD_INST,
+ &&STRT_INST,
+ &&STRBT_INST,
+ &&LDRBT_INST,
+ &&LDRT_INST,
+ &&MRC_INST,
+ &&MCR_INST,
+ &&MSR_INST,
+ &&MSR_INST,
+ &&MSR_INST,
+ &&MSR_INST,
+ &&MSR_INST,
+ &&LDRB_INST,
+ &&STRB_INST,
+ &&LDR_INST,
+ &&LDRCOND_INST,
+ &&STR_INST,
+ &&CDP_INST,
+ &&STC_INST,
+ &&LDC_INST,
+ &&LDREXD_INST,
+ &&STREXD_INST,
+ &&LDREXH_INST,
+ &&STREXH_INST,
+ &&NOP_INST,
+ &&YIELD_INST,
+ &&WFE_INST,
+ &&WFI_INST,
+ &&SEV_INST,
+ &&SWI_INST,
+ &&BBL_INST,
+ &&B_2_THUMB,
+ &&B_COND_THUMB,
+ &&BL_1_THUMB,
+ &&BL_2_THUMB,
+ &&BLX_1_THUMB,
+ &&DISPATCH,
+ &&INIT_INST_LENGTH,
+ &&END};
#endif
arm_inst* inst_base;
unsigned int addr;
@@ -1204,516 +1627,517 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
int ptr;
LOAD_NZCVT;
- DISPATCH:
- {
- if (!cpu->NirqSig) {
- if (!(cpu->Cpsr & 0x80)) {
- goto END;
- }
+DISPATCH : {
+ if (!cpu->NirqSig) {
+ if (!(cpu->Cpsr & 0x80)) {
+ goto END;
}
+ }
- if (cpu->TFlag)
- cpu->Reg[15] &= 0xfffffffe;
- else
- cpu->Reg[15] &= 0xfffffffc;
-
- // Find the cached instruction cream, otherwise translate it...
- auto itr = cpu->instruction_cache.find(cpu->Reg[15]);
- if (itr != cpu->instruction_cache.end()) {
- ptr = itr->second;
- } else if (cpu->NumInstrsToExecute != 1) {
- if (InterpreterTranslateBlock(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
- goto END;
- } else {
- if (InterpreterTranslateSingle(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
- goto END;
- }
+ if (cpu->TFlag)
+ cpu->Reg[15] &= 0xfffffffe;
+ else
+ cpu->Reg[15] &= 0xfffffffc;
+
+ // Find the cached instruction cream, otherwise translate it...
+ auto itr = cpu->instruction_cache.find(cpu->Reg[15]);
+ if (itr != cpu->instruction_cache.end()) {
+ ptr = itr->second;
+ } else if (cpu->NumInstrsToExecute != 1) {
+ if (InterpreterTranslateBlock(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
+ goto END;
+ } else {
+ if (InterpreterTranslateSingle(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
+ goto END;
+ }
- // Find breakpoint if one exists within the block
- if (GDBStub::g_server_enabled && GDBStub::IsConnected()) {
- breakpoint_data = GDBStub::GetNextBreakpointFromAddress(cpu->Reg[15], GDBStub::BreakpointType::Execute);
- }
+ // Find breakpoint if one exists within the block
+ if (GDBStub::g_server_enabled && GDBStub::IsConnected()) {
+ breakpoint_data =
+ GDBStub::GetNextBreakpointFromAddress(cpu->Reg[15], GDBStub::BreakpointType::Execute);
+ }
- inst_base = (arm_inst *)&trans_cache_buf[ptr];
- GOTO_NEXT_INST;
+ inst_base = (arm_inst*)&trans_cache_buf[ptr];
+ GOTO_NEXT_INST;
+}
+ADC_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ adc_inst* const inst_cream = (adc_inst*)inst_base->component;
+
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
+
+ bool carry;
+ bool overflow;
+ RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ cpu->CFlag = carry;
+ cpu->VFlag = overflow;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(adc_inst));
+ goto DISPATCH;
+ }
}
- ADC_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- adc_inst* const inst_cream = (adc_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(adc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+ADD_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ add_inst* const inst_cream = (add_inst*)inst_base->component;
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
+ u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn);
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+ bool carry;
+ bool overflow;
+ RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(adc_inst));
- goto DISPATCH;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
+ LOAD_NZCVT;
}
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ cpu->CFlag = carry;
+ cpu->VFlag = overflow;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(adc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- ADD_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- add_inst* const inst_cream = (add_inst*)inst_base->component;
-
- u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn);
-
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(add_inst));
- goto DISPATCH;
- }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(add_inst));
+ goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(add_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- AND_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- and_inst* const inst_cream = (and_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(add_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+AND_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ and_inst* const inst_cream = (and_inst*)inst_base->component;
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
+ u32 lop = RN;
+ u32 rop = SHIFTER_OPERAND;
- if (inst_cream->Rn == 15)
- lop += 2 * cpu->GetInstructionSize();
+ if (inst_cream->Rn == 15)
+ lop += 2 * cpu->GetInstructionSize();
- RD = lop & rop;
+ RD = lop & rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(and_inst));
- goto DISPATCH;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
+ LOAD_NZCVT;
}
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ UPDATE_CFLAG_WITH_SC;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(and_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BBL_INST:
- {
- if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
- bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
- if (inst_cream->L) {
- LINK_RTN_ADDR;
- }
- SET_PC;
- INC_PC(sizeof(bbl_inst));
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(and_inst));
goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(and_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+BBL_INST : {
+ if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
+ bbl_inst* inst_cream = (bbl_inst*)inst_base->component;
+ if (inst_cream->L) {
+ LINK_RTN_ADDR;
+ }
+ SET_PC;
INC_PC(sizeof(bbl_inst));
goto DISPATCH;
}
- BIC_INST:
- {
- bic_inst *inst_cream = (bic_inst *)inst_base->component;
- if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
- u32 lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * cpu->GetInstructionSize();
- }
- u32 rop = SHIFTER_OPERAND;
- RD = lop & (~rop);
- if ((inst_cream->S) && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(bic_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bic_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BKPT_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
- LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(bbl_inst));
+ goto DISPATCH;
+}
+BIC_INST : {
+ bic_inst* inst_cream = (bic_inst*)inst_base->component;
+ if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
+ u32 lop = RN;
+ if (inst_cream->Rn == 15) {
+ lop += 2 * cpu->GetInstructionSize();
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bkpt_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BLX_INST:
- {
- blx_inst *inst_cream = (blx_inst *)inst_base->component;
- if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
- unsigned int inst = inst_cream->inst;
- if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
- const u32 jump_address = cpu->Reg[inst_cream->val.Rm];
- cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
- if(cpu->TFlag)
- cpu->Reg[14] |= 0x1;
- cpu->Reg[15] = jump_address & 0xfffffffe;
- cpu->TFlag = jump_address & 0x1;
- } else {
- cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
- cpu->TFlag = 0x1;
- int signed_int = inst_cream->val.signed_immed_24;
- signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int;
- signed_int = signed_int << 2;
- cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1);
+ u32 rop = SHIFTER_OPERAND;
+ RD = lop & (~rop);
+ if ((inst_cream->S) && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
}
- INC_PC(sizeof(blx_inst));
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(bic_inst));
goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(bic_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+BKPT_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
+ LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(bkpt_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+BLX_INST : {
+ blx_inst* inst_cream = (blx_inst*)inst_base->component;
+ if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int inst = inst_cream->inst;
+ if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
+ const u32 jump_address = cpu->Reg[inst_cream->val.Rm];
+ cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
+ if (cpu->TFlag)
+ cpu->Reg[14] |= 0x1;
+ cpu->Reg[15] = jump_address & 0xfffffffe;
+ cpu->TFlag = jump_address & 0x1;
+ } else {
+ cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize());
+ cpu->TFlag = 0x1;
+ int signed_int = inst_cream->val.signed_immed_24;
+ signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int;
+ signed_int = signed_int << 2;
+ cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1);
+ }
INC_PC(sizeof(blx_inst));
goto DISPATCH;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(blx_inst));
+ goto DISPATCH;
+}
- BX_INST:
- BXJ_INST:
- {
- // Note that only the 'fail' case of BXJ is emulated. This is because
- // the facilities for Jazelle emulation are not implemented.
- //
- // According to the ARM documentation on BXJ, if setting the J bit in the APSR
- // fails, then BXJ functions identically like a regular BX instruction.
- //
- // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle.
+BX_INST:
+BXJ_INST : {
+ // Note that only the 'fail' case of BXJ is emulated. This is because
+ // the facilities for Jazelle emulation are not implemented.
+ //
+ // According to the ARM documentation on BXJ, if setting the J bit in the APSR
+ // fails, then BXJ functions identically like a regular BX instruction.
+ //
+ // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- bx_inst* const inst_cream = (bx_inst*)inst_base->component;
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ bx_inst* const inst_cream = (bx_inst*)inst_base->component;
- u32 address = RM;
+ u32 address = RM;
- if (inst_cream->Rm == 15)
- address += 2 * cpu->GetInstructionSize();
+ if (inst_cream->Rm == 15)
+ address += 2 * cpu->GetInstructionSize();
- cpu->TFlag = address & 1;
- cpu->Reg[15] = address & 0xfffffffe;
- INC_PC(sizeof(bx_inst));
- goto DISPATCH;
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
+ cpu->TFlag = address & 1;
+ cpu->Reg[15] = address & 0xfffffffe;
INC_PC(sizeof(bx_inst));
goto DISPATCH;
}
- CDP_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- // Undefined instruction here
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(bx_inst));
+ goto DISPATCH;
+}
+
+CDP_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ // Undefined instruction here
+ cpu->NumInstrsToExecute = 0;
+ return num_instrs;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(cdp_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+CLREX_INST : {
+ cpu->UnsetExclusiveMemoryAddress();
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(clrex_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+CLZ_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ clz_inst* inst_cream = (clz_inst*)inst_base->component;
+ RD = clz(RM);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(clz_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+CMN_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ cmn_inst* const inst_cream = (cmn_inst*)inst_base->component;
+
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
+
+ bool carry;
+ bool overflow;
+ u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
+
+ UPDATE_NFLAG(result);
+ UPDATE_ZFLAG(result);
+ cpu->CFlag = carry;
+ cpu->VFlag = overflow;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(cmn_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+CMP_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ cmp_inst* const inst_cream = (cmp_inst*)inst_base->component;
+
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
+
+ bool carry;
+ bool overflow;
+ u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
+
+ UPDATE_NFLAG(result);
+ UPDATE_ZFLAG(result);
+ cpu->CFlag = carry;
+ cpu->VFlag = overflow;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(cmp_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+CPS_INST : {
+ cps_inst* inst_cream = (cps_inst*)inst_base->component;
+ u32 aif_val = 0;
+ u32 aif_mask = 0;
+ if (cpu->InAPrivilegedMode()) {
+ if (inst_cream->imod1) {
+ if (inst_cream->A) {
+ aif_val |= (inst_cream->imod0 << 8);
+ aif_mask |= 1 << 8;
+ }
+ if (inst_cream->I) {
+ aif_val |= (inst_cream->imod0 << 7);
+ aif_mask |= 1 << 7;
+ }
+ if (inst_cream->F) {
+ aif_val |= (inst_cream->imod0 << 6);
+ aif_mask |= 1 << 6;
+ }
+ aif_mask = ~aif_mask;
+ cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cdp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- CLREX_INST:
- {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(clrex_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CLZ_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- clz_inst* inst_cream = (clz_inst*)inst_base->component;
- RD = clz(RM);
+ if (inst_cream->mmod) {
+ cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
+ cpu->ChangePrivilegeMode(inst_cream->mode);
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(clz_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CMN_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- cmn_inst* const inst_cream = (cmn_inst*)inst_base->component;
-
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
-
- bool carry;
- bool overflow;
- u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
-
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(cps_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+CPY_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mov_inst* inst_cream = (mov_inst*)inst_base->component;
+
+ RD = SHIFTER_OPERAND;
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(mov_inst));
+ goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cmn_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CMP_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- cmp_inst* const inst_cream = (cmp_inst*)inst_base->component;
-
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
-
- bool carry;
- bool overflow;
- u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
-
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mov_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+EOR_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ eor_inst* inst_cream = (eor_inst*)inst_base->component;
+
+ u32 lop = RN;
+ if (inst_cream->Rn == 15) {
+ lop += 2 * cpu->GetInstructionSize();
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cmp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- CPS_INST:
- {
- cps_inst *inst_cream = (cps_inst *)inst_base->component;
- u32 aif_val = 0;
- u32 aif_mask = 0;
- if (cpu->InAPrivilegedMode()) {
- if (inst_cream->imod1) {
- if (inst_cream->A) {
- aif_val |= (inst_cream->imod0 << 8);
- aif_mask |= 1 << 8;
- }
- if (inst_cream->I) {
- aif_val |= (inst_cream->imod0 << 7);
- aif_mask |= 1 << 7;
- }
- if (inst_cream->F) {
- aif_val |= (inst_cream->imod0 << 6);
- aif_mask |= 1 << 6;
- }
- aif_mask = ~aif_mask;
- cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
- }
- if (inst_cream->mmod) {
- cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
- cpu->ChangePrivilegeMode(inst_cream->mode);
+ u32 rop = SHIFTER_OPERAND;
+ RD = lop ^ rop;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
}
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(eor_inst));
+ goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(cps_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- CPY_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mov_inst* inst_cream = (mov_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(eor_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDC_INST : {
+ // Instruction not implemented
+ // LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDM_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
- RD = SHIFTER_OPERAND;
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mov_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mov_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- EOR_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- eor_inst* inst_cream = (eor_inst*)inst_base->component;
-
- u32 lop = RN;
- if (inst_cream->Rn == 15) {
- lop += 2 * cpu->GetInstructionSize();
- }
- u32 rop = SHIFTER_OPERAND;
- RD = lop ^ rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
+ unsigned int inst = inst_cream->inst;
+ if (BIT(inst, 22) && !BIT(inst, 15)) {
+ for (int i = 0; i < 13; i++) {
+ if (BIT(inst, i)) {
+ cpu->Reg[i] = cpu->ReadMemory32(addr);
+ addr += 4;
}
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
}
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(eor_inst));
- goto DISPATCH;
+ if (BIT(inst, 13)) {
+ if (cpu->Mode == USER32MODE)
+ cpu->Reg[13] = cpu->ReadMemory32(addr);
+ else
+ cpu->Reg_usr[0] = cpu->ReadMemory32(addr);
+
+ addr += 4;
}
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(eor_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDC_INST:
- {
- // Instruction not implemented
- //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDM_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int inst = inst_cream->inst;
- if (BIT(inst, 22) && !BIT(inst, 15)) {
- for (int i = 0; i < 13; i++) {
- if(BIT(inst, i)) {
- cpu->Reg[i] = cpu->ReadMemory32(addr);
- addr += 4;
+ if (BIT(inst, 14)) {
+ if (cpu->Mode == USER32MODE)
+ cpu->Reg[14] = cpu->ReadMemory32(addr);
+ else
+ cpu->Reg_usr[1] = cpu->ReadMemory32(addr);
+
+ addr += 4;
+ }
+ } else if (!BIT(inst, 22)) {
+ for (int i = 0; i < 16; i++) {
+ if (BIT(inst, i)) {
+ unsigned int ret = cpu->ReadMemory32(addr);
+
+ // For armv5t, should enter thumb when bits[0] is non-zero.
+ if (i == 15) {
+ cpu->TFlag = ret & 0x1;
+ ret &= 0xFFFFFFFE;
}
- }
- if (BIT(inst, 13)) {
- if (cpu->Mode == USER32MODE)
- cpu->Reg[13] = cpu->ReadMemory32(addr);
- else
- cpu->Reg_usr[0] = cpu->ReadMemory32(addr);
+ cpu->Reg[i] = ret;
addr += 4;
}
- if (BIT(inst, 14)) {
- if (cpu->Mode == USER32MODE)
- cpu->Reg[14] = cpu->ReadMemory32(addr);
- else
- cpu->Reg_usr[1] = cpu->ReadMemory32(addr);
-
+ }
+ } else if (BIT(inst, 22) && BIT(inst, 15)) {
+ for (int i = 0; i < 15; i++) {
+ if (BIT(inst, i)) {
+ cpu->Reg[i] = cpu->ReadMemory32(addr);
addr += 4;
}
- } else if (!BIT(inst, 22)) {
- for(int i = 0; i < 16; i++ ){
- if(BIT(inst, i)){
- unsigned int ret = cpu->ReadMemory32(addr);
-
- // For armv5t, should enter thumb when bits[0] is non-zero.
- if(i == 15){
- cpu->TFlag = ret & 0x1;
- ret &= 0xFFFFFFFE;
- }
-
- cpu->Reg[i] = ret;
- addr += 4;
- }
- }
- } else if (BIT(inst, 22) && BIT(inst, 15)) {
- for(int i = 0; i < 15; i++ ){
- if(BIT(inst, i)){
- cpu->Reg[i] = cpu->ReadMemory32(addr);
- addr += 4;
- }
- }
-
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- }
-
- cpu->Reg[15] = cpu->ReadMemory32(addr);
}
- if (BIT(inst, 15)) {
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
+ LOAD_NZCVT;
}
+
+ cpu->Reg[15] = cpu->ReadMemory32(addr);
+ }
+
+ if (BIT(inst, 15)) {
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- SXTH_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxth_inst* inst_cream = (sxth_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+SXTH_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ sxth_inst* inst_cream = (sxth_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
- if (BIT(operand2, 15)) {
- operand2 |= 0xffff0000;
- } else {
- operand2 &= 0xffff;
- }
- RD = operand2;
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
+ if (BIT(operand2, 15)) {
+ operand2 |= 0xffff0000;
+ } else {
+ operand2 &= 0xffff;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxth_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDR_INST:
- {
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ RD = operand2;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(sxth_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDR_INST : {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
+
+ unsigned int value = cpu->ReadMemory32(addr);
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ // For armv5t, should enter thumb when bits[0] is non-zero.
+ cpu->TFlag = value & 0x1;
+ cpu->Reg[15] &= 0xFFFFFFFE;
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
+
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDRCOND_INST : {
+ if (CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr);
unsigned int value = cpu->ReadMemory32(addr);
@@ -1726,2546 +2150,2433 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
INC_PC(sizeof(ldst_inst));
goto DISPATCH;
}
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+UXTH_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
+ RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(uxth_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+UXTAH_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component;
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRCOND_INST:
- {
- if (CondPassed(cpu, inst_base->cond)) {
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int value = cpu->ReadMemory32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
-
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- // For armv5t, should enter thumb when bits[0] is non-zero.
- cpu->TFlag = value & 0x1;
- cpu->Reg[15] &= 0xFFFFFFFE;
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTH_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxth_inst* inst_cream = (uxth_inst*)inst_base->component;
- RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxth_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTAH_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
-
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtah_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = RN + operand2;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(uxtah_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDRB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
+
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr);
}
- LDRBT_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDRBT_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
- const u32 dest_index = BITS(inst_cream->inst, 12, 15);
- const u32 previous_mode = cpu->Mode;
+ const u32 dest_index = BITS(inst_cream->inst, 12, 15);
+ const u32 previous_mode = cpu->Mode;
- cpu->ChangePrivilegeMode(USER32MODE);
- const u8 value = cpu->ReadMemory8(addr);
- cpu->ChangePrivilegeMode(previous_mode);
+ cpu->ChangePrivilegeMode(USER32MODE);
+ const u8 value = cpu->ReadMemory8(addr);
+ cpu->ChangePrivilegeMode(previous_mode);
- cpu->Reg[dest_index] = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRD_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0)
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- // The 3DS doesn't have LPAE (Large Physical Access Extension), so it
- // wouldn't do this as a single read.
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4);
-
- // No dispatch since this operation should not modify R15
- }
- cpu->Reg[15] += 4;
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ cpu->Reg[dest_index] = value;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDRD_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 ||
+ // addr[2] == 0)
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
- LDREX_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
-
- cpu->SetExclusiveMemoryAddress(read_addr);
+ // The 3DS doesn't have LPAE (Large Physical Access Extension), so it
+ // wouldn't do this as a single read.
+ cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr);
+ cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4);
- RD = cpu->ReadMemory32(read_addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ // No dispatch since this operation should not modify R15
}
- LDREXB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
+ cpu->Reg[15] += 4;
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- cpu->SetExclusiveMemoryAddress(read_addr);
+LDREX_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ unsigned int read_addr = RN;
- RD = cpu->ReadMemory8(read_addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ cpu->SetExclusiveMemoryAddress(read_addr);
+
+ RD = cpu->ReadMemory32(read_addr);
}
- LDREXH_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDREXB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ unsigned int read_addr = RN;
- cpu->SetExclusiveMemoryAddress(read_addr);
+ cpu->SetExclusiveMemoryAddress(read_addr);
- RD = cpu->ReadMemory16(read_addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = cpu->ReadMemory8(read_addr);
}
- LDREXD_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int read_addr = RN;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDREXH_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ unsigned int read_addr = RN;
- cpu->SetExclusiveMemoryAddress(read_addr);
+ cpu->SetExclusiveMemoryAddress(read_addr);
- RD = cpu->ReadMemory32(read_addr);
- RD2 = cpu->ReadMemory32(read_addr + 4);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRH_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRSB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->ReadMemory8(addr);
- if (BIT(value, 7)) {
- value |= 0xffffff00;
- }
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- LDRSH_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int value = cpu->ReadMemory16(addr);
- if (BIT(value, 15)) {
- value |= 0xffff0000;
- }
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = cpu->ReadMemory16(read_addr);
}
- LDRT_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDREXD_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ unsigned int read_addr = RN;
- const u32 dest_index = BITS(inst_cream->inst, 12, 15);
- const u32 previous_mode = cpu->Mode;
+ cpu->SetExclusiveMemoryAddress(read_addr);
- cpu->ChangePrivilegeMode(USER32MODE);
- const u32 value = cpu->ReadMemory32(addr);
- cpu->ChangePrivilegeMode(previous_mode);
+ RD = cpu->ReadMemory32(read_addr);
+ RD2 = cpu->ReadMemory32(read_addr + 4);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDRH_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
- cpu->Reg[dest_index] = value;
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDRSB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
+ unsigned int value = cpu->ReadMemory8(addr);
+ if (BIT(value, 7)) {
+ value |= 0xffffff00;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
}
- MCR_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mcr_inst* inst_cream = (mcr_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDRSH_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int inst = inst_cream->inst;
- if (inst_cream->Rd == 15) {
- DEBUG_MSG;
- } else {
- if (inst_cream->cp_num == 15)
- cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2);
- }
+ unsigned int value = cpu->ReadMemory16(addr);
+ if (BIT(value, 15)) {
+ value |= 0xffff0000;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mcr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+LDRT_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
+
+ const u32 dest_index = BITS(inst_cream->inst, 12, 15);
+ const u32 previous_mode = cpu->Mode;
- MCRR_INST:
- {
- // Stubbed, as the MPCore doesn't have any registers that are accessible
- // through this instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
+ cpu->ChangePrivilegeMode(USER32MODE);
+ const u32 value = cpu->ReadMemory32(addr);
+ cpu->ChangePrivilegeMode(previous_mode);
- LOG_ERROR(Core_ARM11, "MCRR executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u",
- inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
+ cpu->Reg[dest_index] = value;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+MCR_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mcr_inst* inst_cream = (mcr_inst*)inst_base->component;
+
+ unsigned int inst = inst_cream->inst;
+ if (inst_cream->Rd == 15) {
+ DEBUG_MSG;
+ } else {
+ if (inst_cream->cp_num == 15)
+ cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2);
}
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mcr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+MCRR_INST : {
+ // Stubbed, as the MPCore doesn't have any registers that are accessible
+ // through this instruction.
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mcrr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ LOG_ERROR(Core_ARM11, "MCRR executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u",
+ inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt,
+ inst_cream->rt2);
}
- MLA_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mla_inst* inst_cream = (mla_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mcrr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- u64 rm = RM;
- u64 rs = RS;
- u64 rn = RN;
+MLA_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mla_inst* inst_cream = (mla_inst*)inst_base->component;
- RD = static_cast<u32>((rm * rs + rn) & 0xffffffff);
- if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- }
+ u64 rm = RM;
+ u64 rs = RS;
+ u64 rn = RN;
+
+ RD = static_cast<u32>((rm * rs + rn) & 0xffffffff);
+ if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MOV_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mov_inst* inst_cream = (mov_inst*)inst_base->component;
-
- RD = SHIFTER_OPERAND;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mov_inst));
- goto DISPATCH;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mla_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+MOV_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mov_inst* inst_cream = (mov_inst*)inst_base->component;
+
+ RD = SHIFTER_OPERAND;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
}
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ UPDATE_CFLAG_WITH_SC;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mov_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MRC_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mrc_inst* inst_cream = (mrc_inst*)inst_base->component;
-
- if (inst_cream->cp_num == 15) {
- const uint32_t value = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
-
- if (inst_cream->Rd == 15) {
- cpu->Cpsr = (cpu->Cpsr & ~0xF0000000) | (value & 0xF0000000);
- LOAD_NZCVT;
- } else {
- RD = value;
- }
- }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(mov_inst));
+ goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mrc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mov_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+MRC_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mrc_inst* inst_cream = (mrc_inst*)inst_base->component;
- MRRC_INST:
- {
- // Stubbed, as the MPCore doesn't have any registers that are accessible
- // through this instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
+ if (inst_cream->cp_num == 15) {
+ const uint32_t value = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2);
- LOG_ERROR(Core_ARM11, "MRRC executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u",
- inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2);
+ if (inst_cream->Rd == 15) {
+ cpu->Cpsr = (cpu->Cpsr & ~0xF0000000) | (value & 0xF0000000);
+ LOAD_NZCVT;
+ } else {
+ RD = value;
+ }
}
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mrc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+MRRC_INST : {
+ // Stubbed, as the MPCore doesn't have any registers that are accessible
+ // through this instruction.
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mcrr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ LOG_ERROR(Core_ARM11, "MRRC executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u",
+ inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt,
+ inst_cream->rt2);
}
- MRS_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mrs_inst* inst_cream = (mrs_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mcrr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+MRS_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mrs_inst* inst_cream = (mrs_inst*)inst_base->component;
- if (inst_cream->R) {
- RD = cpu->Spsr_copy;
- } else {
- SAVE_NZCVT;
- RD = cpu->Cpsr;
- }
+ if (inst_cream->R) {
+ RD = cpu->Spsr_copy;
+ } else {
+ SAVE_NZCVT;
+ RD = cpu->Cpsr;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mrs_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MSR_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- msr_inst* inst_cream = (msr_inst*)inst_base->component;
- const u32 UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
- unsigned int inst = inst_cream->inst;
- unsigned int operand;
-
- if (BIT(inst, 25)) {
- int rot_imm = BITS(inst, 8, 11) * 2;
- operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mrs_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+MSR_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ msr_inst* inst_cream = (msr_inst*)inst_base->component;
+ const u32 UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
+ unsigned int inst = inst_cream->inst;
+ unsigned int operand;
+
+ if (BIT(inst, 25)) {
+ int rot_imm = BITS(inst, 8, 11) * 2;
+ operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
+ } else {
+ operand = cpu->Reg[BITS(inst, 0, 3)];
+ }
+ u32 byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) |
+ (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
+ u32 mask = 0;
+ if (!inst_cream->R) {
+ if (cpu->InAPrivilegedMode()) {
+ if ((operand & StateMask) != 0) {
+ /// UNPREDICTABLE
+ DEBUG_MSG;
+ } else
+ mask = byte_mask & (UserMask | PrivMask);
} else {
- operand = cpu->Reg[BITS(inst, 0, 3)];
+ mask = byte_mask & UserMask;
}
- u32 byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0)
- | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
- u32 mask = 0;
- if (!inst_cream->R) {
- if (cpu->InAPrivilegedMode()) {
- if ((operand & StateMask) != 0) {
- /// UNPREDICTABLE
- DEBUG_MSG;
- } else
- mask = byte_mask & (UserMask | PrivMask);
- } else {
- mask = byte_mask & UserMask;
- }
- SAVE_NZCVT;
+ SAVE_NZCVT;
- cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
- cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
- LOAD_NZCVT;
- } else {
- if (CurrentModeHasSPSR) {
- mask = byte_mask & (UserMask | PrivMask | StateMask);
- cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
- }
+ cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
+ cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F);
+ LOAD_NZCVT;
+ } else {
+ if (CurrentModeHasSPSR) {
+ mask = byte_mask & (UserMask | PrivMask | StateMask);
+ cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
}
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(msr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MUL_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mul_inst* inst_cream = (mul_inst*)inst_base->component;
-
- u64 rm = RM;
- u64 rs = RS;
- RD = static_cast<u32>((rm * rs) & 0xffffffff);
- if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- }
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(msr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+MUL_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mul_inst* inst_cream = (mul_inst*)inst_base->component;
+
+ u64 rm = RM;
+ u64 rs = RS;
+ RD = static_cast<u32>((rm * rs) & 0xffffffff);
+ if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- MVN_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- mvn_inst* const inst_cream = (mvn_inst*)inst_base->component;
-
- RD = ~SHIFTER_OPERAND;
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(mvn_inst));
- goto DISPATCH;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mul_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+MVN_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ mvn_inst* const inst_cream = (mvn_inst*)inst_base->component;
+
+ RD = ~SHIFTER_OPERAND;
+
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
}
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(mvn_inst));
+ goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(mvn_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- ORR_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- orr_inst* const inst_cream = (orr_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(mvn_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+ORR_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ orr_inst* const inst_cream = (orr_inst*)inst_base->component;
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
+ u32 lop = RN;
+ u32 rop = SHIFTER_OPERAND;
- if (inst_cream->Rn == 15)
- lop += 2 * cpu->GetInstructionSize();
+ if (inst_cream->Rn == 15)
+ lop += 2 * cpu->GetInstructionSize();
- RD = lop | rop;
+ RD = lop | rop;
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- UPDATE_CFLAG_WITH_SC;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(orr_inst));
- goto DISPATCH;
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
}
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(orr_inst));
+ goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(orr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(orr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+NOP_INST : {
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC_STUB;
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- NOP_INST:
- {
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
+PKHBT_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ pkh_inst* inst_cream = (pkh_inst*)inst_base->component;
+ RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(pkh_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- PKHBT_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
- RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(pkh_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- PKHTB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
- int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
- RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(pkh_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- PLD_INST:
- {
- // Not implemented. PLD is a hint instruction, so it's optional.
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(pld_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- QADD_INST:
- QDADD_INST:
- QDSUB_INST:
- QSUB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 op1 = inst_cream->op1;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
+PKHTB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ pkh_inst* inst_cream = (pkh_inst*)inst_base->component;
+ int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
+ RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(pkh_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- u32 result = 0;
+PLD_INST : {
+ // Not implemented. PLD is a hint instruction, so it's optional.
- // QADD
- if (op1 == 0x00) {
- result = rm_val + rn_val;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(pld_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- if (AddOverflow(rm_val, rn_val, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
- // QSUB
- else if (op1 == 0x01) {
- result = rm_val - rn_val;
+QADD_INST:
+QDADD_INST:
+QDSUB_INST:
+QSUB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ const u8 op1 = inst_cream->op1;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
- if (SubOverflow(rm_val, rn_val, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
- }
- // QDADD
- else if (op1 == 0x02) {
- u32 mul = (rn_val * 2);
+ u32 result = 0;
- if (AddOverflow(rn_val, rn_val, rn_val * 2)) {
- mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
+ // QADD
+ if (op1 == 0x00) {
+ result = rm_val + rn_val;
- result = mul + rm_val;
+ if (AddOverflow(rm_val, rn_val, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
+ // QSUB
+ else if (op1 == 0x01) {
+ result = rm_val - rn_val;
- if (AddOverflow(rm_val, mul, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
+ if (SubOverflow(rm_val, rn_val, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
}
- // QDSUB
- else if (op1 == 0x03) {
- u32 mul = (rn_val * 2);
+ }
+ // QDADD
+ else if (op1 == 0x02) {
+ u32 mul = (rn_val * 2);
- if (AddOverflow(rn_val, rn_val, mul)) {
- mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
+ if (AddOverflow(rn_val, rn_val, rn_val * 2)) {
+ mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
- result = rm_val - mul;
+ result = mul + rm_val;
- if (SubOverflow(rm_val, mul, result)) {
- result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
- cpu->Cpsr |= (1 << 27);
- }
+ if (AddOverflow(rm_val, mul, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
}
-
- RD = result;
}
+ // QDSUB
+ else if (op1 == 0x03) {
+ u32 mul = (rn_val * 2);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- QADD8_INST:
- QADD16_INST:
- QADDSUBX_INST:
- QSUB8_INST:
- QSUB16_INST:
- QSUBADDX_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u16 rm_lo = (RM & 0xFFFF);
- const u16 rm_hi = ((RM >> 16) & 0xFFFF);
- const u16 rn_lo = (RN & 0xFFFF);
- const u16 rn_hi = ((RN >> 16) & 0xFFFF);
- const u8 op2 = inst_cream->op2;
-
- u16 lo_result = 0;
- u16 hi_result = 0;
-
- // QADD16
- if (op2 == 0x00) {
- lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
- hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
- }
- // QASX
- else if (op2 == 0x01) {
- lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
- hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
- }
- // QSAX
- else if (op2 == 0x02) {
- lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
- hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
- }
- // QSUB16
- else if (op2 == 0x03) {
- lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
- hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
- }
- // QADD8
- else if (op2 == 0x04) {
- lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
- ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
- hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
- ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
+ if (AddOverflow(rn_val, rn_val, mul)) {
+ mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
}
- // QSUB8
- else if (op2 == 0x07) {
- lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
- ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
- hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
- ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
+
+ result = rm_val - mul;
+
+ if (SubOverflow(rm_val, mul, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
}
+ }
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
+ RD = result;
+ }
+
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+QADD8_INST:
+QADD16_INST:
+QADDSUBX_INST:
+QSUB8_INST:
+QSUB16_INST:
+QSUBADDX_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ const u16 rm_lo = (RM & 0xFFFF);
+ const u16 rm_hi = ((RM >> 16) & 0xFFFF);
+ const u16 rn_lo = (RN & 0xFFFF);
+ const u16 rn_hi = ((RN >> 16) & 0xFFFF);
+ const u8 op2 = inst_cream->op2;
+
+ u16 lo_result = 0;
+ u16 hi_result = 0;
+
+ // QADD16
+ if (op2 == 0x00) {
+ lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
+ hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
+ }
+ // QASX
+ else if (op2 == 0x01) {
+ lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
+ hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
+ }
+ // QSAX
+ else if (op2 == 0x02) {
+ lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
+ hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
+ }
+ // QSUB16
+ else if (op2 == 0x03) {
+ lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
+ hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
+ }
+ // QADD8
+ else if (op2 == 0x04) {
+ lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
+ ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
+ hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
+ ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
+ }
+ // QSUB8
+ else if (op2 == 0x07) {
+ lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
+ ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
+ hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
+ ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
}
- REV_INST:
- REV16_INST:
- REVSH_INST:
- {
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- rev_inst* const inst_cream = (rev_inst*)inst_base->component;
+REV_INST:
+REV16_INST:
+REVSH_INST : {
- const u8 op1 = inst_cream->op1;
- const u8 op2 = inst_cream->op2;
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ rev_inst* const inst_cream = (rev_inst*)inst_base->component;
- // REV
- if (op1 == 0x03 && op2 == 0x01) {
- RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) | ((RM >> 24) & 0xFF);
- }
- // REV16
- else if (op1 == 0x03 && op2 == 0x05) {
- RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) | ((RM & 0xFF000000) >> 8);
- }
- // REVSH
- else if (op1 == 0x07 && op2 == 0x05) {
- RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8);
- if (RD & 0x8000)
- RD |= 0xffff0000;
- }
- }
+ const u8 op1 = inst_cream->op1;
+ const u8 op2 = inst_cream->op2;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(rev_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ // REV
+ if (op1 == 0x03 && op2 == 0x01) {
+ RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) |
+ ((RM >> 24) & 0xFF);
+ }
+ // REV16
+ else if (op1 == 0x03 && op2 == 0x05) {
+ RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) |
+ ((RM & 0xFF000000) >> 8);
+ }
+ // REVSH
+ else if (op1 == 0x07 && op2 == 0x05) {
+ RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8);
+ if (RD & 0x8000)
+ RD |= 0xffff0000;
+ }
}
- RFE_INST:
- {
- // RFE is unconditional
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(rev_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- u32 address = 0;
- inst_cream->get_addr(cpu, inst_cream->inst, address);
+RFE_INST : {
+ // RFE is unconditional
+ ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
- cpu->Cpsr = cpu->ReadMemory32(address);
- cpu->Reg[15] = cpu->ReadMemory32(address + 4);
+ u32 address = 0;
+ inst_cream->get_addr(cpu, inst_cream->inst, address);
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
+ cpu->Cpsr = cpu->ReadMemory32(address);
+ cpu->Reg[15] = cpu->ReadMemory32(address + 4);
- RSB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- rsb_inst* const inst_cream = (rsb_inst*)inst_base->component;
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+}
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
+RSB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ rsb_inst* const inst_cream = (rsb_inst*)inst_base->component;
- bool carry;
- bool overflow;
- RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow);
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
+ bool carry;
+ bool overflow;
+ RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow);
+
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
}
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(rsb_inst));
- goto DISPATCH;
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ cpu->CFlag = carry;
+ cpu->VFlag = overflow;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(rsb_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(rsb_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+RSC_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ rsc_inst* const inst_cream = (rsc_inst*)inst_base->component;
+
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
+
+ bool carry;
+ bool overflow;
+ RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
}
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ cpu->CFlag = carry;
+ cpu->VFlag = overflow;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(rsb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- RSC_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- rsc_inst* const inst_cream = (rsc_inst*)inst_base->component;
-
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
-
- bool carry;
- bool overflow;
- RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
-
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(rsc_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(rsc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+SADD8_INST:
+SSUB8_INST:
+SADD16_INST:
+SADDSUBX_INST:
+SSUBADDX_INST:
+SSUB16_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ const u8 op2 = inst_cream->op2;
+
+ if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
+ const s16 rn_lo = (RN & 0xFFFF);
+ const s16 rn_hi = ((RN >> 16) & 0xFFFF);
+ const s16 rm_lo = (RM & 0xFFFF);
+ const s16 rm_hi = ((RM >> 16) & 0xFFFF);
+
+ s32 lo_result = 0;
+ s32 hi_result = 0;
+
+ // SADD16
+ if (inst_cream->op2 == 0x00) {
+ lo_result = (rn_lo + rm_lo);
+ hi_result = (rn_hi + rm_hi);
}
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(rsc_inst));
- goto DISPATCH;
+ // SASX
+ else if (op2 == 0x01) {
+ lo_result = (rn_lo - rm_hi);
+ hi_result = (rn_hi + rm_lo);
+ }
+ // SSAX
+ else if (op2 == 0x02) {
+ lo_result = (rn_lo + rm_hi);
+ hi_result = (rn_hi - rm_lo);
+ }
+ // SSUB16
+ else if (op2 == 0x03) {
+ lo_result = (rn_lo - rm_lo);
+ hi_result = (rn_hi - rm_hi);
}
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(rsc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- SADD8_INST:
- SSUB8_INST:
- SADD16_INST:
- SADDSUBX_INST:
- SSUBADDX_INST:
- SSUB16_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u8 op2 = inst_cream->op2;
-
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
- const s16 rn_lo = (RN & 0xFFFF);
- const s16 rn_hi = ((RN >> 16) & 0xFFFF);
- const s16 rm_lo = (RM & 0xFFFF);
- const s16 rm_hi = ((RM >> 16) & 0xFFFF);
-
- s32 lo_result = 0;
- s32 hi_result = 0;
-
- // SADD16
- if (inst_cream->op2 == 0x00) {
- lo_result = (rn_lo + rm_lo);
- hi_result = (rn_hi + rm_hi);
- }
- // SASX
- else if (op2 == 0x01) {
- lo_result = (rn_lo - rm_hi);
- hi_result = (rn_hi + rm_lo);
- }
- // SSAX
- else if (op2 == 0x02) {
- lo_result = (rn_lo + rm_hi);
- hi_result = (rn_hi - rm_lo);
- }
- // SSUB16
- else if (op2 == 0x03) {
- lo_result = (rn_lo - rm_lo);
- hi_result = (rn_hi - rm_hi);
- }
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
+ RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
- if (lo_result >= 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
+ if (lo_result >= 0) {
+ cpu->Cpsr |= (1 << 16);
+ cpu->Cpsr |= (1 << 17);
+ } else {
+ cpu->Cpsr &= ~(1 << 16);
+ cpu->Cpsr &= ~(1 << 17);
+ }
- if (hi_result >= 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
+ if (hi_result >= 0) {
+ cpu->Cpsr |= (1 << 18);
+ cpu->Cpsr |= (1 << 19);
+ } else {
+ cpu->Cpsr &= ~(1 << 18);
+ cpu->Cpsr &= ~(1 << 19);
+ }
+ } else if (op2 == 0x04 || op2 == 0x07) {
+ s32 lo_val1, lo_val2;
+ s32 hi_val1, hi_val2;
+
+ // SADD8
+ if (op2 == 0x04) {
+ lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF);
+ lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF);
+ hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF);
+ hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF);
+ }
+ // SSUB8
+ else {
+ lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF);
+ lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF);
+ hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF);
+ hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF);
}
- else if (op2 == 0x04 || op2 == 0x07) {
- s32 lo_val1, lo_val2;
- s32 hi_val1, hi_val2;
-
- // SADD8
- if (op2 == 0x04) {
- lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF);
- lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF);
- hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF);
- hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF);
- }
- // SSUB8
- else {
- lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF);
- lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF);
- hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF);
- hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF);
- }
- RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24));
+ RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) |
+ ((hi_val2 & 0xFF) << 24));
- if (lo_val1 >= 0)
- cpu->Cpsr |= (1 << 16);
- else
- cpu->Cpsr &= ~(1 << 16);
+ if (lo_val1 >= 0)
+ cpu->Cpsr |= (1 << 16);
+ else
+ cpu->Cpsr &= ~(1 << 16);
- if (lo_val2 >= 0)
- cpu->Cpsr |= (1 << 17);
- else
- cpu->Cpsr &= ~(1 << 17);
+ if (lo_val2 >= 0)
+ cpu->Cpsr |= (1 << 17);
+ else
+ cpu->Cpsr &= ~(1 << 17);
- if (hi_val1 >= 0)
- cpu->Cpsr |= (1 << 18);
- else
- cpu->Cpsr &= ~(1 << 18);
+ if (hi_val1 >= 0)
+ cpu->Cpsr |= (1 << 18);
+ else
+ cpu->Cpsr &= ~(1 << 18);
- if (hi_val2 >= 0)
- cpu->Cpsr |= (1 << 19);
- else
- cpu->Cpsr &= ~(1 << 19);
- }
+ if (hi_val2 >= 0)
+ cpu->Cpsr |= (1 << 19);
+ else
+ cpu->Cpsr &= ~(1 << 19);
}
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- SBC_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sbc_inst* const inst_cream = (sbc_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- u32 rn_val = RN;
- if (inst_cream->Rn == 15)
- rn_val += 2 * cpu->GetInstructionSize();
+SBC_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ sbc_inst* const inst_cream = (sbc_inst*)inst_base->component;
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+ u32 rn_val = RN;
+ if (inst_cream->Rn == 15)
+ rn_val += 2 * cpu->GetInstructionSize();
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(sbc_inst));
- goto DISPATCH;
+ bool carry;
+ bool overflow;
+ RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
+
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
}
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ cpu->CFlag = carry;
+ cpu->VFlag = overflow;
+ }
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(sbc_inst));
+ goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sbc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(sbc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- SEL_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u32 to = RM;
- const u32 from = RN;
- const u32 cpsr = cpu->Cpsr;
+SEL_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- u32 result;
- if (cpsr & (1 << 16))
- result = from & 0xff;
- else
- result = to & 0xff;
+ const u32 to = RM;
+ const u32 from = RN;
+ const u32 cpsr = cpu->Cpsr;
- if (cpsr & (1 << 17))
- result |= from & 0x0000ff00;
- else
- result |= to & 0x0000ff00;
+ u32 result;
+ if (cpsr & (1 << 16))
+ result = from & 0xff;
+ else
+ result = to & 0xff;
- if (cpsr & (1 << 18))
- result |= from & 0x00ff0000;
- else
- result |= to & 0x00ff0000;
+ if (cpsr & (1 << 17))
+ result |= from & 0x0000ff00;
+ else
+ result |= to & 0x0000ff00;
- if (cpsr & (1 << 19))
- result |= from & 0xff000000;
- else
- result |= to & 0xff000000;
+ if (cpsr & (1 << 18))
+ result |= from & 0x00ff0000;
+ else
+ result |= to & 0x00ff0000;
- RD = result;
- }
+ if (cpsr & (1 << 19))
+ result |= from & 0xff000000;
+ else
+ result |= to & 0xff000000;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = result;
}
- SETEND_INST:
- {
- // SETEND is unconditional
- setend_inst* const inst_cream = (setend_inst*)inst_base->component;
- const bool big_endian = (inst_cream->set_bigend == 1);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- if (big_endian)
- cpu->Cpsr |= (1 << 9);
- else
- cpu->Cpsr &= ~(1 << 9);
+SETEND_INST : {
+ // SETEND is unconditional
+ setend_inst* const inst_cream = (setend_inst*)inst_base->component;
+ const bool big_endian = (inst_cream->set_bigend == 1);
- LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE");
+ if (big_endian)
+ cpu->Cpsr |= (1 << 9);
+ else
+ cpu->Cpsr &= ~(1 << 9);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(setend_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
+ LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE");
- SEV_INST:
- {
- // Stubbed, as SEV is a hint instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM11, "SEV executed.");
- }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(setend_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
+SEV_INST : {
+ // Stubbed, as SEV is a hint instruction.
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ LOG_TRACE(Core_ARM11, "SEV executed.");
}
- SHADD8_INST:
- SHADD16_INST:
- SHADDSUBX_INST:
- SHSUB8_INST:
- SHSUB16_INST:
- SHSUBADDX_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC_STUB;
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
+SHADD8_INST:
+SHADD16_INST:
+SHADDSUBX_INST:
+SHSUB8_INST:
+SHSUB16_INST:
+SHSUBADDX_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
- s32 lo_result = 0;
- s32 hi_result = 0;
+ const u8 op2 = inst_cream->op2;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
- // SHADD16
- if (op2 == 0x00) {
- lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- }
- // SHASX
- else if (op2 == 0x01) {
- lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
- }
- // SHSAX
- else if (op2 == 0x02) {
- lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
- }
- // SHSUB16
- else if (op2 == 0x03) {
- lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
- hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
- }
+ if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
+ s32 lo_result = 0;
+ s32 hi_result = 0;
- RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16));
+ // SHADD16
+ if (op2 == 0x00) {
+ lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
+ hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
+ }
+ // SHASX
+ else if (op2 == 0x01) {
+ lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
+ hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
+ }
+ // SHSAX
+ else if (op2 == 0x02) {
+ lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
+ hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
+ }
+ // SHSUB16
+ else if (op2 == 0x03) {
+ lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
+ hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
}
- else if (op2 == 0x04 || op2 == 0x07) {
- s16 lo_val1, lo_val2;
- s16 hi_val1, hi_val2;
- // SHADD8
- if (op2 == 0x04) {
- lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1;
- lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1;
+ RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16));
+ } else if (op2 == 0x04 || op2 == 0x07) {
+ s16 lo_val1, lo_val2;
+ s16 hi_val1, hi_val2;
- hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1;
- hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1;
- }
- // SHSUB8
- else {
- lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1;
- lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1;
+ // SHADD8
+ if (op2 == 0x04) {
+ lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1;
+ lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1;
- hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1;
- hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1;
- }
-
- RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24);
+ hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1;
+ hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1;
}
- }
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- SMLA_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smla_inst* inst_cream = (smla_inst*)inst_base->component;
- s32 operand1, operand2;
- if (inst_cream->x == 0)
- operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
- else
- operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
+ // SHSUB8
+ else {
+ lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1;
+ lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1;
- if (inst_cream->y == 0)
- operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
- else
- operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
+ hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1;
+ hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1;
+ }
- u32 product = operand1 * operand2;
- u32 result = product + RN;
- if (AddOverflow(product, RN, result))
- cpu->Cpsr |= (1 << 27);
- RD = result;
+ RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) |
+ ((hi_val2 & 0xFF) << 24);
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- SMLAD_INST:
- SMLSD_INST:
- SMUAD_INST:
- SMUSD_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- const u8 op2 = inst_cream->op2;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- u32 rm_val = cpu->Reg[inst_cream->Rm];
- const u32 rn_val = cpu->Reg[inst_cream->Rn];
+SMLA_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ smla_inst* inst_cream = (smla_inst*)inst_base->component;
+ s32 operand1, operand2;
+ if (inst_cream->x == 0)
+ operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
+ else
+ operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
- if (inst_cream->m)
- rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
+ if (inst_cream->y == 0)
+ operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
+ else
+ operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
+
+ u32 product = operand1 * operand2;
+ u32 result = product + RN;
+ if (AddOverflow(product, RN, result))
+ cpu->Cpsr |= (1 << 27);
+ RD = result;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(smla_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- const s16 rm_lo = (rm_val & 0xFFFF);
- const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
- const s16 rn_lo = (rn_val & 0xFFFF);
- const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
+SMLAD_INST:
+SMLSD_INST:
+SMUAD_INST:
+SMUSD_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+ const u8 op2 = inst_cream->op2;
- const u32 product1 = (rn_lo * rm_lo);
- const u32 product2 = (rn_hi * rm_hi);
+ u32 rm_val = cpu->Reg[inst_cream->Rm];
+ const u32 rn_val = cpu->Reg[inst_cream->Rn];
- // SMUAD and SMLAD
- if (BIT(op2, 1) == 0) {
- u32 rd_val = (product1 + product2);
+ if (inst_cream->m)
+ rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
- if (inst_cream->Ra != 15) {
- rd_val += cpu->Reg[inst_cream->Ra];
+ const s16 rm_lo = (rm_val & 0xFFFF);
+ const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
+ const s16 rn_lo = (rn_val & 0xFFFF);
+ const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
- if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra]))
- cpu->Cpsr |= (1 << 27);
- }
+ const u32 product1 = (rn_lo * rm_lo);
+ const u32 product2 = (rn_hi * rm_hi);
+
+ // SMUAD and SMLAD
+ if (BIT(op2, 1) == 0) {
+ u32 rd_val = (product1 + product2);
- RD = rd_val;
+ if (inst_cream->Ra != 15) {
+ rd_val += cpu->Reg[inst_cream->Ra];
- if (ARMul_AddOverflowQ(product1, product2))
+ if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra]))
cpu->Cpsr |= (1 << 27);
}
- // SMUSD and SMLSD
- else {
- u32 rd_val = (product1 - product2);
- if (inst_cream->Ra != 15) {
- rd_val += cpu->Reg[inst_cream->Ra];
+ RD = rd_val;
- if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra]))
- cpu->Cpsr |= (1 << 27);
- }
+ if (ARMul_AddOverflowQ(product1, product2))
+ cpu->Cpsr |= (1 << 27);
+ }
+ // SMUSD and SMLSD
+ else {
+ u32 rd_val = (product1 - product2);
+
+ if (inst_cream->Ra != 15) {
+ rd_val += cpu->Reg[inst_cream->Ra];
- RD = rd_val;
+ if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra]))
+ cpu->Cpsr |= (1 << 27);
}
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = rd_val;
+ }
}
- SMLAL_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
- long long int rm = RM;
- long long int rs = RS;
- if (BIT(rm, 31)) {
- rm |= 0xffffffff00000000LL;
- }
- if (BIT(rs, 31)) {
- rs |= 0xffffffff00000000LL;
- }
- long long int rst = rm * rs;
- long long int rdhi32 = RDHI;
- long long int hilo = (rdhi32 << 32) + RDLO;
- rst += hilo;
- RDLO = BITS(rst, 0, 31);
- RDHI = BITS(rst, 32, 63);
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(smlad_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+SMLAL_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
+ long long int rm = RM;
+ long long int rs = RS;
+ if (BIT(rm, 31)) {
+ rm |= 0xffffffff00000000LL;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umlal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- SMLALXY_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component;
-
- u64 operand1 = RN;
- u64 operand2 = RM;
-
- if (inst_cream->x != 0)
- operand1 >>= 16;
- if (inst_cream->y != 0)
- operand2 >>= 16;
- operand1 &= 0xFFFF;
- if (operand1 & 0x8000)
- operand1 -= 65536;
- operand2 &= 0xFFFF;
- if (operand2 & 0x8000)
- operand2 -= 65536;
-
- u64 dest = ((u64)RDHI << 32 | RDLO) + (operand1 * operand2);
- RDLO = (dest & 0xFFFFFFFF);
- RDHI = ((dest >> 32) & 0xFFFFFFFF);
+ if (BIT(rs, 31)) {
+ rs |= 0xffffffff00000000LL;
+ }
+ long long int rst = rm * rs;
+ long long int rdhi32 = RDHI;
+ long long int hilo = (rdhi32 << 32) + RDLO;
+ rst += hilo;
+ RDLO = BITS(rst, 0, 31);
+ RDHI = BITS(rst, 32, 63);
+ if (inst_cream->S) {
+ cpu->NFlag = BIT(RDHI, 31);
+ cpu->ZFlag = (RDHI == 0 && RDLO == 0);
}
-
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlalxy_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(umlal_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- SMLAW_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+SMLALXY_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component;
+
+ u64 operand1 = RN;
+ u64 operand2 = RM;
+
+ if (inst_cream->x != 0)
+ operand1 >>= 16;
+ if (inst_cream->y != 0)
+ operand2 >>= 16;
+ operand1 &= 0xFFFF;
+ if (operand1 & 0x8000)
+ operand1 -= 65536;
+ operand2 &= 0xFFFF;
+ if (operand2 & 0x8000)
+ operand2 -= 65536;
+
+ u64 dest = ((u64)RDHI << 32 | RDLO) + (operand1 * operand2);
+ RDLO = (dest & 0xFFFFFFFF);
+ RDHI = ((dest >> 32) & 0xFFFFFFFF);
+ }
+
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(smlalxy_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const u32 ra_val = cpu->Reg[inst_cream->Ra];
- const bool high = (inst_cream->m == 1);
+SMLAW_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF);
- const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16);
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+ const u32 ra_val = cpu->Reg[inst_cream->Ra];
+ const bool high = (inst_cream->m == 1);
- RD = BITS(result, 16, 47);
+ const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF);
+ const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16);
- if ((result >> 16) != (s32)RD)
- cpu->Cpsr |= (1 << 27);
- }
+ RD = BITS(result, 16, 47);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((result >> 16) != (s32)RD)
+ cpu->Cpsr |= (1 << 27);
}
- SMLALD_INST:
- SMLSLD_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(smlad_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- const bool do_swap = (inst_cream->swap == 1);
- const u32 rdlo_val = RDLO;
- const u32 rdhi_val = RDHI;
- const u32 rn_val = RN;
- u32 rm_val = RM;
+SMLALD_INST:
+SMLSLD_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
- if (do_swap)
- rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
+ const bool do_swap = (inst_cream->swap == 1);
+ const u32 rdlo_val = RDLO;
+ const u32 rdhi_val = RDHI;
+ const u32 rn_val = RN;
+ u32 rm_val = RM;
- const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
- const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
- s64 result;
+ if (do_swap)
+ rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
- // SMLALD
- if (BIT(inst_cream->op2, 1) == 0) {
- result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
- }
- // SMLSLD
- else {
- result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
- }
+ const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
+ const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
+ s64 result;
- RDLO = (result & 0xFFFFFFFF);
- RDHI = ((result >> 32) & 0xFFFFFFFF);
+ // SMLALD
+ if (BIT(inst_cream->op2, 1) == 0) {
+ result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
+ }
+ // SMLSLD
+ else {
+ result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlald_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RDLO = (result & 0xFFFFFFFF);
+ RDHI = ((result >> 32) & 0xFFFFFFFF);
}
- SMMLA_INST:
- SMMLS_INST:
- SMMUL_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const bool do_round = (inst_cream->m == 1);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(smlald_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- // Assume SMMUL by default.
- s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
+SMMLA_INST:
+SMMLS_INST:
+SMMUL_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- if (inst_cream->Ra != 15) {
- const u32 ra_val = cpu->Reg[inst_cream->Ra];
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+ const bool do_round = (inst_cream->m == 1);
- // SMMLA, otherwise SMMLS
- if (BIT(inst_cream->op2, 1) == 0)
- result += ((s64)ra_val << 32);
- else
- result = ((s64)ra_val << 32) - result;
- }
+ // Assume SMMUL by default.
+ s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
- if (do_round)
- result += 0x80000000;
+ if (inst_cream->Ra != 15) {
+ const u32 ra_val = cpu->Reg[inst_cream->Ra];
- RD = ((result >> 32) & 0xFFFFFFFF);
+ // SMMLA, otherwise SMMLS
+ if (BIT(inst_cream->op2, 1) == 0)
+ result += ((s64)ra_val << 32);
+ else
+ result = ((s64)ra_val << 32) - result;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if (do_round)
+ result += 0x80000000;
+
+ RD = ((result >> 32) & 0xFFFFFFFF);
}
- SMUL_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smul_inst* inst_cream = (smul_inst*)inst_base->component;
- u32 operand1, operand2;
- if (inst_cream->x == 0)
- operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
- else
- operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(smlad_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- if (inst_cream->y == 0)
- operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
- else
- operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
- RD = operand1 * operand2;
+SMUL_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ smul_inst* inst_cream = (smul_inst*)inst_base->component;
+ u32 operand1, operand2;
+ if (inst_cream->x == 0)
+ operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
+ else
+ operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
+
+ if (inst_cream->y == 0)
+ operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
+ else
+ operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
+ RD = operand1 * operand2;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(smul_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+SMULL_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ umull_inst* inst_cream = (umull_inst*)inst_base->component;
+ s64 rm = RM;
+ s64 rs = RS;
+ if (BIT(rm, 31)) {
+ rm |= 0xffffffff00000000LL;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SMULL_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umull_inst* inst_cream = (umull_inst*)inst_base->component;
- s64 rm = RM;
- s64 rs = RS;
- if (BIT(rm, 31)) {
- rm |= 0xffffffff00000000LL;
- }
- if (BIT(rs, 31)) {
- rs |= 0xffffffff00000000LL;
- }
- s64 rst = rm * rs;
- RDHI = BITS(rst, 32, 63);
- RDLO = BITS(rst, 0, 31);
+ if (BIT(rs, 31)) {
+ rs |= 0xffffffff00000000LL;
+ }
+ s64 rst = rm * rs;
+ RDHI = BITS(rst, 32, 63);
+ RDLO = BITS(rst, 0, 31);
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
+ if (inst_cream->S) {
+ cpu->NFlag = BIT(RDHI, 31);
+ cpu->ZFlag = (RDHI == 0 && RDLO == 0);
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umull_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(umull_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- SMULW_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+SMULW_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
- s16 rm = (inst_cream->m == 1) ? ((RM >> 16) & 0xFFFF) : (RM & 0xFFFF);
+ s16 rm = (inst_cream->m == 1) ? ((RM >> 16) & 0xFFFF) : (RM & 0xFFFF);
- s64 result = (s64)rm * (s64)(s32)RN;
- RD = BITS(result, 16, 47);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(smlad_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ s64 result = (s64)rm * (s64)(s32)RN;
+ RD = BITS(result, 16, 47);
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(smlad_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- SRS_INST:
- {
- // SRS is unconditional
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
+SRS_INST : {
+ // SRS is unconditional
+ ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
- u32 address = 0;
- inst_cream->get_addr(cpu, inst_cream->inst, address);
+ u32 address = 0;
+ inst_cream->get_addr(cpu, inst_cream->inst, address);
- cpu->WriteMemory32(address + 0, cpu->Reg[14]);
- cpu->WriteMemory32(address + 4, cpu->Spsr_copy);
+ cpu->WriteMemory32(address + 0, cpu->Reg[14]);
+ cpu->WriteMemory32(address + 4, cpu->Spsr_copy);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- SSAT_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- u8 shift_type = inst_cream->shift_type;
- u8 shift_amount = inst_cream->imm5;
- u32 rn_val = RN;
+SSAT_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- // 32-bit ASR is encoded as an amount of 0.
- if (shift_type == 1 && shift_amount == 0)
- shift_amount = 31;
+ u8 shift_type = inst_cream->shift_type;
+ u8 shift_amount = inst_cream->imm5;
+ u32 rn_val = RN;
- if (shift_type == 0)
- rn_val <<= shift_amount;
- else if (shift_type == 1)
- rn_val = ((s32)rn_val >> shift_amount);
+ // 32-bit ASR is encoded as an amount of 0.
+ if (shift_type == 1 && shift_amount == 0)
+ shift_amount = 31;
- bool saturated = false;
- rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
+ if (shift_type == 0)
+ rn_val <<= shift_amount;
+ else if (shift_type == 1)
+ rn_val = ((s32)rn_val >> shift_amount);
- if (saturated)
- cpu->Cpsr |= (1 << 27);
+ bool saturated = false;
+ rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
- RD = rn_val;
- }
+ if (saturated)
+ cpu->Cpsr |= (1 << 27);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = rn_val;
}
- SSAT16_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- const u8 saturate_to = inst_cream->sat_imm;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ssat_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- bool sat1 = false;
- bool sat2 = false;
+SSAT16_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
+ const u8 saturate_to = inst_cream->sat_imm;
- RD = (ARMul_SignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
- ARMul_SignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
+ bool sat1 = false;
+ bool sat2 = false;
- if (sat1 || sat2)
- cpu->Cpsr |= (1 << 27);
- }
+ RD = (ARMul_SignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
+ ARMul_SignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- STC_INST:
- {
- // Instruction not implemented
- //LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(stc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STM_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- unsigned int inst = inst_cream->inst;
-
- unsigned int Rn = BITS(inst, 16, 19);
- unsigned int old_RN = cpu->Reg[Rn];
-
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- if (BIT(inst_cream->inst, 22) == 1) {
- for (int i = 0; i < 13; i++) {
- if (BIT(inst_cream->inst, i)) {
- cpu->WriteMemory32(addr, cpu->Reg[i]);
- addr += 4;
- }
- }
- if (BIT(inst_cream->inst, 13)) {
- if (cpu->Mode == USER32MODE)
- cpu->WriteMemory32(addr, cpu->Reg[13]);
- else
- cpu->WriteMemory32(addr, cpu->Reg_usr[0]);
+ if (sat1 || sat2)
+ cpu->Cpsr |= (1 << 27);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ssat_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+STC_INST : {
+ // Instruction not implemented
+ // LOG_CRITICAL(Core_ARM11, "unimplemented instruction");
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(stc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STM_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ unsigned int inst = inst_cream->inst;
+
+ unsigned int Rn = BITS(inst, 16, 19);
+ unsigned int old_RN = cpu->Reg[Rn];
+
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
+ if (BIT(inst_cream->inst, 22) == 1) {
+ for (int i = 0; i < 13; i++) {
+ if (BIT(inst_cream->inst, i)) {
+ cpu->WriteMemory32(addr, cpu->Reg[i]);
addr += 4;
}
- if (BIT(inst_cream->inst, 14)) {
- if (cpu->Mode == USER32MODE)
- cpu->WriteMemory32(addr, cpu->Reg[14]);
+ }
+ if (BIT(inst_cream->inst, 13)) {
+ if (cpu->Mode == USER32MODE)
+ cpu->WriteMemory32(addr, cpu->Reg[13]);
+ else
+ cpu->WriteMemory32(addr, cpu->Reg_usr[0]);
+
+ addr += 4;
+ }
+ if (BIT(inst_cream->inst, 14)) {
+ if (cpu->Mode == USER32MODE)
+ cpu->WriteMemory32(addr, cpu->Reg[14]);
+ else
+ cpu->WriteMemory32(addr, cpu->Reg_usr[1]);
+
+ addr += 4;
+ }
+ if (BIT(inst_cream->inst, 15)) {
+ cpu->WriteMemory32(addr, cpu->Reg[15] + 8);
+ }
+ } else {
+ for (int i = 0; i < 15; i++) {
+ if (BIT(inst_cream->inst, i)) {
+ if (i == Rn)
+ cpu->WriteMemory32(addr, old_RN);
else
- cpu->WriteMemory32(addr, cpu->Reg_usr[1]);
+ cpu->WriteMemory32(addr, cpu->Reg[i]);
addr += 4;
}
- if (BIT(inst_cream->inst, 15)) {
- cpu->WriteMemory32(addr, cpu->Reg[15] + 8);
- }
- } else {
- for (int i = 0; i < 15; i++) {
- if (BIT(inst_cream->inst, i)) {
- if (i == Rn)
- cpu->WriteMemory32(addr, old_RN);
- else
- cpu->WriteMemory32(addr, cpu->Reg[i]);
-
- addr += 4;
- }
- }
+ }
- // Check PC reg
- if (BIT(inst_cream->inst, 15)) {
- cpu->WriteMemory32(addr, cpu->Reg[15] + 8);
- }
+ // Check PC reg
+ if (BIT(inst_cream->inst, 15)) {
+ cpu->WriteMemory32(addr, cpu->Reg[15] + 8);
}
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- SXTB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+SXTB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
- if (BIT(operand2, 7)) {
- operand2 |= 0xffffff00;
- } else {
- operand2 &= 0xff;
- }
- RD = operand2;
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
+ if (BIT(operand2, 7)) {
+ operand2 |= 0xffffff00;
+ } else {
+ operand2 &= 0xff;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxtb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = operand2;
}
- STR_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(sxtb_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STR_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int reg = BITS(inst_cream->inst, 12, 15);
- unsigned int value = cpu->Reg[reg];
+ unsigned int reg = BITS(inst_cream->inst, 12, 15);
+ unsigned int value = cpu->Reg[reg];
- if (reg == 15)
- value += 2 * cpu->GetInstructionSize();
+ if (reg == 15)
+ value += 2 * cpu->GetInstructionSize();
- cpu->WriteMemory32(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component;
- RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtb_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UXTAB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component;
-
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
- cpu->WriteMemory8(addr, value);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ cpu->WriteMemory32(addr, value);
}
- STRBT_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+UXTB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component;
+ RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(uxtb_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+UXTAB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component;
- const u32 previous_mode = cpu->Mode;
- const u32 value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
+ RD = RN + operand2;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(uxtab_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STRB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
+ cpu->WriteMemory8(addr, value);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STRBT_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
- cpu->ChangePrivilegeMode(USER32MODE);
- cpu->WriteMemory8(addr, value);
- cpu->ChangePrivilegeMode(previous_mode);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRD_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- // The 3DS doesn't have the Large Physical Access Extension (LPAE)
- // so STRD wouldn't store these as a single write.
- cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
- cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREX_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
-
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->WriteMemory32(write_addr, RM);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREXB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
-
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->WriteMemory8(write_addr, cpu->Reg[inst_cream->Rm]);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREXD_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
-
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
-
- const u32 rt = cpu->Reg[inst_cream->Rm + 0];
- const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
- u64 value;
-
- if (cpu->InBigEndianMode())
- value = (((u64)rt << 32) | rt2);
- else
- value = (((u64)rt2 << 32) | rt);
+ const u32 previous_mode = cpu->Mode;
+ const u32 value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
- cpu->WriteMemory64(write_addr, value);
- RD = 0;
- }
- else {
- // Failed to write due to mutex access
- RD = 1;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STREXH_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- unsigned int write_addr = cpu->Reg[inst_cream->Rn];
-
- if (cpu->IsExclusiveMemoryAccess(write_addr)) {
- cpu->UnsetExclusiveMemoryAddress();
- cpu->WriteMemory16(write_addr, RM);
- RD = 0;
- } else {
- // Failed to write due to mutex access
- RD = 1;
- }
+ cpu->ChangePrivilegeMode(USER32MODE);
+ cpu->WriteMemory8(addr, value);
+ cpu->ChangePrivilegeMode(previous_mode);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STRD_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
+
+ // The 3DS doesn't have the Large Physical Access Extension (LPAE)
+ // so STRD wouldn't store these as a single write.
+ cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
+ cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STREX_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ unsigned int write_addr = cpu->Reg[inst_cream->Rn];
+
+ if (cpu->IsExclusiveMemoryAccess(write_addr)) {
+ cpu->UnsetExclusiveMemoryAddress();
+ cpu->WriteMemory32(write_addr, RM);
+ RD = 0;
+ } else {
+ // Failed to write due to mutex access
+ RD = 1;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- STRH_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
-
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
- cpu->WriteMemory16(addr, value);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STREXB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ unsigned int write_addr = cpu->Reg[inst_cream->Rn];
+
+ if (cpu->IsExclusiveMemoryAccess(write_addr)) {
+ cpu->UnsetExclusiveMemoryAddress();
+ cpu->WriteMemory8(write_addr, cpu->Reg[inst_cream->Rm]);
+ RD = 0;
+ } else {
+ // Failed to write due to mutex access
+ RD = 1;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- STRT_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
- inst_cream->get_addr(cpu, inst_cream->inst, addr);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STREXD_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- const u32 previous_mode = cpu->Mode;
- const u32 rt_index = BITS(inst_cream->inst, 12, 15);
+ if (cpu->IsExclusiveMemoryAccess(write_addr)) {
+ cpu->UnsetExclusiveMemoryAddress();
- u32 value = cpu->Reg[rt_index];
- if (rt_index == 15)
- value += 2 * cpu->GetInstructionSize();
+ const u32 rt = cpu->Reg[inst_cream->Rm + 0];
+ const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
+ u64 value;
- cpu->ChangePrivilegeMode(USER32MODE);
- cpu->WriteMemory32(addr, value);
- cpu->ChangePrivilegeMode(previous_mode);
+ if (cpu->InBigEndianMode())
+ value = (((u64)rt << 32) | rt2);
+ else
+ value = (((u64)rt2 << 32) | rt);
+
+ cpu->WriteMemory64(write_addr, value);
+ RD = 0;
+ } else {
+ // Failed to write due to mutex access
+ RD = 1;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ldst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- SUB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sub_inst* const inst_cream = (sub_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STREXH_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ unsigned int write_addr = cpu->Reg[inst_cream->Rn];
+
+ if (cpu->IsExclusiveMemoryAccess(write_addr)) {
+ cpu->UnsetExclusiveMemoryAddress();
+ cpu->WriteMemory16(write_addr, RM);
+ RD = 0;
+ } else {
+ // Failed to write due to mutex access
+ RD = 1;
+ }
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STRH_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
- u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn);
+ unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
+ cpu->WriteMemory16(addr, value);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+STRT_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+ inst_cream->get_addr(cpu, inst_cream->inst, addr);
- bool carry;
- bool overflow;
- RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
+ const u32 previous_mode = cpu->Mode;
+ const u32 rt_index = BITS(inst_cream->inst, 12, 15);
- if (inst_cream->S && (inst_cream->Rd == 15)) {
- if (CurrentModeHasSPSR) {
- cpu->Cpsr = cpu->Spsr_copy;
- cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
- LOAD_NZCVT;
- }
- } else if (inst_cream->S) {
- UPDATE_NFLAG(RD);
- UPDATE_ZFLAG(RD);
- cpu->CFlag = carry;
- cpu->VFlag = overflow;
- }
- if (inst_cream->Rd == 15) {
- INC_PC(sizeof(sub_inst));
- goto DISPATCH;
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sub_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SWI_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- swi_inst* const inst_cream = (swi_inst*)inst_base->component;
- SVC::CallSVC(inst_cream->num & 0xFFFF);
- }
+ u32 value = cpu->Reg[rt_index];
+ if (rt_index == 15)
+ value += 2 * cpu->GetInstructionSize();
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(swi_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ cpu->ChangePrivilegeMode(USER32MODE);
+ cpu->WriteMemory32(addr, value);
+ cpu->ChangePrivilegeMode(previous_mode);
}
- SWP_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- swp_inst* inst_cream = (swp_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ldst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+SUB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ sub_inst* const inst_cream = (sub_inst*)inst_base->component;
- addr = RN;
- unsigned int value = cpu->ReadMemory32(addr);
- cpu->WriteMemory32(addr, RM);
+ u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn);
- RD = value;
+ bool carry;
+ bool overflow;
+ RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
+
+ if (inst_cream->S && (inst_cream->Rd == 15)) {
+ if (CurrentModeHasSPSR) {
+ cpu->Cpsr = cpu->Spsr_copy;
+ cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F);
+ LOAD_NZCVT;
+ }
+ } else if (inst_cream->S) {
+ UPDATE_NFLAG(RD);
+ UPDATE_ZFLAG(RD);
+ cpu->CFlag = carry;
+ cpu->VFlag = overflow;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(swp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- SWPB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- swp_inst* inst_cream = (swp_inst*)inst_base->component;
- addr = RN;
- unsigned int value = cpu->ReadMemory8(addr);
- cpu->WriteMemory8(addr, (RM & 0xFF));
- RD = value;
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(sub_inst));
+ goto DISPATCH;
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(swp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- SXTAB_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(sub_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+SWI_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ swi_inst* const inst_cream = (swi_inst*)inst_base->component;
+ SVC::CallSVC(inst_cream->num & 0xFFFF);
+ }
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(swi_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+SWP_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ swp_inst* inst_cream = (swp_inst*)inst_base->component;
- // Sign extend for byte
- operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- SXTAB16_INST:
- SXTB16_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
-
- const u8 rotation = inst_cream->rotate * 8;
- u32 rm_val = RM;
- u32 rn_val = RN;
-
- if (rotation)
- rm_val = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
-
- // SXTB16
- if (inst_cream->Rn == 15) {
- u32 lo = (u32)(s8)rm_val;
- u32 hi = (u32)(s8)(rm_val >> 16);
- RD = (lo | (hi << 16));
- }
- // SXTAB16
- else {
- u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF);
- u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF);
- RD = (lo | (hi << 16));
- }
- }
+ addr = RN;
+ unsigned int value = cpu->ReadMemory32(addr);
+ cpu->WriteMemory32(addr, RM);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = value;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(swp_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+SWPB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ swp_inst* inst_cream = (swp_inst*)inst_base->component;
+ addr = RN;
+ unsigned int value = cpu->ReadMemory8(addr);
+ cpu->WriteMemory8(addr, (RM & 0xFF));
+ RD = value;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(swp_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+SXTAB_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component;
- SXTAH_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component;
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff;
- unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
- // Sign extend for half
- operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
- RD = RN + operand2;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(sxtah_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ // Sign extend for byte
+ operand2 = (0x80 & operand2) ? (0xFFFFFF00 | operand2) : operand2;
+ RD = RN + operand2;
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(uxtab_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- TEQ_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- teq_inst* const inst_cream = (teq_inst*)inst_base->component;
-
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
+SXTAB16_INST:
+SXTB16_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
- if (inst_cream->Rn == 15)
- lop += cpu->GetInstructionSize() * 2;
+ const u8 rotation = inst_cream->rotate * 8;
+ u32 rm_val = RM;
+ u32 rn_val = RN;
- u32 result = lop ^ rop;
+ if (rotation)
+ rm_val = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- UPDATE_CFLAG_WITH_SC;
+ // SXTB16
+ if (inst_cream->Rn == 15) {
+ u32 lo = (u32)(s8)rm_val;
+ u32 hi = (u32)(s8)(rm_val >> 16);
+ RD = (lo | (hi << 16));
+ }
+ // SXTAB16
+ else {
+ u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF);
+ u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF);
+ RD = (lo | (hi << 16));
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(teq_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
}
- TST_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- tst_inst* const inst_cream = (tst_inst*)inst_base->component;
- u32 lop = RN;
- u32 rop = SHIFTER_OPERAND;
-
- if (inst_cream->Rn == 15)
- lop += cpu->GetInstructionSize() * 2;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(sxtab_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- u32 result = lop & rop;
+SXTAH_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component;
- UPDATE_NFLAG(result);
- UPDATE_ZFLAG(result);
- UPDATE_CFLAG_WITH_SC;
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(tst_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- UADD8_INST:
- UADD16_INST:
- UADDSUBX_INST:
- USUB8_INST:
- USUB16_INST:
- USUBADDX_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
+ unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
+ // Sign extend for half
+ operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2;
+ RD = RN + operand2;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(sxtah_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- s32 lo_result = 0;
- s32 hi_result = 0;
+TEQ_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ teq_inst* const inst_cream = (teq_inst*)inst_base->component;
- // UADD16
- if (op2 == 0x00) {
- lo_result = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
-
- if (lo_result & 0xFFFF0000) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
+ u32 lop = RN;
+ u32 rop = SHIFTER_OPERAND;
- if (hi_result & 0xFFFF0000) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // UASX
- else if (op2 == 0x01) {
- lo_result = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
-
- if (lo_result >= 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
+ if (inst_cream->Rn == 15)
+ lop += cpu->GetInstructionSize() * 2;
- if (hi_result >= 0x10000) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // USAX
- else if (op2 == 0x02) {
- lo_result = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
-
- if (lo_result >= 0x10000) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
+ u32 result = lop ^ rop;
- if (hi_result >= 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // USUB16
- else if (op2 == 0x03) {
- lo_result = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
- hi_result = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
-
- if ((lo_result & 0xFFFF0000) == 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
- }
+ UPDATE_NFLAG(result);
+ UPDATE_ZFLAG(result);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(teq_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+TST_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ tst_inst* const inst_cream = (tst_inst*)inst_base->component;
- if ((hi_result & 0xFFFF0000) == 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
- }
- }
- // UADD8
- else if (op2 == 0x04) {
- s16 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
- s16 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
- s16 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
- s16 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
-
- if (sum1 >= 0x100)
- cpu->Cpsr |= (1 << 16);
- else
- cpu->Cpsr &= ~(1 << 16);
+ u32 lop = RN;
+ u32 rop = SHIFTER_OPERAND;
- if (sum2 >= 0x100)
- cpu->Cpsr |= (1 << 17);
- else
- cpu->Cpsr &= ~(1 << 17);
+ if (inst_cream->Rn == 15)
+ lop += cpu->GetInstructionSize() * 2;
- if (sum3 >= 0x100)
- cpu->Cpsr |= (1 << 18);
- else
- cpu->Cpsr &= ~(1 << 18);
+ u32 result = lop & rop;
- if (sum4 >= 0x100)
- cpu->Cpsr |= (1 << 19);
- else
- cpu->Cpsr &= ~(1 << 19);
+ UPDATE_NFLAG(result);
+ UPDATE_ZFLAG(result);
+ UPDATE_CFLAG_WITH_SC;
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(tst_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- lo_result = ((sum1 & 0xFF) | (sum2 & 0xFF) << 8);
- hi_result = ((sum3 & 0xFF) | (sum4 & 0xFF) << 8);
+UADD8_INST:
+UADD16_INST:
+UADDSUBX_INST:
+USUB8_INST:
+USUB16_INST:
+USUBADDX_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ const u8 op2 = inst_cream->op2;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+
+ s32 lo_result = 0;
+ s32 hi_result = 0;
+
+ // UADD16
+ if (op2 == 0x00) {
+ lo_result = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
+ hi_result = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
+
+ if (lo_result & 0xFFFF0000) {
+ cpu->Cpsr |= (1 << 16);
+ cpu->Cpsr |= (1 << 17);
+ } else {
+ cpu->Cpsr &= ~(1 << 16);
+ cpu->Cpsr &= ~(1 << 17);
}
- // USUB8
- else if (op2 == 0x07) {
- s16 diff1 = (rn_val & 0xFF) - (rm_val & 0xFF);
- s16 diff2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
- s16 diff3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
- s16 diff4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
-
- if (diff1 >= 0)
- cpu->Cpsr |= (1 << 16);
- else
- cpu->Cpsr &= ~(1 << 16);
- if (diff2 >= 0)
- cpu->Cpsr |= (1 << 17);
- else
- cpu->Cpsr &= ~(1 << 17);
-
- if (diff3 >= 0)
- cpu->Cpsr |= (1 << 18);
- else
- cpu->Cpsr &= ~(1 << 18);
-
- if (diff4 >= 0)
- cpu->Cpsr |= (1 << 19);
- else
- cpu->Cpsr &= ~(1 << 19);
-
- lo_result = (diff1 & 0xFF) | ((diff2 & 0xFF) << 8);
- hi_result = (diff3 & 0xFF) | ((diff4 & 0xFF) << 8);
+ if (hi_result & 0xFFFF0000) {
+ cpu->Cpsr |= (1 << 18);
+ cpu->Cpsr |= (1 << 19);
+ } else {
+ cpu->Cpsr &= ~(1 << 18);
+ cpu->Cpsr &= ~(1 << 19);
}
-
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
}
+ // UASX
+ else if (op2 == 0x01) {
+ lo_result = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
+ hi_result = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
+
+ if (lo_result >= 0) {
+ cpu->Cpsr |= (1 << 16);
+ cpu->Cpsr |= (1 << 17);
+ } else {
+ cpu->Cpsr &= ~(1 << 16);
+ cpu->Cpsr &= ~(1 << 17);
+ }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
-
- UHADD8_INST:
- UHADD16_INST:
- UHADDSUBX_INST:
- UHSUBADDX_INST:
- UHSUB8_INST:
- UHSUB16_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
- const u8 op2 = inst_cream->op2;
-
- if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
- {
- u32 lo_val = 0;
- u32 hi_val = 0;
-
- // UHADD16
- if (op2 == 0x00) {
- lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- }
- // UHASX
- else if (op2 == 0x01) {
- lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
- }
- // UHSAX
- else if (op2 == 0x02) {
- lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
- }
- // UHSUB16
- else if (op2 == 0x03) {
- lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
- hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
- }
-
- lo_val >>= 1;
- hi_val >>= 1;
-
- RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
+ if (hi_result >= 0x10000) {
+ cpu->Cpsr |= (1 << 18);
+ cpu->Cpsr |= (1 << 19);
+ } else {
+ cpu->Cpsr &= ~(1 << 18);
+ cpu->Cpsr &= ~(1 << 19);
+ }
+ }
+ // USAX
+ else if (op2 == 0x02) {
+ lo_result = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
+ hi_result = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
+
+ if (lo_result >= 0x10000) {
+ cpu->Cpsr |= (1 << 16);
+ cpu->Cpsr |= (1 << 17);
+ } else {
+ cpu->Cpsr &= ~(1 << 16);
+ cpu->Cpsr &= ~(1 << 17);
}
- else if (op2 == 0x04 || op2 == 0x07) {
- u32 sum1;
- u32 sum2;
- u32 sum3;
- u32 sum4;
-
- // UHADD8
- if (op2 == 0x04) {
- sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
- sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
- sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
- sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
- }
- // UHSUB8
- else {
- sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
- sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
- sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
- sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
- }
- sum1 >>= 1;
- sum2 >>= 1;
- sum3 >>= 1;
- sum4 >>= 1;
+ if (hi_result >= 0) {
+ cpu->Cpsr |= (1 << 18);
+ cpu->Cpsr |= (1 << 19);
+ } else {
+ cpu->Cpsr &= ~(1 << 18);
+ cpu->Cpsr &= ~(1 << 19);
+ }
+ }
+ // USUB16
+ else if (op2 == 0x03) {
+ lo_result = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
+ hi_result = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
+
+ if ((lo_result & 0xFFFF0000) == 0) {
+ cpu->Cpsr |= (1 << 16);
+ cpu->Cpsr |= (1 << 17);
+ } else {
+ cpu->Cpsr &= ~(1 << 16);
+ cpu->Cpsr &= ~(1 << 17);
+ }
- RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
+ if ((hi_result & 0xFFFF0000) == 0) {
+ cpu->Cpsr |= (1 << 18);
+ cpu->Cpsr |= (1 << 19);
+ } else {
+ cpu->Cpsr &= ~(1 << 18);
+ cpu->Cpsr &= ~(1 << 19);
}
}
+ // UADD8
+ else if (op2 == 0x04) {
+ s16 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
+ s16 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
+ s16 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
+ s16 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
+
+ if (sum1 >= 0x100)
+ cpu->Cpsr |= (1 << 16);
+ else
+ cpu->Cpsr &= ~(1 << 16);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
+ if (sum2 >= 0x100)
+ cpu->Cpsr |= (1 << 17);
+ else
+ cpu->Cpsr &= ~(1 << 17);
- UMAAL_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
- const u64 rm = RM;
- const u64 rn = RN;
- const u64 rd_lo = RDLO;
- const u64 rd_hi = RDHI;
- const u64 result = (rm * rn) + rd_lo + rd_hi;
+ if (sum3 >= 0x100)
+ cpu->Cpsr |= (1 << 18);
+ else
+ cpu->Cpsr &= ~(1 << 18);
- RDLO = (result & 0xFFFFFFFF);
- RDHI = ((result >> 32) & 0xFFFFFFFF);
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umaal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UMLAL_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
- unsigned long long int rm = RM;
- unsigned long long int rs = RS;
- unsigned long long int rst = rm * rs;
- unsigned long long int add = ((unsigned long long) RDHI)<<32;
- add += RDLO;
- rst += add;
- RDLO = BITS(rst, 0, 31);
- RDHI = BITS(rst, 32, 63);
-
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
- }
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umlal_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- UMULL_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- umull_inst* inst_cream = (umull_inst*)inst_base->component;
- unsigned long long int rm = RM;
- unsigned long long int rs = RS;
- unsigned long long int rst = rm * rs;
- RDHI = BITS(rst, 32, 63);
- RDLO = BITS(rst, 0, 31);
-
- if (inst_cream->S) {
- cpu->NFlag = BIT(RDHI, 31);
- cpu->ZFlag = (RDHI == 0 && RDLO == 0);
- }
+ if (sum4 >= 0x100)
+ cpu->Cpsr |= (1 << 19);
+ else
+ cpu->Cpsr &= ~(1 << 19);
+
+ lo_result = ((sum1 & 0xFF) | (sum2 & 0xFF) << 8);
+ hi_result = ((sum3 & 0xFF) | (sum4 & 0xFF) << 8);
}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(umull_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- B_2_THUMB:
- {
- b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component;
- cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
- INC_PC(sizeof(b_2_thumb));
- goto DISPATCH;
- }
- B_COND_THUMB:
- {
- b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component;
+ // USUB8
+ else if (op2 == 0x07) {
+ s16 diff1 = (rn_val & 0xFF) - (rm_val & 0xFF);
+ s16 diff2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
+ s16 diff3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
+ s16 diff4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
+
+ if (diff1 >= 0)
+ cpu->Cpsr |= (1 << 16);
+ else
+ cpu->Cpsr &= ~(1 << 16);
- if(CondPassed(cpu, inst_cream->cond))
- cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
- else
- cpu->Reg[15] += 2;
+ if (diff2 >= 0)
+ cpu->Cpsr |= (1 << 17);
+ else
+ cpu->Cpsr &= ~(1 << 17);
- INC_PC(sizeof(b_cond_thumb));
- goto DISPATCH;
- }
- BL_1_THUMB:
- {
- bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component;
- cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(bl_1_thumb));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
- BL_2_THUMB:
- {
- bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component;
- int tmp = ((cpu->Reg[15] + 2) | 1);
- cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm);
- cpu->Reg[14] = tmp;
- INC_PC(sizeof(bl_2_thumb));
- goto DISPATCH;
- }
- BLX_1_THUMB:
- {
- // BLX 1 for armv5t and above
- u32 tmp = cpu->Reg[15];
- blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component;
- cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
- cpu->Reg[14] = ((tmp + 2) | 1);
- cpu->TFlag = 0;
- INC_PC(sizeof(blx_1_thumb));
- goto DISPATCH;
- }
+ if (diff3 >= 0)
+ cpu->Cpsr |= (1 << 18);
+ else
+ cpu->Cpsr &= ~(1 << 18);
- UQADD8_INST:
- UQADD16_INST:
- UQADDSUBX_INST:
- UQSUB8_INST:
- UQSUB16_INST:
- UQSUBADDX_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ if (diff4 >= 0)
+ cpu->Cpsr |= (1 << 19);
+ else
+ cpu->Cpsr &= ~(1 << 19);
- const u8 op2 = inst_cream->op2;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
+ lo_result = (diff1 & 0xFF) | ((diff2 & 0xFF) << 8);
+ hi_result = (diff3 & 0xFF) | ((diff4 & 0xFF) << 8);
+ }
- u16 lo_val = 0;
- u16 hi_val = 0;
+ RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
+ }
- // UQADD16
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+
+UHADD8_INST:
+UHADD16_INST:
+UHADDSUBX_INST:
+UHSUBADDX_INST:
+UHSUB8_INST:
+UHSUB16_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+ const u8 op2 = inst_cream->op2;
+
+ if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
+ u32 lo_val = 0;
+ u32 hi_val = 0;
+
+ // UHADD16
if (op2 == 0x00) {
- lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
}
- // UQASX
+ // UHASX
else if (op2 == 0x01) {
- lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
}
- // UQSAX
+ // UHSAX
else if (op2 == 0x02) {
- lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
}
- // UQSUB16
+ // UHSUB16
else if (op2 == 0x03) {
- lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
- hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
}
- // UQADD8
- else if (op2 == 0x04) {
- lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
- ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
- hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
- ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
+
+ lo_val >>= 1;
+ hi_val >>= 1;
+
+ RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
+ } else if (op2 == 0x04 || op2 == 0x07) {
+ u32 sum1;
+ u32 sum2;
+ u32 sum3;
+ u32 sum4;
+
+ // UHADD8
+ if (op2 == 0x04) {
+ sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
+ sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
+ sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
+ sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
}
- // UQSUB8
+ // UHSUB8
else {
- lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
- ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
- hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
- ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
+ sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
+ sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
+ sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
+ sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
}
- RD = ((lo_val & 0xFFFF) | hi_val << 16);
+ sum1 >>= 1;
+ sum2 >>= 1;
+ sum3 >>= 1;
+ sum4 >>= 1;
+
+ RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) |
+ ((sum4 & 0xFF) << 24);
}
+ }
+
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+UMAAL_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
+ const u64 rm = RM;
+ const u64 rn = RN;
+ const u64 rd_lo = RDLO;
+ const u64 rd_hi = RDHI;
+ const u64 result = (rm * rn) + rd_lo + rd_hi;
+
+ RDLO = (result & 0xFFFFFFFF);
+ RDHI = ((result >> 32) & 0xFFFFFFFF);
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(umaal_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+UMLAL_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ umlal_inst* inst_cream = (umlal_inst*)inst_base->component;
+ unsigned long long int rm = RM;
+ unsigned long long int rs = RS;
+ unsigned long long int rst = rm * rs;
+ unsigned long long int add = ((unsigned long long)RDHI) << 32;
+ add += RDLO;
+ rst += add;
+ RDLO = BITS(rst, 0, 31);
+ RDHI = BITS(rst, 32, 63);
+
+ if (inst_cream->S) {
+ cpu->NFlag = BIT(RDHI, 31);
+ cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+ }
+ }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(umlal_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+UMULL_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ umull_inst* inst_cream = (umull_inst*)inst_base->component;
+ unsigned long long int rm = RM;
+ unsigned long long int rs = RS;
+ unsigned long long int rst = rm * rs;
+ RDHI = BITS(rst, 32, 63);
+ RDLO = BITS(rst, 0, 31);
+
+ if (inst_cream->S) {
+ cpu->NFlag = BIT(RDHI, 31);
+ cpu->ZFlag = (RDHI == 0 && RDLO == 0);
+ }
}
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(umull_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+B_2_THUMB : {
+ b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component;
+ cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
+ INC_PC(sizeof(b_2_thumb));
+ goto DISPATCH;
+}
+B_COND_THUMB : {
+ b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component;
- USAD8_INST:
- USADA8_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ if (CondPassed(cpu, inst_cream->cond))
+ cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
+ else
+ cpu->Reg[15] += 2;
- const u8 ra_idx = inst_cream->Ra;
- const u32 rm_val = RM;
- const u32 rn_val = RN;
+ INC_PC(sizeof(b_cond_thumb));
+ goto DISPATCH;
+}
+BL_1_THUMB : {
+ bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component;
+ cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(bl_1_thumb));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
+BL_2_THUMB : {
+ bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component;
+ int tmp = ((cpu->Reg[15] + 2) | 1);
+ cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm);
+ cpu->Reg[14] = tmp;
+ INC_PC(sizeof(bl_2_thumb));
+ goto DISPATCH;
+}
+BLX_1_THUMB : {
+ // BLX 1 for armv5t and above
+ u32 tmp = cpu->Reg[15];
+ blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component;
+ cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
+ cpu->Reg[14] = ((tmp + 2) | 1);
+ cpu->TFlag = 0;
+ INC_PC(sizeof(blx_1_thumb));
+ goto DISPATCH;
+}
- const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
- const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
- const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
- const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
+UQADD8_INST:
+UQADD16_INST:
+UQADDSUBX_INST:
+UQSUB8_INST:
+UQSUB16_INST:
+UQSUBADDX_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ const u8 op2 = inst_cream->op2;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+
+ u16 lo_val = 0;
+ u16 hi_val = 0;
+
+ // UQADD16
+ if (op2 == 0x00) {
+ lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ }
+ // UQASX
+ else if (op2 == 0x01) {
+ lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ }
+ // UQSAX
+ else if (op2 == 0x02) {
+ lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ }
+ // UQSUB16
+ else if (op2 == 0x03) {
+ lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ }
+ // UQADD8
+ else if (op2 == 0x04) {
+ lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
+ ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
+ hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
+ ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
+ }
+ // UQSUB8
+ else {
+ lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
+ ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
+ hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
+ ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
+ }
+
+ RD = ((lo_val & 0xFFFF) | hi_val << 16);
+ }
- u32 finalDif = (diff1 + diff2 + diff3 + diff4);
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- // Op is USADA8 if true.
- if (ra_idx != 15)
- finalDif += cpu->Reg[ra_idx];
+USAD8_INST:
+USADA8_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
- RD = finalDif;
- }
+ const u8 ra_idx = inst_cream->Ra;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+
+ const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
+ const u8 diff2 =
+ ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
+ const u8 diff3 =
+ ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
+ const u8 diff4 =
+ ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(generic_arm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ u32 finalDif = (diff1 + diff2 + diff3 + diff4);
+
+ // Op is USADA8 if true.
+ if (ra_idx != 15)
+ finalDif += cpu->Reg[ra_idx];
+
+ RD = finalDif;
}
- USAT_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- u8 shift_type = inst_cream->shift_type;
- u8 shift_amount = inst_cream->imm5;
- u32 rn_val = RN;
+USAT_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- // 32-bit ASR is encoded as an amount of 0.
- if (shift_type == 1 && shift_amount == 0)
- shift_amount = 31;
+ u8 shift_type = inst_cream->shift_type;
+ u8 shift_amount = inst_cream->imm5;
+ u32 rn_val = RN;
- if (shift_type == 0)
- rn_val <<= shift_amount;
- else if (shift_type == 1)
- rn_val = ((s32)rn_val >> shift_amount);
+ // 32-bit ASR is encoded as an amount of 0.
+ if (shift_type == 1 && shift_amount == 0)
+ shift_amount = 31;
- bool saturated = false;
- rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
+ if (shift_type == 0)
+ rn_val <<= shift_amount;
+ else if (shift_type == 1)
+ rn_val = ((s32)rn_val >> shift_amount);
- if (saturated)
- cpu->Cpsr |= (1 << 27);
+ bool saturated = false;
+ rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
- RD = rn_val;
- }
+ if (saturated)
+ cpu->Cpsr |= (1 << 27);
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = rn_val;
}
- USAT16_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
- const u8 saturate_to = inst_cream->sat_imm;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ssat_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- bool sat1 = false;
- bool sat2 = false;
+USAT16_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
+ const u8 saturate_to = inst_cream->sat_imm;
- RD = (ARMul_UnsignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
- ARMul_UnsignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
+ bool sat1 = false;
+ bool sat2 = false;
- if (sat1 || sat2)
- cpu->Cpsr |= (1 << 27);
- }
+ RD = (ARMul_UnsignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) |
+ ARMul_UnsignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(ssat_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if (sat1 || sat2)
+ cpu->Cpsr |= (1 << 27);
}
- UXTAB16_INST:
- UXTB16_INST:
- {
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(ssat_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- const u8 rn_idx = inst_cream->Rn;
- const u32 rm_val = RM;
- const u32 rotation = inst_cream->rotate * 8;
- const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
+UXTAB16_INST:
+UXTB16_INST : {
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
- // UXTB16, otherwise UXTAB16
- if (rn_idx == 15) {
- RD = rotated_rm & 0x00FF00FF;
- } else {
- const u32 rn_val = RN;
- const u8 lo_rotated = (rotated_rm & 0xFF);
- const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
- const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
- const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
+ const u8 rn_idx = inst_cream->Rn;
+ const u32 rm_val = RM;
+ const u32 rotation = inst_cream->rotate * 8;
+ const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
- RD = ((hi_result << 16) | (lo_result & 0xFFFF));
- }
- }
+ // UXTB16, otherwise UXTAB16
+ if (rn_idx == 15) {
+ RD = rotated_rm & 0x00FF00FF;
+ } else {
+ const u32 rn_val = RN;
+ const u8 lo_rotated = (rotated_rm & 0xFF);
+ const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
+ const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
+ const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC(sizeof(uxtab_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ RD = ((hi_result << 16) | (lo_result & 0xFFFF));
+ }
}
- WFE_INST:
- {
- // Stubbed, as WFE is a hint instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM11, "WFE executed.");
- }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC(sizeof(uxtab_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
+WFE_INST : {
+ // Stubbed, as WFE is a hint instruction.
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ LOG_TRACE(Core_ARM11, "WFE executed.");
}
- WFI_INST:
- {
- // Stubbed, as WFI is a hint instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM11, "WFI executed.");
- }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC_STUB;
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
+WFI_INST : {
+ // Stubbed, as WFI is a hint instruction.
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ LOG_TRACE(Core_ARM11, "WFI executed.");
}
- YIELD_INST:
- {
- // Stubbed, as YIELD is a hint instruction.
- if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
- LOG_TRACE(Core_ARM11, "YIELD executed.");
- }
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC_STUB;
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- cpu->Reg[15] += cpu->GetInstructionSize();
- INC_PC_STUB;
- FETCH_INST;
- GOTO_NEXT_INST;
+YIELD_INST : {
+ // Stubbed, as YIELD is a hint instruction.
+ if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
+ LOG_TRACE(Core_ARM11, "YIELD executed.");
}
- #define VFP_INTERPRETER_IMPL
- #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
- #undef VFP_INTERPRETER_IMPL
+ cpu->Reg[15] += cpu->GetInstructionSize();
+ INC_PC_STUB;
+ FETCH_INST;
+ GOTO_NEXT_INST;
+}
- END:
- {
- SAVE_NZCVT;
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
- INIT_INST_LENGTH:
- {
- cpu->NumInstrsToExecute = 0;
- return num_instrs;
- }
+#define VFP_INTERPRETER_IMPL
+#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+#undef VFP_INTERPRETER_IMPL
+
+END : {
+ SAVE_NZCVT;
+ cpu->NumInstrsToExecute = 0;
+ return num_instrs;
+}
+INIT_INST_LENGTH : {
+ cpu->NumInstrsToExecute = 0;
+ return num_instrs;
+}
}