Reed Kotler | 720c5ca | 2014-04-17 22:15:34 +0000 | [diff] [blame] | 1 | //===-- MipsastISel.cpp - Mips FastISel implementation |
| 2 | //---------------------===// |
| 3 | |
| 4 | #include "llvm/CodeGen/FunctionLoweringInfo.h" |
| 5 | #include "llvm/CodeGen/FastISel.h" |
Reed Kotler | 67077b3 | 2014-04-29 17:57:50 +0000 | [diff] [blame] | 6 | |
| 7 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
| 8 | #include "llvm/Target/TargetInstrInfo.h" |
Reed Kotler | 720c5ca | 2014-04-17 22:15:34 +0000 | [diff] [blame] | 9 | #include "llvm/Target/TargetLibraryInfo.h" |
| 10 | #include "MipsISelLowering.h" |
Reed Kotler | 67077b3 | 2014-04-29 17:57:50 +0000 | [diff] [blame] | 11 | #include "MipsMachineFunction.h" |
| 12 | #include "MipsSubtarget.h" |
Reed Kotler | 720c5ca | 2014-04-17 22:15:34 +0000 | [diff] [blame] | 13 | |
| 14 | using namespace llvm; |
| 15 | |
| 16 | namespace { |
| 17 | |
| 18 | class MipsFastISel final : public FastISel { |
| 19 | |
Reed Kotler | 67077b3 | 2014-04-29 17:57:50 +0000 | [diff] [blame] | 20 | /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can |
| 21 | /// make the right decision when generating code for different targets. |
| 22 | const MipsSubtarget *Subtarget; |
| 23 | Module &M; |
| 24 | const TargetMachine &TM; |
| 25 | const TargetInstrInfo &TII; |
| 26 | const TargetLowering &TLI; |
| 27 | MipsFunctionInfo *MFI; |
| 28 | |
| 29 | // Convenience variables to avoid some queries. |
| 30 | LLVMContext *Context; |
| 31 | |
| 32 | bool TargetSupported; |
| 33 | |
Reed Kotler | 720c5ca | 2014-04-17 22:15:34 +0000 | [diff] [blame] | 34 | public: |
| 35 | explicit MipsFastISel(FunctionLoweringInfo &funcInfo, |
| 36 | const TargetLibraryInfo *libInfo) |
Reed Kotler | 67077b3 | 2014-04-29 17:57:50 +0000 | [diff] [blame] | 37 | : FastISel(funcInfo, libInfo), |
| 38 | M(const_cast<Module &>(*funcInfo.Fn->getParent())), |
| 39 | TM(funcInfo.MF->getTarget()), TII(*TM.getInstrInfo()), |
| 40 | TLI(*TM.getTargetLowering()) { |
| 41 | Subtarget = &TM.getSubtarget<MipsSubtarget>(); |
| 42 | MFI = funcInfo.MF->getInfo<MipsFunctionInfo>(); |
| 43 | Context = &funcInfo.Fn->getContext(); |
| 44 | TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) && |
| 45 | (Subtarget->hasMips32r2() && (Subtarget->isABI_O32()))); |
| 46 | } |
| 47 | |
| 48 | bool TargetSelectInstruction(const Instruction *I) override; |
| 49 | |
| 50 | bool SelectRet(const Instruction *I); |
Reed Kotler | 720c5ca | 2014-04-17 22:15:34 +0000 | [diff] [blame] | 51 | }; |
Reed Kotler | 67077b3 | 2014-04-29 17:57:50 +0000 | [diff] [blame] | 52 | |
| 53 | bool MipsFastISel::SelectRet(const Instruction *I) { |
| 54 | const ReturnInst *Ret = cast<ReturnInst>(I); |
| 55 | |
| 56 | if (!FuncInfo.CanLowerReturn) |
| 57 | return false; |
| 58 | if (Ret->getNumOperands() > 0) { |
| 59 | return false; |
| 60 | } |
| 61 | unsigned RetOpc = Mips::RetRA; |
| 62 | BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(RetOpc)); |
| 63 | return true; |
| 64 | } |
| 65 | |
| 66 | bool MipsFastISel::TargetSelectInstruction(const Instruction *I) { |
| 67 | if (!TargetSupported) |
| 68 | return false; |
| 69 | switch (I->getOpcode()) { |
| 70 | default: |
| 71 | break; |
| 72 | case Instruction::Ret: |
| 73 | return SelectRet(I); |
| 74 | } |
| 75 | return false; |
| 76 | } |
Reed Kotler | 720c5ca | 2014-04-17 22:15:34 +0000 | [diff] [blame] | 77 | } |
| 78 | |
| 79 | namespace llvm { |
| 80 | FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo, |
| 81 | const TargetLibraryInfo *libInfo) { |
| 82 | return new MipsFastISel(funcInfo, libInfo); |
| 83 | } |
| 84 | } |