diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MipsISelLowering.h')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/MipsISelLowering.h | 81 |
1 files changed, 75 insertions, 6 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MipsISelLowering.h b/contrib/llvm/lib/Target/Mips/MipsISelLowering.h index cddf090..0e47ed3 100644 --- a/contrib/llvm/lib/Target/Mips/MipsISelLowering.h +++ b/contrib/llvm/lib/Target/Mips/MipsISelLowering.h @@ -37,14 +37,23 @@ namespace llvm { // Tail call TailCall, - // Get the Higher 16 bits from a 32-bit immediate + // Get the Highest (63-48) 16 bits from a 64-bit immediate + Highest, + + // Get the Higher (47-32) 16 bits from a 64-bit immediate + Higher, + + // Get the High 16 bits from a 32/64-bit immediate // No relation with Mips Hi register Hi, - // Get the Lower 16 bits from a 32-bit immediate + // Get the Lower 16 bits from a 32/64-bit immediate // No relation with Mips Lo register Lo, + // Get the High 16 bits from a 32 bit immediate for accessing the GOT. + GotHi, + // Handle gp_rel (small data/bss sections) relocation. GPRel, @@ -107,6 +116,7 @@ namespace llvm { Ext, Ins, + CIns, // EXTR.W instrinsic nodes. EXTP, @@ -238,6 +248,33 @@ namespace llvm { bool isCheapToSpeculateCttz() const override; bool isCheapToSpeculateCtlz() const override; + /// Return the register type for a given MVT, ensuring vectors are treated + /// as a series of gpr sized integers. + virtual MVT getRegisterTypeForCallingConv(MVT VT) const override; + + /// Return the register type for a given MVT, ensuring vectors are treated + /// as a series of gpr sized integers. + virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, + EVT VT) const override; + + /// Return the number of registers for a given MVT, ensuring vectors are + /// treated as a series of gpr sized integers. + virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, + EVT VT) const override; + + /// Break down vectors to the correct number of gpr sized integers. + virtual unsigned getVectorTypeBreakdownForCallingConv( + LLVMContext &Context, EVT VT, EVT &IntermediateVT, + unsigned &NumIntermediates, MVT &RegisterVT) const override; + + /// Return the correct alignment for the current calling convention. + virtual unsigned + getABIAlignmentForCallingConv(Type *ArgTy, DataLayout DL) const override { + if (ArgTy->isVectorTy()) + return std::min(DL.getABITypeAlignment(ArgTy), 8U); + return DL.getABITypeAlignment(ArgTy); + } + ISD::NodeType getExtendForAtomicOps() const override { return ISD::SIGN_EXTEND; } @@ -297,7 +334,7 @@ namespace llvm { } bool isJumpTableRelative() const override { - return getTargetMachine().isPositionIndependent() || ABI.IsN64(); + return getTargetMachine().isPositionIndependent(); } protected: @@ -344,8 +381,8 @@ namespace llvm { SelectionDAG &DAG, unsigned HiFlag, unsigned LoFlag, SDValue Chain, const MachinePointerInfo &PtrInfo) const { - SDValue Hi = - DAG.getNode(MipsISD::Hi, DL, Ty, getTargetNode(N, Ty, DAG, HiFlag)); + SDValue Hi = DAG.getNode(MipsISD::GotHi, 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)); @@ -356,6 +393,8 @@ namespace llvm { // computing a symbol's address in non-PIC mode: // // (add %hi(sym), %lo(sym)) + // + // This method covers O32, N32 and N64 in sym32 mode. template <class NodeTy> SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const { @@ -364,7 +403,37 @@ namespace llvm { return DAG.getNode(ISD::ADD, DL, Ty, DAG.getNode(MipsISD::Hi, DL, Ty, Hi), DAG.getNode(MipsISD::Lo, DL, Ty, Lo)); - } + } + + // This method creates the following nodes, which are necessary for + // computing a symbol's address in non-PIC mode for N64. + // + // (add (shl (add (shl (add %highest(sym), %higher(sim)), 16), %high(sym)), + // 16), %lo(%sym)) + // + // FIXME: This method is not efficent for (micro)MIPS64R6. + template <class NodeTy> + SDValue getAddrNonPICSym64(NodeTy *N, const 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); + + SDValue Highest = + DAG.getNode(MipsISD::Highest, DL, Ty, + getTargetNode(N, Ty, DAG, MipsII::MO_HIGHEST)); + SDValue Higher = getTargetNode(N, Ty, DAG, MipsII::MO_HIGHER); + SDValue HigherPart = + DAG.getNode(ISD::ADD, DL, Ty, Highest, + DAG.getNode(MipsISD::Higher, DL, Ty, Higher)); + SDValue Cst = DAG.getConstant(16, DL, MVT::i32); + SDValue Shift = DAG.getNode(ISD::SHL, DL, Ty, HigherPart, Cst); + SDValue Add = DAG.getNode(ISD::ADD, DL, Ty, Shift, + DAG.getNode(MipsISD::Hi, DL, Ty, Hi)); + SDValue Shift2 = DAG.getNode(ISD::SHL, DL, Ty, Add, Cst); + + return DAG.getNode(ISD::ADD, DL, Ty, Shift2, + 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: |