1 //===-- llvm/lib/Target/X86/X86CallLowering.cpp - Call lowering -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file implements the lowering of LLVM calls to machine code calls for
14 //===----------------------------------------------------------------------===//
16 #include "X86CallLowering.h"
17 #include "X86CallingConv.h"
18 #include "X86ISelLowering.h"
19 #include "X86InstrInfo.h"
20 #include "X86TargetMachine.h"
22 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/MachineValueType.h"
25 #include "llvm/Target/TargetSubtargetInfo.h"
29 #include "X86GenCallingConv.inc"
31 #ifndef LLVM_BUILD_GLOBAL_ISEL
32 #error "This shouldn't be built without GISel"
35 X86CallLowering::X86CallLowering(const X86TargetLowering &TLI)
36 : CallLowering(&TLI) {}
38 void X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
39 SmallVectorImpl<ArgInfo> &SplitArgs,
41 MachineRegisterInfo &MRI,
42 SplitArgTy PerformArgSplit) const {
44 const X86TargetLowering &TLI = *getTLI<X86TargetLowering>();
45 LLVMContext &Context = OrigArg.Ty->getContext();
46 EVT VT = TLI.getValueType(DL, OrigArg.Ty);
47 unsigned NumParts = TLI.getNumRegisters(Context, VT);
50 // replace the original type ( pointer -> GPR ).
51 SplitArgs.emplace_back(OrigArg.Reg, VT.getTypeForEVT(Context),
52 OrigArg.Flags, OrigArg.IsFixed);
56 SmallVector<uint64_t, 4> BitOffsets;
57 SmallVector<unsigned, 8> SplitRegs;
59 EVT PartVT = TLI.getRegisterType(Context, VT);
60 Type *PartTy = PartVT.getTypeForEVT(Context);
62 for (unsigned i = 0; i < NumParts; ++i) {
64 ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)),
65 PartTy, OrigArg.Flags};
66 SplitArgs.push_back(Info);
67 PerformArgSplit(Info.Reg, PartVT.getSizeInBits() * i);
72 struct FuncReturnHandler : public CallLowering::ValueHandler {
73 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
74 MachineInstrBuilder &MIB, CCAssignFn *AssignFn)
75 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
77 unsigned getStackAddress(uint64_t Size, int64_t Offset,
78 MachinePointerInfo &MPO) override {
79 llvm_unreachable("Don't know how to get a stack address yet");
82 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
83 CCValAssign &VA) override {
84 MIB.addUse(PhysReg, RegState::Implicit);
85 unsigned ExtReg = extendRegister(ValVReg, VA);
86 MIRBuilder.buildCopy(PhysReg, ExtReg);
89 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
90 MachinePointerInfo &MPO, CCValAssign &VA) override {
91 llvm_unreachable("Don't know how to assign a value to an address yet");
94 MachineInstrBuilder &MIB;
96 } // End anonymous namespace.
98 bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
99 const Value *Val, unsigned VReg) const {
101 assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg");
103 auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0);
106 MachineFunction &MF = MIRBuilder.getMF();
107 MachineRegisterInfo &MRI = MF.getRegInfo();
108 auto &DL = MF.getDataLayout();
109 const Function &F = *MF.getFunction();
111 ArgInfo OrigArg{VReg, Val->getType()};
112 setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
114 SmallVector<ArgInfo, 8> SplitArgs;
115 splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
116 [&](unsigned Reg, uint64_t Offset) {
117 MIRBuilder.buildExtract(Reg, VReg, Offset);
120 FuncReturnHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86);
121 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
125 MIRBuilder.insertInstr(MIB);
130 struct FormalArgHandler : public CallLowering::ValueHandler {
131 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
132 CCAssignFn *AssignFn, const DataLayout &DL)
133 : ValueHandler(MIRBuilder, MRI, AssignFn), DL(DL) {}
135 unsigned getStackAddress(uint64_t Size, int64_t Offset,
136 MachinePointerInfo &MPO) override {
138 auto &MFI = MIRBuilder.getMF().getFrameInfo();
139 int FI = MFI.CreateFixedObject(Size, Offset, true);
140 MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
142 unsigned AddrReg = MRI.createGenericVirtualRegister(
143 LLT::pointer(0, DL.getPointerSizeInBits(0)));
144 MIRBuilder.buildFrameIndex(AddrReg, FI);
148 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
149 MachinePointerInfo &MPO, CCValAssign &VA) override {
151 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
152 MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
154 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
157 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
158 CCValAssign &VA) override {
159 MIRBuilder.getMBB().addLiveIn(PhysReg);
160 MIRBuilder.buildCopy(ValVReg, PhysReg);
163 const DataLayout &DL;
167 bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
169 ArrayRef<unsigned> VRegs) const {
173 // TODO: handle variadic function
177 MachineFunction &MF = MIRBuilder.getMF();
178 MachineRegisterInfo &MRI = MF.getRegInfo();
179 auto DL = MF.getDataLayout();
181 SmallVector<ArgInfo, 8> SplitArgs;
183 for (auto &Arg : F.args()) {
184 ArgInfo OrigArg(VRegs[Idx], Arg.getType());
185 setArgFlags(OrigArg, Idx + 1, DL, F);
186 LLT Ty = MRI.getType(VRegs[Idx]);
187 unsigned Dst = VRegs[Idx];
189 splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
190 [&](unsigned Reg, uint64_t Offset) {
193 Dst = MRI.createGenericVirtualRegister(Ty);
194 MIRBuilder.buildUndef(Dst);
196 unsigned Tmp = MRI.createGenericVirtualRegister(Ty);
197 MIRBuilder.buildInsert(Tmp, Dst, Reg, Offset);
200 if (Dst != VRegs[Idx])
201 MIRBuilder.buildCopy(VRegs[Idx], Dst);
205 MachineBasicBlock &MBB = MIRBuilder.getMBB();
207 MIRBuilder.setInstr(*MBB.begin());
209 FormalArgHandler Handler(MIRBuilder, MRI, CC_X86, DL);
210 if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
213 // Move back to the end of the basic block.
214 MIRBuilder.setMBB(MBB);