MipsTargetMachine.cpp revision cdb3ba71ce550c5a41c84c3678225a39d6f0a414
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 "Mips16InstrInfo.h"
18#include "MipsSEFrameLowering.h"
19#include "MipsSEInstrInfo.h"
20#include "llvm/PassManager.h"
21#include "llvm/CodeGen/Passes.h"
22#include "llvm/Support/TargetRegistry.h"
23using namespace llvm;
24
25extern "C" void LLVMInitializeMipsTarget() {
26  // Register the target.
27  RegisterTargetMachine<MipsebTargetMachine> X(TheMipsTarget);
28  RegisterTargetMachine<MipselTargetMachine> Y(TheMipselTarget);
29  RegisterTargetMachine<MipsebTargetMachine> A(TheMips64Target);
30  RegisterTargetMachine<MipselTargetMachine> B(TheMips64elTarget);
31}
32
33static const MipsInstrInfo *genInstrInfo(MipsTargetMachine &TM) {
34  const MipsInstrInfo *II;
35
36  if (TM.getSubtargetImpl()->inMips16Mode())
37    II = new Mips16InstrInfo(TM);
38  else
39    II = new MipsSEInstrInfo(TM);
40
41  return II;
42}
43
44static const MipsFrameLowering *genFrameLowering(MipsTargetMachine &TM,
45                                                 const MipsSubtarget &ST) {
46  const MipsFrameLowering *FL;
47
48  if (TM.getSubtargetImpl()->inMips16Mode())
49    FL = new Mips16FrameLowering(ST);
50  else
51    FL = new MipsSEFrameLowering(ST);
52
53  return FL;
54}
55
56// DataLayout --> Big-endian, 32-bit pointer/ABI/alignment
57// The stack is always 8 byte aligned
58// On function prologue, the stack is created by decrementing
59// its pointer. Once decremented, all references are done with positive
60// offset from the stack/frame pointer, using StackGrowsUp enables
61// an easier handling.
62// Using CodeModel::Large enables different CALL behavior.
63MipsTargetMachine::
64MipsTargetMachine(const Target &T, StringRef TT,
65                  StringRef CPU, StringRef FS, const TargetOptions &Options,
66                  Reloc::Model RM, CodeModel::Model CM,
67                  CodeGenOpt::Level OL,
68                  bool isLittle)
69  : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
70    Subtarget(TT, CPU, FS, isLittle),
71    DataLayout(isLittle ?
72               (Subtarget.isABI_N64() ?
73                "e-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-n32" :
74                "e-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32") :
75               (Subtarget.isABI_N64() ?
76                "E-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-n32" :
77                "E-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32")),
78    InstrInfo(genInstrInfo(*this)),
79    FrameLowering(genFrameLowering(*this, Subtarget)),
80    TLInfo(*this), TSInfo(*this), JITInfo() {
81}
82
83void MipsebTargetMachine::anchor() { }
84
85MipsebTargetMachine::
86MipsebTargetMachine(const Target &T, StringRef TT,
87                    StringRef CPU, StringRef FS, const TargetOptions &Options,
88                    Reloc::Model RM, CodeModel::Model CM,
89                    CodeGenOpt::Level OL)
90  : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
91
92void MipselTargetMachine::anchor() { }
93
94MipselTargetMachine::
95MipselTargetMachine(const Target &T, StringRef TT,
96                    StringRef CPU, StringRef FS, const TargetOptions &Options,
97                    Reloc::Model RM, CodeModel::Model CM,
98                    CodeGenOpt::Level OL)
99  : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
100
101namespace {
102/// Mips Code Generator Pass Configuration Options.
103class MipsPassConfig : public TargetPassConfig {
104public:
105  MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM)
106    : TargetPassConfig(TM, PM) {}
107
108  MipsTargetMachine &getMipsTargetMachine() const {
109    return getTM<MipsTargetMachine>();
110  }
111
112  const MipsSubtarget &getMipsSubtarget() const {
113    return *getMipsTargetMachine().getSubtargetImpl();
114  }
115
116  virtual bool addInstSelector();
117  virtual bool addPreEmitPass();
118};
119} // namespace
120
121TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
122  return new MipsPassConfig(this, PM);
123}
124
125// Install an instruction selector pass using
126// the ISelDag to gen Mips code.
127bool MipsPassConfig::addInstSelector() {
128  addPass(createMipsISelDag(getMipsTargetMachine()));
129  return false;
130}
131
132// Implemented by targets that want to run passes immediately before
133// machine code is emitted. return true if -print-machineinstrs should
134// print out the code after the passes.
135bool MipsPassConfig::addPreEmitPass() {
136  MipsTargetMachine &TM = getMipsTargetMachine();
137  addPass(createMipsDelaySlotFillerPass(TM));
138
139  // NOTE: long branch has not been implemented for mips16.
140  if (TM.getSubtarget<MipsSubtarget>().hasStandardEncoding())
141    addPass(createMipsLongBranchPass(TM));
142
143  return true;
144}
145
146bool MipsTargetMachine::addCodeEmitter(PassManagerBase &PM,
147                                       JITCodeEmitter &JCE) {
148  // Machine code emitter pass for Mips.
149  PM.add(createMipsJITCodeEmitterPass(*this, JCE));
150  return false;
151}
152