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 static std::string computeDataLayout(const MipsSubtarget &ST) { 49 std::string Ret = ""; 50 51 // There are both little and big endian mips. 52 if (ST.isLittle()) 53 Ret += "e"; 54 else 55 Ret += "E"; 56 57 Ret += "-m:m"; 58 59 // Pointers are 32 bit on some ABIs. 60 if (!ST.isABI_N64()) 61 Ret += "-p:32:32"; 62 63 // 8 and 16 bit integers only need no have natural alignment, but try to 64 // align them to 32 bits. 64 bit integers have natural alignment. 65 Ret += "-i8:8:32-i16:16:32-i64:64"; 66 67 // 32 bit registers are always available and the stack is at least 64 bit 68 // aligned. On N64 64 bit registers are also available and the stack is 69 // 128 bit aligned. 70 if (ST.isABI_N64() || ST.isABI_N32()) 71 Ret += "-n32:64-S128"; 72 else 73 Ret += "-n32-S64"; 74 75 return Ret; 76 } 77 78 // On function prologue, the stack is created by decrementing 79 // its pointer. Once decremented, all references are done with positive 80 // offset from the stack/frame pointer, using StackGrowsUp enables 81 // an easier handling. 82 // Using CodeModel::Large enables different CALL behavior. 83 MipsTargetMachine::MipsTargetMachine(const Target &T, StringRef TT, 84 StringRef CPU, StringRef FS, 85 const TargetOptions &Options, 86 Reloc::Model RM, CodeModel::Model CM, 87 CodeGenOpt::Level OL, bool isLittle) 88 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 89 Subtarget(TT, CPU, FS, isLittle, RM, this), 90 DL(computeDataLayout(Subtarget)), InstrInfo(MipsInstrInfo::create(*this)), 91 FrameLowering(MipsFrameLowering::create(*this, Subtarget)), 92 TLInfo(MipsTargetLowering::create(*this)), TSInfo(DL) { 93 initAsmInfo(); 94 } 95 96 97 void MipsTargetMachine::setHelperClassesMips16() { 98 InstrInfoSE.swap(InstrInfo); 99 FrameLoweringSE.swap(FrameLowering); 100 TLInfoSE.swap(TLInfo); 101 if (!InstrInfo16) { 102 InstrInfo.reset(MipsInstrInfo::create(*this)); 103 FrameLowering.reset(MipsFrameLowering::create(*this, Subtarget)); 104 TLInfo.reset(MipsTargetLowering::create(*this)); 105 } else { 106 InstrInfo16.swap(InstrInfo); 107 FrameLowering16.swap(FrameLowering); 108 TLInfo16.swap(TLInfo); 109 } 110 assert(TLInfo && "null target lowering 16"); 111 assert(InstrInfo && "null instr info 16"); 112 assert(FrameLowering && "null frame lowering 16"); 113 } 114 115 void MipsTargetMachine::setHelperClassesMipsSE() { 116 InstrInfo16.swap(InstrInfo); 117 FrameLowering16.swap(FrameLowering); 118 TLInfo16.swap(TLInfo); 119 if (!InstrInfoSE) { 120 InstrInfo.reset(MipsInstrInfo::create(*this)); 121 FrameLowering.reset(MipsFrameLowering::create(*this, Subtarget)); 122 TLInfo.reset(MipsTargetLowering::create(*this)); 123 } else { 124 InstrInfoSE.swap(InstrInfo); 125 FrameLoweringSE.swap(FrameLowering); 126 TLInfoSE.swap(TLInfo); 127 } 128 assert(TLInfo && "null target lowering in SE"); 129 assert(InstrInfo && "null instr info SE"); 130 assert(FrameLowering && "null frame lowering SE"); 131 } 132 void MipsebTargetMachine::anchor() { } 133 134 MipsebTargetMachine:: 135 MipsebTargetMachine(const Target &T, StringRef TT, 136 StringRef CPU, StringRef FS, const TargetOptions &Options, 137 Reloc::Model RM, CodeModel::Model CM, 138 CodeGenOpt::Level OL) 139 : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 140 141 void MipselTargetMachine::anchor() { } 142 143 MipselTargetMachine:: 144 MipselTargetMachine(const Target &T, StringRef TT, 145 StringRef CPU, StringRef FS, const TargetOptions &Options, 146 Reloc::Model RM, CodeModel::Model CM, 147 CodeGenOpt::Level OL) 148 : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 149 150 namespace { 151 /// Mips Code Generator Pass Configuration Options. 152 class MipsPassConfig : public TargetPassConfig { 153 public: 154 MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM) 155 : TargetPassConfig(TM, PM) { 156 // The current implementation of long branch pass requires a scratch 157 // register ($at) to be available before branch instructions. Tail merging 158 // can break this requirement, so disable it when long branch pass is 159 // enabled. 160 EnableTailMerge = !getMipsSubtarget().enableLongBranchPass(); 161 } 162 163 MipsTargetMachine &getMipsTargetMachine() const { 164 return getTM<MipsTargetMachine>(); 165 } 166 167 const MipsSubtarget &getMipsSubtarget() const { 168 return *getMipsTargetMachine().getSubtargetImpl(); 169 } 170 171 void addIRPasses() override; 172 bool addInstSelector() override; 173 void addMachineSSAOptimization() override; 174 bool addPreEmitPass() override; 175 176 bool addPreRegAlloc() override; 177 178 }; 179 } // namespace 180 181 TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) { 182 return new MipsPassConfig(this, PM); 183 } 184 185 void MipsPassConfig::addIRPasses() { 186 TargetPassConfig::addIRPasses(); 187 if (getMipsSubtarget().os16()) 188 addPass(createMipsOs16(getMipsTargetMachine())); 189 if (getMipsSubtarget().inMips16HardFloat()) 190 addPass(createMips16HardFloat(getMipsTargetMachine())); 191 addPass(createPartiallyInlineLibCallsPass()); 192 } 193 // Install an instruction selector pass using 194 // the ISelDag to gen Mips code. 195 bool MipsPassConfig::addInstSelector() { 196 if (getMipsSubtarget().allowMixed16_32()) { 197 addPass(createMipsModuleISelDag(getMipsTargetMachine())); 198 addPass(createMips16ISelDag(getMipsTargetMachine())); 199 addPass(createMipsSEISelDag(getMipsTargetMachine())); 200 } else { 201 addPass(createMipsISelDag(getMipsTargetMachine())); 202 } 203 return false; 204 } 205 206 void MipsPassConfig::addMachineSSAOptimization() { 207 addPass(createMipsOptimizePICCallPass(getMipsTargetMachine())); 208 TargetPassConfig::addMachineSSAOptimization(); 209 } 210 211 bool MipsPassConfig::addPreRegAlloc() { 212 if (getOptLevel() == CodeGenOpt::None) { 213 addPass(createMipsOptimizePICCallPass(getMipsTargetMachine())); 214 return true; 215 } 216 else 217 return false; 218 } 219 220 void MipsTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 221 if (Subtarget.allowMixed16_32()) { 222 DEBUG(errs() << "No "); 223 //FIXME: The Basic Target Transform Info 224 // pass needs to become a function pass instead of 225 // being an immutable pass and then this method as it exists now 226 // would be unnecessary. 227 PM.add(createNoTargetTransformInfoPass()); 228 } else 229 LLVMTargetMachine::addAnalysisPasses(PM); 230 DEBUG(errs() << "Target Transform Info Pass Added\n"); 231 } 232 233 // Implemented by targets that want to run passes immediately before 234 // machine code is emitted. return true if -print-machineinstrs should 235 // print out the code after the passes. 236 bool MipsPassConfig::addPreEmitPass() { 237 MipsTargetMachine &TM = getMipsTargetMachine(); 238 const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); 239 addPass(createMipsDelaySlotFillerPass(TM)); 240 241 if (Subtarget.enableLongBranchPass()) 242 addPass(createMipsLongBranchPass(TM)); 243 if (Subtarget.inMips16Mode() || 244 Subtarget.allowMixed16_32()) 245 addPass(createMipsConstantIslandPass(TM)); 246 247 return true; 248 } 249 250 bool MipsTargetMachine::addCodeEmitter(PassManagerBase &PM, 251 JITCodeEmitter &JCE) { 252 // Machine code emitter pass for Mips. 253 PM.add(createMipsJITCodeEmitterPass(*this, JCE)); 254 return false; 255 } 256