From 5aa4f753b6fe19c1f6df819e06e0e2ce886c5705 Mon Sep 17 00:00:00 2001 From: Mat M Date: Fri, 2 Sep 2016 16:10:28 -0400 Subject: [PATCH] load_store: Add checks for unpredictability to other singular store instructions (#11) --- .../translate/translate_arm/load_store.cpp | 57 +++++++++++++++---- .../translate/translate_arm/translate_arm.h | 12 ++-- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/frontend/translate/translate_arm/load_store.cpp b/src/frontend/translate/translate_arm/load_store.cpp index 8d9d07ae..7eaf8b2a 100644 --- a/src/frontend/translate/translate_arm/load_store.cpp +++ b/src/frontend/translate/translate_arm/load_store.cpp @@ -549,40 +549,61 @@ bool ArmTranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg 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)) { 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; } -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)) { const auto shifted = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()); 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; } -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)) { 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)); } 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)) { const auto shifted = EmitImmShift(ir.GetRegister(m), shift, imm5, ir.GetCFlag()); 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)); } @@ -643,20 +664,32 @@ bool ArmTranslatorVisitor::arm_STRD_reg(Cond cond, bool P, bool U, bool W, Reg n 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)) { 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)); } 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)) { 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)); } diff --git a/src/frontend/translate/translate_arm/translate_arm.h b/src/frontend/translate/translate_arm/translate_arm.h index 3bf4a014..07849f68 100644 --- a/src/frontend/translate/translate_arm/translate_arm.h +++ b/src/frontend/translate/translate_arm/translate_arm.h @@ -184,14 +184,14 @@ struct ArmTranslatorVisitor final { 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_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_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_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Imm5 imm5, ShiftType shift, Reg m); + 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 t, Imm5 imm5, ShiftType shift, Reg m); + 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 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_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_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg d, Reg m); + 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 t, Reg m); // Load/Store multiple instructions bool arm_LDM(Cond cond, bool W, Reg n, RegList list);