10b57cec5SDimitry Andric //===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Implements the info about Mips target spec. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "MipsTargetMachine.h" 140b57cec5SDimitry Andric #include "MCTargetDesc/MipsABIInfo.h" 150b57cec5SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h" 160b57cec5SDimitry Andric #include "Mips.h" 170b57cec5SDimitry Andric #include "Mips16ISelDAGToDAG.h" 180b57cec5SDimitry Andric #include "MipsSEISelDAGToDAG.h" 190b57cec5SDimitry Andric #include "MipsSubtarget.h" 200b57cec5SDimitry Andric #include "MipsTargetObjectFile.h" 210b57cec5SDimitry Andric #include "TargetInfo/MipsTargetInfo.h" 220b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 230b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 240b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 250b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/IRTranslator.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/Legalizer.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" 290b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 300b57cec5SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 320b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h" 330b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 340b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 350b57cec5SDimitry Andric #include "llvm/IR/Function.h" 360b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 370b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 380b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h" 390b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 400b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 410b57cec5SDimitry Andric #include <string> 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric using namespace llvm; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric #define DEBUG_TYPE "mips" 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric extern "C" void LLVMInitializeMipsTarget() { 480b57cec5SDimitry Andric // Register the target. 490b57cec5SDimitry Andric RegisterTargetMachine<MipsebTargetMachine> X(getTheMipsTarget()); 500b57cec5SDimitry Andric RegisterTargetMachine<MipselTargetMachine> Y(getTheMipselTarget()); 510b57cec5SDimitry Andric RegisterTargetMachine<MipsebTargetMachine> A(getTheMips64Target()); 520b57cec5SDimitry Andric RegisterTargetMachine<MipselTargetMachine> B(getTheMips64elTarget()); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric PassRegistry *PR = PassRegistry::getPassRegistry(); 550b57cec5SDimitry Andric initializeGlobalISel(*PR); 560b57cec5SDimitry Andric initializeMipsDelaySlotFillerPass(*PR); 570b57cec5SDimitry Andric initializeMipsBranchExpansionPass(*PR); 580b57cec5SDimitry Andric initializeMicroMipsSizeReducePass(*PR); 590b57cec5SDimitry Andric initializeMipsPreLegalizerCombinerPass(*PR); 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric static std::string computeDataLayout(const Triple &TT, StringRef CPU, 630b57cec5SDimitry Andric const TargetOptions &Options, 640b57cec5SDimitry Andric bool isLittle) { 650b57cec5SDimitry Andric std::string Ret; 660b57cec5SDimitry Andric MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric // There are both little and big endian mips. 690b57cec5SDimitry Andric if (isLittle) 700b57cec5SDimitry Andric Ret += "e"; 710b57cec5SDimitry Andric else 720b57cec5SDimitry Andric Ret += "E"; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric if (ABI.IsO32()) 750b57cec5SDimitry Andric Ret += "-m:m"; 760b57cec5SDimitry Andric else 770b57cec5SDimitry Andric Ret += "-m:e"; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric // Pointers are 32 bit on some ABIs. 800b57cec5SDimitry Andric if (!ABI.IsN64()) 810b57cec5SDimitry Andric Ret += "-p:32:32"; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric // 8 and 16 bit integers only need to have natural alignment, but try to 840b57cec5SDimitry Andric // align them to 32 bits. 64 bit integers have natural alignment. 850b57cec5SDimitry Andric Ret += "-i8:8:32-i16:16:32-i64:64"; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric // 32 bit registers are always available and the stack is at least 64 bit 880b57cec5SDimitry Andric // aligned. On N64 64 bit registers are also available and the stack is 890b57cec5SDimitry Andric // 128 bit aligned. 900b57cec5SDimitry Andric if (ABI.IsN64() || ABI.IsN32()) 910b57cec5SDimitry Andric Ret += "-n32:64-S128"; 920b57cec5SDimitry Andric else 930b57cec5SDimitry Andric Ret += "-n32-S64"; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric return Ret; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric static Reloc::Model getEffectiveRelocModel(bool JIT, 990b57cec5SDimitry Andric Optional<Reloc::Model> RM) { 1000b57cec5SDimitry Andric if (!RM.hasValue() || JIT) 1010b57cec5SDimitry Andric return Reloc::Static; 1020b57cec5SDimitry Andric return *RM; 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric // On function prologue, the stack is created by decrementing 1060b57cec5SDimitry Andric // its pointer. Once decremented, all references are done with positive 1070b57cec5SDimitry Andric // offset from the stack/frame pointer, using StackGrowsUp enables 1080b57cec5SDimitry Andric // an easier handling. 1090b57cec5SDimitry Andric // Using CodeModel::Large enables different CALL behavior. 1100b57cec5SDimitry Andric MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT, 1110b57cec5SDimitry Andric StringRef CPU, StringRef FS, 1120b57cec5SDimitry Andric const TargetOptions &Options, 1130b57cec5SDimitry Andric Optional<Reloc::Model> RM, 1140b57cec5SDimitry Andric Optional<CodeModel::Model> CM, 1150b57cec5SDimitry Andric CodeGenOpt::Level OL, bool JIT, 1160b57cec5SDimitry Andric bool isLittle) 1170b57cec5SDimitry Andric : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT, 1180b57cec5SDimitry Andric CPU, FS, Options, getEffectiveRelocModel(JIT, RM), 1190b57cec5SDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), OL), 120*8bcb0991SDimitry Andric isLittle(isLittle), TLOF(std::make_unique<MipsTargetObjectFile>()), 1210b57cec5SDimitry Andric ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)), 122*8bcb0991SDimitry Andric Subtarget(nullptr), 123*8bcb0991SDimitry Andric DefaultSubtarget(TT, CPU, FS, isLittle, *this, 124*8bcb0991SDimitry Andric MaybeAlign(Options.StackAlignmentOverride)), 1250b57cec5SDimitry Andric NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", 126*8bcb0991SDimitry Andric isLittle, *this, 127*8bcb0991SDimitry Andric MaybeAlign(Options.StackAlignmentOverride)), 1280b57cec5SDimitry Andric Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16", 129*8bcb0991SDimitry Andric isLittle, *this, 130*8bcb0991SDimitry Andric MaybeAlign(Options.StackAlignmentOverride)) { 1310b57cec5SDimitry Andric Subtarget = &DefaultSubtarget; 1320b57cec5SDimitry Andric initAsmInfo(); 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric MipsTargetMachine::~MipsTargetMachine() = default; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric void MipsebTargetMachine::anchor() {} 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric MipsebTargetMachine::MipsebTargetMachine(const Target &T, const Triple &TT, 1400b57cec5SDimitry Andric StringRef CPU, StringRef FS, 1410b57cec5SDimitry Andric const TargetOptions &Options, 1420b57cec5SDimitry Andric Optional<Reloc::Model> RM, 1430b57cec5SDimitry Andric Optional<CodeModel::Model> CM, 1440b57cec5SDimitry Andric CodeGenOpt::Level OL, bool JIT) 1450b57cec5SDimitry Andric : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {} 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric void MipselTargetMachine::anchor() {} 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric MipselTargetMachine::MipselTargetMachine(const Target &T, const Triple &TT, 1500b57cec5SDimitry Andric StringRef CPU, StringRef FS, 1510b57cec5SDimitry Andric const TargetOptions &Options, 1520b57cec5SDimitry Andric Optional<Reloc::Model> RM, 1530b57cec5SDimitry Andric Optional<CodeModel::Model> CM, 1540b57cec5SDimitry Andric CodeGenOpt::Level OL, bool JIT) 1550b57cec5SDimitry Andric : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {} 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric const MipsSubtarget * 1580b57cec5SDimitry Andric MipsTargetMachine::getSubtargetImpl(const Function &F) const { 1590b57cec5SDimitry Andric Attribute CPUAttr = F.getFnAttribute("target-cpu"); 1600b57cec5SDimitry Andric Attribute FSAttr = F.getFnAttribute("target-features"); 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric std::string CPU = !CPUAttr.hasAttribute(Attribute::None) 1630b57cec5SDimitry Andric ? CPUAttr.getValueAsString().str() 1640b57cec5SDimitry Andric : TargetCPU; 1650b57cec5SDimitry Andric std::string FS = !FSAttr.hasAttribute(Attribute::None) 1660b57cec5SDimitry Andric ? FSAttr.getValueAsString().str() 1670b57cec5SDimitry Andric : TargetFS; 1680b57cec5SDimitry Andric bool hasMips16Attr = 1690b57cec5SDimitry Andric !F.getFnAttribute("mips16").hasAttribute(Attribute::None); 1700b57cec5SDimitry Andric bool hasNoMips16Attr = 1710b57cec5SDimitry Andric !F.getFnAttribute("nomips16").hasAttribute(Attribute::None); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric bool HasMicroMipsAttr = 1740b57cec5SDimitry Andric !F.getFnAttribute("micromips").hasAttribute(Attribute::None); 1750b57cec5SDimitry Andric bool HasNoMicroMipsAttr = 1760b57cec5SDimitry Andric !F.getFnAttribute("nomicromips").hasAttribute(Attribute::None); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric // FIXME: This is related to the code below to reset the target options, 1790b57cec5SDimitry Andric // we need to know whether or not the soft float flag is set on the 1800b57cec5SDimitry Andric // function, so we can enable it as a subtarget feature. 1810b57cec5SDimitry Andric bool softFloat = 1820b57cec5SDimitry Andric F.hasFnAttribute("use-soft-float") && 1830b57cec5SDimitry Andric F.getFnAttribute("use-soft-float").getValueAsString() == "true"; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric if (hasMips16Attr) 1860b57cec5SDimitry Andric FS += FS.empty() ? "+mips16" : ",+mips16"; 1870b57cec5SDimitry Andric else if (hasNoMips16Attr) 1880b57cec5SDimitry Andric FS += FS.empty() ? "-mips16" : ",-mips16"; 1890b57cec5SDimitry Andric if (HasMicroMipsAttr) 1900b57cec5SDimitry Andric FS += FS.empty() ? "+micromips" : ",+micromips"; 1910b57cec5SDimitry Andric else if (HasNoMicroMipsAttr) 1920b57cec5SDimitry Andric FS += FS.empty() ? "-micromips" : ",-micromips"; 1930b57cec5SDimitry Andric if (softFloat) 1940b57cec5SDimitry Andric FS += FS.empty() ? "+soft-float" : ",+soft-float"; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric auto &I = SubtargetMap[CPU + FS]; 1970b57cec5SDimitry Andric if (!I) { 1980b57cec5SDimitry Andric // This needs to be done before we create a new subtarget since any 1990b57cec5SDimitry Andric // creation will depend on the TM and the code generation flags on the 2000b57cec5SDimitry Andric // function that reside in TargetOptions. 2010b57cec5SDimitry Andric resetTargetOptions(F); 202*8bcb0991SDimitry Andric I = std::make_unique<MipsSubtarget>( 203*8bcb0991SDimitry Andric TargetTriple, CPU, FS, isLittle, *this, 204*8bcb0991SDimitry Andric MaybeAlign(Options.StackAlignmentOverride)); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric return I.get(); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric void MipsTargetMachine::resetSubtarget(MachineFunction *MF) { 2100b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "resetSubtarget\n"); 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric Subtarget = &MF->getSubtarget<MipsSubtarget>(); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric namespace { 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric /// Mips Code Generator Pass Configuration Options. 2180b57cec5SDimitry Andric class MipsPassConfig : public TargetPassConfig { 2190b57cec5SDimitry Andric public: 2200b57cec5SDimitry Andric MipsPassConfig(MipsTargetMachine &TM, PassManagerBase &PM) 2210b57cec5SDimitry Andric : TargetPassConfig(TM, PM) { 2220b57cec5SDimitry Andric // The current implementation of long branch pass requires a scratch 2230b57cec5SDimitry Andric // register ($at) to be available before branch instructions. Tail merging 2240b57cec5SDimitry Andric // can break this requirement, so disable it when long branch pass is 2250b57cec5SDimitry Andric // enabled. 2260b57cec5SDimitry Andric EnableTailMerge = !getMipsSubtarget().enableLongBranchPass(); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric MipsTargetMachine &getMipsTargetMachine() const { 2300b57cec5SDimitry Andric return getTM<MipsTargetMachine>(); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric const MipsSubtarget &getMipsSubtarget() const { 2340b57cec5SDimitry Andric return *getMipsTargetMachine().getSubtargetImpl(); 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric void addIRPasses() override; 2380b57cec5SDimitry Andric bool addInstSelector() override; 2390b57cec5SDimitry Andric void addPreEmitPass() override; 2400b57cec5SDimitry Andric void addPreRegAlloc() override; 2410b57cec5SDimitry Andric bool addIRTranslator() override; 2420b57cec5SDimitry Andric void addPreLegalizeMachineIR() override; 2430b57cec5SDimitry Andric bool addLegalizeMachineIR() override; 2440b57cec5SDimitry Andric bool addRegBankSelect() override; 2450b57cec5SDimitry Andric bool addGlobalInstructionSelect() override; 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric std::unique_ptr<CSEConfigBase> getCSEConfig() const override; 2480b57cec5SDimitry Andric }; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric } // end anonymous namespace 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) { 2530b57cec5SDimitry Andric return new MipsPassConfig(*this, PM); 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric std::unique_ptr<CSEConfigBase> MipsPassConfig::getCSEConfig() const { 2570b57cec5SDimitry Andric return getStandardCSEConfigForOpt(TM->getOptLevel()); 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric void MipsPassConfig::addIRPasses() { 2610b57cec5SDimitry Andric TargetPassConfig::addIRPasses(); 2620b57cec5SDimitry Andric addPass(createAtomicExpandPass()); 2630b57cec5SDimitry Andric if (getMipsSubtarget().os16()) 2640b57cec5SDimitry Andric addPass(createMipsOs16Pass()); 2650b57cec5SDimitry Andric if (getMipsSubtarget().inMips16HardFloat()) 2660b57cec5SDimitry Andric addPass(createMips16HardFloatPass()); 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric // Install an instruction selector pass using 2690b57cec5SDimitry Andric // the ISelDag to gen Mips code. 2700b57cec5SDimitry Andric bool MipsPassConfig::addInstSelector() { 2710b57cec5SDimitry Andric addPass(createMipsModuleISelDagPass()); 2720b57cec5SDimitry Andric addPass(createMips16ISelDag(getMipsTargetMachine(), getOptLevel())); 2730b57cec5SDimitry Andric addPass(createMipsSEISelDag(getMipsTargetMachine(), getOptLevel())); 2740b57cec5SDimitry Andric return false; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric void MipsPassConfig::addPreRegAlloc() { 2780b57cec5SDimitry Andric addPass(createMipsOptimizePICCallPass()); 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric TargetTransformInfo 2820b57cec5SDimitry Andric MipsTargetMachine::getTargetTransformInfo(const Function &F) { 2830b57cec5SDimitry Andric if (Subtarget->allowMixed16_32()) { 2840b57cec5SDimitry Andric LLVM_DEBUG(errs() << "No Target Transform Info Pass Added\n"); 2850b57cec5SDimitry Andric // FIXME: This is no longer necessary as the TTI returned is per-function. 2860b57cec5SDimitry Andric return TargetTransformInfo(F.getParent()->getDataLayout()); 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric LLVM_DEBUG(errs() << "Target Transform Info Pass Added\n"); 2900b57cec5SDimitry Andric return TargetTransformInfo(BasicTTIImpl(this, F)); 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric // Implemented by targets that want to run passes immediately before 2940b57cec5SDimitry Andric // machine code is emitted. return true if -print-machineinstrs should 2950b57cec5SDimitry Andric // print out the code after the passes. 2960b57cec5SDimitry Andric void MipsPassConfig::addPreEmitPass() { 2970b57cec5SDimitry Andric // Expand pseudo instructions that are sensitive to register allocation. 2980b57cec5SDimitry Andric addPass(createMipsExpandPseudoPass()); 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric // The microMIPS size reduction pass performs instruction reselection for 3010b57cec5SDimitry Andric // instructions which can be remapped to a 16 bit instruction. 3020b57cec5SDimitry Andric addPass(createMicroMipsSizeReducePass()); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric // The delay slot filler pass can potientially create forbidden slot hazards 3050b57cec5SDimitry Andric // for MIPSR6 and therefore it should go before MipsBranchExpansion pass. 3060b57cec5SDimitry Andric addPass(createMipsDelaySlotFillerPass()); 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric // This pass expands branches and takes care about the forbidden slot hazards. 3090b57cec5SDimitry Andric // Expanding branches may potentially create forbidden slot hazards for 3100b57cec5SDimitry Andric // MIPSR6, and fixing such hazard may potentially break a branch by extending 3110b57cec5SDimitry Andric // its offset out of range. That's why this pass combine these two tasks, and 3120b57cec5SDimitry Andric // runs them alternately until one of them finishes without any changes. Only 3130b57cec5SDimitry Andric // then we can be sure that all branches are expanded properly and no hazards 3140b57cec5SDimitry Andric // exists. 3150b57cec5SDimitry Andric // Any new pass should go before this pass. 3160b57cec5SDimitry Andric addPass(createMipsBranchExpansion()); 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric addPass(createMipsConstantIslandPass()); 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric bool MipsPassConfig::addIRTranslator() { 3220b57cec5SDimitry Andric addPass(new IRTranslator()); 3230b57cec5SDimitry Andric return false; 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric void MipsPassConfig::addPreLegalizeMachineIR() { 3270b57cec5SDimitry Andric addPass(createMipsPreLegalizeCombiner()); 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric bool MipsPassConfig::addLegalizeMachineIR() { 3310b57cec5SDimitry Andric addPass(new Legalizer()); 3320b57cec5SDimitry Andric return false; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric bool MipsPassConfig::addRegBankSelect() { 3360b57cec5SDimitry Andric addPass(new RegBankSelect()); 3370b57cec5SDimitry Andric return false; 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric bool MipsPassConfig::addGlobalInstructionSelect() { 3410b57cec5SDimitry Andric addPass(new InstructionSelect()); 3420b57cec5SDimitry Andric return false; 3430b57cec5SDimitry Andric } 344