ARM64: track alignment padding registers on AAPCS targets

This implements clause C.8 of the AAPCS in the front-end, so that Clang
accurately knows when the registers run out and it has to insert padding before
the stack objects begin.

PR19432.

llvm-svn: 206296
This commit is contained in:
Tim Northover
2014-04-15 14:55:11 +00:00
parent 64a42b8dd2
commit c801b4a2aa
2 changed files with 23 additions and 1 deletions

View File

@@ -3291,6 +3291,10 @@ ABIArgInfo ARM64ABIInfo::classifyArgumentType(QualType Ty,
Ty = EnumTy->getDecl()->getIntegerType();
if (!Ty->isFloatingType() && !Ty->isVectorType()) {
unsigned Alignment = getContext().getTypeAlign(Ty);
if (!isDarwinPCS() && Alignment > 64)
AllocatedGPR = llvm::RoundUpToAlignment(AllocatedGPR, Alignment / 64);
int RegsNeeded = getContext().getTypeSize(Ty) > 64 ? 2 : 1;
AllocatedGPR += RegsNeeded;
}
@@ -3328,12 +3332,16 @@ ABIArgInfo ARM64ABIInfo::classifyArgumentType(QualType Ty,
// Aggregates <= 16 bytes are passed directly in registers or on the stack.
uint64_t Size = getContext().getTypeSize(Ty);
if (Size <= 128) {
unsigned Alignment = getContext().getTypeAlign(Ty);
if (!isDarwinPCS() && Alignment > 64)
AllocatedGPR = llvm::RoundUpToAlignment(AllocatedGPR, Alignment / 64);
Size = 64 * ((Size + 63) / 64); // round up to multiple of 8 bytes
AllocatedGPR += Size / 64;
IsSmallAggr = true;
// We use a pair of i64 for 16-byte aggregate with 8-byte alignment.
// For aggregates with 16-byte alignment, we use i128.
if (getContext().getTypeAlign(Ty) < 128 && Size == 128) {
if (Alignment < 128 && Size == 128) {
llvm::Type *BaseTy = llvm::Type::getInt64Ty(getVMContext());
return ABIArgInfo::getDirect(llvm::ArrayType::get(BaseTy, Size / 64));
}