#ifndef LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
#define LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
+#include "MCTargetDesc/MipsABIInfo.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "Mips.h"
#include "llvm/CodeGen/CallingConvLower.h"
namespace llvm {
namespace MipsISD {
- enum NodeType {
+ enum NodeType : unsigned {
// Start the numbering from where ISD NodeType finishes.
FIRST_NUMBER = ISD::BUILTIN_OP_END,
FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
const TargetLibraryInfo *libInfo) const override;
- MVT getScalarShiftAmountTy(EVT LHSTy) const override { return MVT::i32; }
+ MVT getScalarShiftAmountTy(const DataLayout &) const override {
+ return MVT::i32;
+ }
void LowerOperationWrapper(SDNode *N,
SmallVectorImpl<SDValue> &Results,
const char *getTargetNodeName(unsigned Opcode) const override;
/// getSetCCResultType - get the ISD::SETCC result ValueType
- EVT getSetCCResultType(LLVMContext &Context, EVT VT) const override;
+ EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
+ EVT VT) const override;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
void HandleByVal(CCState *, unsigned &, unsigned) const override;
+ unsigned getRegisterByName(const char* RegName, EVT VT) const override;
+
protected:
SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;
//
// (add (load (wrapper $gp, %got(sym)), %lo(sym))
template <class NodeTy>
- SDValue getAddrLocal(NodeTy *N, EVT Ty, SelectionDAG &DAG,
+ SDValue getAddrLocal(NodeTy *N, SDLoc DL, EVT Ty, SelectionDAG &DAG,
bool IsN32OrN64) const {
- SDLoc DL(N);
unsigned GOTFlag = IsN32OrN64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
getTargetNode(N, Ty, DAG, GOTFlag));
// computing a global symbol's address:
//
// (load (wrapper $gp, %got(sym)))
- template<class NodeTy>
- SDValue getAddrGlobal(NodeTy *N, EVT Ty, SelectionDAG &DAG,
+ template <class NodeTy>
+ SDValue getAddrGlobal(NodeTy *N, SDLoc DL, EVT Ty, SelectionDAG &DAG,
unsigned Flag, SDValue Chain,
const MachinePointerInfo &PtrInfo) const {
- SDLoc DL(N);
SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
getTargetNode(N, Ty, DAG, Flag));
return DAG.getLoad(Ty, DL, Chain, Tgt, PtrInfo, false, false, false, 0);
// computing a global symbol's address in large-GOT mode:
//
// (load (wrapper (add %hi(sym), $gp), %lo(sym)))
- template<class NodeTy>
- SDValue getAddrGlobalLargeGOT(NodeTy *N, EVT Ty, SelectionDAG &DAG,
- unsigned HiFlag, unsigned LoFlag,
- SDValue Chain,
+ template <class NodeTy>
+ SDValue getAddrGlobalLargeGOT(NodeTy *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG, unsigned HiFlag,
+ unsigned LoFlag, SDValue Chain,
const MachinePointerInfo &PtrInfo) const {
- SDLoc DL(N);
- SDValue Hi = DAG.getNode(MipsISD::Hi, DL, Ty,
- getTargetNode(N, Ty, DAG, HiFlag));
+ SDValue Hi =
+ DAG.getNode(MipsISD::Hi, DL, Ty, getTargetNode(N, Ty, DAG, HiFlag));
Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty));
SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
getTargetNode(N, Ty, DAG, LoFlag));
// computing a symbol's address in non-PIC mode:
//
// (add %hi(sym), %lo(sym))
- template<class NodeTy>
- SDValue getAddrNonPIC(NodeTy *N, EVT Ty, SelectionDAG &DAG) const {
- SDLoc DL(N);
+ template <class NodeTy>
+ SDValue getAddrNonPIC(NodeTy *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG) const {
SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
return DAG.getNode(ISD::ADD, DL, Ty,
// computing a symbol's address using gp-relative addressing:
//
// (add $gp, %gp_rel(sym))
- template<class NodeTy>
- SDValue getAddrGPRel(NodeTy *N, EVT Ty, SelectionDAG &DAG) const {
- SDLoc DL(N);
+ template <class NodeTy>
+ SDValue getAddrGPRel(NodeTy *N, SDLoc DL, EVT Ty, SelectionDAG &DAG) const {
assert(Ty == MVT::i32);
SDValue GPRel = getTargetNode(N, Ty, DAG, MipsII::MO_GPREL);
return DAG.getNode(ISD::ADD, DL, Ty,
// Subtarget Info
const MipsSubtarget &Subtarget;
+ // Cache the ABI from the TargetMachine, we use it everywhere.
+ const MipsABIInfo &ABI;
private:
// Create a TargetGlobalAddress node.
const SmallVectorImpl<SDValue> &OutVals,
SDLoc dl, SelectionDAG &DAG) const override;
+ bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override;
+
// Inline asm support
- ConstraintType
- getConstraintType(const std::string &Constraint) const override;
+ ConstraintType getConstraintType(StringRef Constraint) const override;
/// Examine constraint string and operand type and determine a weight value.
/// The operand object must already have been set up with the operand type.
std::pair<unsigned, const TargetRegisterClass *>
parseRegForInlineAsmConstraint(StringRef C, MVT VT) const;
- std::pair<unsigned, const TargetRegisterClass*>
- getRegForInlineAsmConstraint(const std::string &Constraint,
- MVT VT) const override;
+ std::pair<unsigned, const TargetRegisterClass *>
+ getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
+ StringRef Constraint, MVT VT) const override;
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
/// vector. If it is invalid, don't add anything to Ops. If hasMemory is
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const override;
- bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override;
+ unsigned
+ getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
+ if (ConstraintCode == "R")
+ return InlineAsm::Constraint_R;
+ else if (ConstraintCode == "ZC")
+ return InlineAsm::Constraint_ZC;
+ return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
+ }
+
+ bool isLegalAddressingMode(const AddrMode &AM, Type *Ty,
+ unsigned AS) const override;
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
unsigned getJumpTableEncoding() const override;
+ bool useSoftFloat() const override;
/// Emit a sign-extension using sll/sra, seb, or seh appropriately.
MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr *MI,