JitX64: Implement SETEND

This commit is contained in:
MerryMage 2016-04-02 13:15:47 +01:00
parent d4fc4e209a
commit 089d9ddb05
7 changed files with 54 additions and 29 deletions

View File

@ -277,7 +277,7 @@ void JitX64::LDR_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePostIndexed,
U, Rn_index, imm12);
CompileCallHost(!current.EFlag ? &Load32LE : &Load32BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Load32LE : &Load32BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -301,7 +301,7 @@ void JitX64::LDR_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPostIndexed,
U, Rn_index, imm5, shift, Rm_index);
CompileCallHost(!current.EFlag ? &Load32LE : &Load32BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Load32LE : &Load32BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -325,7 +325,7 @@ void JitX64::LDRB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePostIndexed,
U, Rn_index, imm12);
CompileCallHost(&Load8);
CompileCallHost(reinterpret_cast<const void* const>(&Load8));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -349,7 +349,7 @@ void JitX64::LDRB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPostIndexed,
U, Rn_index, imm5, shift, Rm_index);
CompileCallHost(&Load8);
CompileCallHost(reinterpret_cast<const void* const>(&Load8));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -378,7 +378,7 @@ void JitX64::STR_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index);
CompileCallHost(!current.EFlag ? &Store32LE : &Store32BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Store32LE : &Store32BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.UnlockX64(ABI_PARAM2);
@ -400,7 +400,7 @@ void JitX64::STR_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index);
CompileCallHost(!current.EFlag ? &Store32LE : &Store32BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Store32LE : &Store32BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.UnlockX64(ABI_PARAM2);
@ -422,7 +422,7 @@ void JitX64::STRB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index);
CompileCallHost(&Store8);
CompileCallHost(reinterpret_cast<const void* const>(&Store8));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.UnlockX64(ABI_PARAM2);
@ -444,7 +444,7 @@ void JitX64::STRB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index);
CompileCallHost(&Store8);
CompileCallHost(reinterpret_cast<const void* const>(&Store8));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.UnlockX64(ABI_PARAM2);
@ -492,7 +492,7 @@ void JitX64::LDRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePostIndexed,
U, Rn_index, CombineImm8ab(imm8a, imm8b));
CompileCallHost(!current.EFlag ? &Load64LE : &Load64BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Load64LE : &Load64BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -521,7 +521,7 @@ void JitX64::LDRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPostIndexed,
U, Rn_index, 0, 0, Rm_index);
CompileCallHost(!current.EFlag ? &Load64LE : &Load64BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Load64LE : &Load64BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -550,7 +550,7 @@ void JitX64::LDRH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePostIndexed,
U, Rn_index, CombineImm8ab(imm8a, imm8b));
CompileCallHost(!current.EFlag ? &Load16LE : &Load16BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Load16LE : &Load16BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -575,7 +575,7 @@ void JitX64::LDRH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPostIndexed,
U, Rn_index, 0, 0, Rm_index);
CompileCallHost(!current.EFlag ? &Load16LE : &Load16BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Load16LE : &Load16BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -600,7 +600,7 @@ void JitX64::LDRSB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePostIndexed,
U, Rn_index, CombineImm8ab(imm8a, imm8b));
CompileCallHost(&Load8);
CompileCallHost(reinterpret_cast<const void* const>(&Load8));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -625,7 +625,7 @@ void JitX64::LDRSB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPostIndexed,
U, Rn_index, 0, 0, Rm_index);
CompileCallHost(&Load8);
CompileCallHost(reinterpret_cast<const void* const>(&Load8));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -650,7 +650,7 @@ void JitX64::LDRSH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePostIndexed,
U, Rn_index, CombineImm8ab(imm8a, imm8b));
CompileCallHost(!current.EFlag ? &Load16LE : &Load16BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Load16LE : &Load16BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -675,7 +675,7 @@ void JitX64::LDRSH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPostIndexed,
U, Rn_index, 0, 0, Rm_index);
CompileCallHost(!current.EFlag ? &Load16LE : &Load16BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Load16LE : &Load16BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.LockX64(ABI_RETURN);
@ -710,7 +710,7 @@ void JitX64::STRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index + 0);
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM3, Rd_index + 1);
CompileCallHost(!current.EFlag ? &Store64LE : &Store64BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Store64LE : &Store64BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.UnlockX64(ABI_PARAM2);
@ -738,7 +738,7 @@ void JitX64::STRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index + 0);
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM3, Rd_index + 1);
CompileCallHost(!current.EFlag ? &Store64LE : &Store64BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Store64LE : &Store64BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.UnlockX64(ABI_PARAM2);
@ -761,7 +761,7 @@ void JitX64::STRH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index);
CompileCallHost(!current.EFlag ? &Store16LE : &Store16BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Store16LE : &Store16BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.UnlockX64(ABI_PARAM2);
@ -783,7 +783,7 @@ void JitX64::STRH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index);
CompileCallHost(!current.EFlag ? &Store16LE : &Store16BE);
CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &Store16LE : &Store16BE));
reg_alloc.UnlockX64(ABI_PARAM1);
reg_alloc.UnlockX64(ABI_PARAM2);
@ -949,7 +949,7 @@ void JitX64::LDM(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRegList
// TODO: Optimize
LoadAndStoreMultiple_Helper(code, reg_alloc, P, U, W, Rn_index, list,
[this](){ CompileCallHost(!current.EFlag ? &ExecuteLDMLE : &ExecuteLDMBE); });
[this](){ CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &ExecuteLDMLE : &ExecuteLDMBE)); });
current.arm_pc += GetInstSize();
if (list & (1 << 15)) {
@ -1006,7 +1006,7 @@ void JitX64::STM(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRegList
// TODO: Optimize
LoadAndStoreMultiple_Helper(code, reg_alloc, P, U, W, Rn_index, list,
[this](){ CompileCallHost(!current.EFlag ? &ExecuteSTMLE : &ExecuteSTMBE); });
[this](){ CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &ExecuteSTMLE : &ExecuteSTMBE)); });
current.arm_pc += GetInstSize();
}

View File

@ -6,11 +6,27 @@
namespace JitX64 {
using namespace Gen;
void JitX64::CPS() { CompileInterpretInstruction(); }
void JitX64::MRS() { CompileInterpretInstruction(); }
void JitX64::MSR() { CompileInterpretInstruction(); }
void JitX64::RFE() { CompileInterpretInstruction(); }
void JitX64::SETEND(bool E) { CompileInterpretInstruction(); }
void JitX64::SETEND(bool E) {
cond_manager.Always();
if (E) {
code->OR(32, MJitStateCpsr(), Imm32(1 << 9));
current.EFlag = true;
} else {
code->AND(32, MJitStateCpsr(), Imm32(~(1 << 9)));
current.EFlag = false;
}
current.arm_pc += GetInstSize();
}
void JitX64::SRS() { CompileInterpretInstruction(); }
}

View File

@ -162,6 +162,7 @@ void ARM_Jit::ExecuteInstructions(int num_instructions) {
do {
//state->page_table = reinterpret_cast<void*>(Memory::current_page_table->pointers.data());
bool EFlag = (state->cpu_state.Cpsr >> 9) & 1;
state->cpu_state.TFlag = (state->cpu_state.Cpsr >> 5) & 1;
if (!state->cpu_state.NirqSig) {
@ -173,7 +174,7 @@ void ARM_Jit::ExecuteInstructions(int num_instructions) {
else
state->cpu_state.Reg[15] &= 0xfffffffc;
u8 *ptr = compiler.GetBB(state->cpu_state.Reg[15], state->cpu_state.TFlag, false);
u8 *ptr = compiler.GetBB(state->cpu_state.Reg[15], state->cpu_state.TFlag, EFlag);
unsigned ticks_executed = run_jit.CallCode(state.get(), ptr, num_instructions, state->cpu_state.Reg[15]);
num_instructions -= ticks_executed;

View File

@ -49,8 +49,7 @@ void JitX64::CompileInterpretInstruction() {
code->MOV(64, R(ABI_PARAM3), Imm64(current.TFlag));
code->MOV(64, R(ABI_PARAM4), Imm64(current.EFlag));
const void *const fn = reinterpret_cast<const void* const>(&CallInterpreter);
CompileCallHost(fn);
CompileCallHost(reinterpret_cast<const void* const>(&CallInterpreter));
code->MOV(64, R(reg_alloc.JitStateReg()), R(ABI_RETURN));

View File

@ -241,6 +241,13 @@ Gen::OpArg JitX64::MJitStateVFlag() {
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, cpu_state) + offsetof(ARMul_State, VFlag));
}
Gen::OpArg JitX64::MJitStateCpsr() {
static_assert(std::is_same<decltype(JitState::cpu_state), ARMul_State>::value, "JitState::cpu_state must be ARMul_State");
static_assert(std::is_same<decltype(ARMul_State::Cpsr), u32>::value, "Cpsr must be u32");
return Gen::MDisp(reg_alloc.JitStateReg(), offsetof(JitState, cpu_state) + offsetof(ARMul_State, Cpsr));
}
Gen::OpArg JitX64::MJitStateExclusiveTag() {
static_assert(std::is_same<decltype(JitState::cpu_state), ARMul_State>::value, "JitState::cpu_state must be ARMul_State");
static_assert(std::is_same<decltype(ARMul_State::exclusive_tag), u32>::value, "exclusive_tag must be u32");

View File

@ -91,6 +91,7 @@ private:
Gen::OpArg MJitStateCFlag();
Gen::OpArg MJitStateNFlag();
Gen::OpArg MJitStateVFlag();
Gen::OpArg MJitStateCpsr();
Gen::OpArg MJitStateExclusiveTag();
Gen::OpArg MJitStateExclusiveState();

View File

@ -12,7 +12,7 @@
#include "tests/core/arm/jit_x64/fuzz_arm_common.h"
TEST_CASE("Fuzz ARM load/store instructions (byte, half-word, word)", "[JitX64]") {
const std::array<std::pair<u32, u32>, 16> instructions = {{
const std::array<std::pair<u32, u32>, 17> instructions = {{
FromBitString32("cccc010pu0w1nnnnddddvvvvvvvvvvvv"), // LDR_imm
FromBitString32("cccc011pu0w1nnnnddddvvvvvrr0mmmm"), // LDR_reg
FromBitString32("cccc010pu1w1nnnnddddvvvvvvvvvvvv"), // LDRB_imm
@ -29,6 +29,7 @@ TEST_CASE("Fuzz ARM load/store instructions (byte, half-word, word)", "[JitX64]"
FromBitString32("cccc000pu0w1nnnndddd00001111mmmm"), // LDRSH_reg
FromBitString32("cccc000pu1w0nnnnddddvvvv1011vvvv"), // STRH_imm
FromBitString32("cccc000pu0w0nnnndddd00001011mmmm"), // STRH_reg
FromBitString32("1111000100000001000000e000000000"), // SETEND
}};
auto instruction_select = [&]() -> u32 {
@ -46,7 +47,7 @@ TEST_CASE("Fuzz ARM load/store instructions (byte, half-word, word)", "[JitX64]"
u32 P = RandInt<u32>(0, 1);
if (P) W = RandInt<u32>(0, 1);
u32 U = RandInt<u32>(0, 1);
u32 rand = RandInt<u32>(0, 0xF);
u32 rand = RandInt<u32>(0, 0xFF);
u32 Rm = RandInt<u32>(0, 14);
u32 assemble_randoms = (Rm << 0) | (rand << 4) | (Rd << 12) | (Rn << 16) | (W << 21) | (U << 23) | (P << 24) | (cond << 28);
@ -55,7 +56,7 @@ TEST_CASE("Fuzz ARM load/store instructions (byte, half-word, word)", "[JitX64]"
};
SECTION("short blocks") {
FuzzJit(1, 2, 5000, instruction_select);
FuzzJit(5, 6, 5000, instruction_select);
}
}