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