mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-13 15:37:24 +00:00
X86: Align the stack on word boundaries in LowerFormalArguments()
The goal of the patch is to implement section 3.2.3 of the AMD64 ABI correctly. The controlling sentence is, "The size of each argument gets rounded up to eightbytes. Therefore the stack will always be eightbyte aligned." The equivalent sentence in the i386 ABI page 37 says, "At all times, the stack pointer should point to a word-aligned area." For both architectures, the stack pointer is not being rounded up to the nearest eightbyte or word between the last normal argument and the first variadic argument. Patch by Thomas Jablin! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216119 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ada5f2a2c7
commit
5012f1db20
@ -371,11 +371,16 @@ public:
|
||||
return Reg;
|
||||
}
|
||||
|
||||
/// AlignStack - Align the top of the stakc to the specified alignment.
|
||||
void AlignStack(unsigned Align) {
|
||||
assert(Align && ((Align - 1) & Align) == 0); // Align is power of 2.
|
||||
StackOffset = ((StackOffset + Align - 1) & ~(Align - 1));
|
||||
}
|
||||
|
||||
/// AllocateStack - Allocate a chunk of stack space with the specified size
|
||||
/// and alignment.
|
||||
unsigned AllocateStack(unsigned Size, unsigned Align) {
|
||||
assert(Align && ((Align-1) & Align) == 0); // Align is power of 2.
|
||||
StackOffset = ((StackOffset + Align-1) & ~(Align-1));
|
||||
AlignStack(Align);
|
||||
unsigned Result = StackOffset;
|
||||
StackOffset += Size;
|
||||
MF.getFrameInfo()->ensureMaxAlignment(Align);
|
||||
|
@ -2300,6 +2300,7 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
|
||||
CCInfo.AllocateStack(32, 8);
|
||||
|
||||
CCInfo.AnalyzeFormalArguments(Ins, CC_X86);
|
||||
CCInfo.AlignStack(Is64Bit ? 8 : 4);
|
||||
|
||||
unsigned LastVal = ~0U;
|
||||
SDValue ArgValue;
|
||||
|
30
test/CodeGen/X86/aligned-variadic.ll
Normal file
30
test/CodeGen/X86/aligned-variadic.ll
Normal file
@ -0,0 +1,30 @@
|
||||
; RUN: llc < %s -march=x86-64 | FileCheck %s -check-prefix=X64
|
||||
; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32
|
||||
|
||||
%struct.Baz = type { [17 x i8] }
|
||||
%struct.__va_list_tag = type { i32, i32, i8*, i8* }
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define void @bar(%struct.Baz* byval nocapture readnone align 8 %x, ...) {
|
||||
entry:
|
||||
%va = alloca [1 x %struct.__va_list_tag], align 16
|
||||
%arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i64 0, i64 0
|
||||
%arraydecay1 = bitcast [1 x %struct.__va_list_tag]* %va to i8*
|
||||
call void @llvm.va_start(i8* %arraydecay1)
|
||||
%overflow_arg_area_p = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i64 0, i64 0, i32 2
|
||||
%overflow_arg_area = load i8** %overflow_arg_area_p, align 8
|
||||
%overflow_arg_area.next = getelementptr i8* %overflow_arg_area, i64 24
|
||||
store i8* %overflow_arg_area.next, i8** %overflow_arg_area_p, align 8
|
||||
; X32: leal 68(%esp), [[REG:%.*]]
|
||||
; X32: movl [[REG]], 16(%esp)
|
||||
; X64: leaq 232(%rsp), [[REG:%.*]]
|
||||
; X64: movq [[REG]], 184(%rsp)
|
||||
; X64: leaq 176(%rsp), %rdi
|
||||
call void @qux(%struct.__va_list_tag* %arraydecay)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.va_start(i8*)
|
||||
|
||||
declare void @qux(%struct.__va_list_tag*)
|
Loading…
x
Reference in New Issue
Block a user