@@ -101,9 +101,9 @@ static bool CC_Sparc_Assign_Ret_Split_64(unsigned &ValNo, MVT &ValVT,
101
101
}
102
102
103
103
// Allocate a full-sized argument for the 64-bit ABI.
104
- static bool CC_Sparc64_Full ( unsigned &ValNo, MVT &ValVT,
105
- MVT &LocVT, CCValAssign::LocInfo &LocInfo,
106
- ISD::ArgFlagsTy &ArgFlags, CCState &State) {
104
+ static bool Analyze_CC_Sparc64_Full ( bool IsReturn, unsigned &ValNo, MVT &ValVT,
105
+ MVT &LocVT, CCValAssign::LocInfo &LocInfo,
106
+ ISD::ArgFlagsTy &ArgFlags, CCState &State) {
107
107
assert ((LocVT == MVT::f32 || LocVT == MVT::f128
108
108
|| LocVT.getSizeInBits () == 64 ) &&
109
109
" Can't handle non-64 bits locations" );
@@ -133,6 +133,11 @@ static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT,
133
133
return true ;
134
134
}
135
135
136
+ // Bail out if this is a return CC and we run out of registers to place
137
+ // values into.
138
+ if (IsReturn)
139
+ return false ;
140
+
136
141
// This argument goes on the stack in an 8-byte slot.
137
142
// When passing floats, LocVT is smaller than 8 bytes. Adjust the offset to
138
143
// the right-aligned float. The first 4 bytes of the stack slot are undefined.
@@ -146,9 +151,9 @@ static bool CC_Sparc64_Full(unsigned &ValNo, MVT &ValVT,
146
151
// Allocate a half-sized argument for the 64-bit ABI.
147
152
//
148
153
// This is used when passing { float, int } structs by value in registers.
149
- static bool CC_Sparc64_Half ( unsigned &ValNo, MVT &ValVT,
150
- MVT &LocVT, CCValAssign::LocInfo &LocInfo,
151
- ISD::ArgFlagsTy &ArgFlags, CCState &State) {
154
+ static bool Analyze_CC_Sparc64_Half ( bool IsReturn, unsigned &ValNo, MVT &ValVT,
155
+ MVT &LocVT, CCValAssign::LocInfo &LocInfo,
156
+ ISD::ArgFlagsTy &ArgFlags, CCState &State) {
152
157
assert (LocVT.getSizeInBits () == 32 && " Can't handle non-32 bits locations" );
153
158
unsigned Offset = State.AllocateStack (4 , Align (4 ));
154
159
@@ -174,10 +179,43 @@ static bool CC_Sparc64_Half(unsigned &ValNo, MVT &ValVT,
174
179
return true ;
175
180
}
176
181
182
+ // Bail out if this is a return CC and we run out of registers to place
183
+ // values into.
184
+ if (IsReturn)
185
+ return false ;
186
+
177
187
State.addLoc (CCValAssign::getMem (ValNo, ValVT, Offset, LocVT, LocInfo));
178
188
return true ;
179
189
}
180
190
191
+ static bool CC_Sparc64_Full (unsigned &ValNo, MVT &ValVT, MVT &LocVT,
192
+ CCValAssign::LocInfo &LocInfo,
193
+ ISD::ArgFlagsTy &ArgFlags, CCState &State) {
194
+ return Analyze_CC_Sparc64_Full (false , ValNo, ValVT, LocVT, LocInfo, ArgFlags,
195
+ State);
196
+ }
197
+
198
+ static bool CC_Sparc64_Half (unsigned &ValNo, MVT &ValVT, MVT &LocVT,
199
+ CCValAssign::LocInfo &LocInfo,
200
+ ISD::ArgFlagsTy &ArgFlags, CCState &State) {
201
+ return Analyze_CC_Sparc64_Half (false , ValNo, ValVT, LocVT, LocInfo, ArgFlags,
202
+ State);
203
+ }
204
+
205
+ static bool RetCC_Sparc64_Full (unsigned &ValNo, MVT &ValVT, MVT &LocVT,
206
+ CCValAssign::LocInfo &LocInfo,
207
+ ISD::ArgFlagsTy &ArgFlags, CCState &State) {
208
+ return Analyze_CC_Sparc64_Full (true , ValNo, ValVT, LocVT, LocInfo, ArgFlags,
209
+ State);
210
+ }
211
+
212
+ static bool RetCC_Sparc64_Half (unsigned &ValNo, MVT &ValVT, MVT &LocVT,
213
+ CCValAssign::LocInfo &LocInfo,
214
+ ISD::ArgFlagsTy &ArgFlags, CCState &State) {
215
+ return Analyze_CC_Sparc64_Half (true , ValNo, ValVT, LocVT, LocInfo, ArgFlags,
216
+ State);
217
+ }
218
+
181
219
#include " SparcGenCallingConv.inc"
182
220
183
221
// The calling conventions in SparcCallingConv.td are described in terms of the
@@ -191,6 +229,15 @@ static unsigned toCallerWindow(unsigned Reg) {
191
229
return Reg;
192
230
}
193
231
232
+ bool SparcTargetLowering::CanLowerReturn (
233
+ CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
234
+ const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
235
+ SmallVector<CCValAssign, 16 > RVLocs;
236
+ CCState CCInfo (CallConv, isVarArg, MF, RVLocs, Context);
237
+ return CCInfo.CheckReturn (Outs, Subtarget->is64Bit () ? RetCC_Sparc64
238
+ : RetCC_Sparc32);
239
+ }
240
+
194
241
SDValue
195
242
SparcTargetLowering::LowerReturn (SDValue Chain, CallingConv::ID CallConv,
196
243
bool IsVarArg,
@@ -1030,6 +1077,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
1030
1077
1031
1078
// Copy all of the result registers out of their specified physreg.
1032
1079
for (unsigned i = 0 ; i != RVLocs.size (); ++i) {
1080
+ assert (RVLocs[i].isRegLoc () && " Can only return in registers!" );
1033
1081
if (RVLocs[i].getLocVT () == MVT::v2i32) {
1034
1082
SDValue Vec = DAG.getNode (ISD::UNDEF, dl, MVT::v2i32);
1035
1083
SDValue Lo = DAG.getCopyFromReg (
@@ -1344,6 +1392,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
1344
1392
// Copy all of the result registers out of their specified physreg.
1345
1393
for (unsigned i = 0 ; i != RVLocs.size (); ++i) {
1346
1394
CCValAssign &VA = RVLocs[i];
1395
+ assert (VA.isRegLoc () && " Can only return in registers!" );
1347
1396
unsigned Reg = toCallerWindow (VA.getLocReg ());
1348
1397
1349
1398
// When returning 'inreg {i32, i32 }', two consecutive i32 arguments can
0 commit comments