clang 23.0.0git
SystemZ.cpp
Go to the documentation of this file.
1//===- SystemZ.cpp --------------------------------------------------------===//
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#include "ABIInfoImpl.h"
10#include "TargetInfo.h"
12#include "llvm/IR/IntrinsicsS390.h"
13
14using namespace clang;
15using namespace clang::CodeGen;
16
17//===----------------------------------------------------------------------===//
18// SystemZ ABI Implementation
19//===----------------------------------------------------------------------===//
20
21namespace {
22
23class SystemZABIInfo : public ABIInfo {
24 bool HasVector;
25 bool IsSoftFloatABI;
26
27public:
28 SystemZABIInfo(CodeGenTypes &CGT, bool HV, bool SF)
29 : ABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {}
30
31 bool isPromotableIntegerTypeForABI(QualType Ty) const;
32 bool isCompoundType(QualType Ty) const;
33 bool isVectorArgumentType(QualType Ty) const;
34 llvm::Type *getFPArgumentType(QualType Ty, uint64_t Size) const;
35 QualType getSingleElementType(QualType Ty) const;
36
37 ABIArgInfo classifyReturnType(QualType RetTy) const;
38 ABIArgInfo classifyArgumentType(QualType ArgTy) const;
39
40 void computeInfo(CGFunctionInfo &FI) const override;
41 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
42 AggValueSlot Slot) const override;
43};
44
45class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
46 ASTContext &Ctx;
47
48 // These are used for speeding up the search for a visible vector ABI.
49 mutable bool HasVisibleVecABIFlag = false;
50 mutable std::set<const Type *> SeenTypes;
51
52 // Returns true (the first time) if Ty is, or is found to include, a vector
53 // type that exposes the vector ABI. This is any vector >=16 bytes which
54 // with vector support are aligned to only 8 bytes. When IsParam is true,
55 // the type belongs to a value as passed between functions. If it is a
56 // vector <=16 bytes it will be passed in a vector register (if supported).
57 bool isVectorTypeBased(const Type *Ty, bool IsParam) const;
58
59public:
60 SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI)
61 : TargetCodeGenInfo(
62 std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)),
63 Ctx(CGT.getContext()) {
64 SwiftInfo =
65 std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
66 }
67
68 // The vector ABI is different when the vector facility is present and when
69 // a module e.g. defines an externally visible vector variable, a flag
70 // indicating a visible vector ABI is added. Eventually this will result in
71 // a GNU attribute indicating the vector ABI of the module. Ty is the type
72 // of a variable or function parameter that is globally visible.
73 void handleExternallyVisibleObjABI(const Type *Ty, CodeGen::CodeGenModule &M,
74 bool IsParam) const {
75 if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty, IsParam)) {
76 M.getModule().addModuleFlag(llvm::Module::Warning,
77 "s390x-visible-vector-ABI", 1);
78 HasVisibleVecABIFlag = true;
79 }
80 }
81
82 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
83 CodeGen::CodeGenModule &M) const override {
84 if (!D)
85 return;
86
87 // Check if the vector ABI becomes visible by an externally visible
88 // variable or function.
89 if (const auto *VD = dyn_cast<VarDecl>(D)) {
90 if (VD->isExternallyVisible())
91 handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M,
92 /*IsParam*/false);
93 }
94 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
95 if (FD->isExternallyVisible())
96 handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M,
97 /*IsParam*/false);
98 }
99 }
100
101 llvm::Value *testFPKind(llvm::Value *V, unsigned BuiltinID,
102 CGBuilderTy &Builder,
103 CodeGenModule &CGM) const override {
104 assert(V->getType()->isFloatingPointTy() && "V should have an FP type.");
105 // Only use TDC in constrained FP mode.
106 if (!Builder.getIsFPConstrained())
107 return nullptr;
108
109 llvm::Type *Ty = V->getType();
110 if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy() ||
111 Ty->isFP128Ty()) {
112 llvm::Module &M = CGM.getModule();
113 auto &Ctx = M.getContext();
114 llvm::Function *TDCFunc = llvm::Intrinsic::getOrInsertDeclaration(
115 &M, llvm::Intrinsic::s390_tdc, Ty);
116 unsigned TDCBits = 0;
117 switch (BuiltinID) {
118 case Builtin::BI__builtin_isnan:
119 TDCBits = 0xf;
120 break;
121 case Builtin::BIfinite:
122 case Builtin::BI__finite:
123 case Builtin::BIfinitef:
124 case Builtin::BI__finitef:
125 case Builtin::BIfinitel:
126 case Builtin::BI__finitel:
127 case Builtin::BI__builtin_isfinite:
128 TDCBits = 0xfc0;
129 break;
130 case Builtin::BI__builtin_isinf:
131 TDCBits = 0x30;
132 break;
133 default:
134 break;
135 }
136 if (TDCBits)
137 return Builder.CreateCall(
138 TDCFunc,
139 {V, llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), TDCBits)});
140 }
141 return nullptr;
142 }
143};
144}
145
146bool SystemZABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
147 // Treat an enum type as its underlying type.
148 if (const auto *ED = Ty->getAsEnumDecl())
149 Ty = ED->getIntegerType();
150
151 // Promotable integer types are required to be promoted by the ABI.
153 return true;
154
155 if (const auto *EIT = Ty->getAs<BitIntType>())
156 if (EIT->getNumBits() < 64)
157 return true;
158
159 // 32-bit values must also be promoted.
160 if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
161 switch (BT->getKind()) {
162 case BuiltinType::Int:
163 case BuiltinType::UInt:
164 return true;
165 default:
166 return false;
167 }
168 return false;
169}
170
171bool SystemZABIInfo::isCompoundType(QualType Ty) const {
172 return (Ty->isAnyComplexType() ||
173 Ty->isVectorType() ||
175}
176
177bool SystemZABIInfo::isVectorArgumentType(QualType Ty) const {
178 return (HasVector &&
179 Ty->isVectorType() &&
180 getContext().getTypeSize(Ty) <= 128);
181}
182
183// The Size argument will in case of af an overaligned single element struct
184// reflect the overalignment value. In such a case the argument will be
185// passed using the type matching Size.
186llvm::Type *SystemZABIInfo::getFPArgumentType(QualType Ty,
187 uint64_t Size) const {
188 if (IsSoftFloatABI)
189 return nullptr;
190
191 if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
192 switch (BT->getKind()) {
193 case BuiltinType::Float16:
194 if (Size == 16)
195 return llvm::Type::getHalfTy(getVMContext());
196 [[fallthrough]];
197 case BuiltinType::Float:
198 if (Size == 32)
199 return llvm::Type::getFloatTy(getVMContext());
200 [[fallthrough]];
201 case BuiltinType::Double:
202 return llvm::Type::getDoubleTy(getVMContext());
203 default:
204 return nullptr;
205 }
206
207 return nullptr;
208}
209
210QualType SystemZABIInfo::getSingleElementType(QualType Ty) const {
211 const auto *RD = Ty->getAsRecordDecl();
212 if (RD && RD->isStructureOrClass()) {
213 QualType Found;
214
215 // If this is a C++ record, check the bases first.
216 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
217 if (CXXRD->hasDefinition())
218 for (const auto &I : CXXRD->bases()) {
219 QualType Base = I.getType();
220
221 // Empty bases don't affect things either way.
222 if (isEmptyRecord(getContext(), Base, true))
223 continue;
224
225 if (!Found.isNull())
226 return Ty;
227 Found = getSingleElementType(Base);
228 }
229
230 // Check the fields.
231 for (const auto *FD : RD->fields()) {
232 // Unlike isSingleElementStruct(), empty structure and array fields
233 // do count. So do anonymous bitfields that aren't zero-sized.
234
235 // Like isSingleElementStruct(), ignore C++20 empty data members.
236 if (FD->hasAttr<NoUniqueAddressAttr>() &&
237 isEmptyRecord(getContext(), FD->getType(), true))
238 continue;
239
240 // Unlike isSingleElementStruct(), arrays do not count.
241 // Nested structures still do though.
242 if (!Found.isNull())
243 return Ty;
244 Found = getSingleElementType(FD->getType());
245 }
246
247 // Unlike isSingleElementStruct(), trailing padding is allowed.
248 // An 8-byte aligned struct s { float f; } is passed as a double.
249 if (!Found.isNull())
250 return Found;
251 }
252
253 return Ty;
254}
255
256RValue SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
257 QualType Ty, AggValueSlot Slot) const {
258 // Assume that va_list type is correct; should be pointer to LLVM type:
259 // struct {
260 // i64 __gpr;
261 // i64 __fpr;
262 // i8 *__overflow_arg_area;
263 // i8 *__reg_save_area;
264 // };
265
266 // Every non-vector argument occupies 8 bytes and is passed by preference
267 // in either GPRs or FPRs. Vector arguments occupy 8 or 16 bytes and are
268 // always passed on the stack.
269 const SystemZTargetCodeGenInfo &SZCGI =
270 static_cast<const SystemZTargetCodeGenInfo &>(
271 CGT.getCGM().getTargetCodeGenInfo());
272 Ty = getContext().getCanonicalType(Ty);
273 auto TyInfo = getContext().getTypeInfoInChars(Ty);
274 llvm::Type *ArgTy = CGF.ConvertTypeForMem(Ty);
275 llvm::Type *DirectTy = ArgTy;
276 ABIArgInfo AI = classifyArgumentType(Ty);
277 bool IsIndirect = AI.isIndirect();
278 bool InFPRs = false;
279 bool IsVector = false;
280 CharUnits UnpaddedSize;
281 CharUnits DirectAlign;
282 SZCGI.handleExternallyVisibleObjABI(Ty.getTypePtr(), CGT.getCGM(),
283 /*IsParam*/true);
284 if (IsIndirect) {
285 DirectTy = llvm::PointerType::getUnqual(DirectTy->getContext());
286 UnpaddedSize = DirectAlign = CharUnits::fromQuantity(8);
287 } else {
288 if (AI.getCoerceToType())
289 ArgTy = AI.getCoerceToType();
290 InFPRs = (!IsSoftFloatABI &&
291 (ArgTy->isHalfTy() || ArgTy->isFloatTy() || ArgTy->isDoubleTy()));
292 IsVector = ArgTy->isVectorTy();
293 UnpaddedSize = TyInfo.Width;
294 DirectAlign = TyInfo.Align;
295 }
296 CharUnits PaddedSize = CharUnits::fromQuantity(8);
297 if (IsVector && UnpaddedSize > PaddedSize)
298 PaddedSize = CharUnits::fromQuantity(16);
299 assert((UnpaddedSize <= PaddedSize) && "Invalid argument size.");
300
301 CharUnits Padding = (PaddedSize - UnpaddedSize);
302
303 llvm::Type *IndexTy = CGF.Int64Ty;
304 llvm::Value *PaddedSizeV =
305 llvm::ConstantInt::get(IndexTy, PaddedSize.getQuantity());
306
307 if (IsVector) {
308 // Work out the address of a vector argument on the stack.
309 // Vector arguments are always passed in the high bits of a
310 // single (8 byte) or double (16 byte) stack slot.
311 Address OverflowArgAreaPtr =
312 CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
313 Address OverflowArgArea =
314 Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
315 CGF.Int8Ty, TyInfo.Align);
316 Address MemAddr = OverflowArgArea.withElementType(DirectTy);
317
318 // Update overflow_arg_area_ptr pointer
319 llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP(
320 OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF),
321 PaddedSizeV, "overflow_arg_area");
322 CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
323
324 return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(MemAddr, Ty), Slot);
325 }
326
327 assert(PaddedSize.getQuantity() == 8);
328
329 unsigned MaxRegs, RegCountField, RegSaveIndex;
330 CharUnits RegPadding;
331 if (InFPRs) {
332 MaxRegs = 4; // Maximum of 4 FPR arguments
333 RegCountField = 1; // __fpr
334 RegSaveIndex = 16; // save offset for f0
335 RegPadding = CharUnits(); // floats are passed in the high bits of an FPR
336 } else {
337 MaxRegs = 5; // Maximum of 5 GPR arguments
338 RegCountField = 0; // __gpr
339 RegSaveIndex = 2; // save offset for r2
340 RegPadding = Padding; // values are passed in the low bits of a GPR
341 }
342
343 Address RegCountPtr =
344 CGF.Builder.CreateStructGEP(VAListAddr, RegCountField, "reg_count_ptr");
345 llvm::Value *RegCount = CGF.Builder.CreateLoad(RegCountPtr, "reg_count");
346 llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
347 llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV,
348 "fits_in_regs");
349
350 llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
351 llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem");
352 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
353 CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock);
354
355 // Emit code to load the value if it was passed in registers.
356 CGF.EmitBlock(InRegBlock);
357
358 // Work out the address of an argument register.
359 llvm::Value *ScaledRegCount =
360 CGF.Builder.CreateMul(RegCount, PaddedSizeV, "scaled_reg_count");
361 llvm::Value *RegBase =
362 llvm::ConstantInt::get(IndexTy, RegSaveIndex * PaddedSize.getQuantity()
363 + RegPadding.getQuantity());
364 llvm::Value *RegOffset =
365 CGF.Builder.CreateAdd(ScaledRegCount, RegBase, "reg_offset");
366 Address RegSaveAreaPtr =
367 CGF.Builder.CreateStructGEP(VAListAddr, 3, "reg_save_area_ptr");
368 llvm::Value *RegSaveArea =
369 CGF.Builder.CreateLoad(RegSaveAreaPtr, "reg_save_area");
370 Address RawRegAddr(
371 CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, RegOffset, "raw_reg_addr"),
372 CGF.Int8Ty, PaddedSize);
373 Address RegAddr = RawRegAddr.withElementType(DirectTy);
374
375 // Update the register count
376 llvm::Value *One = llvm::ConstantInt::get(IndexTy, 1);
377 llvm::Value *NewRegCount =
378 CGF.Builder.CreateAdd(RegCount, One, "reg_count");
379 CGF.Builder.CreateStore(NewRegCount, RegCountPtr);
380 CGF.EmitBranch(ContBlock);
381
382 // Emit code to load the value if it was passed in memory.
383 CGF.EmitBlock(InMemBlock);
384
385 // Work out the address of a stack argument.
386 Address OverflowArgAreaPtr =
387 CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
388 Address OverflowArgArea =
389 Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
390 CGF.Int8Ty, PaddedSize);
391 Address RawMemAddr =
392 CGF.Builder.CreateConstByteGEP(OverflowArgArea, Padding, "raw_mem_addr");
393 Address MemAddr = RawMemAddr.withElementType(DirectTy);
394
395 // Update overflow_arg_area_ptr pointer
396 llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP(
397 OverflowArgArea.getElementType(), OverflowArgArea.emitRawPointer(CGF),
398 PaddedSizeV, "overflow_arg_area");
399 CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
400 CGF.EmitBranch(ContBlock);
401
402 // Return the appropriate result.
403 CGF.EmitBlock(ContBlock);
404 Address ResAddr = emitMergePHI(CGF, RegAddr, InRegBlock, MemAddr, InMemBlock,
405 "va_arg.addr");
406
407 if (IsIndirect)
408 ResAddr = Address(CGF.Builder.CreateLoad(ResAddr, "indirect_arg"), ArgTy,
409 TyInfo.Align);
410
411 return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
412}
413
414ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
415 if (RetTy->isVoidType())
416 return ABIArgInfo::getIgnore();
417 if (isVectorArgumentType(RetTy))
418 return ABIArgInfo::getDirect();
419 if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
420 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
421 return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
423}
424
425ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
426 // Handle transparent union types.
428
429 // Handle the generic C++ ABI.
430 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
431 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
433
434 // Integers and enums are extended to full register width.
435 if (isPromotableIntegerTypeForABI(Ty))
436 return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty));
437
438 // Handle vector types and vector-like structure types. Note that
439 // as opposed to float-like structure types, we do not allow any
440 // padding for vector-like structures, so verify the sizes match.
441 uint64_t Size = getContext().getTypeSize(Ty);
442 QualType SingleElementTy = getSingleElementType(Ty);
443 if (isVectorArgumentType(SingleElementTy) &&
444 getContext().getTypeSize(SingleElementTy) == Size)
445 return ABIArgInfo::getDirect(CGT.ConvertType(SingleElementTy));
446
447 // Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly.
448 if (Size != 8 && Size != 16 && Size != 32 && Size != 64)
449 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
450 /*ByVal=*/false);
451
452 // Handle small structures.
453 if (const auto *RD = Ty->getAsRecordDecl()) {
454 // Structures with flexible arrays have variable length, so really
455 // fail the size test above.
456 if (RD->hasFlexibleArrayMember())
457 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
458 /*ByVal=*/false);
459
460 // The structure is passed as an unextended integer, a half, a float,
461 // or a double.
462 if (llvm::Type *FPArgTy = getFPArgumentType(SingleElementTy, Size)) {
463 assert(Size == 16 || Size == 32 || Size == 64);
464 return ABIArgInfo::getDirect(FPArgTy);
465 } else {
466 llvm::IntegerType *PassTy = llvm::IntegerType::get(getVMContext(), Size);
467 return Size <= 32 ? ABIArgInfo::getNoExtend(PassTy)
468 : ABIArgInfo::getDirect(PassTy);
469 }
470 }
471
472 // Non-structure compounds are passed indirectly.
473 if (isCompoundType(Ty))
474 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
475 /*ByVal=*/false);
476
477 return ABIArgInfo::getDirect(nullptr);
478}
479
480void SystemZABIInfo::computeInfo(CGFunctionInfo &FI) const {
481 const SystemZTargetCodeGenInfo &SZCGI =
482 static_cast<const SystemZTargetCodeGenInfo &>(
483 CGT.getCGM().getTargetCodeGenInfo());
484 if (!getCXXABI().classifyReturnType(FI))
486 unsigned Idx = 0;
487 for (auto &I : FI.arguments()) {
488 I.info = classifyArgumentType(I.type);
489 if (FI.isVariadic() && Idx++ >= FI.getNumRequiredArgs())
490 // Check if a vararg vector argument is passed, in which case the
491 // vector ABI becomes visible as the va_list could be passed on to
492 // other functions.
493 SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM(),
494 /*IsParam*/true);
495 }
496}
497
498bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty,
499 bool IsParam) const {
500 if (!SeenTypes.insert(Ty).second)
501 return false;
502
503 if (IsParam) {
504 // A narrow (<16 bytes) vector will as a parameter also expose the ABI as
505 // it will be passed in a vector register. A wide (>16 bytes) vector will
506 // be passed via "hidden" pointer where any extra alignment is not
507 // required (per GCC).
508 const Type *SingleEltTy = getABIInfo<SystemZABIInfo>()
509 .getSingleElementType(QualType(Ty, 0))
510 .getTypePtr();
511 bool SingleVecEltStruct = SingleEltTy != Ty && SingleEltTy->isVectorType() &&
512 Ctx.getTypeSize(SingleEltTy) == Ctx.getTypeSize(Ty);
513 if (Ty->isVectorType() || SingleVecEltStruct)
514 return Ctx.getTypeSize(Ty) / 8 <= 16;
515 }
516
517 // Assume pointers are dereferenced.
518 while (Ty->isPointerType() || Ty->isArrayType())
520
521 // Vectors >= 16 bytes expose the ABI through alignment requirements.
522 if (Ty->isVectorType() && Ctx.getTypeSize(Ty) / 8 >= 16)
523 return true;
524
525 if (const auto *RD = Ty->getAsRecordDecl()) {
526 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
527 if (CXXRD->hasDefinition())
528 for (const auto &I : CXXRD->bases())
529 if (isVectorTypeBased(I.getType().getTypePtr(), /*IsParam*/false))
530 return true;
531 for (const auto *FD : RD->fields())
532 if (isVectorTypeBased(FD->getType().getTypePtr(), /*IsParam*/false))
533 return true;
534 }
535
536 if (const auto *FT = Ty->getAs<FunctionType>())
537 if (isVectorTypeBased(FT->getReturnType().getTypePtr(), /*IsParam*/true))
538 return true;
539 if (const FunctionProtoType *Proto = Ty->getAs<FunctionProtoType>())
540 for (const auto &ParamType : Proto->getParamTypes())
541 if (isVectorTypeBased(ParamType.getTypePtr(), /*IsParam*/true))
542 return true;
543
544 return false;
545}
546
547//===----------------------------------------------------------------------===//
548// z/OS XPLINK ABI Implementation
549//===----------------------------------------------------------------------===//
550
551namespace {
552
553class ZOSXPLinkABIInfo : public ABIInfo {
554 const unsigned GPRBits = 64;
555 bool HasVector;
556
557public:
558 ZOSXPLinkABIInfo(CodeGenTypes &CGT, bool HV) : ABIInfo(CGT), HasVector(HV) {}
559
560 bool isPromotableIntegerTypeForABI(QualType Ty) const;
561 bool isCompoundType(QualType Ty) const;
562 bool isVectorArgumentType(QualType Ty) const;
563 QualType getSingleElementType(QualType Ty) const;
564 std::optional<QualType> getFPTypeOfComplexLikeType(QualType Ty) const;
565
566 ABIArgInfo classifyReturnType(QualType RetTy,
567 unsigned functionCallConv) const;
568 ABIArgInfo classifyArgumentType(QualType ArgTy, bool IsNamedArg,
569 unsigned functionCallConv) const;
570
571 void computeInfo(CGFunctionInfo &FI) const override {
572 if (!getCXXABI().classifyReturnType(FI))
573 FI.getReturnInfo() =
575
576 unsigned NumRequiredArgs = FI.getNumRequiredArgs();
577 unsigned ArgNo = 0;
578
579 for (auto &I : FI.arguments()) {
580 bool IsNamedArg = ArgNo < NumRequiredArgs;
581 I.info =
582 classifyArgumentType(I.type, IsNamedArg, FI.getCallingConvention());
583 ++ArgNo;
584 }
585 }
586
587 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
588 AggValueSlot Slot) const override;
589};
590
591class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo {
592public:
593 ZOSXPLinkTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector)
594 : TargetCodeGenInfo(std::make_unique<ZOSXPLinkABIInfo>(CGT, HasVector)) {
595 SwiftInfo =
596 std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
597 }
598};
599
600} // namespace
601
602// Return true if the ABI requires Ty to be passed sign- or zero-
603// extended to 64 bits.
604bool ZOSXPLinkABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
605 // Treat an enum type as its underlying type.
606 if (const EnumType *EnumTy = Ty->getAs<EnumType>())
607 Ty = EnumTy->getDecl()->getIntegerType();
608
609 // Promotable integer types are required to be promoted by the ABI.
611 return true;
612
613 if (const auto *EIT = Ty->getAs<BitIntType>())
614 if (EIT->getNumBits() < 64)
615 return true;
616
617 // In addition to the usual promotable integer types, we also need to
618 // extend all 32-bit types, since the ABI requires promotion to 64 bits.
619 if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
620 switch (BT->getKind()) {
621 case BuiltinType::Int:
622 case BuiltinType::UInt:
623 case BuiltinType::ULong:
624 case BuiltinType::Long:
625 return true;
626 default:
627 break;
628 }
629
630 return false;
631}
632
633bool ZOSXPLinkABIInfo::isCompoundType(QualType Ty) const {
634 return (Ty->isAnyComplexType() || Ty->isVectorType() ||
636}
637
638bool ZOSXPLinkABIInfo::isVectorArgumentType(QualType Ty) const {
639 return (HasVector && Ty->isVectorType() &&
640 getContext().getTypeSize(Ty) <= 128);
641}
642
643QualType ZOSXPLinkABIInfo::getSingleElementType(QualType Ty) const {
644 // Unions just containing a floating point type, e.g. union { float f1, f2; };
645 // are treated as a single floating point number. Check if the union only
646 // consists of a single type (handling embedded unions recursively), and
647 // return that type.
648 if (const RecordType *RT = Ty->getAsUnionType()) {
649 QualType Found;
650 // Check the fields.
651 const RecordDecl *RD = RT->getDecl();
652 for (const auto *FD : RD->fields()) {
653 if (Found.isNull())
654 Found = getSingleElementType(FD->getType());
655 else if (Found != getSingleElementType(FD->getType()))
656 return Ty;
657 }
658 return Found.isNull() ? Ty : Found;
659 }
660
661 if (const RecordType *RT = Ty->getAsStructureType()) {
662 const RecordDecl *RD = RT->getDecl();
663 QualType Found;
664
665 // If this is a C++ class/struct, inspect its base classes first.
666 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
667 for (const auto &I : CXXRD->bases()) {
668 QualType Base = I.getType();
669
670 // Skip empty base classes, they cannot contribute a data member.
671 if (isEmptyRecord(getContext(), Base, true))
672 continue;
673
674 // A candidate base type was already found; encountering another
675 // non-empty base means the choice is no longer unique. Return the type
676 // from the first candidate.
677 if (!Found.isNull())
678 return Ty;
679 Found = getSingleElementType(Base);
680 }
681
682 // Inspect the record's fields. A struct qualifies as single-element if it
683 // has exactly one non-empty field. Empty fields (zero-size structs, arrays,
684 // bitfields, or [[no_unique_address]] members) don't affect this
685 // classification. Validated by zos-abi.cpp tests.
686 for (const auto *FD : RD->fields()) {
687 if (!Found.isNull())
688 return Ty; // Multiple non-empty fields found
689 Found = getSingleElementType(FD->getType());
690 }
691 return Found.isNull() ? Ty : Found;
692 }
693 return Ty; // not record/union, unchanged
694}
695
696std::optional<QualType>
697ZOSXPLinkABIInfo::getFPTypeOfComplexLikeType(QualType Ty) const {
698 if (const RecordType *RT = Ty->getAsStructureType()) {
699 const RecordDecl *RD = RT->getDecl();
700
701 // Check for non-empty base classes.
702 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
703 if (CXXRD->hasDefinition())
704 for (const auto &I : CXXRD->bases()) {
705 QualType Base = I.getType();
706 if (!isEmptyRecord(getContext(), Base, true))
707 return std::nullopt;
708 }
709
710 // Check for exactly two elements with exactly the same floating point type.
711 // A single-element struct containing only a float, double, or long double
712 // counts as a field of that type. If the struct has one field consisting
713 // of a complex type, it does not count. This design may be somewhat
714 // inconsistent but it matches the behavior of the legacy C compiler.
715 int Count = 0;
717 QualType RetTy;
718 for (const auto *FD : RD->fields()) {
719 if (Count >= 2)
720 return std::nullopt;
721
722 QualType FT = FD->getType();
723 QualType FTSingleTy = getSingleElementType(FT);
724
725 if (const BuiltinType *BT = FTSingleTy->getAs<BuiltinType>()) {
726 switch (BT->getKind()) {
727 case BuiltinType::Float:
728 case BuiltinType::Double:
729 case BuiltinType::LongDouble:
730 if (Count == 0) {
731 elemKind = BT->getKind();
732 RetTy = FTSingleTy;
733 break;
734 } else if (elemKind == BT->getKind())
735 break;
736 else
737 return std::nullopt;
738 default:
739 return std::nullopt;
740 }
741 } else
742 return std::nullopt;
743
744 Count++;
745 }
746
747 if (Count == 2) {
748 // A record can be treated as complex-like if its size is exactly
749 // 2 * sizeof(T), matching the layout of two adjacent FP elements.
750 auto &Ctx = getContext();
751 if (Ctx.getTypeSize(Ty) == 2 * Ctx.getTypeSize(RetTy))
752 return RetTy;
753 }
754 }
755 return std::nullopt;
756}
757
758ABIArgInfo ZOSXPLinkABIInfo::classifyReturnType(QualType RetTy,
759 unsigned CallConv) const {
760
761 // Ignore void types.
762 if (RetTy->isVoidType())
763 return ABIArgInfo::getIgnore();
764
765 // Handle transparent union types.
766 RetTy = useFirstFieldIfTransparentUnion(RetTy);
767
768 // For non-C calling convention, indirect by value for structs and complex.
769 if ((CallConv != llvm::CallingConv::C) &&
770 (isAggregateTypeForABI(RetTy) || RetTy->isAnyComplexType())) {
771 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
772 }
773
774 // Vectors are returned directly.
775 if (isVectorArgumentType(RetTy))
776 return ABIArgInfo::getDirect();
777
778 // Complex types are returned by value as per the XPLINK docs.
779 // Their members will be placed in FPRs.
780 if (RetTy->isAnyComplexType())
781 return ABIArgInfo::getDirect();
782
783 // Complex LIKE structures are returned by value as per the XPLINK docs.
784 // Their members will be placed in FPRs.
785 if (RetTy->getAs<RecordType>()) {
786 if (getFPTypeOfComplexLikeType(RetTy))
787 return ABIArgInfo::getDirect();
788 }
789
790 // Aggregates with a size of less than 3 GPRs are returned in GRPs 1, 2 and 3.
791 // Other aggregates are passed in memory as an implicit first parameter.
792 if (isAggregateTypeForABI(RetTy)) {
793 uint64_t AggregateTypeSize = getContext().getTypeSize(RetTy);
794
795 if (AggregateTypeSize <= 3 * GPRBits) {
796 uint64_t NumElements =
797 AggregateTypeSize / GPRBits + (AggregateTypeSize % GPRBits != 0);
798
799 // Types up to 8 bytes are passed as an integer type in GPR1.
800 // Types between 8 and 16 bytes are passed as integer types in GPR1, 2.
801 // Types between 16 and 24 bytes are passed as integer types in GPR1, 2
802 // and 3.
803 llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits);
804 CoerceTy = llvm::ArrayType::get(CoerceTy, NumElements);
805 return ABIArgInfo::getDirectInReg(CoerceTy);
806 } else
807 return getNaturalAlignIndirect(RetTy,
808 getDataLayout().getAllocaAddrSpace());
809 }
810 return (isPromotableIntegerTypeForABI(RetTy)
811 ? ABIArgInfo::getExtend(RetTy, CGT.ConvertType(RetTy))
812 : ABIArgInfo::getDirect(CGT.ConvertType(RetTy)));
813}
814
815ABIArgInfo ZOSXPLinkABIInfo::classifyArgumentType(QualType Ty, bool IsNamedArg,
816 unsigned CallConv) const {
817 // Handle transparent union types.
819
820 // Handle the generic C++ ABI.
821 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
822 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
824
825 // Integers and enums are extended to full register width.
826 if (isPromotableIntegerTypeForABI(Ty))
827 return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty));
828
829 // For non-C calling conventions, compound types passed by address copy.
830 if ((CallConv != llvm::CallingConv::C) && isCompoundType(Ty))
831 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
832 /*ByVal=*/false);
833
834 // Complex types are passed by value as per the XPLINK docs.
835 // If place available, their members will be placed in FPRs.
836 auto CompTy = getFPTypeOfComplexLikeType(Ty);
837 if (IsNamedArg) {
838 if (Ty->isComplexType()) {
839 auto AI = ABIArgInfo::getDirect(CGT.ConvertType(Ty));
840
841 // Complex types must be preserved as opaque structs per XPLINK ABI.
842 // Without this, flattening would incorrectly split { float, float } into
843 // separate FP registers, breaking ABI compliance.
844 // Example: _Complex float pass_complex_float(_Complex float arg) { return
845 // arg; }
846 AI.setCanBeFlattened(false);
847 return AI;
848 }
849
850 if (CompTy.has_value()) {
851 llvm::Type *FPTy = CGT.ConvertType(*CompTy);
852 llvm::Type *CoerceTy = llvm::StructType::get(FPTy, FPTy);
853 auto AI = ABIArgInfo::getDirect(CoerceTy);
854
855 // Preserve { float, float } signature for complex-like structs per XPLINK
856 // ABI. Flattening would incorrectly decompose into separate FP registers.
857 // Example: struct complexlike_float { float re, im; };
858 // struct complexlike_float pass_complexlike_float2(struct
859 // complexlike_float arg) { return arg; }
860 AI.setCanBeFlattened(false);
861 return AI;
862 }
863 }
864
865 // Vectors are passed directly.
866 if (isVectorArgumentType(Ty))
867 return ABIArgInfo::getDirect();
868
869 // Handle structures. They are returned by value.
870 // If not complex like types, they are passed in GPRs, if possible.
871 // If place available, complex like types will have their members
872 // placed in FPRs.
873 if (Ty->getAs<RecordType>() || Ty->isAnyComplexType() || CompTy.has_value()) {
874 // Since an aggregate may end up in registers, pass the aggregate as
875 // array. This is usually beneficial since we avoid forcing the back-end
876 // to store the argument to memory.
877 uint64_t Bits = getContext().getTypeSize(Ty);
878 llvm::Type *CoerceTy;
879
880 // Struct types up to 8 bytes are passed as integer type (which will be
881 // properly aligned in the argument save area doubleword).
882 if (Bits <= GPRBits)
883 CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits);
884 // Larger types are passed as arrays, with the base type selected
885 // according to the required alignment in the save area.
886 else {
887 uint64_t NumRegs = llvm::alignTo(Bits, GPRBits) / GPRBits;
888 llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), GPRBits);
889 CoerceTy = llvm::ArrayType::get(RegTy, NumRegs);
890 }
891 return ABIArgInfo::getDirect(CoerceTy);
892 }
893
894 // Non-structure compounds are passed indirectly, i.e. arrays.
895 if (isCompoundType(Ty))
896 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
897 /*ByVal=*/false);
898
899 return ABIArgInfo::getDirect();
900}
901
902RValue ZOSXPLinkABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
903 QualType Ty, AggValueSlot Slot) const {
904 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false,
906 CGF.getPointerSize(),
907 /*allowHigherAlign*/ false, Slot);
908}
909
910std::unique_ptr<TargetCodeGenInfo>
912 bool SoftFloatABI) {
913 return std::make_unique<SystemZTargetCodeGenInfo>(CGM.getTypes(), HasVector,
914 SoftFloatABI);
915}
916
917std::unique_ptr<TargetCodeGenInfo>
919 bool SoftFloatABI) {
920 return std::make_unique<ZOSXPLinkTargetCodeGenInfo>(CGM.getTypes(),
921 HasVector);
922}
#define V(N, I)
Defines enum values for all the target-independent builtin functions.
TypeInfoChars getTypeInfoInChars(const Type *T) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
static ABIArgInfo getNoExtend(llvm::IntegerType *T)
static ABIArgInfo getIgnore()
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
llvm::Type * getCoerceToType() const
void setCanBeFlattened(bool Flatten)
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
Definition ABIInfo.h:48
bool isPromotableIntegerTypeForABI(QualType Ty) const
Definition ABIInfo.cpp:162
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Definition Address.h:253
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Definition Address.h:209
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
Definition Address.h:276
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Definition CGBuilder.h:146
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Definition CGBuilder.h:302
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
Definition CGBuilder.h:229
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Definition CGBuilder.h:118
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Definition CGBuilder.h:325
RecordArgABI
Specify how one should pass an argument of a record type.
Definition CGCXXABI.h:150
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
Definition CGCXXABI.h:158
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
Definition CGExpr.cpp:2501
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
Definition CGStmt.cpp:663
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
Definition CGStmt.cpp:643
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Definition TargetInfo.h:50
A (possibly-)qualified type.
Definition TypeBase.h:937
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8447
QualType getCanonicalType() const
Definition TypeBase.h:8499
field_range fields() const
Definition Decl.h:4550
bool isVoidType() const
Definition TypeBase.h:9050
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
Definition TypeBase.h:9237
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
Definition Type.cpp:824
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
Definition Type.cpp:761
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isArrayType() const
Definition TypeBase.h:8783
bool isPointerType() const
Definition TypeBase.h:8684
bool isAnyComplexType() const
Definition TypeBase.h:8819
const RecordType * getAsStructureType() const
Definition Type.cpp:805
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
Definition Type.h:53
bool isVectorType() const
Definition TypeBase.h:8823
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9277
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Definition CGValue.h:146
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
std::unique_ptr< TargetCodeGenInfo > createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI)
Definition SystemZ.cpp:911
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
Address emitMergePHI(CodeGenFunction &CGF, Address Addr1, llvm::BasicBlock *Block1, Address Addr2, llvm::BasicBlock *Block2, const llvm::Twine &Name="")
bool isAggregateTypeForABI(QualType T)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
std::unique_ptr< TargetCodeGenInfo > createSystemZ_ZOS_TargetCodeGenInfo(CodeGenModule &CGM, bool HasVector, bool SoftFloatABI)
Definition SystemZ.cpp:918
@ Address
A pointer to a ValueDecl.
Definition Primitives.h:28
The JSON file list parser is used to communicate input to InstallAPI.
@ Type
The name was classified as a type.
Definition Sema.h:564
unsigned long uint64_t
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64