LLVM API Documentation

MipsSubtarget.cpp
Go to the documentation of this file.
00001 //===-- MipsSubtarget.cpp - Mips Subtarget Information --------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the Mips specific subclass of TargetSubtargetInfo.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "MipsMachineFunction.h"
00015 #include "Mips.h"
00016 #include "MipsRegisterInfo.h"
00017 #include "MipsSubtarget.h"
00018 #include "MipsTargetMachine.h"
00019 #include "llvm/IR/Attributes.h"
00020 #include "llvm/IR/Function.h"
00021 #include "llvm/Support/CommandLine.h"
00022 #include "llvm/Support/Debug.h"
00023 #include "llvm/Support/TargetRegistry.h"
00024 #include "llvm/Support/raw_ostream.h"
00025 
00026 using namespace llvm;
00027 
00028 #define DEBUG_TYPE "mips-subtarget"
00029 
00030 #define GET_SUBTARGETINFO_TARGET_DESC
00031 #define GET_SUBTARGETINFO_CTOR
00032 #include "MipsGenSubtargetInfo.inc"
00033 
00034 // FIXME: Maybe this should be on by default when Mips16 is specified
00035 //
00036 static cl::opt<bool> Mixed16_32(
00037   "mips-mixed-16-32",
00038   cl::init(false),
00039   cl::desc("Allow for a mixture of Mips16 "
00040            "and Mips32 code in a single source file"),
00041   cl::Hidden);
00042 
00043 static cl::opt<bool> Mips_Os16(
00044   "mips-os16",
00045   cl::init(false),
00046   cl::desc("Compile all functions that don' use "
00047            "floating point as Mips 16"),
00048   cl::Hidden);
00049 
00050 static cl::opt<bool>
00051 Mips16HardFloat("mips16-hard-float", cl::NotHidden,
00052                 cl::desc("MIPS: mips16 hard float enable."),
00053                 cl::init(false));
00054 
00055 static cl::opt<bool>
00056 Mips16ConstantIslands(
00057   "mips16-constant-islands", cl::NotHidden,
00058   cl::desc("MIPS: mips16 constant islands enable."),
00059   cl::init(true));
00060 
00061 /// Select the Mips CPU for the given triple and cpu name.
00062 /// FIXME: Merge with the copy in MipsMCTargetDesc.cpp
00063 static StringRef selectMipsCPU(Triple TT, StringRef CPU) {
00064   if (CPU.empty() || CPU == "generic") {
00065     if (TT.getArch() == Triple::mips || TT.getArch() == Triple::mipsel)
00066       CPU = "mips32";
00067     else
00068       CPU = "mips64";
00069   }
00070   return CPU;
00071 }
00072 
00073 void MipsSubtarget::anchor() { }
00074 
00075 static std::string computeDataLayout(const MipsSubtarget &ST) {
00076   std::string Ret = "";
00077 
00078   // There are both little and big endian mips.
00079   if (ST.isLittle())
00080     Ret += "e";
00081   else
00082     Ret += "E";
00083 
00084   Ret += "-m:m";
00085 
00086   // Pointers are 32 bit on some ABIs.
00087   if (!ST.isABI_N64())
00088     Ret += "-p:32:32";
00089 
00090   // 8 and 16 bit integers only need no have natural alignment, but try to
00091   // align them to 32 bits. 64 bit integers have natural alignment.
00092   Ret += "-i8:8:32-i16:16:32-i64:64";
00093 
00094   // 32 bit registers are always available and the stack is at least 64 bit
00095   // aligned. On N64 64 bit registers are also available and the stack is
00096   // 128 bit aligned.
00097   if (ST.isABI_N64() || ST.isABI_N32())
00098     Ret += "-n32:64-S128";
00099   else
00100     Ret += "-n32-S64";
00101 
00102   return Ret;
00103 }
00104 
00105 MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
00106                              const std::string &FS, bool little,
00107                              MipsTargetMachine *_TM)
00108     : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(Mips32),
00109       MipsABI(UnknownABI), IsLittle(little), IsSingleFloat(false),
00110       IsFPXX(false), NoABICalls(false), IsFP64bit(false), UseOddSPReg(true),
00111       IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), HasCnMips(false),
00112       IsLinux(true), HasMips3_32(false), HasMips3_32r2(false),
00113       HasMips4_32(false), HasMips4_32r2(false), HasMips5_32r2(false),
00114       InMips16Mode(false), InMips16HardFloat(Mips16HardFloat),
00115       InMicroMipsMode(false), HasDSP(false), HasDSPR2(false),
00116       AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16),
00117       HasMSA(false), TM(_TM), TargetTriple(TT),
00118       DL(computeDataLayout(initializeSubtargetDependencies(CPU, FS, TM))),
00119       TSInfo(DL), InstrInfo(MipsInstrInfo::create(*this)),
00120       FrameLowering(MipsFrameLowering::create(*this)),
00121       TLInfo(MipsTargetLowering::create(*TM, *this)) {
00122 
00123   PreviousInMips16Mode = InMips16Mode;
00124 
00125   // Don't even attempt to generate code for MIPS-I, MIPS-II, MIPS-III, and
00126   // MIPS-V. They have not been tested and currently exist for the integrated
00127   // assembler only.
00128   if (MipsArchVersion == Mips1)
00129     report_fatal_error("Code generation for MIPS-I is not implemented", false);
00130   if (MipsArchVersion == Mips2)
00131     report_fatal_error("Code generation for MIPS-II is not implemented", false);
00132   if (MipsArchVersion == Mips3)
00133     report_fatal_error("Code generation for MIPS-III is not implemented",
00134                        false);
00135   if (MipsArchVersion == Mips5)
00136     report_fatal_error("Code generation for MIPS-V is not implemented", false);
00137 
00138   // Assert exactly one ABI was chosen.
00139   assert(MipsABI != UnknownABI);
00140   assert((((getFeatureBits() & Mips::FeatureO32) != 0) +
00141           ((getFeatureBits() & Mips::FeatureEABI) != 0) +
00142           ((getFeatureBits() & Mips::FeatureN32) != 0) +
00143           ((getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
00144 
00145   // Check if Architecture and ABI are compatible.
00146   assert(((!isGP64bit() && (isABI_O32() || isABI_EABI())) ||
00147           (isGP64bit() && (isABI_N32() || isABI_N64()))) &&
00148          "Invalid  Arch & ABI pair.");
00149 
00150   if (hasMSA() && !isFP64bit())
00151     report_fatal_error("MSA requires a 64-bit FPU register file (FR=1 mode). "
00152                        "See -mattr=+fp64.",
00153                        false);
00154 
00155   if (!isABI_O32() && !useOddSPReg())
00156     report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false);
00157 
00158   if (IsFPXX && (isABI_N32() || isABI_N64()))
00159     report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
00160 
00161   if (hasMips32r6()) {
00162     StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
00163 
00164     assert(isFP64bit());
00165     assert(isNaN2008());
00166     if (hasDSP())
00167       report_fatal_error(ISA + " is not compatible with the DSP ASE", false);
00168   }
00169 
00170   // Is the target system Linux ?
00171   if (TT.find("linux") == std::string::npos)
00172     IsLinux = false;
00173 
00174   // Set UseSmallSection.
00175   // TODO: Investigate the IsLinux check. I suspect it's really checking for
00176   //       bare-metal.
00177   UseSmallSection = !IsLinux && (TM->getRelocationModel() == Reloc::Static);
00178 }
00179 
00180 /// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
00181 bool MipsSubtarget::enablePostMachineScheduler() const { return true; }
00182 
00183 void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
00184   CriticalPathRCs.clear();
00185   CriticalPathRCs.push_back(isGP64bit() ?
00186                             &Mips::GPR64RegClass : &Mips::GPR32RegClass);
00187 }
00188 
00189 CodeGenOpt::Level MipsSubtarget::getOptLevelToEnablePostRAScheduler() const {
00190   return CodeGenOpt::Aggressive;
00191 }
00192 
00193 MipsSubtarget &
00194 MipsSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS,
00195                                                const TargetMachine *TM) {
00196   std::string CPUName = selectMipsCPU(TargetTriple, CPU);
00197   
00198   // Parse features string.
00199   ParseSubtargetFeatures(CPUName, FS);
00200   // Initialize scheduling itinerary for the specified CPU.
00201   InstrItins = getInstrItineraryForCPU(CPUName);
00202 
00203   if (InMips16Mode && !TM->Options.UseSoftFloat)
00204     InMips16HardFloat = true;
00205 
00206   return *this;
00207 }
00208 
00209 bool MipsSubtarget::abiUsesSoftFloat() const {
00210   return TM->Options.UseSoftFloat && !InMips16HardFloat;
00211 }
00212 
00213 bool MipsSubtarget::useConstantIslands() {
00214   DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands << "\n");
00215   return Mips16ConstantIslands;
00216 }
00217 
00218 Reloc::Model MipsSubtarget::getRelocationModel() const {
00219   return TM->getRelocationModel();
00220 }