1 //===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===// 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 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ARMTargetMachine.h" 14 #include "ARMMCAsmInfo.h" 15 #include "ARMFrameLowering.h" 16 #include "ARM.h" 17 #include "llvm/PassManager.h" 18 #include "llvm/CodeGen/Passes.h" 19 #include "llvm/Support/CommandLine.h" 20 #include "llvm/Support/FormattedStream.h" 21 #include "llvm/Target/TargetOptions.h" 22 #include "llvm/Target/TargetRegistry.h" 23 using namespace llvm; 24 25 static cl::opt<bool>ExpandMLx("expand-fp-mlx", cl::init(false), cl::Hidden); 26 27 static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) { 28 Triple TheTriple(TT); 29 switch (TheTriple.getOS()) { 30 case Triple::Darwin: 31 return new ARMMCAsmInfoDarwin(); 32 default: 33 return new ARMELFMCAsmInfo(); 34 } 35 } 36 37 // This is duplicated code. Refactor this. 38 static MCStreamer *createMCStreamer(const Target &T, const std::string &TT, 39 MCContext &Ctx, TargetAsmBackend &TAB, 40 raw_ostream &OS, 41 MCCodeEmitter *Emitter, 42 bool RelaxAll, 43 bool NoExecStack) { 44 switch (Triple(TT).getOS()) { 45 case Triple::Darwin: 46 return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll); 47 case Triple::MinGW32: 48 case Triple::MinGW64: 49 case Triple::Cygwin: 50 case Triple::Win32: 51 llvm_unreachable("ARM does not support Windows COFF format"); 52 return NULL; 53 default: 54 return createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll, NoExecStack); 55 } 56 } 57 58 extern "C" void LLVMInitializeARMTarget() { 59 // Register the target. 60 RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget); 61 RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget); 62 63 // Register the target asm info. 64 RegisterAsmInfoFn A(TheARMTarget, createMCAsmInfo); 65 RegisterAsmInfoFn B(TheThumbTarget, createMCAsmInfo); 66 67 // Register the MC Code Emitter 68 TargetRegistry::RegisterCodeEmitter(TheARMTarget, createARMMCCodeEmitter); 69 TargetRegistry::RegisterCodeEmitter(TheThumbTarget, createARMMCCodeEmitter); 70 71 // Register the asm backend. 72 TargetRegistry::RegisterAsmBackend(TheARMTarget, createARMAsmBackend); 73 TargetRegistry::RegisterAsmBackend(TheThumbTarget, createARMAsmBackend); 74 75 // Register the object streamer. 76 TargetRegistry::RegisterObjectStreamer(TheARMTarget, createMCStreamer); 77 TargetRegistry::RegisterObjectStreamer(TheThumbTarget, createMCStreamer); 78 79 } 80 81 /// TargetMachine ctor - Create an ARM architecture model. 82 /// 83 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, 84 const std::string &TT, 85 const std::string &FS, 86 bool isThumb) 87 : LLVMTargetMachine(T, TT), 88 Subtarget(TT, FS, isThumb), 89 JITInfo(), 90 InstrItins(Subtarget.getInstrItineraryData()) 91 { 92 DefRelocModel = getRelocationModel(); 93 } 94 95 ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT, 96 const std::string &FS) 97 : ARMBaseTargetMachine(T, TT, FS, false), InstrInfo(Subtarget), 98 DataLayout(Subtarget.isAPCS_ABI() ? 99 std::string("e-p:32:32-f64:32:64-i64:32:64-" 100 "v128:32:128-v64:32:64-n32") : 101 std::string("e-p:32:32-f64:64:64-i64:64:64-" 102 "v128:64:128-v64:64:64-n32")), 103 ELFWriterInfo(*this), 104 TLInfo(*this), 105 TSInfo(*this), 106 FrameLowering(Subtarget) { 107 if (!Subtarget.hasARMOps()) 108 report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not " 109 "support ARM mode execution!"); 110 } 111 112 ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT, 113 const std::string &FS) 114 : ARMBaseTargetMachine(T, TT, FS, true), 115 InstrInfo(Subtarget.hasThumb2() 116 ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget)) 117 : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))), 118 DataLayout(Subtarget.isAPCS_ABI() ? 119 std::string("e-p:32:32-f64:32:64-i64:32:64-" 120 "i16:16:32-i8:8:32-i1:8:32-" 121 "v128:32:128-v64:32:64-a:0:32-n32") : 122 std::string("e-p:32:32-f64:64:64-i64:64:64-" 123 "i16:16:32-i8:8:32-i1:8:32-" 124 "v128:64:128-v64:64:64-a:0:32-n32")), 125 ELFWriterInfo(*this), 126 TLInfo(*this), 127 TSInfo(*this), 128 FrameLowering(Subtarget.hasThumb2() 129 ? new ARMFrameLowering(Subtarget) 130 : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) { 131 } 132 133 // Pass Pipeline Configuration 134 bool ARMBaseTargetMachine::addPreISel(PassManagerBase &PM, 135 CodeGenOpt::Level OptLevel) { 136 if (OptLevel != CodeGenOpt::None) 137 PM.add(createARMGlobalMergePass(getTargetLowering())); 138 139 return false; 140 } 141 142 bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM, 143 CodeGenOpt::Level OptLevel) { 144 PM.add(createARMISelDag(*this, OptLevel)); 145 return false; 146 } 147 148 bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM, 149 CodeGenOpt::Level OptLevel) { 150 // FIXME: temporarily disabling load / store optimization pass for Thumb1. 151 if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only()) 152 PM.add(createARMLoadStoreOptimizationPass(true)); 153 if (ExpandMLx && 154 OptLevel != CodeGenOpt::None && Subtarget.hasVFP2()) 155 PM.add(createMLxExpansionPass()); 156 157 return true; 158 } 159 160 bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM, 161 CodeGenOpt::Level OptLevel) { 162 // FIXME: temporarily disabling load / store optimization pass for Thumb1. 163 if (OptLevel != CodeGenOpt::None) { 164 if (!Subtarget.isThumb1Only()) 165 PM.add(createARMLoadStoreOptimizationPass()); 166 if (Subtarget.hasNEON()) 167 PM.add(createNEONMoveFixPass()); 168 } 169 170 // Expand some pseudo instructions into multiple instructions to allow 171 // proper scheduling. 172 PM.add(createARMExpandPseudoPass()); 173 174 if (OptLevel != CodeGenOpt::None) { 175 if (!Subtarget.isThumb1Only()) 176 PM.add(createIfConverterPass()); 177 } 178 if (Subtarget.isThumb2()) 179 PM.add(createThumb2ITBlockPass()); 180 181 return true; 182 } 183 184 bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM, 185 CodeGenOpt::Level OptLevel) { 186 if (Subtarget.isThumb2() && !Subtarget.prefers32BitThumb()) 187 PM.add(createThumb2SizeReductionPass()); 188 189 PM.add(createARMConstantIslandPass()); 190 return true; 191 } 192 193 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 194 CodeGenOpt::Level OptLevel, 195 JITCodeEmitter &JCE) { 196 // FIXME: Move this to TargetJITInfo! 197 if (DefRelocModel == Reloc::Default) 198 setRelocationModel(Reloc::Static); 199 200 // Machine code emitter pass for ARM. 201 PM.add(createARMJITCodeEmitterPass(*this, JCE)); 202 return false; 203 } 204