From 99fafb72b87f3b63f205bee7b20b8c19724d6305 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 25 Aug 2010 19:10:42 -0500 Subject: ARM: Fix VFP enabled checks for mem instructions --- src/arch/arm/isa.cc | 2 ++ src/arch/arm/isa/insts/fp.isa | 12 ++++++------ src/arch/arm/isa/insts/ldr.isa | 8 ++++++++ src/arch/arm/isa/insts/macromem.isa | 17 +++++++++-------- src/arch/arm/isa/insts/neon.isa | 9 +-------- src/arch/arm/isa/insts/str.isa | 8 ++++++++ src/arch/arm/isa/templates/neon.isa | 8 ++++++++ src/arch/arm/isa/templates/vfp.isa | 19 +++++++++++++++++-- src/arch/arm/utility.hh | 2 +- 9 files changed, 60 insertions(+), 25 deletions(-) (limited to 'src/arch/arm') diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 7991dbfb7..f5bbc3610 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -139,6 +139,8 @@ ISA::clear() (0 << 2) | // 3:2 0; // 1:0 + miscRegs[MISCREG_CPACR] = 0; + miscRegs[MISCREG_FPSID] = 0x410430A0; //XXX We need to initialize the rest of the state. } diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa index 849ce1299..6ba4ac3bf 100644 --- a/src/arch/arm/isa/insts/fp.isa +++ b/src/arch/arm/isa/insts/fp.isa @@ -192,14 +192,14 @@ let {{ exec_output = "" vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegOp", - { "code": vmsrrsEnabledCheckCode + \ + { "code": vmsrEnabledCheckCode + \ "MiscDest = Op1;", "predicate_test": predicateTest }, []) header_output += FpRegRegOpDeclare.subst(vmsrIop); decoder_output += FpRegRegOpConstructor.subst(vmsrIop); exec_output += PredOpExecute.subst(vmsrIop); - vmsrFpscrCode = vmsrrsEnabledCheckCode + ''' + vmsrFpscrCode = vmsrEnabledCheckCode + ''' Fpscr = Op1 & ~FpCondCodesMask; FpCondCodes = Op1 & FpCondCodesMask; ''' @@ -211,7 +211,7 @@ let {{ exec_output += PredOpExecute.subst(vmsrFpscrIop); vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegOp", - { "code": vmsrrsEnabledCheckCode + \ + { "code": vmrsEnabledCheckCode + \ "Dest = MiscOp1;", "predicate_test": predicateTest }, []) header_output += FpRegRegOpDeclare.subst(vmrsIop); @@ -219,14 +219,14 @@ let {{ exec_output += PredOpExecute.subst(vmrsIop); vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp", - { "code": vmsrrsEnabledCheckCode + \ + { "code": vmrsEnabledCheckCode + \ "Dest = Fpscr | FpCondCodes;", "predicate_test": predicateTest }, []) header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop); decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop); exec_output += PredOpExecute.subst(vmrsFpscrIop); - vmrsApsrCode = vmsrrsEnabledCheckCode + ''' + vmrsApsrCode = vmrsEnabledCheckCode + ''' Dest = (MiscOp1 & imm) | (Dest & ~imm); ''' vmrsApsrIop = InstObjParams("vmrs", "VmrsApsr", "FpRegRegImmOp", @@ -236,7 +236,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vmrsApsrIop); exec_output += PredOpExecute.subst(vmrsApsrIop); - vmrsApsrFpscrCode = vmsrrsEnabledCheckCode + ''' + vmrsApsrFpscrCode = vmrsEnabledCheckCode + ''' assert((imm & ~FpCondCodesMask) == 0); Dest = (FpCondCodes & imm) | (Dest & ~imm); ''' diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa index 6919bbca4..a936ffaaf 100644 --- a/src/arch/arm/isa/insts/ldr.isa +++ b/src/arch/arm/isa/insts/ldr.isa @@ -160,6 +160,10 @@ let {{ if not self.post: eaCode += self.offset eaCode += ";" + + if self.flavor == "fp": + eaCode += vfpEnabledCheckCode + self.codeBlobs["ea_code"] = eaCode # Code that actually handles the access @@ -220,6 +224,10 @@ let {{ if not self.post: eaCode += self.offset eaCode += ";" + + if self.flavor == "fp": + eaCode += vfpEnabledCheckCode + self.codeBlobs["ea_code"] = eaCode # Code that actually handles the access diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa index 652a929f1..bcb1e26b8 100644 --- a/src/arch/arm/isa/insts/macromem.isa +++ b/src/arch/arm/isa/insts/macromem.isa @@ -59,7 +59,7 @@ let {{ microLdrFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrFpUop', 'MicroMemOp', {'memacc_code': microLdrFpUopCode, - 'ea_code': + 'ea_code': vfpEnabledCheckCode + 'EA = Rb + (up ? imm : -imm);', 'predicate_test': predicateTest}, ['IsMicroop']) @@ -68,7 +68,7 @@ let {{ microLdrDBFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDBFpUop', 'MicroMemOp', {'memacc_code': microLdrFpUopCode, - 'ea_code': ''' + 'ea_code': vfpEnabledCheckCode + ''' EA = Rb + (up ? imm : -imm) + (((CPSR)Cpsr).e ? 4 : 0); ''', @@ -79,7 +79,7 @@ let {{ microLdrDTFpUopIop = InstObjParams('ldrfp_uop', 'MicroLdrDTFpUop', 'MicroMemOp', {'memacc_code': microLdrFpUopCode, - 'ea_code': ''' + 'ea_code': vfpEnabledCheckCode + ''' EA = Rb + (up ? imm : -imm) - (((CPSR)Cpsr).e ? 4 : 0); ''', @@ -117,7 +117,8 @@ let {{ 'MicroMemOp', {'memacc_code': microStrFpUopCode, 'postacc_code': "", - 'ea_code': 'EA = Rb + (up ? imm : -imm);', + 'ea_code': vfpEnabledCheckCode + + 'EA = Rb + (up ? imm : -imm);', 'predicate_test': predicateTest}, ['IsMicroop']) @@ -126,7 +127,7 @@ let {{ 'MicroMemOp', {'memacc_code': microStrFpUopCode, 'postacc_code': "", - 'ea_code': ''' + 'ea_code': vfpEnabledCheckCode + ''' EA = Rb + (up ? imm : -imm) + (((CPSR)Cpsr).e ? 4 : 0); ''', @@ -138,7 +139,7 @@ let {{ 'MicroMemOp', {'memacc_code': microStrFpUopCode, 'postacc_code': "", - 'ea_code': ''' + 'ea_code': vfpEnabledCheckCode + ''' EA = Rb + (up ? imm : -imm) - (((CPSR)Cpsr).e ? 4 : 0); ''', @@ -222,7 +223,7 @@ let {{ { 'mem_decl' : memDecl, 'size' : size, 'memacc_code' : loadMemAccCode, - 'ea_code' : eaCode, + 'ea_code' : simdEnabledCheckCode + eaCode, 'predicate_test' : predicateTest }, [ 'IsMicroop', 'IsMemRef', 'IsLoad' ]) storeIop = InstObjParams('strneon%(size)d_uop' % subst, @@ -231,7 +232,7 @@ let {{ { 'mem_decl' : memDecl, 'size' : size, 'memacc_code' : storeMemAccCode, - 'ea_code' : eaCode, + 'ea_code' : simdEnabledCheckCode + eaCode, 'predicate_test' : predicateTest }, [ 'IsMicroop', 'IsMemRef', 'IsStore' ]) diff --git a/src/arch/arm/isa/insts/neon.isa b/src/arch/arm/isa/insts/neon.isa index 790c9c3a1..0a3285490 100644 --- a/src/arch/arm/isa/insts/neon.isa +++ b/src/arch/arm/isa/insts/neon.isa @@ -619,13 +619,6 @@ output exec {{ } }}; -let {{ - simdEnabledCheckCode = ''' - if (!neonEnabled(Cpacr, Cpsr, Fpexc)) - return disabledFault(); - ''' -}}; - let {{ header_output = "" @@ -3235,7 +3228,7 @@ let {{ RegVect srcReg1, srcReg2, destReg; ''' for reg in range(rCount): - eWalkCode += ''' + eWalkCode += simdEnabledCheckCode + ''' srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d.uw); srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d.uw); ''' % { "reg" : reg } diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa index 5b0e5b132..66a486ecf 100644 --- a/src/arch/arm/isa/insts/str.isa +++ b/src/arch/arm/isa/insts/str.isa @@ -171,6 +171,10 @@ let {{ if not self.post: eaCode += self.offset eaCode += ";" + + if self.flavor == "fp": + eaCode += vfpEnabledCheckCode + self.codeBlobs["ea_code"] = eaCode # Code that actually handles the access @@ -241,6 +245,10 @@ let {{ if not self.post: eaCode += self.offset eaCode += ";" + + if self.flavor == "fp": + eaCode += vfpEnabledCheckCode + self.codeBlobs["ea_code"] = eaCode # Code that actually handles the access diff --git a/src/arch/arm/isa/templates/neon.isa b/src/arch/arm/isa/templates/neon.isa index 20c1d26b8..0e592c6e4 100644 --- a/src/arch/arm/isa/templates/neon.isa +++ b/src/arch/arm/isa/templates/neon.isa @@ -37,6 +37,14 @@ // // Authors: Gabe Black +let {{ + simdEnabledCheckCode = ''' + if (!neonEnabled(Cpacr, Cpsr, Fpexc)) + return disabledFault(); + ''' +}}; + + def template NeonRegRegRegOpDeclare {{ template class %(class_name)s : public %(base_class)s diff --git a/src/arch/arm/isa/templates/vfp.isa b/src/arch/arm/isa/templates/vfp.isa index 5de52738c..8ccfedd0d 100644 --- a/src/arch/arm/isa/templates/vfp.isa +++ b/src/arch/arm/isa/templates/vfp.isa @@ -43,9 +43,24 @@ let {{ return disabledFault(); ''' - vmsrrsEnabledCheckCode = ''' + vmsrEnabledCheckCode = ''' if (!vfpEnabled(Cpacr, Cpsr)) - return disabledFault(); + if (dest != (int)MISCREG_FPEXC && dest != (int)MISCREG_FPSID) + return disabledFault(); + if (!inPrivilegedMode(Cpsr)) + if (dest != (int)MISCREG_FPSCR) + return disabledFault(); + + ''' + + vmrsEnabledCheckCode = ''' + if (!vfpEnabled(Cpacr, Cpsr)) + if (op1 != (int)MISCREG_FPEXC && op1 != (int)MISCREG_FPSID && + op1 != (int)MISCREG_MVFR0 && op1 != (int)MISCREG_MVFR1) + return disabledFault(); + if (!inPrivilegedMode(Cpsr)) + if (op1 != (int)MISCREG_FPSCR) + return disabledFault(); ''' }}; diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 4256aa047..c2daff99f 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -150,7 +150,7 @@ namespace ArmISA { vfpEnabled(CPACR cpacr, CPSR cpsr) { return cpacr.cp10 == 0x3 || - (cpacr.cp10 == 0x2 && inPrivilegedMode(cpsr)); + (cpacr.cp10 == 0x1 && inPrivilegedMode(cpsr)); } static inline bool -- cgit v1.2.3