2014-04-18 00:15:34 +02:00
|
|
|
//===-- MipsastISel.cpp - Mips FastISel implementation
|
|
|
|
//---------------------===//
|
|
|
|
|
|
|
|
#include "llvm/CodeGen/FunctionLoweringInfo.h"
|
|
|
|
#include "llvm/CodeGen/FastISel.h"
|
2014-04-29 19:57:50 +02:00
|
|
|
|
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
2014-04-18 00:15:34 +02:00
|
|
|
#include "llvm/Target/TargetLibraryInfo.h"
|
|
|
|
#include "MipsISelLowering.h"
|
2014-04-29 19:57:50 +02:00
|
|
|
#include "MipsMachineFunction.h"
|
|
|
|
#include "MipsSubtarget.h"
|
2014-04-18 00:15:34 +02:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
class MipsFastISel final : public FastISel {
|
|
|
|
|
2014-04-29 19:57:50 +02:00
|
|
|
/// 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;
|
|
|
|
|
2014-04-18 00:15:34 +02:00
|
|
|
public:
|
|
|
|
explicit MipsFastISel(FunctionLoweringInfo &funcInfo,
|
|
|
|
const TargetLibraryInfo *libInfo)
|
2014-04-29 19:57:50 +02:00
|
|
|
: FastISel(funcInfo, libInfo),
|
|
|
|
M(const_cast<Module &>(*funcInfo.Fn->getParent())),
|
|
|
|
TM(funcInfo.MF->getTarget()), TII(*TM.getInstrInfo()),
|
|
|
|
TLI(*TM.getTargetLowering()) {
|
|
|
|
Subtarget = &TM.getSubtarget<MipsSubtarget>();
|
|
|
|
MFI = funcInfo.MF->getInfo<MipsFunctionInfo>();
|
|
|
|
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);
|
2014-04-18 00:15:34 +02:00
|
|
|
};
|
2014-04-29 19:57:50 +02:00
|
|
|
|
|
|
|
bool MipsFastISel::SelectRet(const Instruction *I) {
|
|
|
|
const ReturnInst *Ret = cast<ReturnInst>(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;
|
|
|
|
}
|
2014-04-18 00:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
|
|
|
|
const TargetLibraryInfo *libInfo) {
|
|
|
|
return new MipsFastISel(funcInfo, libInfo);
|
|
|
|
}
|
|
|
|
}
|