load_store: Add correctness checks for STRD variants (#7)
STRD doesn't allow the use of the PC in either Rt or Rt2
This commit is contained in:
parent
d16badbc04
commit
00d0f4d5ff
2 changed files with 36 additions and 10 deletions
|
@ -589,13 +589,26 @@ bool ArmTranslatorVisitor::arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm4 imm8a, Imm4 imm8b) {
|
bool ArmTranslatorVisitor::arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm4 imm8a, Imm4 imm8b) {
|
||||||
|
if (size_t(t) % 2 != 0)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
if (!P && W)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
const Reg t2 = t + 1;
|
||||||
|
|
||||||
|
if (W && (n == Reg::PC || n == t || n == t2))
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
if (t2 == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
const auto address_a = GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm8a << 4 | imm8b));
|
const auto address_a = GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm8a << 4 | imm8b));
|
||||||
const auto address_b = ir.Add(address_a, ir.Imm32(4));
|
const auto address_b = ir.Add(address_a, ir.Imm32(4));
|
||||||
const auto value_a = (d == Reg::PC) ? ir.Imm32(ir.PC() - 8) : ir.GetRegister(d);
|
const auto value_a = ir.GetRegister(t);
|
||||||
const Reg reg_b = static_cast<Reg>(std::min(d + 1, Reg::R15));
|
const auto value_b = ir.GetRegister(t2);
|
||||||
const auto value_b = (reg_b == Reg::PC) ? ir.Imm32(ir.PC() - 8) : ir.GetRegister(reg_b);
|
|
||||||
ir.WriteMemory32(address_a, value_a);
|
ir.WriteMemory32(address_a, value_a);
|
||||||
ir.WriteMemory32(address_b, value_b);
|
ir.WriteMemory32(address_b, value_b);
|
||||||
}
|
}
|
||||||
|
@ -603,13 +616,26 @@ bool ArmTranslatorVisitor::arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Reg m) {
|
bool ArmTranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
|
||||||
|
if (size_t(t) % 2 != 0)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
if (!P && W)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
const Reg t2 = t + 1;
|
||||||
|
|
||||||
|
if (t2 == Reg::PC || m == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
if (W && (n == Reg::PC || n == t || n == t2))
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
const auto address_a = GetAddressingMode(ir, P, U, W, n, ir.GetRegister(m));
|
const auto address_a = GetAddressingMode(ir, P, U, W, n, ir.GetRegister(m));
|
||||||
const auto address_b = ir.Add(address_a, ir.Imm32(4));
|
const auto address_b = ir.Add(address_a, ir.Imm32(4));
|
||||||
const auto value_a = (d == Reg::PC) ? ir.Imm32(ir.PC() - 8) : ir.GetRegister(d);
|
const auto value_a = ir.GetRegister(t);
|
||||||
const Reg reg_b = static_cast<Reg>(std::min(d + 1, Reg::R15));
|
const auto value_b = ir.GetRegister(t2);
|
||||||
const auto value_b = (reg_b == Reg::PC) ? ir.Imm32(ir.PC() - 8) : ir.GetRegister(reg_b);
|
|
||||||
ir.WriteMemory32(address_a, value_a);
|
ir.WriteMemory32(address_a, value_a);
|
||||||
ir.WriteMemory32(address_b, value_b);
|
ir.WriteMemory32(address_b, value_b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,8 +188,8 @@ struct ArmTranslatorVisitor final {
|
||||||
bool arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
bool arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
bool arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm12 imm12);
|
bool arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm12 imm12);
|
||||||
bool arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
bool arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
bool arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm4 imm8a, Imm4 imm8b);
|
bool arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm4 imm8a, Imm4 imm8b);
|
||||||
bool arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Reg m);
|
bool arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m);
|
||||||
bool arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm4 imm8a, Imm4 imm8b);
|
bool arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm4 imm8a, Imm4 imm8b);
|
||||||
bool arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Reg m);
|
bool arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Reg m);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue