mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 09:20:18 +00:00
JitX64: Load/Store: Add UNPREDICTABLE ASSERTs, correct LDR R15 behavior
This commit is contained in:
parent
32d81463cf
commit
20d87c315a
@ -92,6 +92,8 @@ void JitX64::BLX_reg(Cond cond, ArmReg Rm_index) {
|
|||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
CompileReturnToDispatch();
|
CompileReturnToDispatch();
|
||||||
|
|
||||||
|
stop_compilation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::BX(Cond cond, ArmReg Rm_index) {
|
void JitX64::BX(Cond cond, ArmReg Rm_index) {
|
||||||
@ -111,6 +113,8 @@ void JitX64::BX(Cond cond, ArmReg Rm_index) {
|
|||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
CompileReturnToDispatch();
|
CompileReturnToDispatch();
|
||||||
|
|
||||||
|
stop_compilation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::BXJ(Cond cond, ArmReg Rm) {
|
void JitX64::BXJ(Cond cond, ArmReg Rm) {
|
||||||
|
@ -271,6 +271,10 @@ static void LoadStoreCommon_AddrMode2(JitX64* jit, RegAlloc& reg_alloc, bool P,
|
|||||||
void JitX64::LDR_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm12 imm12) {
|
void JitX64::LDR_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm12 imm12) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
// Rd == R15 is UNPREDICTABLE only if address[1:0] is not 0b00 or if value loaded into R15[1:0] is 0b10.
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -290,6 +294,12 @@ void JitX64::LDR_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_RETURN);
|
reg_alloc.UnlockX64(ABI_RETURN);
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
|
if (Rd_index == 15) {
|
||||||
|
code->AND(32, MJitStateArmPC(), Imm32(0xFFFFFFFE));
|
||||||
|
code->BT(32, R(ABI_RETURN), Imm8(0));
|
||||||
|
code->SETcc(CC_C, MJitStateTFlag());
|
||||||
|
CompileReturnToDispatch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::LDR_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm_index) {
|
void JitX64::LDR_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm_index) {
|
||||||
@ -314,11 +324,21 @@ void JitX64::LDR_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_RETURN);
|
reg_alloc.UnlockX64(ABI_RETURN);
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
|
if (Rd_index == 15) {
|
||||||
|
code->AND(32, MJitStateArmPC(), Imm32(0xFFFFFFFE));
|
||||||
|
code->BT(32, R(ABI_RETURN), Imm8(0));
|
||||||
|
code->SETcc(CC_C, MJitStateTFlag());
|
||||||
|
CompileReturnToDispatch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::LDRB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm12 imm12) {
|
void JitX64::LDRB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm12 imm12) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -343,6 +363,10 @@ void JitX64::LDRB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
void JitX64::LDRB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm_index) {
|
void JitX64::LDRB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm_index) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
||||||
@ -365,8 +389,15 @@ void JitX64::LDRB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::STR_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm12 imm12) {
|
void JitX64::STR_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm12 imm12) {
|
||||||
|
CompileInterpretInstruction();
|
||||||
|
return;
|
||||||
|
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
// Rd_index == R15 is IMPLEMENTATION DEFINED
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -383,12 +414,21 @@ void JitX64::STR_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.UnlockX64(ABI_PARAM2);
|
reg_alloc.UnlockX64(ABI_PARAM2);
|
||||||
|
|
||||||
|
// TODO: Exclusive stuff
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::STR_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm_index) {
|
void JitX64::STR_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm_index) {
|
||||||
|
CompileInterpretInstruction();
|
||||||
|
return;
|
||||||
|
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
// Rd_index == R15 is IMPLEMENTATION DEFINED
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
||||||
@ -405,12 +445,21 @@ void JitX64::STR_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.UnlockX64(ABI_PARAM2);
|
reg_alloc.UnlockX64(ABI_PARAM2);
|
||||||
|
|
||||||
|
// TODO: Exclusive stuff
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::STRB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm12 imm12) {
|
void JitX64::STRB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm12 imm12) {
|
||||||
|
CompileInterpretInstruction();
|
||||||
|
return;
|
||||||
|
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -427,12 +476,21 @@ void JitX64::STRB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.UnlockX64(ABI_PARAM2);
|
reg_alloc.UnlockX64(ABI_PARAM2);
|
||||||
|
|
||||||
|
//TODO: Exclusive stuff
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::STRB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm_index) {
|
void JitX64::STRB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm_index) {
|
||||||
|
CompileInterpretInstruction();
|
||||||
|
return;
|
||||||
|
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
||||||
@ -449,6 +507,8 @@ void JitX64::STRB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.UnlockX64(ABI_PARAM2);
|
reg_alloc.UnlockX64(ABI_PARAM2);
|
||||||
|
|
||||||
|
//TODO: Exclusive stuff
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,6 +546,11 @@ static ArmImm8 CombineImm8ab(ArmImm4 imm8a, ArmImm4 imm8b) {
|
|||||||
void JitX64::LDRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
void JitX64::LDRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index < 14, "UNPREDICTABLE");
|
||||||
|
ASSERT_MSG(Rd_index % 2 == 0, "UNDEFINED");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index && Rn_index != Rd_index + 1, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -497,8 +562,6 @@ void JitX64::LDRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.LockX64(ABI_RETURN);
|
reg_alloc.LockX64(ABI_RETURN);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index % 2 == 0 && Rd_index != 14, "UNPREDICTABLE");
|
|
||||||
|
|
||||||
X64Reg Rd0 = reg_alloc.BindArmForWrite(Rd_index + 0);
|
X64Reg Rd0 = reg_alloc.BindArmForWrite(Rd_index + 0);
|
||||||
X64Reg Rd1 = reg_alloc.BindArmForWrite(Rd_index + 1);
|
X64Reg Rd1 = reg_alloc.BindArmForWrite(Rd_index + 1);
|
||||||
code->MOV(64, R(Rd0), R(ABI_RETURN));
|
code->MOV(64, R(Rd0), R(ABI_RETURN));
|
||||||
@ -515,6 +578,12 @@ void JitX64::LDRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
void JitX64::LDRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
void JitX64::LDRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index < 14, "UNPREDICTABLE");
|
||||||
|
ASSERT_MSG(Rd_index % 2 == 0, "UNDEFINED");
|
||||||
|
ASSERT_MSG(Rm_index != Rd_index && Rm_index != Rd_index + 1, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index && Rn_index != Rd_index + 1, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
||||||
@ -526,8 +595,6 @@ void JitX64::LDRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.LockX64(ABI_RETURN);
|
reg_alloc.LockX64(ABI_RETURN);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index % 2 == 0 && Rd_index != 14, "UNPREDICTABLE");
|
|
||||||
|
|
||||||
X64Reg Rd0 = reg_alloc.BindArmForWrite(Rd_index + 0);
|
X64Reg Rd0 = reg_alloc.BindArmForWrite(Rd_index + 0);
|
||||||
X64Reg Rd1 = reg_alloc.BindArmForWrite(Rd_index + 1);
|
X64Reg Rd1 = reg_alloc.BindArmForWrite(Rd_index + 1);
|
||||||
code->MOV(64, R(Rd0), R(ABI_RETURN));
|
code->MOV(64, R(Rd0), R(ABI_RETURN));
|
||||||
@ -544,6 +611,10 @@ void JitX64::LDRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
void JitX64::LDRH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
void JitX64::LDRH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -555,8 +626,6 @@ void JitX64::LDRH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.LockX64(ABI_RETURN);
|
reg_alloc.LockX64(ABI_RETURN);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
||||||
|
|
||||||
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
||||||
code->MOVZX(32, 16, Rd, R(ABI_RETURN));
|
code->MOVZX(32, 16, Rd, R(ABI_RETURN));
|
||||||
reg_alloc.UnlockArm(Rd_index);
|
reg_alloc.UnlockArm(Rd_index);
|
||||||
@ -569,6 +638,10 @@ void JitX64::LDRH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
void JitX64::LDRH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
void JitX64::LDRH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
||||||
@ -580,8 +653,6 @@ void JitX64::LDRH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.LockX64(ABI_RETURN);
|
reg_alloc.LockX64(ABI_RETURN);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
||||||
|
|
||||||
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
||||||
code->MOVZX(32, 16, Rd, R(ABI_RETURN));
|
code->MOVZX(32, 16, Rd, R(ABI_RETURN));
|
||||||
reg_alloc.UnlockArm(Rd_index);
|
reg_alloc.UnlockArm(Rd_index);
|
||||||
@ -594,6 +665,10 @@ void JitX64::LDRH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
void JitX64::LDRSB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
void JitX64::LDRSB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -605,8 +680,6 @@ void JitX64::LDRSB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.LockX64(ABI_RETURN);
|
reg_alloc.LockX64(ABI_RETURN);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
||||||
|
|
||||||
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
||||||
code->MOVSX(32, 8, Rd, R(ABI_RETURN));
|
code->MOVSX(32, 8, Rd, R(ABI_RETURN));
|
||||||
reg_alloc.UnlockArm(Rd_index);
|
reg_alloc.UnlockArm(Rd_index);
|
||||||
@ -619,6 +692,10 @@ void JitX64::LDRSB_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
|
|||||||
void JitX64::LDRSB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
void JitX64::LDRSB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
||||||
@ -630,8 +707,6 @@ void JitX64::LDRSB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.LockX64(ABI_RETURN);
|
reg_alloc.LockX64(ABI_RETURN);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
||||||
|
|
||||||
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
||||||
code->MOVSX(32, 8, Rd, R(ABI_RETURN));
|
code->MOVSX(32, 8, Rd, R(ABI_RETURN));
|
||||||
reg_alloc.UnlockArm(Rd_index);
|
reg_alloc.UnlockArm(Rd_index);
|
||||||
@ -644,6 +719,10 @@ void JitX64::LDRSB_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
|
|||||||
void JitX64::LDRSH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
void JitX64::LDRSH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -655,8 +734,6 @@ void JitX64::LDRSH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.LockX64(ABI_RETURN);
|
reg_alloc.LockX64(ABI_RETURN);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
||||||
|
|
||||||
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
||||||
code->MOVSX(32, 16, Rd, R(ABI_RETURN));
|
code->MOVSX(32, 16, Rd, R(ABI_RETURN));
|
||||||
reg_alloc.UnlockArm(Rd_index);
|
reg_alloc.UnlockArm(Rd_index);
|
||||||
@ -669,6 +746,10 @@ void JitX64::LDRSH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
|
|||||||
void JitX64::LDRSH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
void JitX64::LDRSH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
||||||
@ -680,8 +761,6 @@ void JitX64::LDRSH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.LockX64(ABI_RETURN);
|
reg_alloc.LockX64(ABI_RETURN);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
||||||
|
|
||||||
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
||||||
code->MOVSX(32, 16, Rd, R(ABI_RETURN));
|
code->MOVSX(32, 16, Rd, R(ABI_RETURN));
|
||||||
reg_alloc.UnlockArm(Rd_index);
|
reg_alloc.UnlockArm(Rd_index);
|
||||||
@ -692,8 +771,14 @@ void JitX64::LDRSH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::STRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
void JitX64::STRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
||||||
|
CompileInterpretInstruction();
|
||||||
|
return;
|
||||||
|
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index < 14, "UNPREDICTABLE");
|
||||||
|
ASSERT_MSG(Rd_index % 2 == 0, "UNDEFINED");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -705,8 +790,6 @@ void JitX64::STRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.FlushX64(ABI_PARAM3);
|
reg_alloc.FlushX64(ABI_PARAM3);
|
||||||
reg_alloc.LockX64(ABI_PARAM3);
|
reg_alloc.LockX64(ABI_PARAM3);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index % 2 == 0 && Rd_index != 14, "");
|
|
||||||
|
|
||||||
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index + 0);
|
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index + 0);
|
||||||
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM3, Rd_index + 1);
|
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM3, Rd_index + 1);
|
||||||
|
|
||||||
@ -716,12 +799,22 @@ void JitX64::STRD_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM2);
|
reg_alloc.UnlockX64(ABI_PARAM2);
|
||||||
reg_alloc.UnlockX64(ABI_PARAM3);
|
reg_alloc.UnlockX64(ABI_PARAM3);
|
||||||
|
|
||||||
|
// TODO: Exclusive stuff.
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::STRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
void JitX64::STRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
||||||
|
CompileInterpretInstruction();
|
||||||
|
return;
|
||||||
|
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index < 14, "UNPREDICTABLE");
|
||||||
|
ASSERT_MSG(Rd_index % 2 == 0, "UNDEFINED");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rn_index != Rd_index && Rn_index != Rd_index + 1, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
||||||
@ -733,8 +826,6 @@ void JitX64::STRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.FlushX64(ABI_PARAM3);
|
reg_alloc.FlushX64(ABI_PARAM3);
|
||||||
reg_alloc.LockX64(ABI_PARAM3);
|
reg_alloc.LockX64(ABI_PARAM3);
|
||||||
|
|
||||||
ASSERT_MSG(Rd_index % 2 == 0 && Rd_index != 14, "");
|
|
||||||
|
|
||||||
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index + 0);
|
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM2, Rd_index + 0);
|
||||||
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM3, Rd_index + 1);
|
GetValueOfRegister(code, reg_alloc, GetReg15Value(), ABI_PARAM3, Rd_index + 1);
|
||||||
|
|
||||||
@ -744,12 +835,21 @@ void JitX64::STRD_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM2);
|
reg_alloc.UnlockX64(ABI_PARAM2);
|
||||||
reg_alloc.UnlockX64(ABI_PARAM3);
|
reg_alloc.UnlockX64(ABI_PARAM3);
|
||||||
|
|
||||||
|
// TODO: Exclusive stuff.
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::STRH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
void JitX64::STRH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmImm4 imm8a, ArmImm4 imm8b) {
|
||||||
|
CompileInterpretInstruction();
|
||||||
|
return;
|
||||||
|
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rd_index != Rn_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediatePreIndexed,
|
||||||
@ -766,12 +866,21 @@ void JitX64::STRH_imm(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.UnlockX64(ABI_PARAM2);
|
reg_alloc.UnlockX64(ABI_PARAM2);
|
||||||
|
|
||||||
|
// TODO: Exclusive stuff.
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::STRH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
void JitX64::STRH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rm_index) {
|
||||||
|
CompileInterpretInstruction();
|
||||||
|
return;
|
||||||
|
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
||||||
|
if (W)
|
||||||
|
ASSERT_MSG(Rd_index != Rn_index, "UNPREDICTABLE");
|
||||||
|
|
||||||
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
LoadStoreCommon_AddrMode3(this, reg_alloc, P, W,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
||||||
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterPreIndexed,
|
||||||
@ -788,6 +897,8 @@ void JitX64::STRH_reg(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmReg
|
|||||||
reg_alloc.UnlockX64(ABI_PARAM1);
|
reg_alloc.UnlockX64(ABI_PARAM1);
|
||||||
reg_alloc.UnlockX64(ABI_PARAM2);
|
reg_alloc.UnlockX64(ABI_PARAM2);
|
||||||
|
|
||||||
|
// TODO: Exclusive stuff.
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1003,8 +1114,12 @@ static void ExecuteSTMBE(u32 start_address, u16 reg_list, JitState* jit_state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JitX64::STM(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRegList list) {
|
void JitX64::STM(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRegList list) {
|
||||||
|
CompileInterpretInstruction();
|
||||||
|
return;
|
||||||
|
|
||||||
cond_manager.CompileCond((ConditionCode)cond);
|
cond_manager.CompileCond((ConditionCode)cond);
|
||||||
|
|
||||||
|
ASSERT_MSG(Rn_index != 15, "UNPREDICTABLE");
|
||||||
ASSERT_MSG(list != 0, "UNPREDICTABLE");
|
ASSERT_MSG(list != 0, "UNPREDICTABLE");
|
||||||
if (W && (list & (1 << Rn_index)))
|
if (W && (list & (1 << Rn_index)))
|
||||||
ASSERT_MSG((list & ((1 << Rn_index) - 1)) == 0, "UNPREDICTABLE");
|
ASSERT_MSG((list & ((1 << Rn_index) - 1)) == 0, "UNPREDICTABLE");
|
||||||
@ -1014,6 +1129,8 @@ void JitX64::STM(Cond cond, bool P, bool U, bool W, ArmReg Rn_index, ArmRegList
|
|||||||
LoadAndStoreMultiple_Helper(code, reg_alloc, P, U, W, Rn_index, list,
|
LoadAndStoreMultiple_Helper(code, reg_alloc, P, U, W, Rn_index, list,
|
||||||
[this](){ CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &ExecuteSTMLE : &ExecuteSTMBE)); });
|
[this](){ CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &ExecuteSTMLE : &ExecuteSTMBE)); });
|
||||||
|
|
||||||
|
// TODO: Exclusive stuff
|
||||||
|
|
||||||
current.arm_pc += GetInstSize();
|
current.arm_pc += GetInstSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ CodePtr JitX64::Compile(u32 pc, bool TFlag, bool EFlag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reg_alloc.AssertNoLocked();
|
reg_alloc.AssertNoLocked();
|
||||||
|
reg_alloc.FlushEverything();
|
||||||
} while (!stop_compilation && ((current.arm_pc & 0xFFF) != 0));
|
} while (!stop_compilation && ((current.arm_pc & 0xFFF) != 0));
|
||||||
|
|
||||||
if (!stop_compilation) {
|
if (!stop_compilation) {
|
||||||
@ -163,7 +164,6 @@ void JitX64::CompileCallHost(const void* const fn) {
|
|||||||
// There is no need to setup the stack as the stored RSP has already been properly aligned.
|
// There is no need to setup the stack as the stored RSP has already been properly aligned.
|
||||||
|
|
||||||
reg_alloc.FlushABICallerSaved();
|
reg_alloc.FlushABICallerSaved();
|
||||||
reg_alloc.FlushX64(RSP);
|
|
||||||
|
|
||||||
ASSERT(reg_alloc.JitStateReg() != RSP);
|
ASSERT(reg_alloc.JitStateReg() != RSP);
|
||||||
code->MOV(64, R(RSP), MJitStateHostReturnRSP());
|
code->MOV(64, R(RSP), MJitStateHostReturnRSP());
|
||||||
|
@ -270,7 +270,7 @@ void RegAlloc::MarkDirty(ArmReg arm_reg) {
|
|||||||
void RegAlloc::FlushEverything() {
|
void RegAlloc::FlushEverything() {
|
||||||
for (auto i : x64_reg_to_index) {
|
for (auto i : x64_reg_to_index) {
|
||||||
X64State& x64_state = x64_gpr[i.second];
|
X64State& x64_state = x64_gpr[i.second];
|
||||||
ASSERT(!x64_state.locked);
|
ASSERT(!x64_state.locked || x64_state.state == X64State::State::UserManuallyLocked);
|
||||||
FlushX64(i.first);
|
FlushX64(i.first);
|
||||||
ASSERT(x64_state.state == X64State::State::Free);
|
ASSERT(x64_state.state == X64State::State::Free);
|
||||||
}
|
}
|
||||||
@ -278,7 +278,6 @@ void RegAlloc::FlushEverything() {
|
|||||||
|
|
||||||
void RegAlloc::FlushABICallerSaved() {
|
void RegAlloc::FlushABICallerSaved() {
|
||||||
for (auto i : x64_reg_to_index) {
|
for (auto i : x64_reg_to_index) {
|
||||||
if (ABI_ALL_CALLER_SAVED.m_val & (1 << i.first)) {
|
|
||||||
X64State& x64_state = x64_gpr[i.second];
|
X64State& x64_state = x64_gpr[i.second];
|
||||||
if (x64_state.state != X64State::State::UserManuallyLocked) {
|
if (x64_state.state != X64State::State::UserManuallyLocked) {
|
||||||
ASSERT(!x64_state.locked);
|
ASSERT(!x64_state.locked);
|
||||||
@ -288,7 +287,6 @@ void RegAlloc::FlushABICallerSaved() {
|
|||||||
ASSERT(x64_state.locked);
|
ASSERT(x64_state.locked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(!ABI_ALL_CALLER_SAVED[JitStateReg()]);
|
ASSERT(!ABI_ALL_CALLER_SAVED[JitStateReg()]);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,13 @@ TEST_CASE("Fuzz ARM load/store instructions (byte, half-word, word)", "[JitX64]"
|
|||||||
u32 rand = RandInt<u32>(0, 0xFF);
|
u32 rand = RandInt<u32>(0, 0xFF);
|
||||||
u32 Rm = RandInt<u32>(0, 14);
|
u32 Rm = RandInt<u32>(0, 14);
|
||||||
|
|
||||||
|
if (W) {
|
||||||
|
while (Rn == Rd) {
|
||||||
|
Rn = RandInt<u32>(0, 14);
|
||||||
|
Rd = RandInt<u32>(0, 14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32 assemble_randoms = (Rm << 0) | (rand << 4) | (Rd << 12) | (Rn << 16) | (W << 21) | (U << 23) | (P << 24) | (cond << 28);
|
u32 assemble_randoms = (Rm << 0) | (rand << 4) | (Rd << 12) | (Rn << 16) | (W << 21) | (U << 23) | (P << 24) | (cond << 28);
|
||||||
|
|
||||||
return instructions[inst_index].first | (assemble_randoms & (~instructions[inst_index].second));
|
return instructions[inst_index].first | (assemble_randoms & (~instructions[inst_index].second));
|
||||||
@ -86,6 +93,17 @@ TEST_CASE("Fuzz ARM load/store instructions (double-word)", "[JitX64]") {
|
|||||||
u32 rand = RandInt<u32>(0, 0xF);
|
u32 rand = RandInt<u32>(0, 0xF);
|
||||||
u32 Rm = RandInt<u32>(0, 14);
|
u32 Rm = RandInt<u32>(0, 14);
|
||||||
|
|
||||||
|
if (W) {
|
||||||
|
while (Rn == Rd) {
|
||||||
|
Rn = RandInt<u32>(0, 6) * 2;
|
||||||
|
Rd = RandInt<u32>(0, 6) * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (Rm == Rd || Rm == Rd + 1) {
|
||||||
|
Rm = RandInt<u32>(0, 14);
|
||||||
|
}
|
||||||
|
|
||||||
u32 assemble_randoms = (Rm << 0) | (rand << 4) | (Rd << 12) | (Rn << 16) | (W << 21) | (U << 23) | (P << 24) | (cond << 28);
|
u32 assemble_randoms = (Rm << 0) | (rand << 4) | (Rd << 12) | (Rn << 16) | (W << 21) | (U << 23) | (P << 24) | (cond << 28);
|
||||||
|
|
||||||
return instructions[inst_index].first | (assemble_randoms & (~instructions[inst_index].second));
|
return instructions[inst_index].first | (assemble_randoms & (~instructions[inst_index].second));
|
||||||
|
Loading…
Reference in New Issue
Block a user