// Write ByVal Arg to arg registers and stack. static void WriteByValArg(SDValue& ByValChain, SDValue Chain, SDLoc DL, SmallVector<std::pair<unsigned, SDValue>, 16>& RegsToPass, SmallVector<SDValue, 8>& MemOpChains, int& LastFI, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, const CCValAssign &VA, const ISD::ArgFlagsTy& Flags, MVT PtrType, bool isLittle) { unsigned LocMemOffset = VA.getLocMemOffset(); unsigned Offset = 0; uint32_t RemainingSize = Flags.getByValSize(); unsigned ByValAlign = Flags.getByValAlign(); if (RemainingSize == 0) return; // Create a fixed object on stack at offset LocMemOffset and copy // remaining part of byval arg to it using memcpy. SDValue Src = DAG.getNode(ISD::ADD, DL, MVT::i32, Arg, DAG.getConstant(Offset, MVT::i32)); LastFI = MFI->CreateFixedObject(RemainingSize, LocMemOffset, true); SDValue Dst = DAG.getFrameIndex(LastFI, PtrType); ByValChain = DAG.getMemcpy(ByValChain, DL, Dst, Src, DAG.getConstant(RemainingSize, MVT::i32), std::min(ByValAlign, (unsigned)4), /*isVolatile=*/false, /*AlwaysInline=*/false, MachinePointerInfo(0), MachinePointerInfo(0)); }
SDValue MipsTargetLowering:: LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) { if (!Subtarget->isMips1()) return Op; MachineFunction &MF = DAG.getMachineFunction(); unsigned CCReg = AddLiveIn(MF, Mips::FCR31, Mips::CCRRegisterClass); SDValue Chain = DAG.getEntryNode(); DebugLoc dl = Op.getDebugLoc(); SDValue Src = Op.getOperand(0); // Set the condition register SDValue CondReg = DAG.getCopyFromReg(Chain, dl, CCReg, MVT::i32); CondReg = DAG.getCopyToReg(Chain, dl, Mips::AT, CondReg); CondReg = DAG.getCopyFromReg(CondReg, dl, Mips::AT, MVT::i32); SDValue Cst = DAG.getConstant(3, MVT::i32); SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i32, CondReg, Cst); Cst = DAG.getConstant(2, MVT::i32); SDValue Xor = DAG.getNode(ISD::XOR, dl, MVT::i32, Or, Cst); SDValue InFlag(0, 0); CondReg = DAG.getCopyToReg(Chain, dl, Mips::FCR31, Xor, InFlag); // Emit the round instruction and bit convert to integer SDValue Trunc = DAG.getNode(MipsISD::FPRound, dl, MVT::f32, Src, CondReg.getValue(1)); SDValue BitCvt = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Trunc); return BitCvt; }
SDValue Cpu0TargetLowering::lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1); SDValue Shamt = Op.getOperand(2); // if shamt < 32: // lo = (shl lo, shamt) // hi = (or (shl hi, shamt) (srl (srl lo, 1), ~shamt)) // else: // lo = 0 // hi = (shl lo, shamt[4:0]) SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt, DAG.getConstant(-1, MVT::i32)); SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, MVT::i32, Lo, DAG.getConstant(1, MVT::i32)); SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, MVT::i32, ShiftRight1Lo, Not); SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, MVT::i32, Hi, Shamt); SDValue Or = DAG.getNode(ISD::OR, DL, MVT::i32, ShiftLeftHi, ShiftRightLo); SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, MVT::i32, Lo, Shamt); SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt, DAG.getConstant(0x20, MVT::i32)); Lo = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, DAG.getConstant(0, MVT::i32), ShiftLeftLo); Hi = DAG.getNode(ISD::SELECT, DL, MVT::i32, Cond, ShiftLeftLo, Or); SDValue Ops[2] = {Lo, Hi}; return DAG.getMergeValues(Ops, DL); }
static SDValue initAccumulator(SDValue In, DebugLoc DL, SelectionDAG &DAG) { SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, DAG.getConstant(0, MVT::i32)); SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, DAG.getConstant(1, MVT::i32)); return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi); }
static SDValue extractLOHI(SDValue Op, DebugLoc DL, SelectionDAG &DAG) { SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, DAG.getConstant(Mips::sub_lo, MVT::i32)); SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, DAG.getConstant(Mips::sub_hi, MVT::i32)); return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi); }
std::pair<SDValue, SDValue> SystemZSelectionDAGInfo:: EmitTargetCodeForMemchr(SelectionDAG &DAG, SDLoc DL, SDValue Chain, SDValue Src, SDValue Char, SDValue Length, MachinePointerInfo SrcPtrInfo) const { // Use SRST to find the character. End is its address on success. EVT PtrVT = Src.getValueType(); SDVTList VTs = DAG.getVTList(PtrVT, MVT::Other, MVT::Glue); Length = DAG.getZExtOrTrunc(Length, DL, PtrVT); Char = DAG.getZExtOrTrunc(Char, DL, MVT::i32); Char = DAG.getNode(ISD::AND, DL, MVT::i32, Char, DAG.getConstant(255, MVT::i32)); SDValue Limit = DAG.getNode(ISD::ADD, DL, PtrVT, Src, Length); SDValue End = DAG.getNode(SystemZISD::SEARCH_STRING, DL, VTs, Chain, Limit, Src, Char); Chain = End.getValue(1); SDValue Glue = End.getValue(2); // Now select between End and null, depending on whether the character // was found. SmallVector<SDValue, 5> Ops; Ops.push_back(End); Ops.push_back(DAG.getConstant(0, PtrVT)); Ops.push_back(DAG.getConstant(SystemZ::CCMASK_SRST, MVT::i32)); Ops.push_back(DAG.getConstant(SystemZ::CCMASK_SRST_FOUND, MVT::i32)); Ops.push_back(Glue); VTs = DAG.getVTList(PtrVT, MVT::Glue); End = DAG.getNode(SystemZISD::SELECT_CCMASK, DL, VTs, &Ops[0], Ops.size()); return std::make_pair(End, Chain); }
void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain, SDValue &DataPtr, SelectionDAG &DAG) { Chain = N->getOperand(0); SDValue VAListP = N->getOperand(1); const Value *VAListS = cast<SrcValueSDNode>(N->getOperand(2))->getValue(); DebugLoc dl = N->getDebugLoc(); SDValue Base = DAG.getLoad(MVT::i64, dl, Chain, VAListP, VAListS, 0); SDValue Tmp = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP, DAG.getConstant(8, MVT::i64)); SDValue Offset = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Base.getValue(1), Tmp, NULL, 0, MVT::i32); DataPtr = DAG.getNode(ISD::ADD, dl, MVT::i64, Base, Offset); if (N->getValueType(0).isFloatingPoint()) { //if fp && Offset < 6*8, then subtract 6*8 from DataPtr SDValue FPDataPtr = DAG.getNode(ISD::SUB, dl, MVT::i64, DataPtr, DAG.getConstant(8*6, MVT::i64)); SDValue CC = DAG.getSetCC(dl, MVT::i64, Offset, DAG.getConstant(8*6, MVT::i64), ISD::SETLT); DataPtr = DAG.getNode(ISD::SELECT, dl, MVT::i64, CC, FPDataPtr, DataPtr); } SDValue NewOffset = DAG.getNode(ISD::ADD, dl, MVT::i64, Offset, DAG.getConstant(8, MVT::i64)); Chain = DAG.getTruncStore(Offset.getValue(1), dl, NewOffset, Tmp, NULL, 0, MVT::i32); }
// Convert the current CC value into an integer that is 0 if CC == 0, // less than zero if CC == 1 and greater than zero if CC >= 2. // The sequence starts with IPM, which puts CC into bits 29 and 28 // of an integer and clears bits 30 and 31. static SDValue addIPMSequence(SDLoc DL, SDValue Glue, SelectionDAG &DAG) { SDValue IPM = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, Glue); SDValue SRL = DAG.getNode(ISD::SRL, DL, MVT::i32, IPM, DAG.getConstant(28, MVT::i32)); SDValue ROTL = DAG.getNode(ISD::ROTL, DL, MVT::i32, SRL, DAG.getConstant(31, MVT::i32)); return ROTL; }
// Convert the current CC value into an integer that is 0 if CC == 0, // greater than zero if CC == 1 and less than zero if CC >= 2. // The sequence starts with IPM, which puts CC into bits 29 and 28 // of an integer and clears bits 30 and 31. static SDValue addIPMSequence(const SDLoc &DL, SDValue CCReg, SelectionDAG &DAG) { SDValue IPM = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, CCReg); SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, IPM, DAG.getConstant(30 - SystemZ::IPM_CC, DL, MVT::i32)); SDValue SRA = DAG.getNode(ISD::SRA, DL, MVT::i32, SHL, DAG.getConstant(30, DL, MVT::i32)); return SRA; }
SDValue BPFTargetLowering::LowerCallResult( SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); if (Ins.size() >= 2) { fail(DL, DAG, "only small returns supported"); for (unsigned i = 0, e = Ins.size(); i != e; ++i) InVals.push_back(DAG.getConstant(0, DL, Ins[i].VT)); return DAG.getCopyFromReg(Chain, DL, 1, Ins[0].VT, InFlag).getValue(1); } CCInfo.AnalyzeCallResult(Ins, RetCC_BPF64); // Copy all of the result registers out of their specified physreg. for (auto &Val : RVLocs) { Chain = DAG.getCopyFromReg(Chain, DL, Val.getLocReg(), Val.getValVT(), InFlag).getValue(1); InFlag = Chain.getValue(2); InVals.push_back(Chain.getValue(0)); } return Chain; }
static SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) { SDNode *Node = Op.getNode(); EVT VT = Node->getValueType(0); SDValue InChain = Node->getOperand(0); SDValue VAListPtr = Node->getOperand(1); const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); DebugLoc dl = Node->getDebugLoc(); SDValue VAList = DAG.getLoad(MVT::i32, dl, InChain, VAListPtr, SV, 0, false, false, 0); // Increment the pointer, VAList, to the next vaarg SDValue NextPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, VAList, DAG.getConstant(VT.getSizeInBits()/8, MVT::i32)); // Store the incremented VAList to the legalized pointer InChain = DAG.getStore(VAList.getValue(1), dl, NextPtr, VAListPtr, SV, 0, false, false, 0); // Load the actual argument out of the pointer VAList, unless this is an // f64 load. if (VT != MVT::f64) return DAG.getLoad(VT, dl, InChain, VAList, NULL, 0, false, false, 0); // Otherwise, load it as i64, then do a bitconvert. SDValue V = DAG.getLoad(MVT::i64, dl, InChain, VAList, NULL, 0, false, false, 0); // Bit-Convert the value to f64. SDValue Ops[2] = { DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, V), V.getValue(1) }; return DAG.getMergeValues(Ops, 2, dl); }
static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { SDValue LHS = Op.getOperand(0); SDValue RHS = Op.getOperand(1); ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); SDValue TrueVal = Op.getOperand(2); SDValue FalseVal = Op.getOperand(3); DebugLoc dl = Op.getDebugLoc(); unsigned Opc, SPCC = ~0U; // If this is a select_cc of a "setcc", and if the setcc got lowered into // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. LookThroughSetCC(LHS, RHS, CC, SPCC); SDValue CompareFlag; if (LHS.getValueType() == MVT::i32) { std::vector<EVT> VTs; VTs.push_back(LHS.getValueType()); // subcc returns a value VTs.push_back(MVT::Flag); SDValue Ops[2] = { LHS, RHS }; CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1); Opc = SPISD::SELECT_ICC; if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); } else { CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Flag, LHS, RHS); Opc = SPISD::SELECT_FCC; if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); } return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal, DAG.getConstant(SPCC, MVT::i32), CompareFlag); }
static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) { SDValue Chain = Op.getOperand(0); ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); SDValue LHS = Op.getOperand(2); SDValue RHS = Op.getOperand(3); SDValue Dest = Op.getOperand(4); DebugLoc dl = Op.getDebugLoc(); unsigned Opc, SPCC = ~0U; // If this is a br_cc of a "setcc", and if the setcc got lowered into // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. LookThroughSetCC(LHS, RHS, CC, SPCC); // Get the condition flag. SDValue CompareFlag; if (LHS.getValueType() == MVT::i32) { std::vector<MVT> VTs; VTs.push_back(MVT::i32); VTs.push_back(MVT::Flag); SDValue Ops[2] = { LHS, RHS }; CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1); if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); Opc = SPISD::BRICC; } else { CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Flag, LHS, RHS); if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); Opc = SPISD::BRFCC; } return DAG.getNode(Opc, dl, MVT::Other, Chain, Dest, DAG.getConstant(SPCC, MVT::i32), CompareFlag); }
SDValue DCPU16TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { SDValue LHS = Op.getOperand(0); SDValue RHS = Op.getOperand(1); SDValue TrueV = Op.getOperand(2); SDValue FalseV = Op.getOperand(3); ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); DebugLoc dl = Op.getDebugLoc(); ISD::CondCode reverseCC; if (NeedsAdditionalEqualityCC(CC, NULL, &reverseCC)) { // This makes sure we only need one SELECT_CC node. std::swap(TrueV, FalseV); } DCPU16CC::CondCodes simpleCC = GetSimpleCC(reverseCC); SDVTList VTs = DAG.getVTList(Op.getValueType()); SmallVector<SDValue, 5> Ops; Ops.push_back(DAG.getConstant(simpleCC, MVT::i16)); Ops.push_back(LHS); Ops.push_back(RHS); Ops.push_back(TrueV); Ops.push_back(FalseV); return DAG.getNode(DCPU16ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); }
/// getPostIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if this node can be /// combined with a load / store to form a post-indexed load / store. bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const { LoadSDNode *LD = cast<LoadSDNode>(N); if (LD->getExtensionType() != ISD::NON_EXTLOAD) return false; EVT VT = LD->getMemoryVT(); if (VT != MVT::i8 && VT != MVT::i16) return false; if (Op->getOpcode() != ISD::ADD) return false; if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { uint64_t RHSC = RHS->getZExtValue(); if ((VT == MVT::i16 && RHSC != 2) || (VT == MVT::i8 && RHSC != 1)) return false; Base = Op->getOperand(0); Offset = DAG.getConstant(RHSC, VT); AM = ISD::POST_INC; return true; } return false; }
SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const { MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); MFI->setReturnAddressIsTaken(true); if (verifyReturnAddressArgumentIsConstant(Op, DAG)) return SDValue(); unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); SDLoc dl(Op); auto PtrVT = getPointerTy(DAG.getDataLayout()); if (Depth > 0) { SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); SDValue Offset = DAG.getConstant(DAG.getDataLayout().getPointerSize(), dl, MVT::i16); return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset), MachinePointerInfo(), false, false, false, 0); } // Just load the return address. SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI, MachinePointerInfo(), false, false, false, 0); }
// TODO: set SType according to the desired memory barrier behavior. SDValue Cpu0TargetLowering::LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const { unsigned SType = 0; DebugLoc dl = Op.getDebugLoc(); return DAG.getNode(Cpu0ISD::Sync, dl, MVT::Other, Op.getOperand(0), DAG.getConstant(SType, MVT::i32)); }
SDValue AMDGPUTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const { SDValue Data = Op.getOperand(0); VTSDNode *BaseType = cast<VTSDNode>(Op.getOperand(1)); DebugLoc DL = Op.getDebugLoc(); EVT DVT = Data.getValueType(); EVT BVT = BaseType->getVT(); unsigned baseBits = BVT.getScalarType().getSizeInBits(); unsigned srcBits = DVT.isSimple() ? DVT.getScalarType().getSizeInBits() : 1; unsigned shiftBits = srcBits - baseBits; if (srcBits < 32) { // If the op is less than 32 bits, then it needs to extend to 32bits // so it can properly keep the upper bits valid. EVT IVT = genIntType(32, DVT.isVector() ? DVT.getVectorNumElements() : 1); Data = DAG.getNode(ISD::ZERO_EXTEND, DL, IVT, Data); shiftBits = 32 - baseBits; DVT = IVT; } SDValue Shift = DAG.getConstant(shiftBits, DVT); // Shift left by 'Shift' bits. Data = DAG.getNode(ISD::SHL, DL, DVT, Data, Shift); // Signed shift Right by 'Shift' bits. Data = DAG.getNode(ISD::SRA, DL, DVT, Data, Shift); if (srcBits < 32) { // Once the sign extension is done, the op needs to be converted to // its original type. Data = DAG.getSExtOrTrunc(Data, DL, Op.getOperand(0).getValueType()); } return Data; }
SDValue AVM2TargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const { DebugLoc dl = Op.getDebugLoc(); return DAG.getNode(AVM2ISD::EH_SJLJ_LONGJMP, dl, MVT::Other, Op.getOperand(0), Op.getOperand(1), DAG.getConstant(0, MVT::i32)); }
std::pair<SDValue, SDValue> SystemZSelectionDAGInfo::EmitTargetCodeForStrcpy( SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dest, SDValue Src, MachinePointerInfo DestPtrInfo, MachinePointerInfo SrcPtrInfo, bool isStpcpy) const { SDVTList VTs = DAG.getVTList(Dest.getValueType(), MVT::Other); SDValue EndDest = DAG.getNode(SystemZISD::STPCPY, DL, VTs, Chain, Dest, Src, DAG.getConstant(0, DL, MVT::i32)); return std::make_pair(isStpcpy ? EndDest : Dest, EndDest.getValue(1)); }
// Handle a memset of 1, 2, 4 or 8 bytes with the operands given by // Chain, Dst, ByteVal and Size. These cases are expected to use // MVI, MVHHI, MVHI and MVGHI respectively. static SDValue memsetStore(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dst, uint64_t ByteVal, uint64_t Size, unsigned Align, MachinePointerInfo DstPtrInfo) { uint64_t StoreVal = ByteVal; for (unsigned I = 1; I < Size; ++I) StoreVal |= ByteVal << (I * 8); return DAG.getStore( Chain, DL, DAG.getConstant(StoreVal, DL, MVT::getIntegerVT(Size * 8)), Dst, DstPtrInfo, Align); }
SDValue DCPU16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); SDValue LHS = Op.getOperand(2); SDValue RHS = Op.getOperand(3); SDValue Dest = Op.getOperand(4); DebugLoc dl = Op.getDebugLoc(); ISD::CondCode nonEqualCC; if (NeedsAdditionalEqualityCC(CC, &nonEqualCC, NULL)) { SDValue eqCC = DAG.getConstant(DCPU16CC::COND_E, MVT::i16); Chain = DAG.getNode(DCPU16ISD::BR_CC, dl, Op.getValueType(), Chain, eqCC, LHS, RHS, Dest); } DCPU16CC::CondCodes simpleCC = GetSimpleCC(nonEqualCC); return DAG.getNode(DCPU16ISD::BR_CC, dl, Op.getValueType(), Chain, DAG.getConstant(simpleCC, MVT::i16), LHS, RHS, Dest); }
// Use CLC to compare [Src1, Src1 + Size) with [Src2, Src2 + Size), // deciding whether to use a loop or straight-line code. static SDValue emitCLC(SelectionDAG &DAG, SDLoc DL, SDValue Chain, SDValue Src1, SDValue Src2, uint64_t Size) { SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue); EVT PtrVT = Src1.getValueType(); // A two-CLC sequence is a clear win over a loop, not least because it // needs only one branch. A three-CLC sequence needs the same number // of branches as a loop (i.e. 2), but is shorter. That brings us to // lengths greater than 768 bytes. It seems relatively likely that // a difference will be found within the first 768 bytes, so we just // optimize for the smallest number of branch instructions, in order // to avoid polluting the prediction buffer too much. A loop only ever // needs 2 branches, whereas a straight-line sequence would need 3 or more. if (Size > 3 * 256) return DAG.getNode(SystemZISD::CLC_LOOP, DL, VTs, Chain, Src1, Src2, DAG.getConstant(Size, PtrVT), DAG.getConstant(Size / 256, PtrVT)); return DAG.getNode(SystemZISD::CLC, DL, VTs, Chain, Src1, Src2, DAG.getConstant(Size, PtrVT)); }
SDValue ARCTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const { SDValue Op0 = Op.getOperand(0); SDLoc dl(Op); assert(Op.getValueType() == MVT::i32 && "Unhandled target sign_extend_inreg."); // These are legal unsigned Width = cast<VTSDNode>(Op.getOperand(1))->getVT().getSizeInBits(); if (Width == 16 || Width == 8) return Op; if (Width >= 32) { return {}; } SDValue LS = DAG.getNode(ISD::SHL, dl, MVT::i32, Op0, DAG.getConstant(32 - Width, dl, MVT::i32)); SDValue SR = DAG.getNode(ISD::SRA, dl, MVT::i32, LS, DAG.getConstant(32 - Width, dl, MVT::i32)); return SR; }
// Search from Src for a null character, stopping once Src reaches Limit. // Return a pair of values, the first being the number of nonnull characters // and the second being the out chain. // // This can be used for strlen by setting Limit to 0. static std::pair<SDValue, SDValue> getBoundedStrlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain, SDValue Src, SDValue Limit) { EVT PtrVT = Src.getValueType(); SDVTList VTs = DAG.getVTList(PtrVT, MVT::Other, MVT::Glue); SDValue End = DAG.getNode(SystemZISD::SEARCH_STRING, DL, VTs, Chain, Limit, Src, DAG.getConstant(0, MVT::i32)); Chain = End.getValue(1); SDValue Len = DAG.getNode(ISD::SUB, DL, PtrVT, End, Src); return std::make_pair(Len, Chain); }
// (VECTOR, VAL, IDX) // Convert to a vselect with a mask (1 << IDX) and a splatted scalar operand. SDValue VectorProcTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const { MVT VT = Op.getValueType().getSimpleVT(); DebugLoc dl = Op.getDebugLoc(); SDValue mask = DAG.getNode(ISD::SHL, dl, MVT::i32, DAG.getConstant(1, MVT::i32), Op.getOperand(2)); SDValue splat = DAG.getNode(VectorProcISD::SPLAT, dl, VT, Op.getOperand(1)); return DAG.getNode(ISD::VSELECT, dl, VT, mask, splat, Op.getOperand(0)); }
static SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG) { MVT::ValueType PtrVT = Op.getValueType(); JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); SDOperand Zero = DAG.getConstant(0, PtrVT); SDOperand Hi = DAG.getNode(AlphaISD::GPRelHi, MVT::i64, JTI, DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i64)); SDOperand Lo = DAG.getNode(AlphaISD::GPRelLo, MVT::i64, JTI, Hi); return Lo; }
// Use MVC to copy Size bytes from Src to Dest, deciding whether to use // a loop or straight-line code. static SDValue emitMVC(SelectionDAG &DAG, SDLoc DL, SDValue Chain, SDValue Dst, SDValue Src, uint64_t Size) { EVT PtrVT = Src.getValueType(); // The heuristic we use is to prefer loops for anything that would // require 7 or more MVCs. With these kinds of sizes there isn't // much to choose between straight-line code and looping code, // since the time will be dominated by the MVCs themselves. // However, the loop has 4 or 5 instructions (depending on whether // the base addresses can be proved equal), so there doesn't seem // much point using a loop for 5 * 256 bytes or fewer. Anything in // the range (5 * 256, 6 * 256) will need another instruction after // the loop, so it doesn't seem worth using a loop then either. // The next value up, 6 * 256, can be implemented in the same // number of straight-line MVCs as 6 * 256 - 1. if (Size > 6 * 256) return DAG.getNode(SystemZISD::MVC_LOOP, DL, MVT::Other, Chain, Dst, Src, DAG.getConstant(Size, PtrVT), DAG.getConstant(Size / 256, PtrVT)); return DAG.getNode(SystemZISD::MVC, DL, MVT::Other, Chain, Dst, Src, DAG.getConstant(Size, PtrVT)); }
std::pair<SDValue, SDValue> SystemZSelectionDAGInfo:: EmitTargetCodeForStrcmp(SelectionDAG &DAG, SDLoc DL, SDValue Chain, SDValue Src1, SDValue Src2, MachinePointerInfo Op1PtrInfo, MachinePointerInfo Op2PtrInfo) const { SDVTList VTs = DAG.getVTList(Src1.getValueType(), MVT::Other, MVT::Glue); SDValue Unused = DAG.getNode(SystemZISD::STRCMP, DL, VTs, Chain, Src1, Src2, DAG.getConstant(0, MVT::i32)); Chain = Unused.getValue(1); SDValue Glue = Chain.getValue(2); return std::make_pair(addIPMSequence(DL, Glue, DAG), Chain); }
SDValue R600TargetLowering::LowerROTL(SDValue Op, SelectionDAG &DAG) const { DebugLoc DL = Op.getDebugLoc(); EVT VT = Op.getValueType(); return DAG.getNode(AMDGPUISD::BITALIGN, DL, VT, Op.getOperand(0), Op.getOperand(0), DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(32, MVT::i32), Op.getOperand(1))); }