diff options
Diffstat (limited to 'lib/Target/Mips/MipsSubtarget.cpp')
-rw-r--r-- | lib/Target/Mips/MipsSubtarget.cpp | 175 |
1 files changed, 53 insertions, 122 deletions
diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp index 693daa3..8768b12 100644 --- a/lib/Target/Mips/MipsSubtarget.cpp +++ b/lib/Target/Mips/MipsSubtarget.cpp @@ -58,6 +58,10 @@ Mips16ConstantIslands( cl::desc("MIPS: mips16 constant islands enable."), cl::init(true)); +static cl::opt<bool> +GPOpt("mgpopt", cl::Hidden, + cl::desc("MIPS: Enable gp-relative addressing of small data items")); + /// Select the Mips CPU for the given triple and cpu name. /// FIXME: Merge with the copy in MipsMCTargetDesc.cpp static StringRef selectMipsCPU(Triple TT, StringRef CPU) { @@ -104,31 +108,32 @@ static std::string computeDataLayout(const MipsSubtarget &ST) { MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, const std::string &FS, bool little, - Reloc::Model _RM, MipsTargetMachine *_TM) - : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(Mips32), - MipsABI(UnknownABI), IsLittle(little), IsSingleFloat(false), - IsFPXX(false), IsFP64bit(false), UseOddSPReg(true), IsNaN2008bit(false), - IsGP64bit(false), HasVFPU(false), HasCnMips(false), IsLinux(true), - HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false), - HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false), - InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false), - HasDSPR2(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), - HasMSA(false), RM(_RM), OverrideMode(NoOverride), TM(_TM), - TargetTriple(TT), + const MipsTargetMachine *_TM) + : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(MipsDefault), + ABI(MipsABIInfo::Unknown()), IsLittle(little), IsSingleFloat(false), + IsFPXX(false), NoABICalls(false), IsFP64bit(false), UseOddSPReg(true), + IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), HasCnMips(false), + IsLinux(true), HasMips3_32(false), HasMips3_32r2(false), + HasMips4_32(false), HasMips4_32r2(false), HasMips5_32r2(false), + InMips16Mode(false), InMips16HardFloat(Mips16HardFloat), + InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), + AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), + HasMSA(false), TM(_TM), TargetTriple(TT), DL(computeDataLayout(initializeSubtargetDependencies(CPU, FS, TM))), - TSInfo(DL), JITInfo(), InstrInfo(MipsInstrInfo::create(*TM)), - FrameLowering(MipsFrameLowering::create(*TM, *this)), - TLInfo(MipsTargetLowering::create(*TM)) { + TSInfo(DL), InstrInfo(MipsInstrInfo::create(*this)), + FrameLowering(MipsFrameLowering::create(*this)), + TLInfo(MipsTargetLowering::create(*TM, *this)) { PreviousInMips16Mode = InMips16Mode; - // Don't even attempt to generate code for MIPS-I, MIPS-II, MIPS-III, and - // MIPS-V. They have not been tested and currently exist for the integrated + if (MipsArchVersion == MipsDefault) + MipsArchVersion = Mips32; + + // Don't even attempt to generate code for MIPS-I, MIPS-III and MIPS-V. + // They have not been tested and currently exist for the integrated // assembler only. if (MipsArchVersion == Mips1) report_fatal_error("Code generation for MIPS-I is not implemented", false); - if (MipsArchVersion == Mips2) - report_fatal_error("Code generation for MIPS-II is not implemented", false); if (MipsArchVersion == Mips3) report_fatal_error("Code generation for MIPS-III is not implemented", false); @@ -136,7 +141,7 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, report_fatal_error("Code generation for MIPS-V is not implemented", false); // Assert exactly one ABI was chosen. - assert(MipsABI != UnknownABI); + assert(ABI.IsKnown()); assert((((getFeatureBits() & Mips::FeatureO32) != 0) + ((getFeatureBits() & Mips::FeatureEABI) != 0) + ((getFeatureBits() & Mips::FeatureN32) != 0) + @@ -153,9 +158,10 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, false); if (!isABI_O32() && !useOddSPReg()) - report_fatal_error("-mattr=+nooddspreg is not currently permitted for a " - "the O32 ABI.", - false); + report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false); + + if (IsFPXX && (isABI_N32() || isABI_N64())) + report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false); if (hasMips32r6()) { StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6"; @@ -170,21 +176,29 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, if (TT.find("linux") == std::string::npos) IsLinux = false; + if (NoABICalls && TM->getRelocationModel() == Reloc::PIC_) + report_fatal_error("position-independent code requires '-mabicalls'"); + // Set UseSmallSection. - // TODO: Investigate the IsLinux check. I suspect it's really checking for - // bare-metal. - UseSmallSection = !IsLinux && (RM == Reloc::Static); + UseSmallSection = GPOpt; + if (!NoABICalls && GPOpt) { + errs() << "warning: cannot use small-data accesses for '-mabicalls'" + << "\n"; + UseSmallSection = false; + } } -bool -MipsSubtarget::enablePostRAScheduler(CodeGenOpt::Level OptLevel, - TargetSubtargetInfo::AntiDepBreakMode &Mode, - RegClassVector &CriticalPathRCs) const { - Mode = TargetSubtargetInfo::ANTIDEP_NONE; +/// This overrides the PostRAScheduler bit in the SchedModel for any CPU. +bool MipsSubtarget::enablePostMachineScheduler() const { return true; } + +void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { CriticalPathRCs.clear(); - CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass - : &Mips::GPR32RegClass); - return OptLevel >= CodeGenOpt::Aggressive; + CriticalPathRCs.push_back(isGP64bit() ? + &Mips::GPR64RegClass : &Mips::GPR32RegClass); +} + +CodeGenOpt::Level MipsSubtarget::getOptLevelToEnablePostRAScheduler() const { + return CodeGenOpt::Aggressive; } MipsSubtarget & @@ -197,100 +211,13 @@ MipsSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS, // Initialize scheduling itinerary for the specified CPU. InstrItins = getInstrItineraryForCPU(CPUName); - if (InMips16Mode && !TM->Options.UseSoftFloat) { - // Hard float for mips16 means essentially to compile as soft float - // but to use a runtime library for soft float that is written with - // native mips32 floating point instructions (those runtime routines - // run in mips32 hard float mode). - TM->Options.UseSoftFloat = true; - TM->Options.FloatABIType = FloatABI::Soft; + if (InMips16Mode && !TM->Options.UseSoftFloat) InMips16HardFloat = true; - } return *this; } -//FIXME: This logic for reseting the subtarget along with -// the helper classes can probably be simplified but there are a lot of -// cases so we will defer rewriting this to later. -// -void MipsSubtarget::resetSubtarget(MachineFunction *MF) { - bool ChangeToMips16 = false, ChangeToNoMips16 = false; - DEBUG(dbgs() << "resetSubtargetFeatures" << "\n"); - AttributeSet FnAttrs = MF->getFunction()->getAttributes(); - ChangeToMips16 = FnAttrs.hasAttribute(AttributeSet::FunctionIndex, - "mips16"); - ChangeToNoMips16 = FnAttrs.hasAttribute(AttributeSet::FunctionIndex, - "nomips16"); - assert (!(ChangeToMips16 & ChangeToNoMips16) && - "mips16 and nomips16 specified on the same function"); - if (ChangeToMips16) { - if (PreviousInMips16Mode) - return; - OverrideMode = Mips16Override; - PreviousInMips16Mode = true; - setHelperClassesMips16(); - return; - } else if (ChangeToNoMips16) { - if (!PreviousInMips16Mode) - return; - OverrideMode = NoMips16Override; - PreviousInMips16Mode = false; - setHelperClassesMipsSE(); - return; - } else { - if (OverrideMode == NoOverride) - return; - OverrideMode = NoOverride; - DEBUG(dbgs() << "back to default" << "\n"); - if (inMips16Mode() && !PreviousInMips16Mode) { - setHelperClassesMips16(); - PreviousInMips16Mode = true; - } else if (!inMips16Mode() && PreviousInMips16Mode) { - setHelperClassesMipsSE(); - PreviousInMips16Mode = false; - } - return; - } -} - -void MipsSubtarget::setHelperClassesMips16() { - InstrInfoSE.swap(InstrInfo); - FrameLoweringSE.swap(FrameLowering); - TLInfoSE.swap(TLInfo); - if (!InstrInfo16) { - InstrInfo.reset(MipsInstrInfo::create(*TM)); - FrameLowering.reset(MipsFrameLowering::create(*TM, *this)); - TLInfo.reset(MipsTargetLowering::create(*TM)); - } else { - InstrInfo16.swap(InstrInfo); - FrameLowering16.swap(FrameLowering); - TLInfo16.swap(TLInfo); - } - assert(TLInfo && "null target lowering 16"); - assert(InstrInfo && "null instr info 16"); - assert(FrameLowering && "null frame lowering 16"); -} - -void MipsSubtarget::setHelperClassesMipsSE() { - InstrInfo16.swap(InstrInfo); - FrameLowering16.swap(FrameLowering); - TLInfo16.swap(TLInfo); - if (!InstrInfoSE) { - InstrInfo.reset(MipsInstrInfo::create(*TM)); - FrameLowering.reset(MipsFrameLowering::create(*TM, *this)); - TLInfo.reset(MipsTargetLowering::create(*TM)); - } else { - InstrInfoSE.swap(InstrInfo); - FrameLoweringSE.swap(FrameLowering); - TLInfoSE.swap(TLInfo); - } - assert(TLInfo && "null target lowering in SE"); - assert(InstrInfo && "null instr info SE"); - assert(FrameLowering && "null frame lowering SE"); -} - -bool MipsSubtarget::mipsSEUsesSoftFloat() const { +bool MipsSubtarget::abiUsesSoftFloat() const { return TM->Options.UseSoftFloat && !InMips16HardFloat; } @@ -298,3 +225,7 @@ bool MipsSubtarget::useConstantIslands() { DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands << "\n"); return Mips16ConstantIslands; } + +Reloc::Model MipsSubtarget::getRelocationModel() const { + return TM->getRelocationModel(); +} |