Home | History | Annotate | Download | only in Mips
      1 //===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===//
      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 // Implements the info about Mips target spec.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "MipsTargetMachine.h"
     15 #include "Mips.h"
     16 #include "MipsFrameLowering.h"
     17 #include "MipsInstrInfo.h"
     18 #include "MipsModuleISelDAGToDAG.h"
     19 #include "MipsOs16.h"
     20 #include "MipsSEFrameLowering.h"
     21 #include "MipsSEInstrInfo.h"
     22 #include "MipsSEISelLowering.h"
     23 #include "MipsSEISelDAGToDAG.h"
     24 #include "Mips16FrameLowering.h"
     25 #include "Mips16HardFloat.h"
     26 #include "Mips16InstrInfo.h"
     27 #include "Mips16ISelDAGToDAG.h"
     28 #include "Mips16ISelLowering.h"
     29 #include "llvm/Analysis/TargetTransformInfo.h"
     30 #include "llvm/CodeGen/Passes.h"
     31 #include "llvm/PassManager.h"
     32 #include "llvm/Support/Debug.h"
     33 #include "llvm/Support/raw_ostream.h"
     34 #include "llvm/Support/TargetRegistry.h"
     35 using namespace llvm;
     36 
     37 
     38 
     39 extern "C" void LLVMInitializeMipsTarget() {
     40   // Register the target.
     41   RegisterTargetMachine<MipsebTargetMachine> X(TheMipsTarget);
     42   RegisterTargetMachine<MipselTargetMachine> Y(TheMipselTarget);
     43   RegisterTargetMachine<MipsebTargetMachine> A(TheMips64Target);
     44   RegisterTargetMachine<MipselTargetMachine> B(TheMips64elTarget);
     45 }
     46 
     47 // DataLayout --> Big-endian, 32-bit pointer/ABI/alignment
     48 // The stack is always 8 byte aligned
     49 // On function prologue, the stack is created by decrementing
     50 // its pointer. Once decremented, all references are done with positive
     51 // offset from the stack/frame pointer, using StackGrowsUp enables
     52 // an easier handling.
     53 // Using CodeModel::Large enables different CALL behavior.
     54 MipsTargetMachine::
     55 MipsTargetMachine(const Target &T, StringRef TT,
     56                   StringRef CPU, StringRef FS, const TargetOptions &Options,
     57                   Reloc::Model RM, CodeModel::Model CM,
     58                   CodeGenOpt::Level OL,
     59                   bool isLittle)
     60   : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
     61     Subtarget(TT, CPU, FS, isLittle, RM, this),
     62     DL(isLittle ?
     63                (Subtarget.isABI_N64() ?
     64                 "e-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-"
     65                 "n32:64-S128" :
     66                 "e-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32-S64") :
     67                (Subtarget.isABI_N64() ?
     68                 "E-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-"
     69                 "n32:64-S128" :
     70                 "E-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32-S64")),
     71     InstrInfo(MipsInstrInfo::create(*this)),
     72     FrameLowering(MipsFrameLowering::create(*this, Subtarget)),
     73     TLInfo(MipsTargetLowering::create(*this)), TSInfo(*this),
     74     InstrItins(Subtarget.getInstrItineraryData()), JITInfo() {
     75   initAsmInfo();
     76 }
     77 
     78 
     79 void MipsTargetMachine::setHelperClassesMips16() {
     80   InstrInfoSE.swap(InstrInfo);
     81   FrameLoweringSE.swap(FrameLowering);
     82   TLInfoSE.swap(TLInfo);
     83   if (!InstrInfo16) {
     84     InstrInfo.reset(MipsInstrInfo::create(*this));
     85     FrameLowering.reset(MipsFrameLowering::create(*this, Subtarget));
     86     TLInfo.reset(MipsTargetLowering::create(*this));
     87   } else {
     88     InstrInfo16.swap(InstrInfo);
     89     FrameLowering16.swap(FrameLowering);
     90     TLInfo16.swap(TLInfo);
     91   }
     92   assert(TLInfo && "null target lowering 16");
     93   assert(InstrInfo && "null instr info 16");
     94   assert(FrameLowering && "null frame lowering 16");
     95 }
     96 
     97 void MipsTargetMachine::setHelperClassesMipsSE() {
     98   InstrInfo16.swap(InstrInfo);
     99   FrameLowering16.swap(FrameLowering);
    100   TLInfo16.swap(TLInfo);
    101   if (!InstrInfoSE) {
    102     InstrInfo.reset(MipsInstrInfo::create(*this));
    103     FrameLowering.reset(MipsFrameLowering::create(*this, Subtarget));
    104     TLInfo.reset(MipsTargetLowering::create(*this));
    105   } else {
    106     InstrInfoSE.swap(InstrInfo);
    107     FrameLoweringSE.swap(FrameLowering);
    108     TLInfoSE.swap(TLInfo);
    109   }
    110   assert(TLInfo && "null target lowering in SE");
    111   assert(InstrInfo && "null instr info SE");
    112   assert(FrameLowering && "null frame lowering SE");
    113 }
    114 void MipsebTargetMachine::anchor() { }
    115 
    116 MipsebTargetMachine::
    117 MipsebTargetMachine(const Target &T, StringRef TT,
    118                     StringRef CPU, StringRef FS, const TargetOptions &Options,
    119                     Reloc::Model RM, CodeModel::Model CM,
    120                     CodeGenOpt::Level OL)
    121   : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
    122 
    123 void MipselTargetMachine::anchor() { }
    124 
    125 MipselTargetMachine::
    126 MipselTargetMachine(const Target &T, StringRef TT,
    127                     StringRef CPU, StringRef FS, const TargetOptions &Options,
    128                     Reloc::Model RM, CodeModel::Model CM,
    129                     CodeGenOpt::Level OL)
    130   : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
    131 
    132 namespace {
    133 /// Mips Code Generator Pass Configuration Options.
    134 class MipsPassConfig : public TargetPassConfig {
    135 public:
    136   MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM)
    137     : TargetPassConfig(TM, PM) {}
    138 
    139   MipsTargetMachine &getMipsTargetMachine() const {
    140     return getTM<MipsTargetMachine>();
    141   }
    142 
    143   const MipsSubtarget &getMipsSubtarget() const {
    144     return *getMipsTargetMachine().getSubtargetImpl();
    145   }
    146 
    147   virtual void addIRPasses();
    148   virtual bool addInstSelector();
    149   virtual bool addPreEmitPass();
    150 };
    151 } // namespace
    152 
    153 TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
    154   return new MipsPassConfig(this, PM);
    155 }
    156 
    157 void MipsPassConfig::addIRPasses() {
    158   TargetPassConfig::addIRPasses();
    159   if (getMipsSubtarget().os16())
    160     addPass(createMipsOs16(getMipsTargetMachine()));
    161   if (getMipsSubtarget().inMips16HardFloat())
    162     addPass(createMips16HardFloat(getMipsTargetMachine()));
    163   addPass(createMipsOptimizeMathLibCalls(getMipsTargetMachine()));
    164 }
    165 // Install an instruction selector pass using
    166 // the ISelDag to gen Mips code.
    167 bool MipsPassConfig::addInstSelector() {
    168   if (getMipsSubtarget().allowMixed16_32()) {
    169     addPass(createMipsModuleISelDag(getMipsTargetMachine()));
    170     addPass(createMips16ISelDag(getMipsTargetMachine()));
    171     addPass(createMipsSEISelDag(getMipsTargetMachine()));
    172   } else {
    173     addPass(createMipsISelDag(getMipsTargetMachine()));
    174   }
    175   return false;
    176 }
    177 
    178 void MipsTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
    179   if (Subtarget.allowMixed16_32()) {
    180     DEBUG(errs() << "No ");
    181     //FIXME: The Basic Target Transform Info
    182     // pass needs to become a function pass instead of
    183     // being an immutable pass and then this method as it exists now
    184     // would be unnecessary.
    185     PM.add(createNoTargetTransformInfoPass());
    186   } else
    187     LLVMTargetMachine::addAnalysisPasses(PM);
    188   DEBUG(errs() << "Target Transform Info Pass Added\n");
    189 }
    190 
    191 // Implemented by targets that want to run passes immediately before
    192 // machine code is emitted. return true if -print-machineinstrs should
    193 // print out the code after the passes.
    194 bool MipsPassConfig::addPreEmitPass() {
    195   MipsTargetMachine &TM = getMipsTargetMachine();
    196   const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
    197   addPass(createMipsDelaySlotFillerPass(TM));
    198 
    199   if (Subtarget.hasStandardEncoding() ||
    200       Subtarget.allowMixed16_32())
    201     addPass(createMipsLongBranchPass(TM));
    202   if (Subtarget.inMips16Mode() ||
    203       Subtarget.allowMixed16_32())
    204     addPass(createMipsConstantIslandPass(TM));
    205 
    206   return true;
    207 }
    208 
    209 bool MipsTargetMachine::addCodeEmitter(PassManagerBase &PM,
    210                                        JITCodeEmitter &JCE) {
    211   // Machine code emitter pass for Mips.
    212   PM.add(createMipsJITCodeEmitterPass(*this, JCE));
    213   return false;
    214 }
    215