static SDValue PerformDivRemCombine(SDNode *N, SelectionDAG& DAG, TargetLowering::DAGCombinerInfo &DCI, const Cpu0Subtarget* Subtarget) { if (DCI.isBeforeLegalizeOps()) return SDValue(); EVT Ty = N->getValueType(0); unsigned LO = Cpu0::LO; unsigned HI = Cpu0::HI; unsigned opc = N->getOpcode() == ISD::SDIVREM ? Cpu0ISD::DivRem : Cpu0ISD::DivRemU; SDLoc DL(N); SDValue DivRem = DAG.getNode(opc, DL, MVT::Glue, N->getOperand(0), N->getOperand(1)); SDValue InChain = DAG.getEntryNode(); SDValue InGlue = DivRem; // insert MFLO if (N->hasAnyUseOfValue(0)) { SDValue CopyFromLo = DAG.getCopyFromReg(InChain, DL, LO, Ty, InGlue); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), CopyFromLo); InChain = CopyFromLo.getValue(1); InGlue = CopyFromLo.getValue(2); } // insert MFHI if (N->hasAnyUseOfValue(1)) { SDValue CopyFromHi = DAG.getCopyFromReg(InChain, DL, HI, Ty, InGlue); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), CopyFromHi); } return SDValue(); }
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); }