@@ -4177,21 +4177,38 @@ namespace {
4177
4177
// / PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
4178
4178
class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
4179
4179
bool IsSoftFloatABI;
4180
+ bool IsRetSmallStructInRegABI;
4180
4181
4181
4182
CharUnits getParamTypeAlignment (QualType Ty) const ;
4182
4183
4183
4184
public:
4184
- PPC32_SVR4_ABIInfo (CodeGen::CodeGenTypes &CGT, bool SoftFloatABI)
4185
- : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI) {}
4185
+ PPC32_SVR4_ABIInfo (CodeGen::CodeGenTypes &CGT, bool SoftFloatABI,
4186
+ bool RetSmallStructInRegABI)
4187
+ : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI),
4188
+ IsRetSmallStructInRegABI (RetSmallStructInRegABI) {}
4189
+
4190
+ ABIArgInfo classifyReturnType (QualType RetTy) const ;
4191
+
4192
+ void computeInfo (CGFunctionInfo &FI) const override {
4193
+ if (!getCXXABI ().classifyReturnType (FI))
4194
+ FI.getReturnInfo () = classifyReturnType (FI.getReturnType ());
4195
+ for (auto &I : FI.arguments ())
4196
+ I.info = classifyArgumentType (I.type );
4197
+ }
4186
4198
4187
4199
Address EmitVAArg (CodeGenFunction &CGF, Address VAListAddr,
4188
4200
QualType Ty) const override ;
4189
4201
};
4190
4202
4191
4203
class PPC32TargetCodeGenInfo : public TargetCodeGenInfo {
4192
4204
public:
4193
- PPC32TargetCodeGenInfo (CodeGenTypes &CGT, bool SoftFloatABI)
4194
- : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI)) {}
4205
+ PPC32TargetCodeGenInfo (CodeGenTypes &CGT, bool SoftFloatABI,
4206
+ bool RetSmallStructInRegABI)
4207
+ : TargetCodeGenInfo(new PPC32_SVR4_ABIInfo(CGT, SoftFloatABI,
4208
+ RetSmallStructInRegABI)) {}
4209
+
4210
+ static bool isStructReturnInRegABI (const llvm::Triple &Triple,
4211
+ const CodeGenOptions &Opts);
4195
4212
4196
4213
int getDwarfEHStackPointer (CodeGen::CodeGenModule &M) const override {
4197
4214
// This is recovered from gcc output.
@@ -4227,6 +4244,34 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
4227
4244
return CharUnits::fromQuantity (4 );
4228
4245
}
4229
4246
4247
+ ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType (QualType RetTy) const {
4248
+ uint64_t Size;
4249
+
4250
+ // -msvr4-struct-return puts small aggregates in GPR3 and GPR4.
4251
+ if (isAggregateTypeForABI (RetTy) && IsRetSmallStructInRegABI &&
4252
+ (Size = getContext ().getTypeSize (RetTy)) <= 64 ) {
4253
+ // System V ABI (1995), page 3-22, specified:
4254
+ // > A structure or union whose size is less than or equal to 8 bytes
4255
+ // > shall be returned in r3 and r4, as if it were first stored in the
4256
+ // > 8-byte aligned memory area and then the low addressed word were
4257
+ // > loaded into r3 and the high-addressed word into r4. Bits beyond
4258
+ // > the last member of the structure or union are not defined.
4259
+ //
4260
+ // GCC for big-endian PPC32 inserts the pad before the first member,
4261
+ // not "beyond the last member" of the struct. To stay compatible
4262
+ // with GCC, we coerce the struct to an integer of the same size.
4263
+ // LLVM will extend it and return i32 in r3, or i64 in r3:r4.
4264
+ if (Size == 0 )
4265
+ return ABIArgInfo::getIgnore ();
4266
+ else {
4267
+ llvm::Type *CoerceTy = llvm::Type::getIntNTy (getVMContext (), Size);
4268
+ return ABIArgInfo::getDirect (CoerceTy);
4269
+ }
4270
+ }
4271
+
4272
+ return DefaultABIInfo::classifyReturnType (RetTy);
4273
+ }
4274
+
4230
4275
// TODO: this implementation is now likely redundant with
4231
4276
// DefaultABIInfo::EmitVAArg.
4232
4277
Address PPC32_SVR4_ABIInfo::EmitVAArg (CodeGenFunction &CGF, Address VAList,
@@ -4382,6 +4427,25 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
4382
4427
return Result;
4383
4428
}
4384
4429
4430
+ bool PPC32TargetCodeGenInfo::isStructReturnInRegABI (
4431
+ const llvm::Triple &Triple, const CodeGenOptions &Opts) {
4432
+ assert (Triple.getArch () == llvm::Triple::ppc);
4433
+
4434
+ switch (Opts.getStructReturnConvention ()) {
4435
+ case CodeGenOptions::SRCK_Default:
4436
+ break ;
4437
+ case CodeGenOptions::SRCK_OnStack: // -maix-struct-return
4438
+ return false ;
4439
+ case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return
4440
+ return true ;
4441
+ }
4442
+
4443
+ if (Triple.isOSBinFormatELF () && !Triple.isOSLinux ())
4444
+ return true ;
4445
+
4446
+ return false ;
4447
+ }
4448
+
4385
4449
bool
4386
4450
PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable (CodeGen::CodeGenFunction &CGF,
4387
4451
llvm::Value *Address) const {
@@ -10264,10 +10328,14 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
10264
10328
return SetCGInfo (new ARMTargetCodeGenInfo (Types, Kind));
10265
10329
}
10266
10330
10267
- case llvm::Triple::ppc:
10331
+ case llvm::Triple::ppc: {
10332
+ bool IsSoftFloat =
10333
+ CodeGenOpts.FloatABI == " soft" || getTarget ().hasFeature (" spe" );
10334
+ bool RetSmallStructInRegABI =
10335
+ PPC32TargetCodeGenInfo::isStructReturnInRegABI (Triple, CodeGenOpts);
10268
10336
return SetCGInfo (
10269
- new PPC32TargetCodeGenInfo (Types, CodeGenOpts. FloatABI == " soft " ||
10270
- getTarget (). hasFeature ( " spe " )));
10337
+ new PPC32TargetCodeGenInfo (Types, IsSoftFloat, RetSmallStructInRegABI));
10338
+ }
10271
10339
case llvm::Triple::ppc64:
10272
10340
if (Triple.isOSBinFormatELF ()) {
10273
10341
PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1;
0 commit comments