summaryrefslogtreecommitdiffstats
path: root/src/core/arm/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/interpreter')
-rw-r--r--src/core/arm/interpreter/armemu.cpp56
1 files changed, 33 insertions, 23 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 4e11e068f..b21d97e12 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -5681,11 +5681,8 @@ L_stm_s_takeabort:
/* Attempt to emulate an ARMv6 instruction.
Returns non-zero upon success. */
- static int
- handle_v6_insn (ARMul_State * state, ARMword instr) {
- ARMword lhs, temp;
-
- switch (BITS (20, 27)) {
+ static int handle_v6_insn(ARMul_State* state, ARMword instr) {
+ switch (BITS(20, 27)) {
case 0x03:
printf ("Unhandled v6 insn: ldr\n");
break;
@@ -5719,7 +5716,7 @@ L_stm_s_takeabort:
/* strex */
u32 l = LHSReg;
u32 r = RHSReg;
- lhs = LHS;
+ u32 lhs = LHS;
bool enter = false;
@@ -5744,7 +5741,7 @@ L_stm_s_takeabort:
case 0x19:
/* ldrex */
if (BITS(4, 7) == 0x9) {
- lhs = LHS;
+ u32 lhs = LHS;
state->currentexaddr = lhs;
state->currentexval = ARMul_ReadWord(state, lhs);
@@ -5763,7 +5760,7 @@ L_stm_s_takeabort:
case 0x1c:
if (BITS(4, 7) == 0x9) {
/* strexb */
- lhs = LHS;
+ u32 lhs = LHS;
bool enter = false;
@@ -5793,11 +5790,11 @@ L_stm_s_takeabort:
case 0x1d:
if ((BITS(4, 7)) == 0x9) {
/* ldrexb */
- temp = LHS;
- LoadByte(state, instr, temp, LUNSIGNED);
+ u32 lhs = LHS;
+ LoadByte(state, instr, lhs, LUNSIGNED);
- state->currentexaddr = temp;
- state->currentexval = (u32)ARMul_ReadByte(state, temp);
+ state->currentexaddr = lhs;
+ state->currentexval = (u32)ARMul_ReadByte(state, lhs);
//state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]);
//printf("ldrexb\n");
@@ -5885,8 +5882,10 @@ L_stm_s_takeabort:
printf("Unhandled v6 insn: %08x", BITS(20, 27));
}
break;
- case 0x62: // QSUB16 and QADD16
- if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) {
+ case 0x62: // QADD16, QASX, QSAX, and QSUB16
+ if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 ||
+ (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70)
+ {
const u8 rd_idx = BITS(12, 15);
const u8 rn_idx = BITS(16, 19);
const u8 rm_idx = BITS(0, 3);
@@ -5898,15 +5897,26 @@ L_stm_s_takeabort:
s32 lo_result;
s32 hi_result;
+ // QADD16
+ if ((instr & 0xFF0) == 0xf10) {
+ lo_result = (rn_lo + rm_lo);
+ hi_result = (rn_hi + rm_hi);
+ }
+ // QASX
+ else if ((instr & 0xFF0) == 0xf30) {
+ lo_result = (rn_lo - rm_hi);
+ hi_result = (rn_hi + rm_lo);
+ }
+ // QSAX
+ else if ((instr & 0xFF0) == 0xf50) {
+ lo_result = (rn_lo + rm_hi);
+ hi_result = (rn_hi - rm_lo);
+ }
// QSUB16
- if ((instr & 0xFF0) == 0xf70) {
+ else {
lo_result = (rn_lo - rm_lo);
hi_result = (rn_hi - rm_hi);
}
- else { // QADD16
- lo_result = (rn_lo + rm_lo);
- hi_result = (rn_hi + rm_hi);
- }
if (lo_result > 0x7FFF)
lo_result = 0x7FFF;
@@ -6109,7 +6119,7 @@ L_stm_s_takeabort:
break;
}
- Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF;
+ Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF);
if (Rm & 0x80)
Rm |= 0xffffff00;
@@ -6154,7 +6164,7 @@ L_stm_s_takeabort:
if (ror == -1)
break;
- Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF;
+ Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF);
if (Rm & 0x8000)
Rm |= 0xffff0000;
@@ -6250,7 +6260,7 @@ L_stm_s_takeabort:
break;
}
- Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF;
+ Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF);
if (BITS(16, 19) == 0xf)
/* UXTB */
@@ -6294,7 +6304,7 @@ L_stm_s_takeabort:
if (ror == -1)
break;
- Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF;
+ Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF);
/* UXT */
/* state->Reg[BITS (12, 15)] = Rm; */