Beispiel #1
0
// 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;
}
Beispiel #3
0
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;
}
Beispiel #10
0
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);
}
Beispiel #13
0
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());
}
Beispiel #15
0
/// 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;
}
Beispiel #16
0
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);
}
Beispiel #17
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));
}
Beispiel #24
0
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);
}
Beispiel #30
0
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)));
}