diff options
Diffstat (limited to 'lib/Target/Mips/MipsISelLowering.h')
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.h | 174 |
1 files changed, 52 insertions, 122 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 4701bc4..60e53da 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef MipsISELLOWERING_H -#define MipsISELLOWERING_H +#ifndef LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H +#define LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H #include "MCTargetDesc/MipsBaseInfo.h" #include "Mips.h" @@ -210,13 +210,16 @@ namespace llvm { //===--------------------------------------------------------------------===// class MipsFunctionInfo; class MipsSubtarget; + class MipsCCState; class MipsTargetLowering : public TargetLowering { bool isMicroMips; public: - explicit MipsTargetLowering(MipsTargetMachine &TM); + explicit MipsTargetLowering(const MipsTargetMachine &TM, + const MipsSubtarget &STI); - static const MipsTargetLowering *create(MipsTargetMachine &TM); + static const MipsTargetLowering *create(const MipsTargetMachine &TM, + const MipsSubtarget &STI); /// createFastISel - This method returns a target specific FastISel object, /// or null if the target does not support "fast" ISel. @@ -257,6 +260,8 @@ namespace llvm { } }; + void HandleByVal(CCState *, unsigned &, unsigned) const override; + protected: SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const; @@ -327,6 +332,21 @@ namespace llvm { DAG.getNode(MipsISD::Lo, DL, Ty, Lo)); } + // This method creates the following nodes, which are necessary for + // 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); + assert(Ty == MVT::i32); + SDValue GPRel = getTargetNode(N, Ty, DAG, MipsII::MO_GPREL); + return DAG.getNode(ISD::ADD, DL, Ty, + DAG.getRegister(Mips::GP, Ty), + DAG.getNode(MipsISD::GPRel, DL, DAG.getVTList(Ty), + GPRel)); + } + /// This function fills Ops, which is the list of operands that will later /// be used when a function call node is created. It also generates /// copyToReg nodes to set up argument registers. @@ -334,109 +354,15 @@ namespace llvm { getOpndList(SmallVectorImpl<SDValue> &Ops, std::deque< std::pair<unsigned, SDValue> > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, - CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const; - - /// ByValArgInfo - Byval argument information. - struct ByValArgInfo { - unsigned FirstIdx; // Index of the first register used. - unsigned NumRegs; // Number of registers used for this argument. - unsigned Address; // Offset of the stack area used to pass this argument. - - ByValArgInfo() : FirstIdx(0), NumRegs(0), Address(0) {} - }; - - /// MipsCC - This class provides methods used to analyze formal and call - /// arguments and inquire about calling convention information. - class MipsCC { - public: - enum SpecialCallingConvType { - Mips16RetHelperConv, NoSpecialCallingConv - }; - - MipsCC(CallingConv::ID CallConv, bool IsO32, bool IsFP64, CCState &Info, - SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv); - - - void analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, - bool IsVarArg, bool IsSoftFloat, - const SDNode *CallNode, - std::vector<ArgListEntry> &FuncArgs); - void analyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, - bool IsSoftFloat, - Function::const_arg_iterator FuncArg); - - void analyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, - bool IsSoftFloat, const SDNode *CallNode, - const Type *RetTy) const; - - void analyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, - bool IsSoftFloat, const Type *RetTy) const; + bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, + SDValue Chain) const; - const CCState &getCCInfo() const { return CCInfo; } - - /// hasByValArg - Returns true if function has byval arguments. - bool hasByValArg() const { return !ByValArgs.empty(); } - - /// regSize - Size (in number of bits) of integer registers. - unsigned regSize() const { return IsO32 ? 4 : 8; } - - /// numIntArgRegs - Number of integer registers available for calls. - unsigned numIntArgRegs() const; - - /// reservedArgArea - The size of the area the caller reserves for - /// register arguments. This is 16-byte if ABI is O32. - unsigned reservedArgArea() const; - - /// Return pointer to array of integer argument registers. - const MCPhysReg *intArgRegs() const; - - typedef SmallVectorImpl<ByValArgInfo>::const_iterator byval_iterator; - byval_iterator byval_begin() const { return ByValArgs.begin(); } - byval_iterator byval_end() const { return ByValArgs.end(); } - - private: - void handleByValArg(unsigned ValNo, MVT ValVT, MVT LocVT, - CCValAssign::LocInfo LocInfo, - ISD::ArgFlagsTy ArgFlags); - - /// useRegsForByval - Returns true if the calling convention allows the - /// use of registers to pass byval arguments. - bool useRegsForByval() const { return CallConv != CallingConv::Fast; } - - /// Return the function that analyzes fixed argument list functions. - llvm::CCAssignFn *fixedArgFn() const; - - /// Return the function that analyzes variable argument list functions. - llvm::CCAssignFn *varArgFn() const; - - const MCPhysReg *shadowRegs() const; - - void allocateRegs(ByValArgInfo &ByVal, unsigned ByValSize, - unsigned Align); - - /// Return the type of the register which is used to pass an argument or - /// return a value. This function returns f64 if the argument is an i64 - /// value which has been generated as a result of softening an f128 value. - /// Otherwise, it just returns VT. - MVT getRegVT(MVT VT, const Type *OrigTy, const SDNode *CallNode, - bool IsSoftFloat) const; - - template<typename Ty> - void analyzeReturn(const SmallVectorImpl<Ty> &RetVals, bool IsSoftFloat, - const SDNode *CallNode, const Type *RetTy) const; - - CCState &CCInfo; - CallingConv::ID CallConv; - bool IsO32, IsFP64; - SpecialCallingConvType SpecialCallingConv; - SmallVector<ByValArgInfo, 2> ByValArgs; - }; protected: SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; // Subtarget Info - const MipsSubtarget *Subtarget; + const MipsSubtarget &Subtarget; private: // Create a TargetGlobalAddress node. @@ -459,14 +385,12 @@ namespace llvm { SDValue getTargetNode(ConstantPoolSDNode *N, EVT Ty, SelectionDAG &DAG, unsigned Flag) const; - MipsCC::SpecialCallingConvType getSpecialCallingConv(SDValue Callee) const; // Lower Operand helpers SDValue LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl<ISD::InputArg> &Ins, - SDLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals, - const SDNode *CallNode, const Type *RetTy) const; + const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, + SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, + TargetLowering::CallLoweringInfo &CLI) const; // Lower Operand specifics SDValue lowerBR_JT(SDValue Op, SelectionDAG &DAG) const; @@ -480,6 +404,7 @@ namespace llvm { SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const; SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const; SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const; SDValue lowerFABS(SDValue Op, SelectionDAG &DAG) const; SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; @@ -495,33 +420,34 @@ namespace llvm { /// isEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. virtual bool - isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, + isEligibleForTailCallOptimization(const CCState &CCInfo, unsigned NextStackOffset, - const MipsFunctionInfo& FI) const = 0; + const MipsFunctionInfo &FI) const = 0; /// copyByValArg - Copy argument registers which were used to pass a byval /// argument to the stack. Create a stack frame object for the byval /// argument. - void copyByValRegs(SDValue Chain, SDLoc DL, - std::vector<SDValue> &OutChains, SelectionDAG &DAG, - const ISD::ArgFlagsTy &Flags, + void copyByValRegs(SDValue Chain, SDLoc DL, std::vector<SDValue> &OutChains, + SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags, SmallVectorImpl<SDValue> &InVals, - const Argument *FuncArg, - const MipsCC &CC, const ByValArgInfo &ByVal) const; + const Argument *FuncArg, unsigned FirstReg, + unsigned LastReg, const CCValAssign &VA, + MipsCCState &State) const; /// passByValArg - Pass a byval argument in registers or on stack. void passByValArg(SDValue Chain, SDLoc DL, - std::deque< std::pair<unsigned, SDValue> > &RegsToPass, + std::deque<std::pair<unsigned, SDValue>> &RegsToPass, SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, - const MipsCC &CC, const ByValArgInfo &ByVal, - const ISD::ArgFlagsTy &Flags, bool isLittle) const; + unsigned FirstReg, unsigned LastReg, + const ISD::ArgFlagsTy &Flags, bool isLittle, + const CCValAssign &VA) const; /// writeVarArgRegs - Write variable function arguments passed in registers /// to the stack. Also create a stack frame object for the first variable /// argument. - void writeVarArgRegs(std::vector<SDValue> &OutChains, const MipsCC &CC, - SDValue Chain, SDLoc DL, SelectionDAG &DAG) const; + void writeVarArgRegs(std::vector<SDValue> &OutChains, SDValue Chain, + SDLoc DL, SelectionDAG &DAG, CCState &State) const; SDValue LowerFormalArguments(SDValue Chain, @@ -560,7 +486,7 @@ namespace llvm { /// This function parses registers that appear in inline-asm constraints. /// It returns pair (0, 0) on failure. std::pair<unsigned, const TargetRegisterClass *> - parseRegForInlineAsmConstraint(const StringRef &C, MVT VT) const; + parseRegForInlineAsmConstraint(StringRef C, MVT VT) const; std::pair<unsigned, const TargetRegisterClass*> getRegForInlineAsmConstraint(const std::string &Constraint, @@ -611,8 +537,12 @@ namespace llvm { }; /// Create MipsTargetLowering objects. - const MipsTargetLowering *createMips16TargetLowering(MipsTargetMachine &TM); - const MipsTargetLowering *createMipsSETargetLowering(MipsTargetMachine &TM); + const MipsTargetLowering * + createMips16TargetLowering(const MipsTargetMachine &TM, + const MipsSubtarget &STI); + const MipsTargetLowering * + createMipsSETargetLowering(const MipsTargetMachine &TM, + const MipsSubtarget &STI); namespace Mips { FastISel *createFastISel(FunctionLoweringInfo &funcInfo, @@ -620,4 +550,4 @@ namespace llvm { } } -#endif // MipsISELLOWERING_H +#endif |