diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp | 190 |
1 files changed, 148 insertions, 42 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp b/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp index 9c511bd77822..93c5f496ce97 100644 --- a/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/contrib/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -112,8 +112,11 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::FIRST_NUMBER: break; case MipsISD::JmpLink: return "MipsISD::JmpLink"; case MipsISD::TailCall: return "MipsISD::TailCall"; + case MipsISD::Highest: return "MipsISD::Highest"; + case MipsISD::Higher: return "MipsISD::Higher"; case MipsISD::Hi: return "MipsISD::Hi"; case MipsISD::Lo: return "MipsISD::Lo"; + case MipsISD::GotHi: return "MipsISD::GotHi"; case MipsISD::GPRel: return "MipsISD::GPRel"; case MipsISD::ThreadPointer: return "MipsISD::ThreadPointer"; case MipsISD::Ret: return "MipsISD::Ret"; @@ -144,6 +147,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::Sync: return "MipsISD::Sync"; case MipsISD::Ext: return "MipsISD::Ext"; case MipsISD::Ins: return "MipsISD::Ins"; + case MipsISD::CIns: return "MipsISD::CIns"; case MipsISD::LWL: return "MipsISD::LWL"; case MipsISD::LWR: return "MipsISD::LWR"; case MipsISD::SWL: return "MipsISD::SWL"; @@ -425,6 +429,7 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM, setTargetDAGCombine(ISD::OR); setTargetDAGCombine(ISD::ADD); setTargetDAGCombine(ISD::AssertZext); + setTargetDAGCombine(ISD::SHL); if (ABI.IsO32()) { // These libcalls are not available in 32-bit. @@ -699,41 +704,81 @@ static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG, static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget) { - // Pattern match EXT. - // $dst = and ((sra or srl) $src , pos), (2**size - 1) - // => ext $dst, $src, size, pos if (DCI.isBeforeLegalizeOps() || !Subtarget.hasExtractInsert()) return SDValue(); - SDValue ShiftRight = N->getOperand(0), Mask = N->getOperand(1); - unsigned ShiftRightOpc = ShiftRight.getOpcode(); - - // Op's first operand must be a shift right. - if (ShiftRightOpc != ISD::SRA && ShiftRightOpc != ISD::SRL) - return SDValue(); + SDValue FirstOperand = N->getOperand(0); + unsigned FirstOperandOpc = FirstOperand.getOpcode(); + SDValue Mask = N->getOperand(1); + EVT ValTy = N->getValueType(0); + SDLoc DL(N); - // The second operand of the shift must be an immediate. + uint64_t Pos = 0, SMPos, SMSize; ConstantSDNode *CN; - if (!(CN = dyn_cast<ConstantSDNode>(ShiftRight.getOperand(1)))) - return SDValue(); - - uint64_t Pos = CN->getZExtValue(); - uint64_t SMPos, SMSize; + SDValue NewOperand; + unsigned Opc; // Op's second operand must be a shifted mask. if (!(CN = dyn_cast<ConstantSDNode>(Mask)) || !isShiftedMask(CN->getZExtValue(), SMPos, SMSize)) return SDValue(); - // Return if the shifted mask does not start at bit 0 or the sum of its size - // and Pos exceeds the word's size. - EVT ValTy = N->getValueType(0); - if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits()) - return SDValue(); + if (FirstOperandOpc == ISD::SRA || FirstOperandOpc == ISD::SRL) { + // Pattern match EXT. + // $dst = and ((sra or srl) $src , pos), (2**size - 1) + // => ext $dst, $src, pos, size + + // The second operand of the shift must be an immediate. + if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1)))) + return SDValue(); + + Pos = CN->getZExtValue(); + + // Return if the shifted mask does not start at bit 0 or the sum of its size + // and Pos exceeds the word's size. + if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits()) + return SDValue(); + + Opc = MipsISD::Ext; + NewOperand = FirstOperand.getOperand(0); + } else if (FirstOperandOpc == ISD::SHL && Subtarget.hasCnMips()) { + // Pattern match CINS. + // $dst = and (shl $src , pos), mask + // => cins $dst, $src, pos, size + // mask is a shifted mask with consecutive 1's, pos = shift amount, + // size = population count. + + // The second operand of the shift must be an immediate. + if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1)))) + return SDValue(); + + Pos = CN->getZExtValue(); + + if (SMPos != Pos || Pos >= ValTy.getSizeInBits() || SMSize >= 32 || + Pos + SMSize > ValTy.getSizeInBits()) + return SDValue(); + + NewOperand = FirstOperand.getOperand(0); + // SMSize is 'location' (position) in this case, not size. + SMSize--; + Opc = MipsISD::CIns; + } else { + // Pattern match EXT. + // $dst = and $src, (2**size - 1) , if size > 16 + // => ext $dst, $src, pos, size , pos = 0 - SDLoc DL(N); - return DAG.getNode(MipsISD::Ext, DL, ValTy, - ShiftRight.getOperand(0), + // If the mask is <= 0xffff, andi can be used instead. + if (CN->getZExtValue() <= 0xffff) + return SDValue(); + + // Return if the mask doesn't start at position 0. + if (SMPos) + return SDValue(); + + Opc = MipsISD::Ext; + NewOperand = FirstOperand; + } + return DAG.getNode(Opc, DL, ValTy, NewOperand, DAG.getConstant(Pos, DL, MVT::i32), DAG.getConstant(SMSize, DL, MVT::i32)); } @@ -852,6 +897,58 @@ static SDValue performAssertZextCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); } + +static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG, + TargetLowering::DAGCombinerInfo &DCI, + const MipsSubtarget &Subtarget) { + // Pattern match CINS. + // $dst = shl (and $src , imm), pos + // => cins $dst, $src, pos, size + + if (DCI.isBeforeLegalizeOps() || !Subtarget.hasCnMips()) + return SDValue(); + + SDValue FirstOperand = N->getOperand(0); + unsigned FirstOperandOpc = FirstOperand.getOpcode(); + SDValue SecondOperand = N->getOperand(1); + EVT ValTy = N->getValueType(0); + SDLoc DL(N); + + uint64_t Pos = 0, SMPos, SMSize; + ConstantSDNode *CN; + SDValue NewOperand; + + // The second operand of the shift must be an immediate. + if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand))) + return SDValue(); + + Pos = CN->getZExtValue(); + + if (Pos >= ValTy.getSizeInBits()) + return SDValue(); + + if (FirstOperandOpc != ISD::AND) + return SDValue(); + + // AND's second operand must be a shifted mask. + if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))) || + !isShiftedMask(CN->getZExtValue(), SMPos, SMSize)) + return SDValue(); + + // Return if the shifted mask does not start at bit 0 or the sum of its size + // and Pos exceeds the word's size. + if (SMPos != 0 || SMSize > 32 || Pos + SMSize > ValTy.getSizeInBits()) + return SDValue(); + + NewOperand = FirstOperand.getOperand(0); + // SMSize is 'location' (position) in this case, not size. + SMSize--; + + return DAG.getNode(MipsISD::CIns, DL, ValTy, NewOperand, + DAG.getConstant(Pos, DL, MVT::i32), + DAG.getConstant(SMSize, DL, MVT::i32)); +} + SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; @@ -875,6 +972,8 @@ SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) return performADDCombine(N, DAG, DCI, Subtarget); case ISD::AssertZext: return performAssertZextCombine(N, DAG, DCI, Subtarget); + case ISD::SHL: + return performSHLCombine(N, DAG, DCI, Subtarget); } return SDValue(); @@ -1733,7 +1832,7 @@ SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op, GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op); const GlobalValue *GV = N->getGlobal(); - if (!isPositionIndependent() && !ABI.IsN64()) { + if (!isPositionIndependent()) { const MipsTargetObjectFile *TLOF = static_cast<const MipsTargetObjectFile *>( getTargetMachine().getObjFileLowering()); @@ -1742,8 +1841,10 @@ SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op, // %gp_rel relocation return getAddrGPRel(N, SDLoc(N), Ty, DAG); - // %hi/%lo relocation - return getAddrNonPIC(N, SDLoc(N), Ty, DAG); + // %hi/%lo relocation + return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) + // %highest/%higher/%hi/%lo relocation + : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); } // Every other architecture would use shouldAssumeDSOLocal in here, but @@ -1777,8 +1878,9 @@ SDValue MipsTargetLowering::lowerBlockAddress(SDValue Op, BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op); EVT Ty = Op.getValueType(); - if (!isPositionIndependent() && !ABI.IsN64()) - return getAddrNonPIC(N, SDLoc(N), Ty, DAG); + if (!isPositionIndependent()) + return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) + : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64()); } @@ -1820,8 +1922,9 @@ lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const Args.push_back(Entry); TargetLowering::CallLoweringInfo CLI(DAG); - CLI.setDebugLoc(DL).setChain(DAG.getEntryNode()) - .setCallee(CallingConv::C, PtrTy, TlsGetAddr, std::move(Args)); + CLI.setDebugLoc(DL) + .setChain(DAG.getEntryNode()) + .setLibCallee(CallingConv::C, PtrTy, TlsGetAddr, std::move(Args)); std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI); SDValue Ret = CallResult.first; @@ -1870,8 +1973,9 @@ lowerJumpTable(SDValue Op, SelectionDAG &DAG) const JumpTableSDNode *N = cast<JumpTableSDNode>(Op); EVT Ty = Op.getValueType(); - if (!isPositionIndependent() && !ABI.IsN64()) - return getAddrNonPIC(N, SDLoc(N), Ty, DAG); + if (!isPositionIndependent()) + return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) + : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64()); } @@ -1882,7 +1986,7 @@ lowerConstantPool(SDValue Op, SelectionDAG &DAG) const ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op); EVT Ty = Op.getValueType(); - if (!isPositionIndependent() && !ABI.IsN64()) { + if (!isPositionIndependent()) { const MipsTargetObjectFile *TLOF = static_cast<const MipsTargetObjectFile *>( getTargetMachine().getObjFileLowering()); @@ -1892,10 +1996,11 @@ lowerConstantPool(SDValue Op, SelectionDAG &DAG) const // %gp_rel relocation return getAddrGPRel(N, SDLoc(N), Ty, DAG); - return getAddrNonPIC(N, SDLoc(N), Ty, DAG); + return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) + : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); } - return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64()); + return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64()); } SDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const { @@ -2796,14 +2901,13 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. - bool IsPICCall = (ABI.IsN64() || IsPIC); // true if calls are translated to - // jalr $25 + SDValue CalleeLo; EVT Ty = Callee.getValueType(); bool GlobalOrExternal = false, IsCallReloc = false; if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { - if (IsPICCall) { + if (IsPIC) { const GlobalValue *Val = G->getGlobal(); InternalLinkage = Val->hasInternalLinkage(); @@ -2828,7 +2932,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { const char *Sym = S->getSymbol(); - if (!ABI.IsN64() && !IsPIC) // !N64 && static + if (!IsPIC) // static Callee = DAG.getTargetExternalSymbol( Sym, getPointerTy(DAG.getDataLayout()), MipsII::MO_NO_FLAG); else if (LargeGOT) { @@ -2836,7 +2940,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, MipsII::MO_CALL_LO16, Chain, FuncInfo->callPtrInfo(Sym)); IsCallReloc = true; - } else { // N64 || PIC + } else { // PIC Callee = getAddrGlobal(S, DL, Ty, DAG, MipsII::MO_GOT_CALL, Chain, FuncInfo->callPtrInfo(Sym)); IsCallReloc = true; @@ -2848,7 +2952,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVector<SDValue, 8> Ops(1, Chain); SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); - getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage, + getOpndList(Ops, RegsToPass, IsPIC, GlobalOrExternal, InternalLinkage, IsCallReloc, CLI, Callee, Chain); if (IsTailCall) { @@ -3683,7 +3787,9 @@ bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { } unsigned MipsTargetLowering::getJumpTableEncoding() const { - if (ABI.IsN64()) + + // FIXME: For space reasons this should be: EK_GPRel32BlockAddress. + if (ABI.IsN64() && isPositionIndependent()) return MachineJumpTableInfo::EK_GPRel64BlockAddress; return TargetLowering::getJumpTableEncoding(); |