1 //===-- llvm/lib/Target/X86/X86CallLowering.cpp - Call lowering -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file implements the lowering of LLVM calls to machine code calls for
12 /// GlobalISel.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "X86CallLowering.h"
17 #include "X86ISelLowering.h"
18 #include "X86InstrInfo.h"
19 #include "X86TargetMachine.h"
20 #include "X86CallingConv.h"
21 
22 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
23 #include "llvm/CodeGen/MachineValueType.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 #include "llvm/Target/TargetSubtargetInfo.h"
26 
27 using namespace llvm;
28 
29 #include "X86GenCallingConv.inc"
30 
31 #ifndef LLVM_BUILD_GLOBAL_ISEL
32 #error "This shouldn't be built without GISel"
33 #endif
34 
35 X86CallLowering::X86CallLowering(const X86TargetLowering &TLI)
36     : CallLowering(&TLI) {}
37 
38 bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
39                                   const Value *Val, unsigned VReg) const {
40   // TODO: handle functions returning non-void values.
41   if (Val)
42     return false;
43 
44   // silence unused-function warning, remove after the function implementation.
45   (void)RetCC_X86;
46 
47   MIRBuilder.buildInstr(X86::RET).addImm(0);
48 
49   return true;
50 }
51 
52 namespace {
53 struct FormalArgHandler : public CallLowering::ValueHandler {
54   FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
55                    CCAssignFn *AssignFn, const DataLayout &DL)
56       : ValueHandler(MIRBuilder, MRI, AssignFn), DL(DL) {}
57 
58   unsigned getStackAddress(uint64_t Size, int64_t Offset,
59                            MachinePointerInfo &MPO) override {
60 
61     auto &MFI = MIRBuilder.getMF().getFrameInfo();
62     int FI = MFI.CreateFixedObject(Size, Offset, true);
63     MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
64 
65     unsigned AddrReg =
66         MRI.createGenericVirtualRegister(LLT::pointer(0,
67                                          DL.getPointerSizeInBits(0)));
68     MIRBuilder.buildFrameIndex(AddrReg, FI);
69     return AddrReg;
70   }
71 
72   void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
73                             MachinePointerInfo &MPO, CCValAssign &VA) override {
74 
75     auto MMO = MIRBuilder.getMF().getMachineMemOperand(
76         MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size,
77         0);
78     MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
79   }
80 
81   void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
82                         CCValAssign &VA) override {
83     MIRBuilder.getMBB().addLiveIn(PhysReg);
84     MIRBuilder.buildCopy(ValVReg, PhysReg);
85   }
86 
87   const DataLayout &DL;
88 };
89 }
90 
91 bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
92                                            const Function &F,
93                                            ArrayRef<unsigned> VRegs) const {
94   if (F.arg_empty())
95     return true;
96 
97   //TODO: handle variadic function
98   if (F.isVarArg())
99     return false;
100 
101   auto DL = MIRBuilder.getMF().getDataLayout();
102 
103   SmallVector<ArgInfo, 8> ArgInfos;
104   unsigned Idx = 0;
105   for (auto &Arg : F.getArgumentList()) {
106     ArgInfo AInfo(VRegs[Idx], Arg.getType());
107     setArgFlags(AInfo, Idx + 1, DL, F);
108     ArgInfos.push_back(AInfo);
109     Idx++;
110   }
111 
112   FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(),
113                               CC_X86, DL);
114   return handleAssignments(MIRBuilder, ArgInfos, ArgHandler);
115 }
116