Example #1
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);
}