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 "Mips16FrameLowering.h" 17 #include "Mips16HardFloat.h" 18 #include "Mips16ISelDAGToDAG.h" 19 #include "Mips16ISelLowering.h" 20 #include "Mips16InstrInfo.h" 21 #include "MipsFrameLowering.h" 22 #include "MipsInstrInfo.h" 23 #include "MipsModuleISelDAGToDAG.h" 24 #include "MipsOs16.h" 25 #include "MipsSEFrameLowering.h" 26 #include "MipsSEISelDAGToDAG.h" 27 #include "MipsSEISelLowering.h" 28 #include "MipsSEInstrInfo.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/TargetRegistry.h" 34 #include "llvm/Support/raw_ostream.h" 35 #include "llvm/Transforms/Scalar.h" 36 using namespace llvm; 37 38 #define DEBUG_TYPE "mips" 39 40 extern "C" void LLVMInitializeMipsTarget() { 41 // Register the target. 42 RegisterTargetMachine<MipsebTargetMachine> X(TheMipsTarget); 43 RegisterTargetMachine<MipselTargetMachine> Y(TheMipselTarget); 44 RegisterTargetMachine<MipsebTargetMachine> A(TheMips64Target); 45 RegisterTargetMachine<MipselTargetMachine> B(TheMips64elTarget); 46 } 47 48 // On function prologue, the stack is created by decrementing 49 // its pointer. Once decremented, all references are done with positive 50 // offset from the stack/frame pointer, using StackGrowsUp enables 51 // an easier handling. 52 // Using CodeModel::Large enables different CALL behavior. 53 MipsTargetMachine::MipsTargetMachine(const Target &T, StringRef TT, 54 StringRef CPU, StringRef FS, 55 const TargetOptions &Options, 56 Reloc::Model RM, CodeModel::Model CM, 57 CodeGenOpt::Level OL, bool isLittle) 58 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 59 Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, this), 60 NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", 61 isLittle, this), 62 Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16", 63 isLittle, this) { 64 Subtarget = &DefaultSubtarget; 65 initAsmInfo(); 66 } 67 68 void MipsebTargetMachine::anchor() { } 69 70 MipsebTargetMachine:: 71 MipsebTargetMachine(const Target &T, StringRef TT, 72 StringRef CPU, StringRef FS, const TargetOptions &Options, 73 Reloc::Model RM, CodeModel::Model CM, 74 CodeGenOpt::Level OL) 75 : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 76 77 void MipselTargetMachine::anchor() { } 78 79 MipselTargetMachine:: 80 MipselTargetMachine(const Target &T, StringRef TT, 81 StringRef CPU, StringRef FS, const TargetOptions &Options, 82 Reloc::Model RM, CodeModel::Model CM, 83 CodeGenOpt::Level OL) 84 : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 85 86 void MipsTargetMachine::resetSubtarget(MachineFunction *MF) { 87 DEBUG(dbgs() << "resetSubtarget\n"); 88 AttributeSet FnAttrs = MF->getFunction()->getAttributes(); 89 bool Mips16Attr = FnAttrs.hasAttribute(AttributeSet::FunctionIndex, "mips16"); 90 bool NoMips16Attr = 91 FnAttrs.hasAttribute(AttributeSet::FunctionIndex, "nomips16"); 92 assert(!(Mips16Attr && NoMips16Attr) && 93 "mips16 and nomips16 specified on the same function"); 94 if (Mips16Attr) 95 Subtarget = &Mips16Subtarget; 96 else if (NoMips16Attr) 97 Subtarget = &NoMips16Subtarget; 98 else 99 Subtarget = &DefaultSubtarget; 100 MF->setSubtarget(Subtarget); 101 return; 102 } 103 104 namespace { 105 /// Mips Code Generator Pass Configuration Options. 106 class MipsPassConfig : public TargetPassConfig { 107 public: 108 MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM) 109 : TargetPassConfig(TM, PM) { 110 // The current implementation of long branch pass requires a scratch 111 // register ($at) to be available before branch instructions. Tail merging 112 // can break this requirement, so disable it when long branch pass is 113 // enabled. 114 EnableTailMerge = !getMipsSubtarget().enableLongBranchPass(); 115 } 116 117 MipsTargetMachine &getMipsTargetMachine() const { 118 return getTM<MipsTargetMachine>(); 119 } 120 121 const MipsSubtarget &getMipsSubtarget() const { 122 return *getMipsTargetMachine().getSubtargetImpl(); 123 } 124 125 void addIRPasses() override; 126 bool addInstSelector() override; 127 void addMachineSSAOptimization() override; 128 bool addPreEmitPass() override; 129 130 bool addPreRegAlloc() override; 131 132 }; 133 } // namespace 134 135 TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) { 136 return new MipsPassConfig(this, PM); 137 } 138 139 void MipsPassConfig::addIRPasses() { 140 TargetPassConfig::addIRPasses(); 141 if (getMipsSubtarget().os16()) 142 addPass(createMipsOs16(getMipsTargetMachine())); 143 if (getMipsSubtarget().inMips16HardFloat()) 144 addPass(createMips16HardFloat(getMipsTargetMachine())); 145 } 146 // Install an instruction selector pass using 147 // the ISelDag to gen Mips code. 148 bool MipsPassConfig::addInstSelector() { 149 addPass(createMipsModuleISelDag(getMipsTargetMachine())); 150 addPass(createMips16ISelDag(getMipsTargetMachine())); 151 addPass(createMipsSEISelDag(getMipsTargetMachine())); 152 return false; 153 } 154 155 void MipsPassConfig::addMachineSSAOptimization() { 156 addPass(createMipsOptimizePICCallPass(getMipsTargetMachine())); 157 TargetPassConfig::addMachineSSAOptimization(); 158 } 159 160 bool MipsPassConfig::addPreRegAlloc() { 161 if (getOptLevel() == CodeGenOpt::None) { 162 addPass(createMipsOptimizePICCallPass(getMipsTargetMachine())); 163 return true; 164 } 165 else 166 return false; 167 } 168 169 void MipsTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 170 if (Subtarget->allowMixed16_32()) { 171 DEBUG(errs() << "No "); 172 //FIXME: The Basic Target Transform Info 173 // pass needs to become a function pass instead of 174 // being an immutable pass and then this method as it exists now 175 // would be unnecessary. 176 PM.add(createNoTargetTransformInfoPass()); 177 } else 178 LLVMTargetMachine::addAnalysisPasses(PM); 179 DEBUG(errs() << "Target Transform Info Pass Added\n"); 180 } 181 182 // Implemented by targets that want to run passes immediately before 183 // machine code is emitted. return true if -print-machineinstrs should 184 // print out the code after the passes. 185 bool MipsPassConfig::addPreEmitPass() { 186 MipsTargetMachine &TM = getMipsTargetMachine(); 187 addPass(createMipsDelaySlotFillerPass(TM)); 188 addPass(createMipsLongBranchPass(TM)); 189 addPass(createMipsConstantIslandPass(TM)); 190 return true; 191 } 192 193 bool MipsTargetMachine::addCodeEmitter(PassManagerBase &PM, 194 JITCodeEmitter &JCE) { 195 // Machine code emitter pass for Mips. 196 PM.add(createMipsJITCodeEmitterPass(*this, JCE)); 197 return false; 198 } 199