Home | History | Annotate | Download | only in Mips
      1 //===-- MipsSubtarget.cpp - Mips Subtarget Information --------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the Mips specific subclass of TargetSubtargetInfo.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #define DEBUG_TYPE "mips-subtarget"
     15 
     16 #include "MipsMachineFunction.h"
     17 #include "MipsSubtarget.h"
     18 #include "MipsTargetMachine.h"
     19 #include "Mips.h"
     20 #include "MipsRegisterInfo.h"
     21 #include "llvm/IR/Attributes.h"
     22 #include "llvm/IR/Function.h"
     23 #include "llvm/Support/CommandLine.h"
     24 #include "llvm/Support/Debug.h"
     25 #include "llvm/Support/TargetRegistry.h"
     26 #include "llvm/Support/raw_ostream.h"
     27 
     28 #define GET_SUBTARGETINFO_TARGET_DESC
     29 #define GET_SUBTARGETINFO_CTOR
     30 #include "MipsGenSubtargetInfo.inc"
     31 
     32 
     33 using namespace llvm;
     34 
     35 // FIXME: Maybe this should be on by default when Mips16 is specified
     36 //
     37 static cl::opt<bool> Mixed16_32(
     38   "mips-mixed-16-32",
     39   cl::init(false),
     40   cl::desc("Allow for a mixture of Mips16 "
     41            "and Mips32 code in a single source file"),
     42   cl::Hidden);
     43 
     44 static cl::opt<bool> Mips_Os16(
     45   "mips-os16",
     46   cl::init(false),
     47   cl::desc("Compile all functions that don' use "
     48            "floating point as Mips 16"),
     49   cl::Hidden);
     50 
     51 static cl::opt<bool>
     52 Mips16HardFloat("mips16-hard-float", cl::NotHidden,
     53                 cl::desc("MIPS: mips16 hard float enable."),
     54                 cl::init(false));
     55 
     56 void MipsSubtarget::anchor() { }
     57 
     58 MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
     59                              const std::string &FS, bool little,
     60                              Reloc::Model _RM, MipsTargetMachine *_TM) :
     61   MipsGenSubtargetInfo(TT, CPU, FS),
     62   MipsArchVersion(Mips32), MipsABI(UnknownABI), IsLittle(little),
     63   IsSingleFloat(false), IsFP64bit(false), IsGP64bit(false), HasVFPU(false),
     64   IsLinux(true), HasSEInReg(false), HasCondMov(false), HasSwap(false),
     65   HasBitCount(false), HasFPIdx(false),
     66   InMips16Mode(false), InMips16HardFloat(Mips16HardFloat),
     67   InMicroMipsMode(false), HasDSP(false), HasDSPR2(false),
     68   AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16),
     69   RM(_RM), OverrideMode(NoOverride), TM(_TM)
     70 {
     71   std::string CPUName = CPU;
     72   if (CPUName.empty())
     73     CPUName = "mips32";
     74 
     75   // Parse features string.
     76   ParseSubtargetFeatures(CPUName, FS);
     77 
     78   PreviousInMips16Mode = InMips16Mode;
     79 
     80   // Initialize scheduling itinerary for the specified CPU.
     81   InstrItins = getInstrItineraryForCPU(CPUName);
     82 
     83   // Set MipsABI if it hasn't been set yet.
     84   if (MipsABI == UnknownABI)
     85     MipsABI = hasMips64() ? N64 : O32;
     86 
     87   // Check if Architecture and ABI are compatible.
     88   assert(((!hasMips64() && (isABI_O32() || isABI_EABI())) ||
     89           (hasMips64() && (isABI_N32() || isABI_N64()))) &&
     90          "Invalid  Arch & ABI pair.");
     91 
     92   // Is the target system Linux ?
     93   if (TT.find("linux") == std::string::npos)
     94     IsLinux = false;
     95 
     96   // Set UseSmallSection.
     97   UseSmallSection = !IsLinux && (RM == Reloc::Static);
     98 }
     99 
    100 bool
    101 MipsSubtarget::enablePostRAScheduler(CodeGenOpt::Level OptLevel,
    102                                     TargetSubtargetInfo::AntiDepBreakMode &Mode,
    103                                      RegClassVector &CriticalPathRCs) const {
    104   Mode = TargetSubtargetInfo::ANTIDEP_NONE;
    105   CriticalPathRCs.clear();
    106   CriticalPathRCs.push_back(hasMips64() ?
    107                             &Mips::GPR64RegClass : &Mips::GPR32RegClass);
    108   return OptLevel >= CodeGenOpt::Aggressive;
    109 }
    110 
    111 //FIXME: This logic for reseting the subtarget along with
    112 // the helper classes can probably be simplified but there are a lot of
    113 // cases so we will defer rewriting this to later.
    114 //
    115 void MipsSubtarget::resetSubtarget(MachineFunction *MF) {
    116   bool ChangeToMips16 = false, ChangeToNoMips16 = false;
    117   DEBUG(dbgs() << "resetSubtargetFeatures" << "\n");
    118   AttributeSet FnAttrs = MF->getFunction()->getAttributes();
    119   ChangeToMips16 = FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
    120                                         "mips16");
    121   ChangeToNoMips16 = FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
    122                                         "nomips16");
    123   assert (!(ChangeToMips16 & ChangeToNoMips16) &&
    124           "mips16 and nomips16 specified on the same function");
    125   if (ChangeToMips16) {
    126     if (PreviousInMips16Mode)
    127       return;
    128     OverrideMode = Mips16Override;
    129     PreviousInMips16Mode = true;
    130     TM->setHelperClassesMips16();
    131     return;
    132   } else if (ChangeToNoMips16) {
    133     if (!PreviousInMips16Mode)
    134       return;
    135     OverrideMode = NoMips16Override;
    136     PreviousInMips16Mode = false;
    137     TM->setHelperClassesMipsSE();
    138     return;
    139   } else {
    140     if (OverrideMode == NoOverride)
    141       return;
    142     OverrideMode = NoOverride;
    143     DEBUG(dbgs() << "back to default" << "\n");
    144     if (inMips16Mode() && !PreviousInMips16Mode) {
    145       TM->setHelperClassesMips16();
    146       PreviousInMips16Mode = true;
    147     } else if (!inMips16Mode() && PreviousInMips16Mode) {
    148       TM->setHelperClassesMipsSE();
    149       PreviousInMips16Mode = false;
    150     }
    151     return;
    152   }
    153 }
    154 
    155