unsigned CallLowering::ValueHandler::extendRegister(unsigned ValReg, CCValAssign &VA) { LLT LocTy{VA.getLocVT()}; switch (VA.getLocInfo()) { default: break; case CCValAssign::Full: case CCValAssign::BCvt: // FIXME: bitconverting between vector types may or may not be a // nop in big-endian situations. return ValReg; case CCValAssign::AExt: { auto MIB = MIRBuilder.buildAnyExt(LocTy, ValReg); return MIB->getOperand(0).getReg(); } case CCValAssign::SExt: { unsigned NewReg = MRI.createGenericVirtualRegister(LocTy); MIRBuilder.buildSExt(NewReg, ValReg); return NewReg; } case CCValAssign::ZExt: { unsigned NewReg = MRI.createGenericVirtualRegister(LocTy); MIRBuilder.buildZExt(NewReg, ValReg); return NewReg; } } llvm_unreachable("unable to extend register"); }
unsigned CallLowering::ValueHandler::extendRegister(unsigned ValReg, CCValAssign &VA) { LLT LocTy{VA.getLocVT()}; switch (VA.getLocInfo()) { default: break; case CCValAssign::Full: case CCValAssign::BCvt: // FIXME: bitconverting between vector types may or may not be a // nop in big-endian situations. return ValReg; case CCValAssign::AExt: assert(!VA.getLocVT().isVector() && "unexpected vector extend"); // Otherwise, it's a nop. return ValReg; case CCValAssign::SExt: { unsigned NewReg = MRI.createGenericVirtualRegister(LocTy); MIRBuilder.buildSExt(NewReg, ValReg); return NewReg; } case CCValAssign::ZExt: { unsigned NewReg = MRI.createGenericVirtualRegister(LocTy); MIRBuilder.buildZExt(NewReg, ValReg); return NewReg; } } llvm_unreachable("unable to extend register"); }
// 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)); }
//===----------------------------------------------------------------------===// // Formal Arguments Calling Convention Implementation //===----------------------------------------------------------------------===// static void ReadByValArg(MachineFunction &MF, SDValue Chain, SDLoc DL, std::vector<SDValue>& OutChains, SelectionDAG &DAG, unsigned NumWords, SDValue FIN, const CCValAssign &VA, const ISD::ArgFlagsTy& Flags, const Argument *FuncArg) { unsigned LocMem = VA.getLocMemOffset(); unsigned FirstWord = LocMem / 4; // copy register A0 - A1 to frame object for (unsigned i = 0; i < NumWords; ++i) { unsigned CurWord = FirstWord + i; if (CurWord >= IntRegsSize) break; unsigned SrcReg = IntRegs[CurWord]; unsigned Reg = AddLiveIn(MF, SrcReg, &Cpu0::CPURegsRegClass); SDValue StorePtr = DAG.getNode(ISD::ADD, DL, MVT::i32, FIN, DAG.getConstant(i * 4, MVT::i32)); SDValue Store = DAG.getStore(Chain, DL, DAG.getRegister(Reg, MVT::i32), StorePtr, MachinePointerInfo(FuncArg, i * 4), false, false, 0); OutChains.push_back(Store); } }