//===-- MipsastISel.cpp - Mips FastISel implementation //---------------------===// #include "llvm/CodeGen/FunctionLoweringInfo.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLibraryInfo.h" #include "MipsISelLowering.h" #include "MipsMachineFunction.h" #include "MipsSubtarget.h" using namespace llvm; namespace { class MipsFastISel final : public FastISel { /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can /// make the right decision when generating code for different targets. const MipsSubtarget *Subtarget; Module &M; const TargetMachine &TM; const TargetInstrInfo &TII; const TargetLowering &TLI; MipsFunctionInfo *MFI; // Convenience variables to avoid some queries. LLVMContext *Context; bool TargetSupported; public: explicit MipsFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo) : FastISel(funcInfo, libInfo), M(const_cast(*funcInfo.Fn->getParent())), TM(funcInfo.MF->getTarget()), TII(*TM.getInstrInfo()), TLI(*TM.getTargetLowering()) { Subtarget = &TM.getSubtarget(); MFI = funcInfo.MF->getInfo(); Context = &funcInfo.Fn->getContext(); TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) && (Subtarget->hasMips32r2() && (Subtarget->isABI_O32()))); } bool TargetSelectInstruction(const Instruction *I) override; bool SelectRet(const Instruction *I); }; bool MipsFastISel::SelectRet(const Instruction *I) { const ReturnInst *Ret = cast(I); if (!FuncInfo.CanLowerReturn) return false; if (Ret->getNumOperands() > 0) { return false; } unsigned RetOpc = Mips::RetRA; BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(RetOpc)); return true; } bool MipsFastISel::TargetSelectInstruction(const Instruction *I) { if (!TargetSupported) return false; switch (I->getOpcode()) { default: break; case Instruction::Ret: return SelectRet(I); } return false; } } namespace llvm { FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo) { return new MipsFastISel(funcInfo, libInfo); } }