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); }
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); }
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))); }
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); }
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); }