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