Beispiel #1
0
static void UpdateNodeOperand(SelectionDAG &DAG,  SDNode *N, unsigned Num,
                              SDValue Val) {
  SmallVector<SDValue, 8> ops(N->op_begin(), N->op_end());
  ops[Num] = Val;
  SDNode *New = DAG.UpdateNodeOperands(N, ops.data(), ops.size());
  DAG.ReplaceAllUsesWith(N, New);
}
Beispiel #2
0
void VDAGToDAGISel::LowerADDEForISel(SDNode *N, SelectionDAG &DAG) {
  SDValue LHS = N->getOperand(0), RHS = N->getOperand(1), C = N->getOperand(2);
  unsigned OpSize = VTargetLowering::computeSizeInBits(LHS);
  unsigned AddSize = OpSize + 1;
  DebugLoc dl = N->getDebugLoc();
  LLVMContext &Cntx = *DAG.getContext();

  EVT VT = LHS.getValueType(),
           NewVT = VTargetLowering::getRoundIntegerOrBitType(AddSize, Cntx);
  SDValue NewAdd = DAG.getNode(VTMISD::ADDCS, dl, NewVT, LHS, RHS, C);
  SDValue NewValues[] = {
    VTargetLowering::getBitSlice(DAG, dl, NewAdd, OpSize, 0),
    VTargetLowering::getBitSlice(DAG, dl, NewAdd, OpSize + 1, OpSize)
  };

  DAG.ReplaceAllUsesWith(N, NewValues);
}
Beispiel #3
0
void VDAGToDAGISel::LowerICmpForISel(SDNode *N, SelectionDAG &DAG) {
  CondCodeSDNode *CCNode = cast<CondCodeSDNode>(N->getOperand(2));

  DebugLoc dl = N->getDebugLoc();
  LLVMContext &Cntx = *DAG.getContext();

  SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
  unsigned OpSize = VTargetLowering::computeSizeInBits(LHS);
  //assert(OpSize > 1 && "Unexpected 1bit comparison!");
  EVT FUVT = EVT::getIntegerVT(Cntx, OpSize);
  ISD::CondCode CC = CCNode->get();

  switch (CC) {
  case ISD::SETEQ:
  case ISD::SETNE:
  case ISD::SETGT:
  case ISD::SETGE:
  case ISD::SETUGT:
  case ISD::SETUGE:
    break;
  case ISD::SETLT:
  case ISD::SETLE:
  case ISD::SETULT:
  case ISD::SETULE:
    CC = ISD::getSetCCSwappedOperands(CC);
    std::swap(LHS, RHS);
    break;
  default: llvm_unreachable("Unexpected CondCode!");
  }

  unsigned CCNum = (CC == ISD::SETEQ || CC == ISD::SETNE) ? VFUs::CmpEQ
    : (ISD::isSignedIntSetCC(CC) ? VFUs::CmpSigned
    : VFUs::CmpUnsigned);

  SDValue NewICmp = DAG.getNode(VTMISD::ICmp, dl, MVT::i8, LHS, RHS,
                                DAG.getTargetConstant(CCNum, FUVT));
  // Read the result from specific bit of the result.
  unsigned ResultPort = getICmpPort(CC);

  DAG.ReplaceAllUsesWith(SDValue(N, 0),
                         VTargetLowering::getBitSlice(DAG, dl, NewICmp,
                                                      ResultPort + 1, ResultPort,
                                                      N->getValueSizeInBits(0)));
}
Beispiel #4
0
void VDAGToDAGISel::LowerUMUL_LOHIForISel(SDNode *N, SelectionDAG &DAG){
  SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
  unsigned OpSize = VTargetLowering::computeSizeInBits(LHS);
  unsigned MulSize = OpSize * 2;
  assert(MulSize <= 64 && "Unsupported multiplier width!");

  DebugLoc dl = N->getDebugLoc();
  LLVMContext &Cntx = *DAG.getContext();

  EVT VT = LHS.getValueType(),
           NewVT = VTargetLowering::getRoundIntegerOrBitType(MulSize, Cntx);

  SDValue NewMul = DAG.getNode(VTMISD::MULHiLo, dl, NewVT, LHS, RHS);
  SDValue NewValues[] = {
    VTargetLowering::getBitSlice(DAG, dl, NewMul, OpSize, 0),
    VTargetLowering::getBitSlice(DAG, dl, NewMul, MulSize, OpSize)
  };

  DAG.ReplaceAllUsesWith(N, NewValues);
}
Beispiel #5
0
void VDAGToDAGISel::LowerMemAccessISel(SDNode *N, SelectionDAG &DAG,
                                       bool isStore) {
  LSBaseSDNode *LSNode = cast<LSBaseSDNode>(N);
  // FIXME: Handle the index.
  assert(LSNode->isUnindexed() && "Indexed load/store is not supported!");

  EVT VT = LSNode->getMemoryVT();

  unsigned VTSize = VT.getSizeInBits();

  SDValue StoreVal = isStore ? cast<StoreSDNode>(LSNode)->getValue()
                             : DAG.getUNDEF(VT);

  LLVMContext *Cntx = DAG.getContext();
  EVT CmdVT = EVT::getIntegerVT(*Cntx, VFUMemBus::CMDWidth);
  SDValue SDOps[] = {// The chain.
                     LSNode->getChain(),
                     // The Value to store (if any), and the address.
                     LSNode->getBasePtr(), StoreVal,
                     // Is load?
                     DAG.getTargetConstant(isStore, CmdVT),
                     // Byte enable.
                     DAG.getTargetConstant(getByteEnable(VT.getStoreSize()),
                                           MVT::i8)
                    };

  unsigned DataBusWidth = getFUDesc<VFUMemBus>()->getDataWidth();
  MachineMemOperand *MemOp = LSNode->getMemOperand();
  if (unsigned AS = MemOp->getPointerInfo().getAddrSpace()) {
    VFInfo *VFI = DAG.getMachineFunction().getInfo<VFInfo>();
    DataBusWidth = VFI->getBRamInfo(AS).ElemSizeInBytes * 8;
  }

  assert(DataBusWidth >= VTSize && "Unexpected large data!");

  MVT DataBusVT =
    EVT::getIntegerVT(*DAG.getContext(), DataBusWidth).getSimpleVT();

  DebugLoc dl = N->getDebugLoc();
  SDValue Result  =
    DAG.getMemIntrinsicNode(VTMISD::MemAccess, dl,
                            // Result and the chain.
                            DAG.getVTList(DataBusVT, MVT::Other),
                            // SDValue operands
                            SDOps, array_lengthof(SDOps),
                            // Memory operands.
                            LSNode->getMemoryVT(), MemOp);

  if (isStore)  {
    DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result.getValue(1));
    return;
  }

  SDValue Val = Result;
  // Truncate the data bus, the system bus should place the valid data start
  // from LSM.
  if (DataBusWidth > VTSize)
    Val = VTargetLowering::getTruncate(DAG, dl, Result, VTSize);

  // Check if this an extend load.
  LoadSDNode *LD = cast<LoadSDNode>(LSNode);
  ISD::LoadExtType ExtType = LD->getExtensionType();
  if (ExtType != ISD::NON_EXTLOAD) {
    unsigned DstSize = LD->getValueSizeInBits(0);
    Val = VTargetLowering::getExtend(DAG, dl, Val, DstSize,
                                     ExtType == ISD::SEXTLOAD);
  }

  // Do we need to replace the result of the load operation?
  SDValue NewValues[] = { Val, Result.getValue(1) };
  DAG.ReplaceAllUsesWith(N, NewValues);
}