File: | llvm/lib/Target/Mips/MipsCallLowering.cpp |
Warning: | line 318, column 13 Forming reference to null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- MipsCallLowering.cpp -------------------------------------*- C++ -*-===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | // | |||
9 | /// \file | |||
10 | /// This file implements the lowering of LLVM calls to machine code calls for | |||
11 | /// GlobalISel. | |||
12 | // | |||
13 | //===----------------------------------------------------------------------===// | |||
14 | ||||
15 | #include "MipsCallLowering.h" | |||
16 | #include "MipsCCState.h" | |||
17 | #include "MipsMachineFunction.h" | |||
18 | #include "MipsTargetMachine.h" | |||
19 | #include "llvm/CodeGen/Analysis.h" | |||
20 | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" | |||
21 | ||||
22 | using namespace llvm; | |||
23 | ||||
24 | MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI) | |||
25 | : CallLowering(&TLI) {} | |||
26 | ||||
27 | struct MipsOutgoingValueAssigner : public CallLowering::OutgoingValueAssigner { | |||
28 | /// This is the name of the function being called | |||
29 | /// FIXME: Relying on this is unsound | |||
30 | const char *Func = nullptr; | |||
31 | ||||
32 | /// Is this a return value, or an outgoing call operand. | |||
33 | bool IsReturn; | |||
34 | ||||
35 | MipsOutgoingValueAssigner(CCAssignFn *AssignFn_, const char *Func, | |||
36 | bool IsReturn) | |||
37 | : OutgoingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {} | |||
38 | ||||
39 | bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, | |||
40 | CCValAssign::LocInfo LocInfo, | |||
41 | const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags, | |||
42 | CCState &State_) override { | |||
43 | MipsCCState &State = static_cast<MipsCCState &>(State_); | |||
44 | ||||
45 | if (IsReturn) | |||
46 | State.PreAnalyzeReturnValue(EVT::getEVT(Info.Ty)); | |||
47 | else | |||
48 | State.PreAnalyzeCallOperand(Info.Ty, Info.IsFixed, Func); | |||
49 | ||||
50 | return CallLowering::OutgoingValueAssigner::assignArg( | |||
51 | ValNo, OrigVT, ValVT, LocVT, LocInfo, Info, Flags, State); | |||
52 | } | |||
53 | }; | |||
54 | ||||
55 | struct MipsIncomingValueAssigner : public CallLowering::IncomingValueAssigner { | |||
56 | /// This is the name of the function being called | |||
57 | /// FIXME: Relying on this is unsound | |||
58 | const char *Func = nullptr; | |||
59 | ||||
60 | /// Is this a call return value, or an incoming function argument. | |||
61 | bool IsReturn; | |||
62 | ||||
63 | MipsIncomingValueAssigner(CCAssignFn *AssignFn_, const char *Func, | |||
64 | bool IsReturn) | |||
65 | : IncomingValueAssigner(AssignFn_), Func(Func), IsReturn(IsReturn) {} | |||
66 | ||||
67 | bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, | |||
68 | CCValAssign::LocInfo LocInfo, | |||
69 | const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags, | |||
70 | CCState &State_) override { | |||
71 | MipsCCState &State = static_cast<MipsCCState &>(State_); | |||
72 | ||||
73 | if (IsReturn) | |||
74 | State.PreAnalyzeCallResult(Info.Ty, Func); | |||
75 | else | |||
76 | State.PreAnalyzeFormalArgument(Info.Ty, Flags); | |||
77 | ||||
78 | return CallLowering::IncomingValueAssigner::assignArg( | |||
79 | ValNo, OrigVT, ValVT, LocVT, LocInfo, Info, Flags, State); | |||
80 | } | |||
81 | }; | |||
82 | ||||
83 | namespace { | |||
84 | class MipsIncomingValueHandler : public CallLowering::IncomingValueHandler { | |||
85 | const MipsSubtarget &STI; | |||
86 | ||||
87 | public: | |||
88 | MipsIncomingValueHandler(MachineIRBuilder &MIRBuilder, | |||
89 | MachineRegisterInfo &MRI) | |||
90 | : IncomingValueHandler(MIRBuilder, MRI), | |||
91 | STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()) {} | |||
92 | ||||
93 | private: | |||
94 | void assignValueToReg(Register ValVReg, Register PhysReg, | |||
95 | CCValAssign &VA) override; | |||
96 | ||||
97 | Register getStackAddress(uint64_t Size, int64_t Offset, | |||
98 | MachinePointerInfo &MPO, | |||
99 | ISD::ArgFlagsTy Flags) override; | |||
100 | void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, | |||
101 | MachinePointerInfo &MPO, CCValAssign &VA) override; | |||
102 | ||||
103 | unsigned assignCustomValue(CallLowering::ArgInfo &Arg, | |||
104 | ArrayRef<CCValAssign> VAs) override; | |||
105 | ||||
106 | virtual void markPhysRegUsed(unsigned PhysReg) { | |||
107 | MIRBuilder.getMRI()->addLiveIn(PhysReg); | |||
108 | MIRBuilder.getMBB().addLiveIn(PhysReg); | |||
109 | } | |||
110 | }; | |||
111 | ||||
112 | class CallReturnHandler : public MipsIncomingValueHandler { | |||
113 | public: | |||
114 | CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, | |||
115 | MachineInstrBuilder &MIB) | |||
116 | : MipsIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {} | |||
117 | ||||
118 | private: | |||
119 | void markPhysRegUsed(unsigned PhysReg) override { | |||
120 | MIB.addDef(PhysReg, RegState::Implicit); | |||
121 | } | |||
122 | ||||
123 | MachineInstrBuilder &MIB; | |||
124 | }; | |||
125 | ||||
126 | } // end anonymous namespace | |||
127 | ||||
128 | void MipsIncomingValueHandler::assignValueToReg(Register ValVReg, | |||
129 | Register PhysReg, | |||
130 | CCValAssign &VA) { | |||
131 | markPhysRegUsed(PhysReg); | |||
132 | IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); | |||
133 | } | |||
134 | ||||
135 | Register MipsIncomingValueHandler::getStackAddress(uint64_t Size, | |||
136 | int64_t Offset, | |||
137 | MachinePointerInfo &MPO, | |||
138 | ISD::ArgFlagsTy Flags) { | |||
139 | ||||
140 | MachineFunction &MF = MIRBuilder.getMF(); | |||
141 | MachineFrameInfo &MFI = MF.getFrameInfo(); | |||
142 | ||||
143 | // FIXME: This should only be immutable for non-byval memory arguments. | |||
144 | int FI = MFI.CreateFixedObject(Size, Offset, true); | |||
145 | MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); | |||
146 | ||||
147 | return MIRBuilder.buildFrameIndex(LLT::pointer(0, 32), FI).getReg(0); | |||
148 | } | |||
149 | ||||
150 | void MipsIncomingValueHandler::assignValueToAddress(Register ValVReg, | |||
151 | Register Addr, LLT MemTy, | |||
152 | MachinePointerInfo &MPO, | |||
153 | CCValAssign &VA) { | |||
154 | MachineFunction &MF = MIRBuilder.getMF(); | |||
155 | auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, MemTy, | |||
156 | inferAlignFromPtrInfo(MF, MPO)); | |||
157 | MIRBuilder.buildLoad(ValVReg, Addr, *MMO); | |||
158 | } | |||
159 | ||||
160 | /// Handle cases when f64 is split into 2 32-bit GPRs. This is a custom | |||
161 | /// assignment because generic code assumes getNumRegistersForCallingConv is | |||
162 | /// accurate. In this case it is not because the type/number are context | |||
163 | /// dependent on other arguments. | |||
164 | unsigned | |||
165 | MipsIncomingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg, | |||
166 | ArrayRef<CCValAssign> VAs) { | |||
167 | const CCValAssign &VALo = VAs[0]; | |||
168 | const CCValAssign &VAHi = VAs[1]; | |||
169 | ||||
170 | assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&(static_cast <bool> (VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT ::f64 && VAHi.getValVT() == MVT::f64 && "unexpected custom value" ) ? void (0) : __assert_fail ("VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 && \"unexpected custom value\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/Target/Mips/MipsCallLowering.cpp" , 172, __extension__ __PRETTY_FUNCTION__)) | |||
171 | VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&(static_cast <bool> (VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT ::f64 && VAHi.getValVT() == MVT::f64 && "unexpected custom value" ) ? void (0) : __assert_fail ("VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 && \"unexpected custom value\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/Target/Mips/MipsCallLowering.cpp" , 172, __extension__ __PRETTY_FUNCTION__)) | |||
172 | "unexpected custom value")(static_cast <bool> (VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT ::f64 && VAHi.getValVT() == MVT::f64 && "unexpected custom value" ) ? void (0) : __assert_fail ("VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 && \"unexpected custom value\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/Target/Mips/MipsCallLowering.cpp" , 172, __extension__ __PRETTY_FUNCTION__)); | |||
173 | ||||
174 | auto CopyLo = MIRBuilder.buildCopy(LLT::scalar(32), VALo.getLocReg()); | |||
175 | auto CopyHi = MIRBuilder.buildCopy(LLT::scalar(32), VAHi.getLocReg()); | |||
176 | if (!STI.isLittle()) | |||
177 | std::swap(CopyLo, CopyHi); | |||
178 | ||||
179 | Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end()); | |||
180 | Arg.Regs = { CopyLo.getReg(0), CopyHi.getReg(0) }; | |||
181 | MIRBuilder.buildMerge(Arg.OrigRegs[0], {CopyLo, CopyHi}); | |||
182 | ||||
183 | markPhysRegUsed(VALo.getLocReg()); | |||
184 | markPhysRegUsed(VAHi.getLocReg()); | |||
185 | return 2; | |||
186 | } | |||
187 | ||||
188 | namespace { | |||
189 | class MipsOutgoingValueHandler : public CallLowering::OutgoingValueHandler { | |||
190 | const MipsSubtarget &STI; | |||
191 | ||||
192 | public: | |||
193 | MipsOutgoingValueHandler(MachineIRBuilder &MIRBuilder, | |||
194 | MachineRegisterInfo &MRI, MachineInstrBuilder &MIB) | |||
195 | : OutgoingValueHandler(MIRBuilder, MRI), | |||
196 | STI(MIRBuilder.getMF().getSubtarget<MipsSubtarget>()), MIB(MIB) {} | |||
197 | ||||
198 | private: | |||
199 | void assignValueToReg(Register ValVReg, Register PhysReg, | |||
200 | CCValAssign &VA) override; | |||
201 | ||||
202 | Register getStackAddress(uint64_t Size, int64_t Offset, | |||
203 | MachinePointerInfo &MPO, | |||
204 | ISD::ArgFlagsTy Flags) override; | |||
205 | ||||
206 | void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, | |||
207 | MachinePointerInfo &MPO, CCValAssign &VA) override; | |||
208 | unsigned assignCustomValue(CallLowering::ArgInfo &Arg, | |||
209 | ArrayRef<CCValAssign> VAs) override; | |||
210 | ||||
211 | MachineInstrBuilder &MIB; | |||
212 | }; | |||
213 | } // end anonymous namespace | |||
214 | ||||
215 | void MipsOutgoingValueHandler::assignValueToReg(Register ValVReg, | |||
216 | Register PhysReg, | |||
217 | CCValAssign &VA) { | |||
218 | Register ExtReg = extendRegister(ValVReg, VA); | |||
219 | MIRBuilder.buildCopy(PhysReg, ExtReg); | |||
220 | MIB.addUse(PhysReg, RegState::Implicit); | |||
221 | } | |||
222 | ||||
223 | Register MipsOutgoingValueHandler::getStackAddress(uint64_t Size, | |||
224 | int64_t Offset, | |||
225 | MachinePointerInfo &MPO, | |||
226 | ISD::ArgFlagsTy Flags) { | |||
227 | MachineFunction &MF = MIRBuilder.getMF(); | |||
228 | MPO = MachinePointerInfo::getStack(MF, Offset); | |||
229 | ||||
230 | LLT p0 = LLT::pointer(0, 32); | |||
231 | LLT s32 = LLT::scalar(32); | |||
232 | auto SPReg = MIRBuilder.buildCopy(p0, Register(Mips::SP)); | |||
233 | ||||
234 | auto OffsetReg = MIRBuilder.buildConstant(s32, Offset); | |||
235 | auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg); | |||
236 | return AddrReg.getReg(0); | |||
237 | } | |||
238 | ||||
239 | void MipsOutgoingValueHandler::assignValueToAddress(Register ValVReg, | |||
240 | Register Addr, LLT MemTy, | |||
241 | MachinePointerInfo &MPO, | |||
242 | CCValAssign &VA) { | |||
243 | MachineFunction &MF = MIRBuilder.getMF(); | |||
244 | uint64_t LocMemOffset = VA.getLocMemOffset(); | |||
245 | ||||
246 | auto MMO = MF.getMachineMemOperand( | |||
247 | MPO, MachineMemOperand::MOStore, MemTy, | |||
248 | commonAlignment(STI.getStackAlignment(), LocMemOffset)); | |||
249 | ||||
250 | Register ExtReg = extendRegister(ValVReg, VA); | |||
251 | MIRBuilder.buildStore(ExtReg, Addr, *MMO); | |||
252 | } | |||
253 | ||||
254 | unsigned | |||
255 | MipsOutgoingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg, | |||
256 | ArrayRef<CCValAssign> VAs) { | |||
257 | const CCValAssign &VALo = VAs[0]; | |||
258 | const CCValAssign &VAHi = VAs[1]; | |||
259 | ||||
260 | assert(VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 &&(static_cast <bool> (VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT ::f64 && VAHi.getValVT() == MVT::f64 && "unexpected custom value" ) ? void (0) : __assert_fail ("VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 && \"unexpected custom value\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/Target/Mips/MipsCallLowering.cpp" , 262, __extension__ __PRETTY_FUNCTION__)) | |||
261 | VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 &&(static_cast <bool> (VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT ::f64 && VAHi.getValVT() == MVT::f64 && "unexpected custom value" ) ? void (0) : __assert_fail ("VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 && \"unexpected custom value\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/Target/Mips/MipsCallLowering.cpp" , 262, __extension__ __PRETTY_FUNCTION__)) | |||
262 | "unexpected custom value")(static_cast <bool> (VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT ::f64 && VAHi.getValVT() == MVT::f64 && "unexpected custom value" ) ? void (0) : __assert_fail ("VALo.getLocVT() == MVT::i32 && VAHi.getLocVT() == MVT::i32 && VALo.getValVT() == MVT::f64 && VAHi.getValVT() == MVT::f64 && \"unexpected custom value\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/Target/Mips/MipsCallLowering.cpp" , 262, __extension__ __PRETTY_FUNCTION__)); | |||
263 | ||||
264 | auto Unmerge = | |||
265 | MIRBuilder.buildUnmerge({LLT::scalar(32), LLT::scalar(32)}, Arg.Regs[0]); | |||
266 | Register Lo = Unmerge.getReg(0); | |||
267 | Register Hi = Unmerge.getReg(1); | |||
268 | ||||
269 | Arg.OrigRegs.assign(Arg.Regs.begin(), Arg.Regs.end()); | |||
270 | Arg.Regs = { Lo, Hi }; | |||
271 | if (!STI.isLittle()) | |||
272 | std::swap(Lo, Hi); | |||
273 | ||||
274 | MIRBuilder.buildCopy(VALo.getLocReg(), Lo); | |||
275 | MIRBuilder.buildCopy(VAHi.getLocReg(), Hi); | |||
276 | return 2; | |||
277 | } | |||
278 | ||||
279 | static bool isSupportedArgumentType(Type *T) { | |||
280 | if (T->isIntegerTy()) | |||
281 | return true; | |||
282 | if (T->isPointerTy()) | |||
283 | return true; | |||
284 | if (T->isFloatingPointTy()) | |||
285 | return true; | |||
286 | return false; | |||
287 | } | |||
288 | ||||
289 | static bool isSupportedReturnType(Type *T) { | |||
290 | if (T->isIntegerTy()) | |||
291 | return true; | |||
292 | if (T->isPointerTy()) | |||
293 | return true; | |||
294 | if (T->isFloatingPointTy()) | |||
295 | return true; | |||
296 | if (T->isAggregateType()) | |||
297 | return true; | |||
298 | return false; | |||
299 | } | |||
300 | ||||
301 | bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, | |||
302 | const Value *Val, ArrayRef<Register> VRegs, | |||
303 | FunctionLoweringInfo &FLI) const { | |||
304 | ||||
305 | MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA); | |||
306 | ||||
307 | if (Val != nullptr && !isSupportedReturnType(Val->getType())) | |||
| ||||
308 | return false; | |||
309 | ||||
310 | if (!VRegs.empty()) { | |||
311 | MachineFunction &MF = MIRBuilder.getMF(); | |||
312 | const Function &F = MF.getFunction(); | |||
313 | const DataLayout &DL = MF.getDataLayout(); | |||
314 | const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); | |||
315 | ||||
316 | SmallVector<ArgInfo, 8> RetInfos; | |||
317 | ||||
318 | ArgInfo ArgRetInfo(VRegs, *Val, 0); | |||
| ||||
319 | setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F); | |||
320 | splitToValueTypes(ArgRetInfo, RetInfos, DL, F.getCallingConv()); | |||
321 | ||||
322 | SmallVector<CCValAssign, 16> ArgLocs; | |||
323 | SmallVector<ISD::OutputArg, 8> Outs; | |||
324 | ||||
325 | MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, | |||
326 | F.getContext()); | |||
327 | ||||
328 | MipsOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret); | |||
329 | std::string FuncName = F.getName().str(); | |||
330 | MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForReturn(), | |||
331 | FuncName.c_str(), /*IsReturn*/ true); | |||
332 | ||||
333 | if (!determineAssignments(Assigner, RetInfos, CCInfo)) | |||
334 | return false; | |||
335 | ||||
336 | if (!handleAssignments(RetHandler, RetInfos, CCInfo, ArgLocs, MIRBuilder)) | |||
337 | return false; | |||
338 | } | |||
339 | ||||
340 | MIRBuilder.insertInstr(Ret); | |||
341 | return true; | |||
342 | } | |||
343 | ||||
344 | bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, | |||
345 | const Function &F, | |||
346 | ArrayRef<ArrayRef<Register>> VRegs, | |||
347 | FunctionLoweringInfo &FLI) const { | |||
348 | ||||
349 | // Quick exit if there aren't any args. | |||
350 | if (F.arg_empty()) | |||
351 | return true; | |||
352 | ||||
353 | for (auto &Arg : F.args()) { | |||
354 | if (!isSupportedArgumentType(Arg.getType())) | |||
355 | return false; | |||
356 | } | |||
357 | ||||
358 | MachineFunction &MF = MIRBuilder.getMF(); | |||
359 | const DataLayout &DL = MF.getDataLayout(); | |||
360 | const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); | |||
361 | ||||
362 | SmallVector<ArgInfo, 8> ArgInfos; | |||
363 | unsigned i = 0; | |||
364 | for (auto &Arg : F.args()) { | |||
365 | ArgInfo AInfo(VRegs[i], Arg, i); | |||
366 | setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F); | |||
367 | ||||
368 | splitToValueTypes(AInfo, ArgInfos, DL, F.getCallingConv()); | |||
369 | ++i; | |||
370 | } | |||
371 | ||||
372 | SmallVector<ISD::InputArg, 8> Ins; | |||
373 | ||||
374 | SmallVector<CCValAssign, 16> ArgLocs; | |||
375 | MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, | |||
376 | F.getContext()); | |||
377 | ||||
378 | const MipsTargetMachine &TM = | |||
379 | static_cast<const MipsTargetMachine &>(MF.getTarget()); | |||
380 | const MipsABIInfo &ABI = TM.getABI(); | |||
381 | CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(F.getCallingConv()), | |||
382 | Align(1)); | |||
383 | ||||
384 | const std::string FuncName = F.getName().str(); | |||
385 | MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForCall(), FuncName.c_str(), | |||
386 | /*IsReturn*/ false); | |||
387 | if (!determineAssignments(Assigner, ArgInfos, CCInfo)) | |||
388 | return false; | |||
389 | ||||
390 | MipsIncomingValueHandler Handler(MIRBuilder, MF.getRegInfo()); | |||
391 | if (!handleAssignments(Handler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) | |||
392 | return false; | |||
393 | ||||
394 | if (F.isVarArg()) { | |||
395 | ArrayRef<MCPhysReg> ArgRegs = ABI.GetVarArgRegs(); | |||
396 | unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs); | |||
397 | ||||
398 | int VaArgOffset; | |||
399 | unsigned RegSize = 4; | |||
400 | if (ArgRegs.size() == Idx) | |||
401 | VaArgOffset = alignTo(CCInfo.getNextStackOffset(), RegSize); | |||
402 | else { | |||
403 | VaArgOffset = | |||
404 | (int)ABI.GetCalleeAllocdArgSizeInBytes(CCInfo.getCallingConv()) - | |||
405 | (int)(RegSize * (ArgRegs.size() - Idx)); | |||
406 | } | |||
407 | ||||
408 | MachineFrameInfo &MFI = MF.getFrameInfo(); | |||
409 | int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true); | |||
410 | MF.getInfo<MipsFunctionInfo>()->setVarArgsFrameIndex(FI); | |||
411 | ||||
412 | for (unsigned I = Idx; I < ArgRegs.size(); ++I, VaArgOffset += RegSize) { | |||
413 | MIRBuilder.getMBB().addLiveIn(ArgRegs[I]); | |||
414 | LLT RegTy = LLT::scalar(RegSize * 8); | |||
415 | MachineInstrBuilder Copy = | |||
416 | MIRBuilder.buildCopy(RegTy, Register(ArgRegs[I])); | |||
417 | FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true); | |||
418 | MachinePointerInfo MPO = MachinePointerInfo::getFixedStack(MF, FI); | |||
419 | ||||
420 | const LLT PtrTy = LLT::pointer(MPO.getAddrSpace(), 32); | |||
421 | auto FrameIndex = MIRBuilder.buildFrameIndex(PtrTy, FI); | |||
422 | MachineMemOperand *MMO = MF.getMachineMemOperand( | |||
423 | MPO, MachineMemOperand::MOStore, RegTy, Align(RegSize)); | |||
424 | MIRBuilder.buildStore(Copy, FrameIndex, *MMO); | |||
425 | } | |||
426 | } | |||
427 | ||||
428 | return true; | |||
429 | } | |||
430 | ||||
431 | bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, | |||
432 | CallLoweringInfo &Info) const { | |||
433 | ||||
434 | if (Info.CallConv != CallingConv::C) | |||
435 | return false; | |||
436 | ||||
437 | for (auto &Arg : Info.OrigArgs) { | |||
438 | if (!isSupportedArgumentType(Arg.Ty)) | |||
439 | return false; | |||
440 | if (Arg.Flags[0].isByVal()) | |||
441 | return false; | |||
442 | if (Arg.Flags[0].isSRet() && !Arg.Ty->isPointerTy()) | |||
443 | return false; | |||
444 | } | |||
445 | ||||
446 | if (!Info.OrigRet.Ty->isVoidTy() && !isSupportedReturnType(Info.OrigRet.Ty)) | |||
447 | return false; | |||
448 | ||||
449 | MachineFunction &MF = MIRBuilder.getMF(); | |||
450 | const Function &F = MF.getFunction(); | |||
451 | const DataLayout &DL = MF.getDataLayout(); | |||
452 | const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); | |||
453 | const MipsTargetMachine &TM = | |||
454 | static_cast<const MipsTargetMachine &>(MF.getTarget()); | |||
455 | const MipsABIInfo &ABI = TM.getABI(); | |||
456 | ||||
457 | MachineInstrBuilder CallSeqStart = | |||
458 | MIRBuilder.buildInstr(Mips::ADJCALLSTACKDOWN); | |||
459 | ||||
460 | const bool IsCalleeGlobalPIC = | |||
461 | Info.Callee.isGlobal() && TM.isPositionIndependent(); | |||
462 | ||||
463 | MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert( | |||
464 | Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL); | |||
465 | MIB.addDef(Mips::SP, RegState::Implicit); | |||
466 | if (IsCalleeGlobalPIC) { | |||
467 | Register CalleeReg = | |||
468 | MF.getRegInfo().createGenericVirtualRegister(LLT::pointer(0, 32)); | |||
469 | MachineInstr *CalleeGlobalValue = | |||
470 | MIRBuilder.buildGlobalValue(CalleeReg, Info.Callee.getGlobal()); | |||
471 | if (!Info.Callee.getGlobal()->hasLocalLinkage()) | |||
472 | CalleeGlobalValue->getOperand(1).setTargetFlags(MipsII::MO_GOT_CALL); | |||
473 | MIB.addUse(CalleeReg); | |||
474 | } else | |||
475 | MIB.add(Info.Callee); | |||
476 | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); | |||
477 | MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv)); | |||
478 | ||||
479 | TargetLowering::ArgListTy FuncOrigArgs; | |||
480 | FuncOrigArgs.reserve(Info.OrigArgs.size()); | |||
481 | ||||
482 | SmallVector<ArgInfo, 8> ArgInfos; | |||
483 | for (auto &Arg : Info.OrigArgs) | |||
484 | splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv); | |||
485 | ||||
486 | SmallVector<CCValAssign, 8> ArgLocs; | |||
487 | bool IsCalleeVarArg = false; | |||
488 | if (Info.Callee.isGlobal()) { | |||
489 | const Function *CF = static_cast<const Function *>(Info.Callee.getGlobal()); | |||
490 | IsCalleeVarArg = CF->isVarArg(); | |||
491 | } | |||
492 | ||||
493 | // FIXME: Should use MipsCCState::getSpecialCallingConvForCallee, but it | |||
494 | // depends on looking directly at the call target. | |||
495 | MipsCCState CCInfo(Info.CallConv, IsCalleeVarArg, MF, ArgLocs, | |||
496 | F.getContext()); | |||
497 | ||||
498 | CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(Info.CallConv), | |||
499 | Align(1)); | |||
500 | ||||
501 | const char *Call = | |||
502 | Info.Callee.isSymbol() ? Info.Callee.getSymbolName() : nullptr; | |||
503 | ||||
504 | MipsOutgoingValueAssigner Assigner(TLI.CCAssignFnForCall(), Call, | |||
505 | /*IsReturn*/ false); | |||
506 | if (!determineAssignments(Assigner, ArgInfos, CCInfo)) | |||
507 | return false; | |||
508 | ||||
509 | MipsOutgoingValueHandler ArgHandler(MIRBuilder, MF.getRegInfo(), MIB); | |||
510 | if (!handleAssignments(ArgHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) | |||
511 | return false; | |||
512 | ||||
513 | unsigned NextStackOffset = CCInfo.getNextStackOffset(); | |||
514 | unsigned StackAlignment = F.getParent()->getOverrideStackAlignment(); | |||
515 | if (!StackAlignment) { | |||
516 | const TargetFrameLowering *TFL = MF.getSubtarget().getFrameLowering(); | |||
517 | StackAlignment = TFL->getStackAlignment(); | |||
518 | } | |||
519 | NextStackOffset = alignTo(NextStackOffset, StackAlignment); | |||
520 | CallSeqStart.addImm(NextStackOffset).addImm(0); | |||
521 | ||||
522 | if (IsCalleeGlobalPIC) { | |||
523 | MIRBuilder.buildCopy( | |||
524 | Register(Mips::GP), | |||
525 | MF.getInfo<MipsFunctionInfo>()->getGlobalBaseRegForGlobalISel(MF)); | |||
526 | MIB.addDef(Mips::GP, RegState::Implicit); | |||
527 | } | |||
528 | MIRBuilder.insertInstr(MIB); | |||
529 | if (MIB->getOpcode() == Mips::JALRPseudo) { | |||
530 | const MipsSubtarget &STI = | |||
531 | static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget()); | |||
532 | MIB.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(), | |||
533 | *STI.getRegBankInfo()); | |||
534 | } | |||
535 | ||||
536 | if (!Info.OrigRet.Ty->isVoidTy()) { | |||
537 | ArgInfos.clear(); | |||
538 | ||||
539 | CallLowering::splitToValueTypes(Info.OrigRet, ArgInfos, DL, | |||
540 | F.getCallingConv()); | |||
541 | ||||
542 | const std::string FuncName = F.getName().str(); | |||
543 | SmallVector<ISD::InputArg, 8> Ins; | |||
544 | SmallVector<CCValAssign, 8> ArgLocs; | |||
545 | MipsIncomingValueAssigner Assigner(TLI.CCAssignFnForReturn(), | |||
546 | FuncName.c_str(), | |||
547 | /*IsReturn*/ true); | |||
548 | CallReturnHandler RetHandler(MIRBuilder, MF.getRegInfo(), MIB); | |||
549 | ||||
550 | MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, | |||
551 | F.getContext()); | |||
552 | ||||
553 | if (!determineAssignments(Assigner, ArgInfos, CCInfo)) | |||
554 | return false; | |||
555 | ||||
556 | if (!handleAssignments(RetHandler, ArgInfos, CCInfo, ArgLocs, MIRBuilder)) | |||
557 | return false; | |||
558 | } | |||
559 | ||||
560 | MIRBuilder.buildInstr(Mips::ADJCALLSTACKUP).addImm(NextStackOffset).addImm(0); | |||
561 | ||||
562 | return true; | |||
563 | } |