blob: f266e1889505018ac032fef7350efa78587227e4 [file] [log] [blame]
Diana Picus22274932016-11-11 08:27:37 +00001//===-- llvm/lib/Target/ARM/ARMCallLowering.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 "ARMCallLowering.h"
17
18#include "ARMBaseInstrInfo.h"
19#include "ARMISelLowering.h"
20
21#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
22
23using namespace llvm;
24
25#ifndef LLVM_BUILD_GLOBAL_ISEL
26#error "This shouldn't be built without GISel"
27#endif
28
29ARMCallLowering::ARMCallLowering(const ARMTargetLowering &TLI)
30 : CallLowering(&TLI) {}
31
Diana Picus812caee2016-12-16 12:54:46 +000032static bool isSupportedType(const DataLayout DL, const ARMTargetLowering &TLI,
33 Type *T) {
34 EVT VT = TLI.getValueType(DL, T);
35 return VT.isSimple() && VT.isInteger() &&
36 VT.getSimpleVT().getSizeInBits() == 32;
37}
38
39namespace {
40struct FuncReturnHandler : public CallLowering::ValueHandler {
41 FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
42 MachineInstrBuilder &MIB)
43 : ValueHandler(MIRBuilder, MRI), MIB(MIB) {}
44
45 unsigned getStackAddress(uint64_t Size, int64_t Offset,
46 MachinePointerInfo &MPO) override {
47 llvm_unreachable("Don't know how to get a stack address yet");
48 }
49
50 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
51 CCValAssign &VA) override {
52 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
53 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
54
55 assert(VA.getValVT().getSizeInBits() == 32 && "Unsupported value size");
56 assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
57
58 MIRBuilder.buildCopy(PhysReg, ValVReg);
59 MIB.addUse(PhysReg, RegState::Implicit);
60 }
61
62 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
63 MachinePointerInfo &MPO, CCValAssign &VA) override {
64 llvm_unreachable("Don't know how to assign a value to an address yet");
65 }
66
67 MachineInstrBuilder &MIB;
68};
69} // End anonymous namespace.
70
71/// Lower the return value for the already existing \p Ret. This assumes that
72/// \p MIRBuilder's insertion point is correct.
73bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
74 const Value *Val, unsigned VReg,
75 MachineInstrBuilder &Ret) const {
76 if (!Val)
77 // Nothing to do here.
78 return true;
79
80 auto &MF = MIRBuilder.getMF();
81 const auto &F = *MF.getFunction();
82
83 auto DL = MF.getDataLayout();
84 auto &TLI = *getTLI<ARMTargetLowering>();
85 if (!isSupportedType(DL, TLI, Val->getType()))
Diana Picus22274932016-11-11 08:27:37 +000086 return false;
87
Diana Picus812caee2016-12-16 12:54:46 +000088 CCAssignFn *AssignFn =
89 TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
Diana Picus22274932016-11-11 08:27:37 +000090
Diana Picus812caee2016-12-16 12:54:46 +000091 ArgInfo RetInfo(VReg, Val->getType());
92 setArgFlags(RetInfo, AttributeSet::ReturnIndex, DL, F);
93
94 FuncReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
95 return handleAssignments(MIRBuilder, AssignFn, RetInfo, RetHandler);
96}
97
98bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
99 const Value *Val, unsigned VReg) const {
100 assert(!Val == !VReg && "Return value without a vreg");
101
102 auto Ret = AddDefaultPred(MIRBuilder.buildInstrNoInsert(ARM::BX_RET));
103
104 if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
105 return false;
106
107 MIRBuilder.insertInstr(Ret);
Diana Picus22274932016-11-11 08:27:37 +0000108 return true;
109}
110
Diana Picus812caee2016-12-16 12:54:46 +0000111namespace {
112struct FormalArgHandler : public CallLowering::ValueHandler {
113 FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
114 : ValueHandler(MIRBuilder, MRI) {}
115
116 unsigned getStackAddress(uint64_t Size, int64_t Offset,
117 MachinePointerInfo &MPO) override {
118 llvm_unreachable("Don't know how to get a stack address yet");
119 }
120
121 void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
122 CCValAssign &VA) override {
123 assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
124 assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
125
126 assert(VA.getValVT().getSizeInBits() == 32 && "Unsupported value size");
127 assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
128
129 MIRBuilder.getMBB().addLiveIn(PhysReg);
130 MIRBuilder.buildCopy(ValVReg, PhysReg);
131 }
132
133 void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
134 MachinePointerInfo &MPO, CCValAssign &VA) override {
135 llvm_unreachable("Don't know how to assign a value to an address yet");
136 }
137};
138} // End anonymous namespace
139
Diana Picus22274932016-11-11 08:27:37 +0000140bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
141 const Function &F,
142 ArrayRef<unsigned> VRegs) const {
Diana Picus812caee2016-12-16 12:54:46 +0000143 // Quick exit if there aren't any args
144 if (F.arg_empty())
145 return true;
146
147 // Stick to only 4 arguments for now
148 if (F.arg_size() > 4)
149 return false;
150
151 if (F.isVarArg())
152 return false;
153
154 auto DL = MIRBuilder.getMF().getDataLayout();
155 auto &TLI = *getTLI<ARMTargetLowering>();
156
157 auto &Args = F.getArgumentList();
158 for (auto &Arg : Args)
159 if (!isSupportedType(DL, TLI, Arg.getType()))
160 return false;
161
162 CCAssignFn *AssignFn =
163 TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
164
165 SmallVector<ArgInfo, 8> ArgInfos;
166 unsigned Idx = 0;
167 for (auto &Arg : Args) {
168 ArgInfo AInfo(VRegs[Idx], Arg.getType());
169 setArgFlags(AInfo, Idx + 1, DL, F);
170 ArgInfos.push_back(AInfo);
171 Idx++;
172 }
173
174 FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo());
175 return handleAssignments(MIRBuilder, AssignFn, ArgInfos, ArgHandler);
Diana Picus22274932016-11-11 08:27:37 +0000176}