xref: /aosp_15_r20/external/llvm/lib/Target/ARM/ARMCallingConv.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //=== ARMCallingConv.h - ARM Custom Calling Convention Routines -*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the custom routines for the ARM Calling Convention that
11*9880d681SAndroid Build Coastguard Worker // aren't done by tablegen.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_ARM_ARMCALLINGCONV_H
16*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_ARM_ARMCALLINGCONV_H
17*9880d681SAndroid Build Coastguard Worker 
18*9880d681SAndroid Build Coastguard Worker #include "ARM.h"
19*9880d681SAndroid Build Coastguard Worker #include "ARMBaseInstrInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "ARMSubtarget.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/CallingConvLower.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/CallingConv.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
24*9880d681SAndroid Build Coastguard Worker 
25*9880d681SAndroid Build Coastguard Worker namespace llvm {
26*9880d681SAndroid Build Coastguard Worker 
27*9880d681SAndroid Build Coastguard Worker // APCS f64 is in register pairs, possibly split to stack
f64AssignAPCS(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,CCState & State,bool CanFail)28*9880d681SAndroid Build Coastguard Worker static bool f64AssignAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
29*9880d681SAndroid Build Coastguard Worker                           CCValAssign::LocInfo &LocInfo,
30*9880d681SAndroid Build Coastguard Worker                           CCState &State, bool CanFail) {
31*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker   // Try to get the first register.
34*9880d681SAndroid Build Coastguard Worker   if (unsigned Reg = State.AllocateReg(RegList))
35*9880d681SAndroid Build Coastguard Worker     State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
36*9880d681SAndroid Build Coastguard Worker   else {
37*9880d681SAndroid Build Coastguard Worker     // For the 2nd half of a v2f64, do not fail.
38*9880d681SAndroid Build Coastguard Worker     if (CanFail)
39*9880d681SAndroid Build Coastguard Worker       return false;
40*9880d681SAndroid Build Coastguard Worker 
41*9880d681SAndroid Build Coastguard Worker     // Put the whole thing on the stack.
42*9880d681SAndroid Build Coastguard Worker     State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
43*9880d681SAndroid Build Coastguard Worker                                            State.AllocateStack(8, 4),
44*9880d681SAndroid Build Coastguard Worker                                            LocVT, LocInfo));
45*9880d681SAndroid Build Coastguard Worker     return true;
46*9880d681SAndroid Build Coastguard Worker   }
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker   // Try to get the second register.
49*9880d681SAndroid Build Coastguard Worker   if (unsigned Reg = State.AllocateReg(RegList))
50*9880d681SAndroid Build Coastguard Worker     State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
51*9880d681SAndroid Build Coastguard Worker   else
52*9880d681SAndroid Build Coastguard Worker     State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
53*9880d681SAndroid Build Coastguard Worker                                            State.AllocateStack(4, 4),
54*9880d681SAndroid Build Coastguard Worker                                            LocVT, LocInfo));
55*9880d681SAndroid Build Coastguard Worker   return true;
56*9880d681SAndroid Build Coastguard Worker }
57*9880d681SAndroid Build Coastguard Worker 
CC_ARM_APCS_Custom_f64(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)58*9880d681SAndroid Build Coastguard Worker static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
59*9880d681SAndroid Build Coastguard Worker                                    CCValAssign::LocInfo &LocInfo,
60*9880d681SAndroid Build Coastguard Worker                                    ISD::ArgFlagsTy &ArgFlags,
61*9880d681SAndroid Build Coastguard Worker                                    CCState &State) {
62*9880d681SAndroid Build Coastguard Worker   if (!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
63*9880d681SAndroid Build Coastguard Worker     return false;
64*9880d681SAndroid Build Coastguard Worker   if (LocVT == MVT::v2f64 &&
65*9880d681SAndroid Build Coastguard Worker       !f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, false))
66*9880d681SAndroid Build Coastguard Worker     return false;
67*9880d681SAndroid Build Coastguard Worker   return true;  // we handled it
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker // AAPCS f64 is in aligned register pairs
f64AssignAAPCS(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,CCState & State,bool CanFail)71*9880d681SAndroid Build Coastguard Worker static bool f64AssignAAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
72*9880d681SAndroid Build Coastguard Worker                            CCValAssign::LocInfo &LocInfo,
73*9880d681SAndroid Build Coastguard Worker                            CCState &State, bool CanFail) {
74*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
75*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
76*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg ShadowRegList[] = { ARM::R0, ARM::R1 };
77*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg GPRArgRegs[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker   unsigned Reg = State.AllocateReg(HiRegList, ShadowRegList);
80*9880d681SAndroid Build Coastguard Worker   if (Reg == 0) {
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker     // If we had R3 unallocated only, now we still must to waste it.
83*9880d681SAndroid Build Coastguard Worker     Reg = State.AllocateReg(GPRArgRegs);
84*9880d681SAndroid Build Coastguard Worker     assert((!Reg || Reg == ARM::R3) && "Wrong GPRs usage for f64");
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker     // For the 2nd half of a v2f64, do not just fail.
87*9880d681SAndroid Build Coastguard Worker     if (CanFail)
88*9880d681SAndroid Build Coastguard Worker       return false;
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker     // Put the whole thing on the stack.
91*9880d681SAndroid Build Coastguard Worker     State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
92*9880d681SAndroid Build Coastguard Worker                                            State.AllocateStack(8, 8),
93*9880d681SAndroid Build Coastguard Worker                                            LocVT, LocInfo));
94*9880d681SAndroid Build Coastguard Worker     return true;
95*9880d681SAndroid Build Coastguard Worker   }
96*9880d681SAndroid Build Coastguard Worker 
97*9880d681SAndroid Build Coastguard Worker   unsigned i;
98*9880d681SAndroid Build Coastguard Worker   for (i = 0; i < 2; ++i)
99*9880d681SAndroid Build Coastguard Worker     if (HiRegList[i] == Reg)
100*9880d681SAndroid Build Coastguard Worker       break;
101*9880d681SAndroid Build Coastguard Worker 
102*9880d681SAndroid Build Coastguard Worker   unsigned T = State.AllocateReg(LoRegList[i]);
103*9880d681SAndroid Build Coastguard Worker   (void)T;
104*9880d681SAndroid Build Coastguard Worker   assert(T == LoRegList[i] && "Could not allocate register");
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker   State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
107*9880d681SAndroid Build Coastguard Worker   State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
108*9880d681SAndroid Build Coastguard Worker                                          LocVT, LocInfo));
109*9880d681SAndroid Build Coastguard Worker   return true;
110*9880d681SAndroid Build Coastguard Worker }
111*9880d681SAndroid Build Coastguard Worker 
CC_ARM_AAPCS_Custom_f64(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)112*9880d681SAndroid Build Coastguard Worker static bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
113*9880d681SAndroid Build Coastguard Worker                                     CCValAssign::LocInfo &LocInfo,
114*9880d681SAndroid Build Coastguard Worker                                     ISD::ArgFlagsTy &ArgFlags,
115*9880d681SAndroid Build Coastguard Worker                                     CCState &State) {
116*9880d681SAndroid Build Coastguard Worker   if (!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
117*9880d681SAndroid Build Coastguard Worker     return false;
118*9880d681SAndroid Build Coastguard Worker   if (LocVT == MVT::v2f64 &&
119*9880d681SAndroid Build Coastguard Worker       !f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, false))
120*9880d681SAndroid Build Coastguard Worker     return false;
121*9880d681SAndroid Build Coastguard Worker   return true;  // we handled it
122*9880d681SAndroid Build Coastguard Worker }
123*9880d681SAndroid Build Coastguard Worker 
f64RetAssign(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,CCState & State)124*9880d681SAndroid Build Coastguard Worker static bool f64RetAssign(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
125*9880d681SAndroid Build Coastguard Worker                          CCValAssign::LocInfo &LocInfo, CCState &State) {
126*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
127*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker   unsigned Reg = State.AllocateReg(HiRegList, LoRegList);
130*9880d681SAndroid Build Coastguard Worker   if (Reg == 0)
131*9880d681SAndroid Build Coastguard Worker     return false; // we didn't handle it
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker   unsigned i;
134*9880d681SAndroid Build Coastguard Worker   for (i = 0; i < 2; ++i)
135*9880d681SAndroid Build Coastguard Worker     if (HiRegList[i] == Reg)
136*9880d681SAndroid Build Coastguard Worker       break;
137*9880d681SAndroid Build Coastguard Worker 
138*9880d681SAndroid Build Coastguard Worker   State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
139*9880d681SAndroid Build Coastguard Worker   State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
140*9880d681SAndroid Build Coastguard Worker                                          LocVT, LocInfo));
141*9880d681SAndroid Build Coastguard Worker   return true;
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker 
RetCC_ARM_APCS_Custom_f64(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)144*9880d681SAndroid Build Coastguard Worker static bool RetCC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
145*9880d681SAndroid Build Coastguard Worker                                       CCValAssign::LocInfo &LocInfo,
146*9880d681SAndroid Build Coastguard Worker                                       ISD::ArgFlagsTy &ArgFlags,
147*9880d681SAndroid Build Coastguard Worker                                       CCState &State) {
148*9880d681SAndroid Build Coastguard Worker   if (!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
149*9880d681SAndroid Build Coastguard Worker     return false;
150*9880d681SAndroid Build Coastguard Worker   if (LocVT == MVT::v2f64 && !f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
151*9880d681SAndroid Build Coastguard Worker     return false;
152*9880d681SAndroid Build Coastguard Worker   return true;  // we handled it
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker 
RetCC_ARM_AAPCS_Custom_f64(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)155*9880d681SAndroid Build Coastguard Worker static bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
156*9880d681SAndroid Build Coastguard Worker                                        CCValAssign::LocInfo &LocInfo,
157*9880d681SAndroid Build Coastguard Worker                                        ISD::ArgFlagsTy &ArgFlags,
158*9880d681SAndroid Build Coastguard Worker                                        CCState &State) {
159*9880d681SAndroid Build Coastguard Worker   return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
160*9880d681SAndroid Build Coastguard Worker                                    State);
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker 
163*9880d681SAndroid Build Coastguard Worker static const MCPhysReg RRegList[] = { ARM::R0,  ARM::R1,  ARM::R2,  ARM::R3 };
164*9880d681SAndroid Build Coastguard Worker 
165*9880d681SAndroid Build Coastguard Worker static const MCPhysReg SRegList[] = { ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
166*9880d681SAndroid Build Coastguard Worker                                       ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
167*9880d681SAndroid Build Coastguard Worker                                       ARM::S8,  ARM::S9,  ARM::S10, ARM::S11,
168*9880d681SAndroid Build Coastguard Worker                                       ARM::S12, ARM::S13, ARM::S14,  ARM::S15 };
169*9880d681SAndroid Build Coastguard Worker static const MCPhysReg DRegList[] = { ARM::D0, ARM::D1, ARM::D2, ARM::D3,
170*9880d681SAndroid Build Coastguard Worker                                       ARM::D4, ARM::D5, ARM::D6, ARM::D7 };
171*9880d681SAndroid Build Coastguard Worker static const MCPhysReg QRegList[] = { ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3 };
172*9880d681SAndroid Build Coastguard Worker 
173*9880d681SAndroid Build Coastguard Worker 
174*9880d681SAndroid Build Coastguard Worker // Allocate part of an AAPCS HFA or HVA. We assume that each member of the HA
175*9880d681SAndroid Build Coastguard Worker // has InConsecutiveRegs set, and that the last member also has
176*9880d681SAndroid Build Coastguard Worker // InConsecutiveRegsLast set. We must process all members of the HA before
177*9880d681SAndroid Build Coastguard Worker // we can allocate it, as we need to know the total number of registers that
178*9880d681SAndroid Build Coastguard Worker // will be needed in order to (attempt to) allocate a contiguous block.
CC_ARM_AAPCS_Custom_Aggregate(unsigned & ValNo,MVT & ValVT,MVT & LocVT,CCValAssign::LocInfo & LocInfo,ISD::ArgFlagsTy & ArgFlags,CCState & State)179*9880d681SAndroid Build Coastguard Worker static bool CC_ARM_AAPCS_Custom_Aggregate(unsigned &ValNo, MVT &ValVT,
180*9880d681SAndroid Build Coastguard Worker                                           MVT &LocVT,
181*9880d681SAndroid Build Coastguard Worker                                           CCValAssign::LocInfo &LocInfo,
182*9880d681SAndroid Build Coastguard Worker                                           ISD::ArgFlagsTy &ArgFlags,
183*9880d681SAndroid Build Coastguard Worker                                           CCState &State) {
184*9880d681SAndroid Build Coastguard Worker   SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
185*9880d681SAndroid Build Coastguard Worker 
186*9880d681SAndroid Build Coastguard Worker   // AAPCS HFAs must have 1-4 elements, all of the same type
187*9880d681SAndroid Build Coastguard Worker   if (PendingMembers.size() > 0)
188*9880d681SAndroid Build Coastguard Worker     assert(PendingMembers[0].getLocVT() == LocVT);
189*9880d681SAndroid Build Coastguard Worker 
190*9880d681SAndroid Build Coastguard Worker   // Add the argument to the list to be allocated once we know the size of the
191*9880d681SAndroid Build Coastguard Worker   // aggregate. Store the type's required alignmnent as extra info for later: in
192*9880d681SAndroid Build Coastguard Worker   // the [N x i64] case all trace has been removed by the time we actually get
193*9880d681SAndroid Build Coastguard Worker   // to do allocation.
194*9880d681SAndroid Build Coastguard Worker   PendingMembers.push_back(CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo,
195*9880d681SAndroid Build Coastguard Worker                                                    ArgFlags.getOrigAlign()));
196*9880d681SAndroid Build Coastguard Worker 
197*9880d681SAndroid Build Coastguard Worker   if (!ArgFlags.isInConsecutiveRegsLast())
198*9880d681SAndroid Build Coastguard Worker     return true;
199*9880d681SAndroid Build Coastguard Worker 
200*9880d681SAndroid Build Coastguard Worker   // Try to allocate a contiguous block of registers, each of the correct
201*9880d681SAndroid Build Coastguard Worker   // size to hold one member.
202*9880d681SAndroid Build Coastguard Worker   auto &DL = State.getMachineFunction().getDataLayout();
203*9880d681SAndroid Build Coastguard Worker   unsigned StackAlign = DL.getStackAlignment();
204*9880d681SAndroid Build Coastguard Worker   unsigned Align = std::min(PendingMembers[0].getExtraInfo(), StackAlign);
205*9880d681SAndroid Build Coastguard Worker 
206*9880d681SAndroid Build Coastguard Worker   ArrayRef<MCPhysReg> RegList;
207*9880d681SAndroid Build Coastguard Worker   switch (LocVT.SimpleTy) {
208*9880d681SAndroid Build Coastguard Worker   case MVT::i32: {
209*9880d681SAndroid Build Coastguard Worker     RegList = RRegList;
210*9880d681SAndroid Build Coastguard Worker     unsigned RegIdx = State.getFirstUnallocated(RegList);
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker     // First consume all registers that would give an unaligned object. Whether
213*9880d681SAndroid Build Coastguard Worker     // we go on stack or in regs, no-one will be using them in future.
214*9880d681SAndroid Build Coastguard Worker     unsigned RegAlign = alignTo(Align, 4) / 4;
215*9880d681SAndroid Build Coastguard Worker     while (RegIdx % RegAlign != 0 && RegIdx < RegList.size())
216*9880d681SAndroid Build Coastguard Worker       State.AllocateReg(RegList[RegIdx++]);
217*9880d681SAndroid Build Coastguard Worker 
218*9880d681SAndroid Build Coastguard Worker     break;
219*9880d681SAndroid Build Coastguard Worker   }
220*9880d681SAndroid Build Coastguard Worker   case MVT::f32:
221*9880d681SAndroid Build Coastguard Worker     RegList = SRegList;
222*9880d681SAndroid Build Coastguard Worker     break;
223*9880d681SAndroid Build Coastguard Worker   case MVT::f64:
224*9880d681SAndroid Build Coastguard Worker     RegList = DRegList;
225*9880d681SAndroid Build Coastguard Worker     break;
226*9880d681SAndroid Build Coastguard Worker   case MVT::v2f64:
227*9880d681SAndroid Build Coastguard Worker     RegList = QRegList;
228*9880d681SAndroid Build Coastguard Worker     break;
229*9880d681SAndroid Build Coastguard Worker   default:
230*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unexpected member type for block aggregate");
231*9880d681SAndroid Build Coastguard Worker     break;
232*9880d681SAndroid Build Coastguard Worker   }
233*9880d681SAndroid Build Coastguard Worker 
234*9880d681SAndroid Build Coastguard Worker   unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
235*9880d681SAndroid Build Coastguard Worker   if (RegResult) {
236*9880d681SAndroid Build Coastguard Worker     for (SmallVectorImpl<CCValAssign>::iterator It = PendingMembers.begin();
237*9880d681SAndroid Build Coastguard Worker          It != PendingMembers.end(); ++It) {
238*9880d681SAndroid Build Coastguard Worker       It->convertToReg(RegResult);
239*9880d681SAndroid Build Coastguard Worker       State.addLoc(*It);
240*9880d681SAndroid Build Coastguard Worker       ++RegResult;
241*9880d681SAndroid Build Coastguard Worker     }
242*9880d681SAndroid Build Coastguard Worker     PendingMembers.clear();
243*9880d681SAndroid Build Coastguard Worker     return true;
244*9880d681SAndroid Build Coastguard Worker   }
245*9880d681SAndroid Build Coastguard Worker 
246*9880d681SAndroid Build Coastguard Worker   // Register allocation failed, we'll be needing the stack
247*9880d681SAndroid Build Coastguard Worker   unsigned Size = LocVT.getSizeInBits() / 8;
248*9880d681SAndroid Build Coastguard Worker   if (LocVT == MVT::i32 && State.getNextStackOffset() == 0) {
249*9880d681SAndroid Build Coastguard Worker     // If nothing else has used the stack until this point, a non-HFA aggregate
250*9880d681SAndroid Build Coastguard Worker     // can be split between regs and stack.
251*9880d681SAndroid Build Coastguard Worker     unsigned RegIdx = State.getFirstUnallocated(RegList);
252*9880d681SAndroid Build Coastguard Worker     for (auto &It : PendingMembers) {
253*9880d681SAndroid Build Coastguard Worker       if (RegIdx >= RegList.size())
254*9880d681SAndroid Build Coastguard Worker         It.convertToMem(State.AllocateStack(Size, Size));
255*9880d681SAndroid Build Coastguard Worker       else
256*9880d681SAndroid Build Coastguard Worker         It.convertToReg(State.AllocateReg(RegList[RegIdx++]));
257*9880d681SAndroid Build Coastguard Worker 
258*9880d681SAndroid Build Coastguard Worker       State.addLoc(It);
259*9880d681SAndroid Build Coastguard Worker     }
260*9880d681SAndroid Build Coastguard Worker     PendingMembers.clear();
261*9880d681SAndroid Build Coastguard Worker     return true;
262*9880d681SAndroid Build Coastguard Worker   } else if (LocVT != MVT::i32)
263*9880d681SAndroid Build Coastguard Worker     RegList = SRegList;
264*9880d681SAndroid Build Coastguard Worker 
265*9880d681SAndroid Build Coastguard Worker   // Mark all regs as unavailable (AAPCS rule C.2.vfp for VFP, C.6 for core)
266*9880d681SAndroid Build Coastguard Worker   for (auto Reg : RegList)
267*9880d681SAndroid Build Coastguard Worker     State.AllocateReg(Reg);
268*9880d681SAndroid Build Coastguard Worker 
269*9880d681SAndroid Build Coastguard Worker   for (auto &It : PendingMembers) {
270*9880d681SAndroid Build Coastguard Worker     It.convertToMem(State.AllocateStack(Size, Align));
271*9880d681SAndroid Build Coastguard Worker     State.addLoc(It);
272*9880d681SAndroid Build Coastguard Worker 
273*9880d681SAndroid Build Coastguard Worker     // After the first item has been allocated, the rest are packed as tightly
274*9880d681SAndroid Build Coastguard Worker     // as possible. (E.g. an incoming i64 would have starting Align of 8, but
275*9880d681SAndroid Build Coastguard Worker     // we'll be allocating a bunch of i32 slots).
276*9880d681SAndroid Build Coastguard Worker     Align = Size;
277*9880d681SAndroid Build Coastguard Worker   }
278*9880d681SAndroid Build Coastguard Worker 
279*9880d681SAndroid Build Coastguard Worker   // All pending members have now been allocated
280*9880d681SAndroid Build Coastguard Worker   PendingMembers.clear();
281*9880d681SAndroid Build Coastguard Worker 
282*9880d681SAndroid Build Coastguard Worker   // This will be allocated by the last member of the aggregate
283*9880d681SAndroid Build Coastguard Worker   return true;
284*9880d681SAndroid Build Coastguard Worker }
285*9880d681SAndroid Build Coastguard Worker 
286*9880d681SAndroid Build Coastguard Worker } // End llvm namespace
287*9880d681SAndroid Build Coastguard Worker 
288*9880d681SAndroid Build Coastguard Worker #endif
289