Add Simple return instruction to Mips fast-isel
[oota-llvm.git] / lib / Target / Mips / MipsFastISel.cpp
1 //===-- MipsastISel.cpp - Mips FastISel implementation
2 //---------------------===//
3
4 #include "llvm/CodeGen/FunctionLoweringInfo.h"
5 #include "llvm/CodeGen/FastISel.h"
6
7 #include "llvm/CodeGen/MachineInstrBuilder.h"
8 #include "llvm/Target/TargetInstrInfo.h"
9 #include "llvm/Target/TargetLibraryInfo.h"
10 #include "MipsISelLowering.h"
11 #include "MipsMachineFunction.h"
12 #include "MipsSubtarget.h"
13
14 using namespace llvm;
15
16 namespace {
17
18 class MipsFastISel final : public FastISel {
19
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
34 public:
35   explicit MipsFastISel(FunctionLoweringInfo &funcInfo,
36                         const TargetLibraryInfo *libInfo)
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);
51 };
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 }
77 }
78
79 namespace llvm {
80 FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
81                                const TargetLibraryInfo *libInfo) {
82   return new MipsFastISel(funcInfo, libInfo);
83 }
84 }