|
|
|
@ -4362,30 +4362,30 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
if (BIT(inst, 22) && !BIT(inst, 15)) { |
|
|
|
for (int i = 0; i < 13; i++) { |
|
|
|
if(BIT(inst, i)) { |
|
|
|
cpu->Reg[i] = Memory::Read32(addr); |
|
|
|
cpu->Reg[i] = ReadMemory32(cpu, addr); |
|
|
|
addr += 4; |
|
|
|
} |
|
|
|
} |
|
|
|
if (BIT(inst, 13)) { |
|
|
|
if (cpu->Mode == USER32MODE) |
|
|
|
cpu->Reg[13] = Memory::Read32(addr); |
|
|
|
cpu->Reg[13] = ReadMemory32(cpu, addr); |
|
|
|
else |
|
|
|
cpu->Reg_usr[0] = Memory::Read32(addr); |
|
|
|
cpu->Reg_usr[0] = ReadMemory32(cpu, addr); |
|
|
|
|
|
|
|
addr += 4; |
|
|
|
} |
|
|
|
if (BIT(inst, 14)) { |
|
|
|
if (cpu->Mode == USER32MODE) |
|
|
|
cpu->Reg[14] = Memory::Read32(addr); |
|
|
|
cpu->Reg[14] = ReadMemory32(cpu, addr); |
|
|
|
else |
|
|
|
cpu->Reg_usr[1] = Memory::Read32(addr); |
|
|
|
cpu->Reg_usr[1] = ReadMemory32(cpu, addr); |
|
|
|
|
|
|
|
addr += 4; |
|
|
|
} |
|
|
|
} else if (!BIT(inst, 22)) { |
|
|
|
for(int i = 0; i < 16; i++ ){ |
|
|
|
if(BIT(inst, i)){ |
|
|
|
unsigned int ret = Memory::Read32(addr); |
|
|
|
unsigned int ret = ReadMemory32(cpu, addr); |
|
|
|
|
|
|
|
// For armv5t, should enter thumb when bits[0] is non-zero.
|
|
|
|
if(i == 15){ |
|
|
|
@ -4400,7 +4400,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
} else if (BIT(inst, 22) && BIT(inst, 15)) { |
|
|
|
for(int i = 0; i < 15; i++ ){ |
|
|
|
if(BIT(inst, i)){ |
|
|
|
cpu->Reg[i] = Memory::Read32(addr); |
|
|
|
cpu->Reg[i] = ReadMemory32(cpu, addr); |
|
|
|
addr += 4; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -4411,7 +4411,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
LOAD_NZCVT; |
|
|
|
} |
|
|
|
|
|
|
|
cpu->Reg[15] = Memory::Read32(addr); |
|
|
|
cpu->Reg[15] = ReadMemory32(cpu, addr); |
|
|
|
} |
|
|
|
|
|
|
|
if (BIT(inst, 15)) { |
|
|
|
@ -4445,10 +4445,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
LDR_INST: |
|
|
|
{ |
|
|
|
ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
|
|
|
//if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
|
|
|
|
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
|
|
|
|
|
|
|
unsigned int value = Memory::Read32(addr); |
|
|
|
unsigned int value = ReadMemory32(cpu, addr); |
|
|
|
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
|
|
|
|
|
|
|
if (BITS(inst_cream->inst, 12, 15) == 15) { |
|
|
|
@ -4458,7 +4457,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
INC_PC(sizeof(ldst_inst)); |
|
|
|
goto DISPATCH; |
|
|
|
} |
|
|
|
//}
|
|
|
|
|
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu); |
|
|
|
INC_PC(sizeof(ldst_inst)); |
|
|
|
@ -4471,7 +4469,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
|
|
|
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
|
|
|
|
|
|
|
unsigned int value = Memory::Read32(addr); |
|
|
|
unsigned int value = ReadMemory32(cpu, addr); |
|
|
|
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
|
|
|
|
|
|
|
if (BITS(inst_cream->inst, 12, 15) == 15) { |
|
|
|
@ -4554,8 +4552,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
// 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, 1); |
|
|
|
|
|
|
|
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read32(addr); |
|
|
|
cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = Memory::Read32(addr + 4); |
|
|
|
// 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] = ReadMemory32(cpu, addr); |
|
|
|
cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = ReadMemory32(cpu, addr + 4); |
|
|
|
|
|
|
|
// No dispatch since this operation should not modify R15
|
|
|
|
} |
|
|
|
@ -4574,7 +4574,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
add_exclusive_addr(cpu, read_addr); |
|
|
|
cpu->exclusive_state = 1; |
|
|
|
|
|
|
|
RD = Memory::Read32(read_addr); |
|
|
|
RD = ReadMemory32(cpu, read_addr); |
|
|
|
if (inst_cream->Rd == 15) { |
|
|
|
INC_PC(sizeof(generic_arm_inst)); |
|
|
|
goto DISPATCH; |
|
|
|
@ -4614,7 +4614,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
add_exclusive_addr(cpu, read_addr); |
|
|
|
cpu->exclusive_state = 1; |
|
|
|
|
|
|
|
RD = Memory::Read16(read_addr); |
|
|
|
RD = ReadMemory16(cpu, read_addr); |
|
|
|
if (inst_cream->Rd == 15) { |
|
|
|
INC_PC(sizeof(generic_arm_inst)); |
|
|
|
goto DISPATCH; |
|
|
|
@ -4634,8 +4634,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
add_exclusive_addr(cpu, read_addr); |
|
|
|
cpu->exclusive_state = 1; |
|
|
|
|
|
|
|
RD = Memory::Read32(read_addr); |
|
|
|
RD2 = Memory::Read32(read_addr + 4); |
|
|
|
RD = ReadMemory32(cpu, read_addr); |
|
|
|
RD2 = ReadMemory32(cpu, read_addr + 4); |
|
|
|
|
|
|
|
if (inst_cream->Rd == 15) { |
|
|
|
INC_PC(sizeof(generic_arm_inst)); |
|
|
|
@ -4652,7 +4652,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
|
|
|
ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
|
|
|
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
|
|
|
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read16(addr); |
|
|
|
|
|
|
|
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ReadMemory16(cpu, addr); |
|
|
|
if (BITS(inst_cream->inst, 12, 15) == 15) { |
|
|
|
INC_PC(sizeof(ldst_inst)); |
|
|
|
goto DISPATCH; |
|
|
|
@ -4688,7 +4689,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
|
|
|
ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
|
|
|
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
|
|
|
unsigned int value = Memory::Read16(addr); |
|
|
|
|
|
|
|
unsigned int value = ReadMemory16(cpu, addr); |
|
|
|
if (BIT(value, 15)) { |
|
|
|
value |= 0xffff0000; |
|
|
|
} |
|
|
|
@ -4709,7 +4711,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
|
|
|
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
|
|
|
|
|
|
|
unsigned int value = Memory::Read32(addr); |
|
|
|
unsigned int value = ReadMemory32(cpu, addr); |
|
|
|
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
|
|
|
|
|
|
|
if (BITS(inst_cream->inst, 12, 15) == 15) { |
|
|
|
@ -6010,36 +6012,36 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
if (BIT(inst_cream->inst, 22) == 1) { |
|
|
|
for (int i = 0; i < 13; i++) { |
|
|
|
if (BIT(inst_cream->inst, i)) { |
|
|
|
Memory::Write32(addr, cpu->Reg[i]); |
|
|
|
WriteMemory32(cpu, addr, cpu->Reg[i]); |
|
|
|
addr += 4; |
|
|
|
} |
|
|
|
} |
|
|
|
if (BIT(inst_cream->inst, 13)) { |
|
|
|
if (cpu->Mode == USER32MODE) |
|
|
|
Memory::Write32(addr, cpu->Reg[13]); |
|
|
|
WriteMemory32(cpu, addr, cpu->Reg[13]); |
|
|
|
else |
|
|
|
Memory::Write32(addr, cpu->Reg_usr[0]); |
|
|
|
WriteMemory32(cpu, addr, cpu->Reg_usr[0]); |
|
|
|
|
|
|
|
addr += 4; |
|
|
|
} |
|
|
|
if (BIT(inst_cream->inst, 14)) { |
|
|
|
if (cpu->Mode == USER32MODE) |
|
|
|
Memory::Write32(addr, cpu->Reg[14]); |
|
|
|
WriteMemory32(cpu, addr, cpu->Reg[14]); |
|
|
|
else |
|
|
|
Memory::Write32(addr, cpu->Reg_usr[1]); |
|
|
|
WriteMemory32(cpu, addr, cpu->Reg_usr[1]); |
|
|
|
|
|
|
|
addr += 4; |
|
|
|
} |
|
|
|
if (BIT(inst_cream->inst, 15)) { |
|
|
|
Memory::Write32(addr, cpu->Reg_usr[1] + 8); |
|
|
|
WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8); |
|
|
|
} |
|
|
|
} else { |
|
|
|
for (int i = 0; i < 15; i++) { |
|
|
|
if (BIT(inst_cream->inst, i)) { |
|
|
|
if (i == Rn) |
|
|
|
Memory::Write32(addr, old_RN); |
|
|
|
WriteMemory32(cpu, addr, old_RN); |
|
|
|
else |
|
|
|
Memory::Write32(addr, cpu->Reg[i]); |
|
|
|
WriteMemory32(cpu, addr, cpu->Reg[i]); |
|
|
|
|
|
|
|
addr += 4; |
|
|
|
} |
|
|
|
@ -6047,7 +6049,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
|
|
|
|
// Check PC reg
|
|
|
|
if (BIT(inst_cream->inst, 15)) |
|
|
|
Memory::Write32(addr, cpu->Reg_usr[1] + 8); |
|
|
|
WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8); |
|
|
|
} |
|
|
|
} |
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu); |
|
|
|
@ -6080,7 +6082,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
|
|
|
|
|
|
|
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
|
|
|
Memory::Write32(addr, value); |
|
|
|
WriteMemory32(cpu, addr, value); |
|
|
|
} |
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu); |
|
|
|
INC_PC(sizeof(ldst_inst)); |
|
|
|
@ -6143,10 +6145,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
|
|
|
inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
|
|
|
|
|
|
|
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
|
|
|
Memory::Write32(addr, value); |
|
|
|
value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; |
|
|
|
Memory::Write32(addr + 4, value); |
|
|
|
// The 3DS doesn't have the Large Physical Access Extension (LPAE)
|
|
|
|
// so STRD wouldn't store these as a single write.
|
|
|
|
WriteMemory32(cpu, addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]); |
|
|
|
WriteMemory32(cpu, addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]); |
|
|
|
} |
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu); |
|
|
|
INC_PC(sizeof(ldst_inst)); |
|
|
|
@ -6163,7 +6165,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
remove_exclusive(cpu, write_addr); |
|
|
|
cpu->exclusive_state = 0; |
|
|
|
|
|
|
|
Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); |
|
|
|
WriteMemory32(cpu, write_addr, RM); |
|
|
|
RD = 0; |
|
|
|
} else { |
|
|
|
// Failed to write due to mutex access
|
|
|
|
@ -6207,8 +6209,16 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
remove_exclusive(cpu, write_addr); |
|
|
|
cpu->exclusive_state = 0; |
|
|
|
|
|
|
|
Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); |
|
|
|
Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]); |
|
|
|
const u32 rt = cpu->Reg[inst_cream->Rm + 0]; |
|
|
|
const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; |
|
|
|
u64 value; |
|
|
|
|
|
|
|
if (InBigEndianMode(cpu)) |
|
|
|
value = (((u64)rt << 32) | rt2); |
|
|
|
else |
|
|
|
value = (((u64)rt2 << 32) | rt); |
|
|
|
|
|
|
|
WriteMemory64(cpu, write_addr, value); |
|
|
|
RD = 0; |
|
|
|
} |
|
|
|
else { |
|
|
|
@ -6231,7 +6241,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
remove_exclusive(cpu, write_addr); |
|
|
|
cpu->exclusive_state = 0; |
|
|
|
|
|
|
|
Memory::Write16(write_addr, cpu->Reg[inst_cream->Rm]); |
|
|
|
WriteMemory16(cpu, write_addr, RM); |
|
|
|
RD = 0; |
|
|
|
} else { |
|
|
|
// Failed to write due to mutex access
|
|
|
|
@ -6250,7 +6260,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
|
|
|
|
|
|
|
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; |
|
|
|
Memory::Write16(addr, value); |
|
|
|
WriteMemory16(cpu, addr, value); |
|
|
|
} |
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu); |
|
|
|
INC_PC(sizeof(ldst_inst)); |
|
|
|
@ -6264,7 +6274,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
|
|
|
|
|
|
|
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
|
|
|
Memory::Write32(addr, value); |
|
|
|
WriteMemory32(cpu, addr, value); |
|
|
|
} |
|
|
|
cpu->Reg[15] += GET_INST_SIZE(cpu); |
|
|
|
INC_PC(sizeof(ldst_inst)); |
|
|
|
@ -6323,8 +6333,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { |
|
|
|
swp_inst* inst_cream = (swp_inst*)inst_base->component; |
|
|
|
|
|
|
|
addr = RN; |
|
|
|
unsigned int value = Memory::Read32(addr); |
|
|
|
Memory::Write32(addr, RM); |
|
|
|
unsigned int value = ReadMemory32(cpu, addr); |
|
|
|
WriteMemory32(cpu, addr, RM); |
|
|
|
|
|
|
|
RD = value; |
|
|
|
} |
|
|
|
|