From faf6c727f6f206238eb6cbd4f6c84f6136c739a2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Jun 2010 12:58:10 -0500 Subject: [PATCH] ARM: Respect the E bit of the CPSR when doing loads and stores. --- src/arch/arm/insts/static_inst.hh | 11 +++++++++++ src/arch/arm/isa/insts/ldr.isa | 26 ++++++++++++++++---------- src/arch/arm/isa/insts/macromem.isa | 17 +++++++++++------ src/arch/arm/isa/insts/str.isa | 18 ++++++++++++++---- src/arch/arm/isa/insts/swap.isa | 6 ++++-- 5 files changed, 56 insertions(+), 22 deletions(-) diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index c0d313680..c26053cef 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -231,6 +231,17 @@ class ArmStaticInst : public StaticInst (val & ~PcModeMask)); } + template + static T + cSwap(T val, bool big) + { + if (big) { + return gtobe(val); + } else { + return gtole(val); + } + } + // Perform an interworking branch. template static void diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa index b216daa6d..c170da688 100644 --- a/src/arch/arm/isa/insts/ldr.isa +++ b/src/arch/arm/isa/insts/ldr.isa @@ -104,7 +104,8 @@ let {{ if ldrex: memFlags.append("Request::LLSC") Name = "%s_%s" % (mnem.upper(), Name) - accCode = "IWDest = Mem%s;\n" % buildMemSuffix(sign, size) + accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \ + buildMemSuffix(sign, size) if not prefetch and not ldrex: memFlags.append("ArmISA::TLB::AllowUnaligned") @@ -131,10 +132,12 @@ let {{ if add: wbDiff = 8 accCode = ''' - NPC = bits(Mem.ud, 31, 0); - uint32_t newCpsr = cpsrWriteByInstr(Cpsr | CondCodes, - bits(Mem.ud, 63, 32), - 0xF, true); + CPSR cpsr = Cpsr; + NPC = cSwap(Mem.ud, cpsr.e); + uint32_t newCpsr = + cpsrWriteByInstr(cpsr | CondCodes, + cSwap(Mem.ud >> 32, cpsr.e), + 0xF, true); Cpsr = ~CondCodesMask & newCpsr; CondCodes = CondCodesMask & newCpsr; ''' @@ -179,7 +182,8 @@ let {{ temp = temp; ''' % buildMemSuffix(sign, size) else: - accCode = "IWDest = Mem%s;\n" % buildMemSuffix(sign, size) + accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \ + buildMemSuffix(sign, size) if writeback: accCode += "Base = Base %s;\n" % offset @@ -207,8 +211,9 @@ let {{ eaCode += ";" accCode = ''' - Dest = bits(Mem.ud, 31, 0); - Dest2 = bits(Mem.ud, 63, 32); + CPSR cpsr = Cpsr; + Dest = cSwap(Mem.ud, cpsr.e); + Dest2 = cSwap(Mem.ud >> 32, cpsr.e); ''' if ldrex: memFlags = ["Request::LLSC"] @@ -242,8 +247,9 @@ let {{ eaCode += ";" accCode = ''' - Dest = bits(Mem.ud, 31, 0); - Dest2 = bits(Mem.ud, 63, 32); + CPSR cpsr = Cpsr; + Dest = cSwap(Mem.ud, cpsr.e); + Dest2 = cSwap(Mem.ud >> 32, cpsr.e); ''' if writeback: accCode += "Base = Base %s;\n" % offset diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa index 13eb70b39..f393c74f0 100644 --- a/src/arch/arm/isa/insts/macromem.isa +++ b/src/arch/arm/isa/insts/macromem.isa @@ -51,26 +51,29 @@ let {{ }}; let {{ + microLdrUopCode = "IWRa = cSwap(Mem.uw, ((CPSR)Cpsr).e);" microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop', 'MicroMemOp', - {'memacc_code': 'IWRa = Mem;', + {'memacc_code': microLdrUopCode, 'ea_code': 'EA = Rb + (up ? imm : -imm);', 'predicate_test': predicateTest}, ['IsMicroop']) + microLdrFpUopCode = "Fa = cSwap(Mem.uw, ((CPSR)Cpsr).e);" microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop', 'MicroMemOp', - {'memacc_code': 'Fa = Mem;', + {'memacc_code': microLdrFpUopCode, 'ea_code': 'EA = Rb + (up ? imm : -imm);', 'predicate_test': predicateTest}, ['IsMicroop']) microLdrRetUopCode = ''' + CPSR cpsr = Cpsr; uint32_t newCpsr = - cpsrWriteByInstr(Cpsr | CondCodes, Spsr, 0xF, true); + cpsrWriteByInstr(cpsr | CondCodes, Spsr, 0xF, true); Cpsr = ~CondCodesMask & newCpsr; CondCodes = CondCodesMask & newCpsr; - IWNPC = Mem | ((Spsr & 0x20) ? 1 : 0); + IWNPC = cSwap(Mem.uw, cpsr.e) | ((Spsr & 0x20) ? 1 : 0); ''' microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', 'MicroMemOp', @@ -80,16 +83,18 @@ let {{ 'predicate_test': predicateTest}, ['IsMicroop']) + microStrUopCode = "Mem = cSwap(Ra.uw, ((CPSR)Cpsr).e);" microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 'MicroMemOp', - {'memacc_code': 'Mem = Ra;', + {'memacc_code': microStrUopCode, 'ea_code': 'EA = Rb + (up ? imm : -imm);', 'predicate_test': predicateTest}, ['IsMicroop']) + microStrFpUopCode = "Mem = cSwap(Fa.uw, ((CPSR)Cpsr).e);" microStrFpUopIop = InstObjParams('strfp_uop', 'MicroStrFpUop', 'MicroMemOp', - {'memacc_code': 'Mem = Fa;', + {'memacc_code': microStrFpUopCode, 'ea_code': 'EA = Rb + (up ? imm : -imm);', 'predicate_test': predicateTest}, ['IsMicroop']) diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa index c22245947..0c92b20df 100644 --- a/src/arch/arm/isa/insts/str.isa +++ b/src/arch/arm/isa/insts/str.isa @@ -93,7 +93,8 @@ let {{ eaCode += offset eaCode += ";" - accCode = "Mem%s = Dest;\n" % buildMemSuffix(sign, size) + accCode = "Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);" % \ + { "suffix" : buildMemSuffix(sign, size) } if writeback: accCode += "Base = Base %s;\n" % offset base = buildMemBase("MemoryImm", post, writeback) @@ -121,7 +122,8 @@ let {{ eaCode += offset eaCode += ";" - accCode = "Mem%s = Dest;\n" % buildMemSuffix(sign, size) + accCode = "Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);" % \ + { "suffix" : buildMemSuffix(sign, size) } if writeback: accCode += "Base = Base %s;\n" % offset base = buildMemBase("MemoryReg", post, writeback) @@ -146,7 +148,11 @@ let {{ eaCode += offset eaCode += ";" - accCode = 'Mem.ud = (Dest.ud & mask(32)) | (Dest2.ud << 32);' + accCode = ''' + CPSR cpsr = Cpsr; + Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) | + ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32); + ''' if writeback: accCode += "Base = Base %s;\n" % offset base = buildMemBase("MemoryDImm", post, writeback) @@ -171,7 +177,11 @@ let {{ eaCode += offset eaCode += ";" - accCode = 'Mem.ud = (Dest.ud & mask(32)) | (Dest2.ud << 32);' + accCode = ''' + CPSR cpsr = Cpsr; + Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) | + ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32); + ''' if writeback: accCode += "Base = Base %s;\n" % offset base = buildMemBase("MemoryDReg", post, writeback) diff --git a/src/arch/arm/isa/insts/swap.isa b/src/arch/arm/isa/insts/swap.isa index 9456c1314..29b5b444f 100644 --- a/src/arch/arm/isa/insts/swap.isa +++ b/src/arch/arm/isa/insts/swap.isa @@ -44,7 +44,8 @@ let {{ (newHeader, newDecoder, newExec) = SwapBase("swp", "Swp", "EA = Base;", - "Mem = Op1;", "Dest = memData;", + "Mem = cSwap(Op1.uw, ((CPSR)Cpsr).e);", + "Dest = cSwap((uint32_t)memData, ((CPSR)Cpsr).e);", ["Request::MEM_SWAP", "ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], []) @@ -55,7 +56,8 @@ let {{ (newHeader, newDecoder, newExec) = SwapBase("swpb", "Swpb", "EA = Base;", - "Mem.ub = Op1.ub;", "Dest.ub = (uint8_t)memData;", + "Mem.ub = cSwap(Op1.ub, ((CPSR)Cpsr).e);", + "Dest.ub = cSwap((uint8_t)memData, ((CPSR)Cpsr).e);", ["Request::MEM_SWAP", "ArmISA::TLB::AlignByte", "ArmISA::TLB::MustBeOne"], []) -- 2.30.2