namespace {
/// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information.
class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
-bool IsSoftFloatABI;
+ bool IsSoftFloatABI;
+
+ CharUnits getParamTypeAlignment(QualType Ty) const;
+
public:
PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI)
: DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI) {}
bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const override;
};
+}
+
+CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
+ // Complex types are passed just like their elements
+ if (const ComplexType *CTy = Ty->getAs<ComplexType>())
+ Ty = CTy->getElementType();
+
+ if (Ty->isVectorType())
+ return CharUnits::fromQuantity(getContext().getTypeSize(Ty) == 128 ? 16
+ : 4);
+ // For single-element float/vector structs, we consider the whole type
+ // to have the same alignment requirements as its single element.
+ const Type *AlignTy = nullptr;
+ if (const Type *EltType = isSingleElementStruct(Ty, getContext())) {
+ const BuiltinType *BT = EltType->getAs<BuiltinType>();
+ if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) ||
+ (BT && BT->isFloatingPoint()))
+ AlignTy = EltType;
+ }
+
+ if (AlignTy)
+ return CharUnits::fromQuantity(AlignTy->isVectorType() ? 16 : 4);
+ return CharUnits::fromQuantity(4);
}
// TODO: this implementation is now likely redundant with
// DefaultABIInfo::EmitVAArg.
Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
QualType Ty) const {
+ if (getTarget().getTriple().isOSDarwin()) {
+ auto TI = getContext().getTypeInfoInChars(Ty);
+ TI.second = getParamTypeAlignment(Ty);
+
+ CharUnits SlotSize = CharUnits::fromQuantity(4);
+ return emitVoidPtrVAArg(CGF, VAList, Ty,
+ classifyArgumentType(Ty).isIndirect(), TI, SlotSize,
+ /*AllowHigherAlign=*/true);
+ }
+
const unsigned OverflowLimit = 8;
if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
// TODO: Implement this. For now ignore.
--- /dev/null
+// RUN: %clang_cc1 -triple powerpc-apple-macosx10.5.0 -target-feature +altivec -Os -emit-llvm -o - %s | FileCheck %s
+
+int f(__builtin_va_list args) { return __builtin_va_arg(args, int); }
+
+// CHECK: @f(i8* {{.*}}[[PARAM:%[a-zA-Z0-9]+]])
+// CHECK: [[BITCAST:%[0-9]+]] = bitcast i8* [[PARAM]] to i32*
+// CHECK: [[VALUE:%[0-9]+]] = load i32, i32* [[BITCAST]], align 4
+// CHECK: ret i32 [[VALUE]]
+
+void h(vector int);
+int g(__builtin_va_list args) {
+ int i = __builtin_va_arg(args, int);
+ h(__builtin_va_arg(args, vector int));
+ int j = __builtin_va_arg(args, int);
+ return i + j;
+}
+
+// CHECK: @g(i8* {{.*}}[[PARAM:%[a-zA-Z0-9]+]])
+// CHECK: [[NEXT:%[-_.a-zA-Z0-9]+]] = getelementptr inbounds i8, i8* [[PARAM]], i32 4
+// CHECK: [[BITCAST:%[0-9]+]] = bitcast i8* [[PARAM]] to i32*
+// CHECK: [[LOAD:%[0-9]+]] = load i32, i32* [[BITCAST]], align 4
+// CHECK: [[PTRTOINT:%[0-9]+]] = ptrtoint i8* [[NEXT]] to i32
+// CHECK: [[ADD:%[0-9]+]] = add i32 [[PTRTOINT]], 15
+// CHECK: [[AND:%[0-9]+]] = and i32 [[ADD]], -16
+// CHECK: [[INTTOPTR:%[0-9]+]] = inttoptr i32 [[AND]] to <4 x i32>*
+// CHECK: [[ARG:%[0-9]]] = load <4 x i32>, <4 x i32>* [[INTTOPTR]], align 16
+// CHECK: call void @h(<4 x i32> [[ARG]]
+