load_store: Add checks for unpredictability to other singular store instructions (#11)
This commit is contained in:
parent
e8764c129f
commit
5aa4f753b6
2 changed files with 51 additions and 18 deletions
|
@ -549,40 +549,61 @@ bool ArmTranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STR_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm12 imm12) {
|
bool ArmTranslatorVisitor::arm_STR_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm12 imm12) {
|
||||||
|
if (W && (n == Reg::PC || n == t))
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
const auto address = GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm12));
|
const auto address = GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm12));
|
||||||
ir.WriteMemory32(address, ir.GetRegister(d));
|
ir.WriteMemory32(address, ir.GetRegister(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
bool ArmTranslatorVisitor::arm_STR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
if (m == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
if (W && (n == Reg::PC || n == t))
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
const auto shifted = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag());
|
const auto shifted = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag());
|
||||||
const auto address = GetAddressingMode(ir, P, U, W, n, shifted.result);
|
const auto address = GetAddressingMode(ir, P, U, W, n, shifted.result);
|
||||||
ir.WriteMemory32(address, ir.GetRegister(d));
|
ir.WriteMemory32(address, ir.GetRegister(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm12 imm12) {
|
bool ArmTranslatorVisitor::arm_STRB_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm12 imm12) {
|
||||||
|
if (t == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
if (W && (n == Reg::PC || n == t))
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
const auto address = GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm12));
|
const auto address = GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm12));
|
||||||
const auto value = (d == Reg::PC) ? ir.Imm8(ir.PC() - 8) : ir.GetRegister(d);
|
const auto value = (t == Reg::PC) ? ir.Imm8(ir.PC() - 8) : ir.GetRegister(t);
|
||||||
ir.WriteMemory8(address, ir.LeastSignificantByte(value));
|
ir.WriteMemory8(address, ir.LeastSignificantByte(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m) {
|
bool ArmTranslatorVisitor::arm_STRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm5 imm5, ShiftType shift, Reg m) {
|
||||||
|
if (t == Reg::PC || m == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
if (W && (n == Reg::PC || n == t))
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
const auto shifted = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag());
|
const auto shifted = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag());
|
||||||
const auto address = GetAddressingMode(ir, P, U, W, n, shifted.result);
|
const auto address = GetAddressingMode(ir, P, U, W, n, shifted.result);
|
||||||
const auto value = (d == Reg::PC) ? ir.Imm8(ir.PC() - 8) : ir.GetRegister(d);
|
const auto value = (t == Reg::PC) ? ir.Imm8(ir.PC() - 8) : ir.GetRegister(t);
|
||||||
ir.WriteMemory8(address, ir.LeastSignificantByte(value));
|
ir.WriteMemory8(address, ir.LeastSignificantByte(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,20 +664,32 @@ bool ArmTranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm4 imm8a, Imm4 imm8b) {
|
bool ArmTranslatorVisitor::arm_STRH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm4 imm8a, Imm4 imm8b) {
|
||||||
|
if (t == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
if (W && (n == Reg::PC || n == t))
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
const auto address = GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm8a << 4 | imm8b));
|
const auto address = GetAddressingMode(ir, P, U, W, n, ir.Imm32(imm8a << 4 | imm8b));
|
||||||
const auto value = (d == Reg::PC) ? ir.Imm32(ir.PC() - 8) : ir.GetRegister(d);
|
const auto value = (t == Reg::PC) ? ir.Imm32(ir.PC() - 8) : ir.GetRegister(t);
|
||||||
ir.WriteMemory16(address, ir.LeastSignificantHalf(value));
|
ir.WriteMemory16(address, ir.LeastSignificantHalf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Reg m) {
|
bool ArmTranslatorVisitor::arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
|
||||||
|
if (t == Reg::PC || m == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
if (W && (n == Reg::PC || n == t))
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
const auto address = GetAddressingMode(ir, P, U, W, n, ir.GetRegister(m));
|
const auto address = GetAddressingMode(ir, P, U, W, n, ir.GetRegister(m));
|
||||||
const auto value = (d == Reg::PC) ? ir.Imm32(ir.PC() - 8) : ir.GetRegister(d);
|
const auto value = (t == Reg::PC) ? ir.Imm32(ir.PC() - 8) : ir.GetRegister(t);
|
||||||
ir.WriteMemory16(address, ir.LeastSignificantHalf(value));
|
ir.WriteMemory16(address, ir.LeastSignificantHalf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,14 +184,14 @@ struct ArmTranslatorVisitor final {
|
||||||
bool arm_LDRSH_lit(Cond cond, bool U, Reg t, Imm4 imm8a, Imm4 imm8b);
|
bool arm_LDRSH_lit(Cond cond, bool U, Reg t, Imm4 imm8a, Imm4 imm8b);
|
||||||
bool arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm4 imm8a, Imm4 imm8b);
|
bool arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm4 imm8a, Imm4 imm8b);
|
||||||
bool arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m);
|
bool arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m);
|
||||||
bool arm_STR_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm12 imm12);
|
bool arm_STR_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm12 imm12);
|
||||||
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 t, 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 t, 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 t, Imm5 imm5, ShiftType shift, Reg m);
|
||||||
bool arm_STRD_imm(Cond cond, bool P, bool U, bool W, Reg n, Reg t, 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 t, 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 t, 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 t, Reg m);
|
||||||
|
|
||||||
// Load/Store multiple instructions
|
// Load/Store multiple instructions
|
||||||
bool arm_LDM(Cond cond, bool W, Reg n, RegList list);
|
bool arm_LDM(Cond cond, bool W, Reg n, RegList list);
|
||||||
|
|
Loading…
Reference in a new issue