1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===//
2972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
3972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//                     The LLVM Compiler Infrastructure
4972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
84552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
9972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
10972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// Implements the info about Mips target spec.
11972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes//
124552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
13972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
14972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "MipsTargetMachine.h"
1579aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "Mips.h"
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Mips16FrameLowering.h"
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Mips16ISelDAGToDAG.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Mips16ISelLowering.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Mips16InstrInfo.h"
20af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanaka#include "MipsFrameLowering.h"
21af2662606745bdebaa2cb43096274ce3d33b665fAkira Hatanaka#include "MipsInstrInfo.h"
22a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler#include "MipsSEFrameLowering.h"
23a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler#include "MipsSEISelDAGToDAG.h"
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MipsSEISelLowering.h"
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MipsSEInstrInfo.h"
2637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "MipsTargetObjectFile.h"
27a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler#include "llvm/Analysis/TargetTransformInfo.h"
28843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick#include "llvm/CodeGen/Passes.h"
29ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LegacyPassManager.h"
30a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler#include "llvm/Support/Debug.h"
313e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/raw_ostream.h"
33a8a7099c1849fcbb4a68642a292fd0250aa46505Richard Sandiford#include "llvm/Transforms/Scalar.h"
344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
35972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopesusing namespace llvm;
36972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mips"
38a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler
390c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbarextern "C" void LLVMInitializeMipsTarget() {
400c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar  // Register the target.
412464810ac27af8dd8b11da7519b719c254854c19Akira Hatanaka  RegisterTargetMachine<MipsebTargetMachine> X(TheMipsTarget);
42e2c74081998af2e64ed498d65cf501704796ccc0Eli Friedman  RegisterTargetMachine<MipselTargetMachine> Y(TheMipselTarget);
43b4f921b1f0ae34d6cfda6034a7d32c73b0738351Akira Hatanaka  RegisterTargetMachine<MipsebTargetMachine> A(TheMips64Target);
44b4f921b1f0ae34d6cfda6034a7d32c73b0738351Akira Hatanaka  RegisterTargetMachine<MipselTargetMachine> B(TheMips64elTarget);
45972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
46972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic std::string computeDataLayout(const Triple &TT, StringRef CPU,
484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                     const TargetOptions &Options,
494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                     bool isLittle) {
50ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::string Ret = "";
516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions);
52ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
53ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // There are both little and big endian mips.
54ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (isLittle)
55ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Ret += "e";
56ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
57ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Ret += "E";
58ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
59ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Ret += "-m:m";
60ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
61ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Pointers are 32 bit on some ABIs.
62ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!ABI.IsN64())
63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Ret += "-p:32:32";
64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
65cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // 8 and 16 bit integers only need to have natural alignment, but try to
66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // align them to 32 bits. 64 bit integers have natural alignment.
67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Ret += "-i8:8:32-i16:16:32-i64:64";
68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // 32 bit registers are always available and the stack is at least 64 bit
70ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // aligned. On N64 64 bit registers are also available and the stack is
71ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // 128 bit aligned.
72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ABI.IsN64() || ABI.IsN32())
73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Ret += "-n32:64-S128";
74ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Ret += "-n32-S64";
76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return Ret;
78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8051195af45f4142035f23c7d58d1311face3900a4Bruno Cardoso Lopes// On function prologue, the stack is created by decrementing
8151195af45f4142035f23c7d58d1311face3900a4Bruno Cardoso Lopes// its pointer. Once decremented, all references are done with positive
8233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// offset from the stack/frame pointer, using StackGrowsUp enables
83bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes// an easier handling.
84225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes// Using CodeModel::Large enables different CALL behavior.
856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarMipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT,
86c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                     StringRef CPU, StringRef FS,
87c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                     const TargetOptions &Options,
88c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                     Reloc::Model RM, CodeModel::Model CM,
89c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                     CodeGenOpt::Level OL, bool isLittle)
904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                        CPU, FS, Options, RM, CM, OL),
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      isLittle(isLittle), TLOF(make_unique<MipsTargetObjectFile>()),
936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)),
944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this),
9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16",
96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                        isLittle, *this),
9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16",
98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                      isLittle, *this) {
9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Subtarget = &DefaultSubtarget;
1004a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola  initAsmInfo();
101a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler}
102a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler
10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMipsTargetMachine::~MipsTargetMachine() {}
10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1052d24e2a396a1d211baaeedf32148a3b657240170David Blaikievoid MipsebTargetMachine::anchor() { }
1062d24e2a396a1d211baaeedf32148a3b657240170David Blaikie
1076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarMipsebTargetMachine::MipsebTargetMachine(const Target &T, const Triple &TT,
1086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         StringRef CPU, StringRef FS,
1096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         const TargetOptions &Options,
1106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         Reloc::Model RM, CodeModel::Model CM,
1116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         CodeGenOpt::Level OL)
1126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
1132464810ac27af8dd8b11da7519b719c254854c19Akira Hatanaka
1142d24e2a396a1d211baaeedf32148a3b657240170David Blaikievoid MipselTargetMachine::anchor() { }
1152d24e2a396a1d211baaeedf32148a3b657240170David Blaikie
1166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarMipselTargetMachine::MipselTargetMachine(const Target &T, const Triple &TT,
1176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         StringRef CPU, StringRef FS,
1186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         const TargetOptions &Options,
1196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         Reloc::Model RM, CodeModel::Model CM,
1206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                         CodeGenOpt::Level OL)
1216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
122d2947ee33e810b24a016b944b375d34910f8f5ddBruno Cardoso Lopes
12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesconst MipsSubtarget *
12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMipsTargetMachine::getSubtargetImpl(const Function &F) const {
125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Attribute CPUAttr = F.getFnAttribute("target-cpu");
126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Attribute FSAttr = F.getFnAttribute("target-features");
12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
12837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
12937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                        ? CPUAttr.getValueAsString().str()
13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                        : TargetCPU;
13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string FS = !FSAttr.hasAttribute(Attribute::None)
13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       ? FSAttr.getValueAsString().str()
13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       : TargetFS;
13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasMips16Attr =
135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      !F.getFnAttribute("mips16").hasAttribute(Attribute::None);
13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasNoMips16Attr =
137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      !F.getFnAttribute("nomips16").hasAttribute(Attribute::None);
13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // FIXME: This is related to the code below to reset the target options,
14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // we need to know whether or not the soft float flag is set on the
1416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // function, so we can enable it as a subtarget feature.
1426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool softFloat =
1436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      F.hasFnAttribute("use-soft-float") &&
1446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      F.getFnAttribute("use-soft-float").getValueAsString() == "true";
14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (hasMips16Attr)
14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    FS += FS.empty() ? "+mips16" : ",+mips16";
14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (hasNoMips16Attr)
14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    FS += FS.empty() ? "-mips16" : ",-mips16";
1506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (softFloat)
1516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    FS += FS.empty() ? "+soft-float" : ",+soft-float";
15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  auto &I = SubtargetMap[CPU + FS];
15437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!I) {
15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // This needs to be done before we create a new subtarget since any
15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // creation will depend on the TM and the code generation flags on the
15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // function that reside in TargetOptions.
15837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    resetTargetOptions(F);
159cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    I = llvm::make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle,
160cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                         *this);
16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return I.get();
16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid MipsTargetMachine::resetSubtarget(MachineFunction *MF) {
16637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DEBUG(dbgs() << "resetSubtarget\n");
16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Subtarget = const_cast<MipsSubtarget *>(getSubtargetImpl(*MF->getFunction()));
16937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MF->setSubtarget(Subtarget);
17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return;
17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
173843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Tricknamespace {
174843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick/// Mips Code Generator Pass Configuration Options.
175843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trickclass MipsPassConfig : public TargetPassConfig {
176843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trickpublic:
177061efcfb3e79899493d857f49e50d09f29037e0aAndrew Trick  MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM)
178c746503425fc04e25af680d244f9f351675210d5Akira Hatanaka    : TargetPassConfig(TM, PM) {
179c746503425fc04e25af680d244f9f351675210d5Akira Hatanaka    // The current implementation of long branch pass requires a scratch
180c746503425fc04e25af680d244f9f351675210d5Akira Hatanaka    // register ($at) to be available before branch instructions. Tail merging
181c746503425fc04e25af680d244f9f351675210d5Akira Hatanaka    // can break this requirement, so disable it when long branch pass is
182c746503425fc04e25af680d244f9f351675210d5Akira Hatanaka    // enabled.
183c746503425fc04e25af680d244f9f351675210d5Akira Hatanaka    EnableTailMerge = !getMipsSubtarget().enableLongBranchPass();
184c746503425fc04e25af680d244f9f351675210d5Akira Hatanaka  }
185843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick
186843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick  MipsTargetMachine &getMipsTargetMachine() const {
187843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick    return getTM<MipsTargetMachine>();
188843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick  }
189843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick
190843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick  const MipsSubtarget &getMipsSubtarget() const {
191843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick    return *getMipsTargetMachine().getSubtargetImpl();
192843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick  }
193843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick
194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addIRPasses() override;
195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool addInstSelector() override;
196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addMachineSSAOptimization() override;
197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void addPreEmitPass() override;
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void addPreRegAlloc() override;
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
201843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick};
202843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick} // namespace
203843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick
204061efcfb3e79899493d857f49e50d09f29037e0aAndrew TrickTargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
205061efcfb3e79899493d857f49e50d09f29037e0aAndrew Trick  return new MipsPassConfig(this, PM);
206843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick}
207843ee2e6a46b2b2d74a84c2eea68dec35cb359ccAndrew Trick
20874adad6de8cf947257a53bb08364fa0f4f71b10eReed Kotlervoid MipsPassConfig::addIRPasses() {
20974adad6de8cf947257a53bb08364fa0f4f71b10eReed Kotler  TargetPassConfig::addIRPasses();
21037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  addPass(createAtomicExpandPass(&getMipsTargetMachine()));
21174adad6de8cf947257a53bb08364fa0f4f71b10eReed Kotler  if (getMipsSubtarget().os16())
2124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    addPass(createMipsOs16Pass(getMipsTargetMachine()));
21346090914b783b632618268f2a5c99aab83732688Reed Kotler  if (getMipsSubtarget().inMips16HardFloat())
2144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    addPass(createMips16HardFloatPass(getMipsTargetMachine()));
21574adad6de8cf947257a53bb08364fa0f4f71b10eReed Kotler}
21633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Install an instruction selector pass using
217972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// the ISelDag to gen Mips code.
2187c4ce30ea6a9d0410f306e805403dd224c3df65cBill Wendlingbool MipsPassConfig::addInstSelector() {
2194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  addPass(createMipsModuleISelDagPass(getMipsTargetMachine()));
22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  addPass(createMips16ISelDag(getMipsTargetMachine()));
22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  addPass(createMipsSEISelDag(getMipsTargetMachine()));
222972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes  return false;
223972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
224972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsPassConfig::addMachineSSAOptimization() {
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  addPass(createMipsOptimizePICCallPass(getMipsTargetMachine()));
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TargetPassConfig::addMachineSSAOptimization();
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid MipsPassConfig::addPreRegAlloc() {
231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (getOptLevel() == CodeGenOpt::None)
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    addPass(createMipsOptimizePICCallPass(getMipsTargetMachine()));
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
235ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesTargetIRAnalysis MipsTargetMachine::getTargetIRAnalysis() {
236cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return TargetIRAnalysis([this](const Function &F) {
237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Subtarget->allowMixed16_32()) {
238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DEBUG(errs() << "No Target Transform Info Pass Added\n");
239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // FIXME: This is no longer necessary as the TTI returned is per-function.
240cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      return TargetTransformInfo(F.getParent()->getDataLayout());
241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DEBUG(errs() << "Target Transform Info Pass Added\n");
244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return TargetTransformInfo(BasicTTIImpl(this, F));
245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  });
246a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler}
247a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler
24833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// Implemented by targets that want to run passes immediately before
24933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// machine code is emitted. return true if -print-machineinstrs should
250972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// print out the code after the passes.
251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid MipsPassConfig::addPreEmitPass() {
2529e97587e022ac38258cd59339b4bae66894f9bfbAkira Hatanaka  MipsTargetMachine &TM = getMipsTargetMachine();
253564fbf6aff8fb95646a1290078a37c2d4dbe629fBob Wilson  addPass(createMipsDelaySlotFillerPass(TM));
25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  addPass(createMipsLongBranchPass(TM));
25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  addPass(createMipsConstantIslandPass(TM));
256972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes}
257