mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-04 00:20:14 +00:00
A bunch of fixes to argument passing and va_arg on Darwin x86-32 for structures containing an SSE vector.
llvm-svn: 144963
This commit is contained in:
parent
1cdc6e9567
commit
1d7dd3b682
@ -620,7 +620,7 @@ static bool isRecordWithSSEVectorType(ASTContext &Context, QualType Ty) {
|
||||
i != e; ++i) {
|
||||
QualType FT = i->getType();
|
||||
|
||||
if (FT->getAs<VectorType>() && Context.getTypeSize(Ty) == 128)
|
||||
if (FT->getAs<VectorType>() && Context.getTypeSize(FT) == 128)
|
||||
return true;
|
||||
|
||||
if (isRecordWithSSEVectorType(Context, FT))
|
||||
@ -644,7 +644,7 @@ unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty,
|
||||
}
|
||||
|
||||
// Otherwise, if the type contains an SSE vector type, the alignment is 16.
|
||||
if (isRecordWithSSEVectorType(getContext(), Ty))
|
||||
if (Align >= 16 && isRecordWithSSEVectorType(getContext(), Ty))
|
||||
return 16;
|
||||
|
||||
return MinABIStackAlignInBytes;
|
||||
@ -739,12 +739,30 @@ llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,
|
||||
"ap");
|
||||
llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
|
||||
|
||||
// Compute if the address needs to be aligned
|
||||
unsigned Align = CGF.getContext().getTypeAlignInChars(Ty).getQuantity();
|
||||
Align = getTypeStackAlignInBytes(Ty, Align);
|
||||
Align = std::max(Align, 4U);
|
||||
if (Align > 4) {
|
||||
// addr = (addr + align - 1) & -align;
|
||||
llvm::Value *Offset =
|
||||
llvm::ConstantInt::get(CGF.Int32Ty, Align - 1);
|
||||
Addr = CGF.Builder.CreateGEP(Addr, Offset);
|
||||
llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(Addr,
|
||||
CGF.Int32Ty);
|
||||
llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -Align);
|
||||
Addr = CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask),
|
||||
Addr->getType(),
|
||||
"ap.cur.aligned");
|
||||
}
|
||||
|
||||
llvm::Type *PTy =
|
||||
llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
|
||||
llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);
|
||||
|
||||
uint64_t Offset =
|
||||
llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4);
|
||||
llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, Align);
|
||||
llvm::Value *NextAddr =
|
||||
Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset),
|
||||
"ap.next");
|
||||
|
@ -292,3 +292,27 @@ struct s59 f59() { while (1) {} }
|
||||
// CHECK: define void @f60(%struct.s60* byval align 4, i32 %y)
|
||||
struct s60 { int x __attribute((aligned(8))); };
|
||||
void f60(struct s60 x, int y) {}
|
||||
|
||||
// CHECK: define void @f61(i32 %x, %struct.s61* byval align 16 %y)
|
||||
typedef int T61 __attribute((vector_size(16)));
|
||||
struct s61 { T61 x; int y; };
|
||||
void f61(int x, struct s61 y) {}
|
||||
|
||||
// CHECK: define void @f62(i32 %x, %struct.s62* byval align 4)
|
||||
typedef int T62 __attribute((vector_size(16)));
|
||||
struct s62 { T62 x; int y; } __attribute((packed, aligned(8)));
|
||||
void f62(int x, struct s62 y) {}
|
||||
|
||||
// CHECK: define i32 @f63
|
||||
// CHECK: ptrtoint
|
||||
// CHECK: and {{.*}}, -16
|
||||
// CHECK: inttoptr
|
||||
typedef int T63 __attribute((vector_size(16)));
|
||||
struct s63 { T63 x; int y; };
|
||||
int f63(int i, ...) {
|
||||
__builtin_va_list ap;
|
||||
__builtin_va_start(ap, i);
|
||||
struct s63 s = __builtin_va_arg(ap, struct s63);
|
||||
__builtin_va_end(ap);
|
||||
return s.y;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user