|
|
|
@@ -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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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);
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
@@ -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);
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
|
|
|
|
&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) {
|
|
|
|
|
CompileInterpretInstruction();
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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_PARAM2);
|
|
|
|
|
|
|
|
|
|
// TODO: Exclusive stuff
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
CompileInterpretInstruction();
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
|
|
|
|
&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_PARAM2);
|
|
|
|
|
|
|
|
|
|
// TODO: Exclusive stuff
|
|
|
|
|
|
|
|
|
|
current.arm_pc += GetInstSize();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
|
|
|
if (W)
|
|
|
|
|
ASSERT_MSG(Rn_index != Rd_index, "UNPREDICTABLE");
|
|
|
|
|
|
|
|
|
|
LoadStoreCommon_AddrMode2(this, reg_alloc, P, W,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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_PARAM2);
|
|
|
|
|
|
|
|
|
|
//TODO: Exclusive stuff
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
CompileInterpretInstruction();
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
|
|
|
|
&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_PARAM2);
|
|
|
|
|
|
|
|
|
|
//TODO: Exclusive stuff
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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.LockX64(ABI_RETURN);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rd_index % 2 == 0 && Rd_index != 14, "UNPREDICTABLE");
|
|
|
|
|
|
|
|
|
|
X64Reg Rd0 = reg_alloc.BindArmForWrite(Rd_index + 0);
|
|
|
|
|
X64Reg Rd1 = reg_alloc.BindArmForWrite(Rd_index + 1);
|
|
|
|
|
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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
|
|
|
|
&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.LockX64(ABI_RETURN);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rd_index % 2 == 0 && Rd_index != 14, "UNPREDICTABLE");
|
|
|
|
|
|
|
|
|
|
X64Reg Rd0 = reg_alloc.BindArmForWrite(Rd_index + 0);
|
|
|
|
|
X64Reg Rd1 = reg_alloc.BindArmForWrite(Rd_index + 1);
|
|
|
|
|
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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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.LockX64(ABI_RETURN);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
|
|
|
|
|
|
|
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
|
|
|
|
code->MOVZX(32, 16, Rd, R(ABI_RETURN));
|
|
|
|
|
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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
|
|
|
|
&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.LockX64(ABI_RETURN);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
|
|
|
|
|
|
|
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
|
|
|
|
code->MOVZX(32, 16, Rd, R(ABI_RETURN));
|
|
|
|
|
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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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.LockX64(ABI_RETURN);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
|
|
|
|
|
|
|
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
|
|
|
|
code->MOVSX(32, 8, Rd, R(ABI_RETURN));
|
|
|
|
|
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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
|
|
|
|
&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.LockX64(ABI_RETURN);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
|
|
|
|
|
|
|
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
|
|
|
|
code->MOVSX(32, 8, Rd, R(ABI_RETURN));
|
|
|
|
|
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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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.LockX64(ABI_RETURN);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
|
|
|
|
|
|
|
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
|
|
|
|
code->MOVSX(32, 16, Rd, R(ABI_RETURN));
|
|
|
|
|
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) {
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
|
|
|
|
&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.LockX64(ABI_RETURN);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rd_index != 15, "UNPREDICTABLE");
|
|
|
|
|
|
|
|
|
|
X64Reg Rd = reg_alloc.BindArmForWrite(Rd_index);
|
|
|
|
|
code->MOVSX(32, 16, Rd, R(ABI_RETURN));
|
|
|
|
|
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) {
|
|
|
|
|
CompileInterpretInstruction();
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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.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_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_PARAM3);
|
|
|
|
|
|
|
|
|
|
// TODO: Exclusive stuff.
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
CompileInterpretInstruction();
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
|
|
|
|
&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.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_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_PARAM3);
|
|
|
|
|
|
|
|
|
|
// TODO: Exclusive stuff.
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
CompileInterpretInstruction();
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ImmediateOffset,
|
|
|
|
|
&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_PARAM2);
|
|
|
|
|
|
|
|
|
|
// TODO: Exclusive stuff.
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
CompileInterpretInstruction();
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
&JitX64::LoadAndStoreWordOrUnsignedByte_ScaledRegisterOffset,
|
|
|
|
|
&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_PARAM2);
|
|
|
|
|
|
|
|
|
|
// TODO: Exclusive stuff.
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
CompileInterpretInstruction();
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
cond_manager.CompileCond((ConditionCode)cond);
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(Rn_index != 15, "UNPREDICTABLE");
|
|
|
|
|
ASSERT_MSG(list != 0, "UNPREDICTABLE");
|
|
|
|
|
if (W && (list & (1 << Rn_index)))
|
|
|
|
|
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,
|
|
|
|
|
[this](){ CompileCallHost(reinterpret_cast<const void* const>(!current.EFlag ? &ExecuteSTMLE : &ExecuteSTMBE)); });
|
|
|
|
|
|
|
|
|
|
// TODO: Exclusive stuff
|
|
|
|
|
|
|
|
|
|
current.arm_pc += GetInstSize();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|