diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 793f9d3a4..79973185d 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -159,8 +159,12 @@ Reset::invoke(ThreadContext *tc) void UndefinedInstruction::invoke(ThreadContext *tc) { + // If the mnemonic isn't defined this has to be an unknown instruction. assert(unknown || mnemonic != NULL); - if (unknown) { + if (disabled) { + panic("Attempted to execute disabled instruction " + "'%s' (inst 0x%08x)", mnemonic, machInst); + } else if (unknown) { panic("Attempted to execute unknown instruction (inst 0x%08x)", machInst); } else { diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh index f9d25abdf..7dd881435 100644 --- a/src/arch/arm/faults.hh +++ b/src/arch/arm/faults.hh @@ -153,12 +153,15 @@ class UndefinedInstruction : public ArmFaultVals ExtMachInst machInst; bool unknown; const char *mnemonic; + bool disabled; public: UndefinedInstruction(ExtMachInst _machInst, bool _unknown, - const char *_mnemonic = NULL) : - machInst(_machInst), unknown(_unknown), mnemonic(_mnemonic) + const char *_mnemonic = NULL, + bool _disabled = false) : + machInst(_machInst), unknown(_unknown), + mnemonic(_mnemonic), disabled(_disabled) { } diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index e98f85a3b..7ea3405af 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -42,6 +42,7 @@ #ifndef __ARCH_ARM_INSTS_STATICINST_HH__ #define __ARCH_ARM_INSTS_STATICINST_HH__ +#include "arch/arm/faults.hh" #include "base/trace.hh" #include "cpu/static_inst.hh" @@ -319,6 +320,16 @@ class ArmStaticInst : public StaticInst setNextPC(xc, val); } } + + inline Fault + disabledFault() const + { +#if FULL_SYSTEM + return new UndefinedInstruction(); +#else + return new UndefinedInstruction(machInst, false, mnemonic, true); +#endif + } }; } diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index ac012fc3c..7991dbfb7 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -66,17 +66,6 @@ ISA::clear() miscRegs[MISCREG_SCTLR] = sctlr; miscRegs[MISCREG_SCTLR_RST] = sctlr_rst; - - /* - * Technically this should be 0, but we don't support those - * settings. - */ - CPACR cpacr = 0; - // Enable CP 10, 11 - cpacr.cp10 = 0x3; - cpacr.cp11 = 0x3; - miscRegs[MISCREG_CPACR] = cpacr; - /* Start with an event in the mailbox */ miscRegs[MISCREG_SEV_MAILBOX] = 1; @@ -278,9 +267,9 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) CPACR valCpacr = val; newCpacr.cp10 = valCpacr.cp10; newCpacr.cp11 = valCpacr.cp11; - if (newCpacr.cp10 != 0x3 || newCpacr.cp11 != 3) { - panic("Disabling coprocessors isn't implemented.\n"); - } + //XXX d32dis isn't implemented. The manual says whether or not + //it works is implementation defined. + newCpacr.asedis = valCpacr.asedis; newVal = newCpacr; } break; diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa index 9748c8a49..51a6b1e4e 100644 --- a/src/arch/arm/isa/insts/fp.isa +++ b/src/arch/arm/isa/insts/fp.isa @@ -192,14 +192,16 @@ let {{ exec_output = "" vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegOp", - { "code": "MiscDest = Op1;", + { "code": vmsrrsEnabledCheckCode + \ + "MiscDest = Op1;", "predicate_test": predicateTest }, []) header_output += FpRegRegOpDeclare.subst(vmsrIop); decoder_output += FpRegRegOpConstructor.subst(vmsrIop); exec_output += PredOpExecute.subst(vmsrIop); vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegOp", - { "code": "Dest = MiscOp1;", + { "code": vmsrrsEnabledCheckCode + \ + "Dest = MiscOp1;", "predicate_test": predicateTest }, []) header_output += FpRegRegOpDeclare.subst(vmrsIop); decoder_output += FpRegRegOpConstructor.subst(vmrsIop); @@ -213,7 +215,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vmrsApsrIop); exec_output += PredOpExecute.subst(vmrsApsrIop); - vmovImmSCode = ''' + vmovImmSCode = vfpEnabledCheckCode + ''' FpDest.uw = bits(imm, 31, 0); ''' vmovImmSIop = InstObjParams("vmov", "VmovImmS", "FpRegImmOp", @@ -223,7 +225,7 @@ let {{ decoder_output += FpRegImmOpConstructor.subst(vmovImmSIop); exec_output += PredOpExecute.subst(vmovImmSIop); - vmovImmDCode = ''' + vmovImmDCode = vfpEnabledCheckCode + ''' FpDestP0.uw = bits(imm, 31, 0); FpDestP1.uw = bits(imm, 63, 32); ''' @@ -234,7 +236,7 @@ let {{ decoder_output += FpRegImmOpConstructor.subst(vmovImmDIop); exec_output += PredOpExecute.subst(vmovImmDIop); - vmovImmQCode = ''' + vmovImmQCode = vfpEnabledCheckCode + ''' FpDestP0.uw = bits(imm, 31, 0); FpDestP1.uw = bits(imm, 63, 32); FpDestP2.uw = bits(imm, 31, 0); @@ -247,7 +249,7 @@ let {{ decoder_output += FpRegImmOpConstructor.subst(vmovImmQIop); exec_output += PredOpExecute.subst(vmovImmQIop); - vmovRegSCode = ''' + vmovRegSCode = vfpEnabledCheckCode + ''' FpDest.uw = FpOp1.uw; ''' vmovRegSIop = InstObjParams("vmov", "VmovRegS", "FpRegRegOp", @@ -257,7 +259,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vmovRegSIop); exec_output += PredOpExecute.subst(vmovRegSIop); - vmovRegDCode = ''' + vmovRegDCode = vfpEnabledCheckCode + ''' FpDestP0.uw = FpOp1P0.uw; FpDestP1.uw = FpOp1P1.uw; ''' @@ -268,7 +270,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vmovRegDIop); exec_output += PredOpExecute.subst(vmovRegDIop); - vmovRegQCode = ''' + vmovRegQCode = vfpEnabledCheckCode + ''' FpDestP0.uw = FpOp1P0.uw; FpDestP1.uw = FpOp1P1.uw; FpDestP2.uw = FpOp1P2.uw; @@ -281,7 +283,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vmovRegQIop); exec_output += PredOpExecute.subst(vmovRegQIop); - vmovCoreRegBCode = ''' + vmovCoreRegBCode = vfpEnabledCheckCode + ''' FpDest.uw = insertBits(FpDest.uw, imm * 8 + 7, imm * 8, Op1.ub); ''' vmovCoreRegBIop = InstObjParams("vmov", "VmovCoreRegB", "FpRegRegImmOp", @@ -291,7 +293,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegBIop); exec_output += PredOpExecute.subst(vmovCoreRegBIop); - vmovCoreRegHCode = ''' + vmovCoreRegHCode = vfpEnabledCheckCode + ''' FpDest.uw = insertBits(FpDest.uw, imm * 16 + 15, imm * 16, Op1.uh); ''' vmovCoreRegHIop = InstObjParams("vmov", "VmovCoreRegH", "FpRegRegImmOp", @@ -301,7 +303,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegHIop); exec_output += PredOpExecute.subst(vmovCoreRegHIop); - vmovCoreRegWCode = ''' + vmovCoreRegWCode = vfpEnabledCheckCode + ''' FpDest.uw = Op1.uw; ''' vmovCoreRegWIop = InstObjParams("vmov", "VmovCoreRegW", "FpRegRegOp", @@ -311,7 +313,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vmovCoreRegWIop); exec_output += PredOpExecute.subst(vmovCoreRegWIop); - vmovRegCoreUBCode = ''' + vmovRegCoreUBCode = vfpEnabledCheckCode + ''' assert(imm < 4); Dest = bits(FpOp1.uw, imm * 8 + 7, imm * 8); ''' @@ -322,7 +324,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUBIop); exec_output += PredOpExecute.subst(vmovRegCoreUBIop); - vmovRegCoreUHCode = ''' + vmovRegCoreUHCode = vfpEnabledCheckCode + ''' assert(imm < 2); Dest = bits(FpOp1.uw, imm * 16 + 15, imm * 16); ''' @@ -333,7 +335,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUHIop); exec_output += PredOpExecute.subst(vmovRegCoreUHIop); - vmovRegCoreSBCode = ''' + vmovRegCoreSBCode = vfpEnabledCheckCode + ''' assert(imm < 4); Dest = sext<8>(bits(FpOp1.uw, imm * 8 + 7, imm * 8)); ''' @@ -344,7 +346,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSBIop); exec_output += PredOpExecute.subst(vmovRegCoreSBIop); - vmovRegCoreSHCode = ''' + vmovRegCoreSHCode = vfpEnabledCheckCode + ''' assert(imm < 2); Dest = sext<16>(bits(FpOp1.uw, imm * 16 + 15, imm * 16)); ''' @@ -355,7 +357,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSHIop); exec_output += PredOpExecute.subst(vmovRegCoreSHIop); - vmovRegCoreWCode = ''' + vmovRegCoreWCode = vfpEnabledCheckCode + ''' Dest = FpOp1.uw; ''' vmovRegCoreWIop = InstObjParams("vmov", "VmovRegCoreW", "FpRegRegOp", @@ -365,7 +367,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vmovRegCoreWIop); exec_output += PredOpExecute.subst(vmovRegCoreWIop); - vmov2Reg2CoreCode = ''' + vmov2Reg2CoreCode = vfpEnabledCheckCode + ''' FpDestP0.uw = Op1.uw; FpDestP1.uw = Op2.uw; ''' @@ -376,7 +378,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vmov2Reg2CoreIop); exec_output += PredOpExecute.subst(vmov2Reg2CoreIop); - vmov2Core2RegCode = ''' + vmov2Core2RegCode = vfpEnabledCheckCode + ''' Dest.uw = FpOp2P0.uw; Op1.uw = FpOp2P1.uw; ''' @@ -394,7 +396,7 @@ let {{ decoder_output = "" exec_output = "" - singleCode = ''' + singleCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; FpDest = %(op)s; Fpscr = fpscr; @@ -402,7 +404,7 @@ let {{ singleBinOp = "binaryOp(fpscr, FpOp1, FpOp2," + \ "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)" singleUnaryOp = "unaryOp(fpscr, FpOp1, %(func)s, fpscr.fz, fpscr.rMode)" - doubleCode = ''' + doubleCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double dest = %(op)s; Fpscr = fpscr; @@ -500,7 +502,7 @@ let {{ decoder_output = "" exec_output = "" - vmlaSCode = ''' + vmlaSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; float mid = binaryOp(fpscr, FpOp1, FpOp2, fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode); @@ -515,7 +517,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vmlaSIop); exec_output += PredOpExecute.subst(vmlaSIop); - vmlaDCode = ''' + vmlaDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double mid = binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw), dbl(FpOp2P0.uw, FpOp2P1.uw), @@ -534,7 +536,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vmlaDIop); exec_output += PredOpExecute.subst(vmlaDIop); - vmlsSCode = ''' + vmlsSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; float mid = binaryOp(fpscr, FpOp1, FpOp2, fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode); @@ -549,7 +551,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vmlsSIop); exec_output += PredOpExecute.subst(vmlsSIop); - vmlsDCode = ''' + vmlsDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double mid = binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw), dbl(FpOp2P0.uw, FpOp2P1.uw), @@ -568,7 +570,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vmlsDIop); exec_output += PredOpExecute.subst(vmlsDIop); - vnmlaSCode = ''' + vnmlaSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; float mid = binaryOp(fpscr, FpOp1, FpOp2, fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode); @@ -583,7 +585,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vnmlaSIop); exec_output += PredOpExecute.subst(vnmlaSIop); - vnmlaDCode = ''' + vnmlaDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double mid = binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw), dbl(FpOp2P0.uw, FpOp2P1.uw), @@ -602,7 +604,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vnmlaDIop); exec_output += PredOpExecute.subst(vnmlaDIop); - vnmlsSCode = ''' + vnmlsSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; float mid = binaryOp(fpscr, FpOp1, FpOp2, fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode); @@ -617,7 +619,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vnmlsSIop); exec_output += PredOpExecute.subst(vnmlsSIop); - vnmlsDCode = ''' + vnmlsDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double mid = binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw), dbl(FpOp2P0.uw, FpOp2P1.uw), @@ -636,7 +638,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vnmlsDIop); exec_output += PredOpExecute.subst(vnmlsDIop); - vnmulSCode = ''' + vnmulSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode); @@ -649,7 +651,7 @@ let {{ decoder_output += FpRegRegRegOpConstructor.subst(vnmulSIop); exec_output += PredOpExecute.subst(vnmulSIop); - vnmulDCode = ''' + vnmulDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double dest = -binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw), dbl(FpOp2P0.uw, FpOp2P1.uw), @@ -673,7 +675,7 @@ let {{ decoder_output = "" exec_output = "" - vcvtUIntFpSCode = ''' + vcvtUIntFpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); __asm__ __volatile__("" : "=m" (FpOp1.uw) : "m" (FpOp1.uw)); @@ -689,7 +691,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop); exec_output += PredOpExecute.subst(vcvtUIntFpSIop); - vcvtUIntFpDCode = ''' + vcvtUIntFpDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); __asm__ __volatile__("" : "=m" (FpOp1P0.uw) : "m" (FpOp1P0.uw)); @@ -707,7 +709,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop); exec_output += PredOpExecute.subst(vcvtUIntFpDIop); - vcvtSIntFpSCode = ''' + vcvtSIntFpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); __asm__ __volatile__("" : "=m" (FpOp1.sw) : "m" (FpOp1.sw)); @@ -723,7 +725,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop); exec_output += PredOpExecute.subst(vcvtSIntFpSIop); - vcvtSIntFpDCode = ''' + vcvtSIntFpDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); __asm__ __volatile__("" : "=m" (FpOp1P0.sw) : "m" (FpOp1P0.sw)); @@ -741,7 +743,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop); exec_output += PredOpExecute.subst(vcvtSIntFpDIop); - vcvtFpUIntSRCode = ''' + vcvtFpUIntSRCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); vfpFlushToZero(fpscr, FpOp1); @@ -758,7 +760,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop); exec_output += PredOpExecute.subst(vcvtFpUIntSRIop); - vcvtFpUIntDRCode = ''' + vcvtFpUIntDRCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); vfpFlushToZero(fpscr, cOp1); @@ -777,7 +779,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop); exec_output += PredOpExecute.subst(vcvtFpUIntDRIop); - vcvtFpSIntSRCode = ''' + vcvtFpSIntSRCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); vfpFlushToZero(fpscr, FpOp1); @@ -794,7 +796,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop); exec_output += PredOpExecute.subst(vcvtFpSIntSRIop); - vcvtFpSIntDRCode = ''' + vcvtFpSIntDRCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); vfpFlushToZero(fpscr, cOp1); @@ -813,7 +815,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop); exec_output += PredOpExecute.subst(vcvtFpSIntDRIop); - vcvtFpUIntSCode = ''' + vcvtFpUIntSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -831,7 +833,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSIop); exec_output += PredOpExecute.subst(vcvtFpUIntSIop); - vcvtFpUIntDCode = ''' + vcvtFpUIntDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); vfpFlushToZero(fpscr, cOp1); @@ -851,7 +853,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDIop); exec_output += PredOpExecute.subst(vcvtFpUIntDIop); - vcvtFpSIntSCode = ''' + vcvtFpSIntSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -869,7 +871,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSIop); exec_output += PredOpExecute.subst(vcvtFpSIntSIop); - vcvtFpSIntDCode = ''' + vcvtFpSIntDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); vfpFlushToZero(fpscr, cOp1); @@ -889,7 +891,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDIop); exec_output += PredOpExecute.subst(vcvtFpSIntDIop); - vcvtFpSFpDCode = ''' + vcvtFpSFpDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -908,7 +910,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop); exec_output += PredOpExecute.subst(vcvtFpSFpDIop); - vcvtFpDFpSCode = ''' + vcvtFpDFpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); vfpFlushToZero(fpscr, cOp1); @@ -926,7 +928,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop); exec_output += PredOpExecute.subst(vcvtFpDFpSIop); - vcvtFpHTFpSCode = ''' + vcvtFpHTFpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -944,7 +946,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop); exec_output += PredOpExecute.subst(vcvtFpHTFpSIop); - vcvtFpHBFpSCode = ''' + vcvtFpHBFpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); @@ -961,7 +963,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop); exec_output += PredOpExecute.subst(vcvtFpHBFpSIop); - vcvtFpSFpHTCode = ''' + vcvtFpSFpHTCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -981,7 +983,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop); exec_output += PredOpExecute.subst(vcvtFpSFpHTIop); - vcvtFpSFpHBCode = ''' + vcvtFpSFpHBCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -1001,7 +1003,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop); exec_output += PredOpExecute.subst(vcvtFpSFpHBIop); - vcmpSCode = ''' + vcmpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpDest, FpOp1); if (FpDest == FpOp1) { @@ -1029,7 +1031,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcmpSIop); exec_output += PredOpExecute.subst(vcmpSIop); - vcmpDCode = ''' + vcmpDCode = vfpEnabledCheckCode + ''' double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); double cDest = dbl(FpDestP0.uw, FpDestP1.uw); FPSCR fpscr = Fpscr; @@ -1059,7 +1061,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcmpDIop); exec_output += PredOpExecute.subst(vcmpDIop); - vcmpZeroSCode = ''' + vcmpZeroSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpDest); // This only handles imm == 0 for now. @@ -1087,7 +1089,7 @@ let {{ decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop); exec_output += PredOpExecute.subst(vcmpZeroSIop); - vcmpZeroDCode = ''' + vcmpZeroDCode = vfpEnabledCheckCode + ''' // This only handles imm == 0 for now. assert(imm == 0); double cDest = dbl(FpDestP0.uw, FpDestP1.uw); @@ -1116,7 +1118,7 @@ let {{ decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop); exec_output += PredOpExecute.subst(vcmpZeroDIop); - vcmpeSCode = ''' + vcmpeSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpDest, FpOp1); if (FpDest == FpOp1) { @@ -1138,7 +1140,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop); exec_output += PredOpExecute.subst(vcmpeSIop); - vcmpeDCode = ''' + vcmpeDCode = vfpEnabledCheckCode + ''' double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); double cDest = dbl(FpDestP0.uw, FpDestP1.uw); FPSCR fpscr = Fpscr; @@ -1162,7 +1164,7 @@ let {{ decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop); exec_output += PredOpExecute.subst(vcmpeDIop); - vcmpeZeroSCode = ''' + vcmpeZeroSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpDest); if (FpDest == imm) { @@ -1184,7 +1186,7 @@ let {{ decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop); exec_output += PredOpExecute.subst(vcmpeZeroSIop); - vcmpeZeroDCode = ''' + vcmpeZeroDCode = vfpEnabledCheckCode + ''' double cDest = dbl(FpDestP0.uw, FpDestP1.uw); FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, cDest); @@ -1214,7 +1216,7 @@ let {{ decoder_output = "" exec_output = "" - vcvtFpSFixedSCode = ''' + vcvtFpSFixedSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -1231,7 +1233,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop); exec_output += PredOpExecute.subst(vcvtFpSFixedSIop); - vcvtFpSFixedDCode = ''' + vcvtFpSFixedDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); vfpFlushToZero(fpscr, cOp1); @@ -1251,7 +1253,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop); exec_output += PredOpExecute.subst(vcvtFpSFixedDIop); - vcvtFpUFixedSCode = ''' + vcvtFpUFixedSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -1268,7 +1270,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop); exec_output += PredOpExecute.subst(vcvtFpUFixedSIop); - vcvtFpUFixedDCode = ''' + vcvtFpUFixedDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); vfpFlushToZero(fpscr, cOp1); @@ -1288,7 +1290,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop); exec_output += PredOpExecute.subst(vcvtFpUFixedDIop); - vcvtSFixedFpSCode = ''' + vcvtSFixedFpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); __asm__ __volatile__("" : "=m" (FpOp1.sw) : "m" (FpOp1.sw)); @@ -1304,7 +1306,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop); exec_output += PredOpExecute.subst(vcvtSFixedFpSIop); - vcvtSFixedFpDCode = ''' + vcvtSFixedFpDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); VfpSavedState state = prepFpState(fpscr.rMode); @@ -1323,7 +1325,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop); exec_output += PredOpExecute.subst(vcvtSFixedFpDIop); - vcvtUFixedFpSCode = ''' + vcvtUFixedFpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); __asm__ __volatile__("" : "=m" (FpOp1.uw) : "m" (FpOp1.uw)); @@ -1339,7 +1341,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop); exec_output += PredOpExecute.subst(vcvtUFixedFpSIop); - vcvtUFixedFpDCode = ''' + vcvtUFixedFpDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); VfpSavedState state = prepFpState(fpscr.rMode); @@ -1358,7 +1360,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop); exec_output += PredOpExecute.subst(vcvtUFixedFpDIop); - vcvtFpSHFixedSCode = ''' + vcvtFpSHFixedSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -1376,7 +1378,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop); exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop); - vcvtFpSHFixedDCode = ''' + vcvtFpSHFixedDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); vfpFlushToZero(fpscr, cOp1); @@ -1397,7 +1399,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop); exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop); - vcvtFpUHFixedSCode = ''' + vcvtFpUHFixedSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; vfpFlushToZero(fpscr, FpOp1); VfpSavedState state = prepFpState(fpscr.rMode); @@ -1415,7 +1417,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop); exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop); - vcvtFpUHFixedDCode = ''' + vcvtFpUHFixedDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw); vfpFlushToZero(fpscr, cOp1); @@ -1436,7 +1438,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop); exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop); - vcvtSHFixedFpSCode = ''' + vcvtSHFixedFpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); __asm__ __volatile__("" : "=m" (FpOp1.sh) : "m" (FpOp1.sh)); @@ -1453,7 +1455,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop); exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop); - vcvtSHFixedFpDCode = ''' + vcvtSHFixedFpDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); VfpSavedState state = prepFpState(fpscr.rMode); @@ -1473,7 +1475,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop); exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop); - vcvtUHFixedFpSCode = ''' + vcvtUHFixedFpSCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; VfpSavedState state = prepFpState(fpscr.rMode); __asm__ __volatile__("" : "=m" (FpOp1.uh) : "m" (FpOp1.uh)); @@ -1490,7 +1492,7 @@ let {{ decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop); exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop); - vcvtUHFixedFpDCode = ''' + vcvtUHFixedFpDCode = vfpEnabledCheckCode + ''' FPSCR fpscr = Fpscr; uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); VfpSavedState state = prepFpState(fpscr.rMode); diff --git a/src/arch/arm/isa/insts/neon.isa b/src/arch/arm/isa/insts/neon.isa index b629c6fe8..1568b755b 100644 --- a/src/arch/arm/isa/insts/neon.isa +++ b/src/arch/arm/isa/insts/neon.isa @@ -619,6 +619,13 @@ output exec {{ } }}; +let {{ + simdEnabledCheckCode = ''' + if (!neonEnabled(Cpacr, Cpsr, Fpexc)) + return disabledFault(); + ''' +}}; + let {{ header_output = "" @@ -634,7 +641,7 @@ let {{ def threeEqualRegInst(name, Name, types, rCount, op, readDest=False, pairwise=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcReg1, srcReg2, destReg; ''' for reg in range(rCount): @@ -694,7 +701,7 @@ let {{ def threeEqualRegInstFp(name, Name, types, rCount, op, readDest=False, pairwise=False, toInt=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' typedef FloatReg FloatVect[rCount]; FloatVect srcRegs1, srcRegs2; ''' @@ -789,7 +796,7 @@ let {{ if bigDest: destCnt = 4 destPrefix = 'Big' - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' %sRegVect srcReg1; %sRegVect srcReg2; %sRegVect destReg; @@ -852,7 +859,7 @@ let {{ def twoEqualRegInst(name, Name, types, rCount, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcReg1, srcReg2, destReg; ''' for reg in range(rCount): @@ -897,7 +904,7 @@ let {{ def twoRegLongInst(name, Name, types, op, readDest=False): global header_output, exec_output rCount = 2 - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcReg1, srcReg2; BigRegVect destReg; ''' @@ -943,7 +950,7 @@ let {{ def twoEqualRegInstFp(name, Name, types, rCount, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' typedef FloatReg FloatVect[rCount]; FloatVect srcRegs1, srcRegs2, destRegs; ''' @@ -989,7 +996,7 @@ let {{ def twoRegShiftInst(name, Name, types, rCount, op, readDest=False, toInt=False, fromInt=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcRegs1, destRegs; ''' for reg in range(rCount): @@ -1044,7 +1051,7 @@ let {{ def twoRegNarrowShiftInst(name, Name, types, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' BigRegVect srcReg1; RegVect destReg; ''' @@ -1087,7 +1094,7 @@ let {{ def twoRegLongShiftInst(name, Name, types, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcReg1; BigRegVect destReg; ''' @@ -1130,7 +1137,7 @@ let {{ def twoRegMiscInst(name, Name, types, rCount, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcReg1, destReg; ''' for reg in range(rCount): @@ -1172,7 +1179,7 @@ let {{ def twoRegMiscScInst(name, Name, types, rCount, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcReg1, destReg; ''' for reg in range(rCount): @@ -1213,7 +1220,7 @@ let {{ def twoRegMiscScramble(name, Name, types, rCount, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcReg1, destReg; ''' for reg in range(rCount): @@ -1248,7 +1255,7 @@ let {{ def twoRegMiscInstFp(name, Name, types, rCount, op, readDest=False, toInt=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' typedef FloatReg FloatVect[rCount]; FloatVect srcRegs1; ''' @@ -1312,7 +1319,7 @@ let {{ def twoRegCondenseInst(name, Name, types, rCount, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcRegs; BigRegVect destReg; ''' @@ -1355,7 +1362,7 @@ let {{ def twoRegNarrowMiscInst(name, Name, types, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' BigRegVect srcReg1; RegVect destReg; ''' @@ -1398,7 +1405,7 @@ let {{ def oneRegImmInst(name, Name, types, rCount, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect destReg; ''' if readDest: @@ -1435,7 +1442,7 @@ let {{ def twoRegLongMiscInst(name, Name, types, op, readDest=False): global header_output, exec_output - eWalkCode = ''' + eWalkCode = simdEnabledCheckCode + ''' RegVect srcReg1; BigRegVect destReg; ''' diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 5490a28e0..7b2b50290 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -205,6 +205,7 @@ def operands {{ 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', None, 2), 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', None, 2), 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', None, 2), + 'Cpacr': ('ControlReg', 'uw', 'MISCREG_CPACR', (None, None, 'IsControl'), 2), 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', None, 2), 'Sctlr': ('ControlReg', 'uw', 'MISCREG_SCTLR', None, 2), 'SevMailbox': ('ControlReg', 'uw', 'MISCREG_SEV_MAILBOX', None, 2), diff --git a/src/arch/arm/isa/templates/vfp.isa b/src/arch/arm/isa/templates/vfp.isa index b0443c734..5de52738c 100644 --- a/src/arch/arm/isa/templates/vfp.isa +++ b/src/arch/arm/isa/templates/vfp.isa @@ -37,6 +37,18 @@ // // Authors: Gabe Black +let {{ + vfpEnabledCheckCode = ''' + if (!vfpEnabled(Cpacr, Cpsr, Fpexc)) + return disabledFault(); + ''' + + vmsrrsEnabledCheckCode = ''' + if (!vfpEnabled(Cpacr, Cpsr)) + return disabledFault(); + ''' +}}; + def template FpRegRegOpDeclare {{ class %(class_name)s : public %(base_class)s { diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 86a11d508..453893908 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -354,6 +354,12 @@ namespace ArmISA Bitfield<31> n; EndBitUnion(FPSCR) + BitUnion32(FPEXC) + Bitfield<31> ex; + Bitfield<30> en; + Bitfield<29, 0> subArchDefined; + EndBitUnion(FPEXC) + BitUnion32(MVFR0) Bitfield<3, 0> advSimdRegisters; Bitfield<7, 4> singlePrecision; diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc index e7748ad50..e8dda1af0 100644 --- a/src/arch/arm/process.cc +++ b/src/arch/arm/process.cc @@ -78,6 +78,18 @@ ArmLiveProcess::startup() { LiveProcess::startup(); argsInit(MachineBytes, VMPageSize); + for (int i = 0; i < contextIds.size(); i++) { + ThreadContext * tc = system->getThreadContext(contextIds[i]); + CPACR cpacr = tc->readMiscReg(MISCREG_CPACR); + // Enable the floating point coprocessors. + cpacr.cp10 = 0x3; + cpacr.cp11 = 0x3; + tc->setMiscReg(MISCREG_CPACR, cpacr); + // Generically enable floating point support. + FPEXC fpexc = tc->readMiscReg(MISCREG_FPEXC); + fpexc.en = 1; + tc->setMiscReg(MISCREG_FPEXC, fpexc); + } } void diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 65c94926e..4256aa047 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -146,6 +146,25 @@ namespace ArmISA { return !inUserMode(tc); } + static inline bool + vfpEnabled(CPACR cpacr, CPSR cpsr) + { + return cpacr.cp10 == 0x3 || + (cpacr.cp10 == 0x2 && inPrivilegedMode(cpsr)); + } + + static inline bool + vfpEnabled(CPACR cpacr, CPSR cpsr, FPEXC fpexc) + { + return fpexc.en && vfpEnabled(cpacr, cpsr); + } + + static inline bool + neonEnabled(CPACR cpacr, CPSR cpsr, FPEXC fpexc) + { + return !cpacr.asedis && vfpEnabled(cpacr, cpsr, fpexc); + } + uint64_t getArgument(ThreadContext *tc, int number, bool fp); Fault setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2);