mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-07 11:38:04 +00:00
22b7cb051b
The previous attempt, which made do with a single offset in computeCalleeSaveRegisterPairs, wasn't quite enough. The previous attempt only worked as long as CombineSPBump == true (since the offset would be adjusted later in fixupCalleeSaveRestoreStackOffset). Instead include the size for the fixed stack area used for win64 varargs in calculations in emitPrologue/emitEpilogue. The stack consists of mainly three parts; - AFI->getLocalStackSize() - AFI->getCalleeSavedStackSize() - FixedObject Most of the places in the code which previously used the CSStackSize now use PrologueSaveSize instead, which is the sum of the latter two, while some cases which need exactly the middle one use AFI->getCalleeSavedStackSize() explicitly instead of a local variable. In addition to moving the offsetting into emitPrologue/emitEpilogue (which fixes functions with CombineSPBump == false), also set the frame pointer to point to the right location, where the frame pointer and link register actually are stored. In addition to the prologue/epilogue, this also requires changes to resolveFrameIndexReference. Add tests for a function that keeps a frame pointer and another one that uses a VLA. Differential Revision: https://reviews.llvm.org/D35919 llvm-svn: 309744
77 lines
2.1 KiB
LLVM
77 lines
2.1 KiB
LLVM
; RUN: llc < %s -mtriple=aarch64-linux-gnu | FileCheck %s
|
|
|
|
define win64cc void @pass_va(i32 %count, ...) nounwind {
|
|
entry:
|
|
; CHECK: str x30, [sp, #-80]!
|
|
; CHECK: add x8, sp, #24
|
|
; CHECK: add x0, sp, #24
|
|
; CHECK: stp x6, x7, [sp, #64]
|
|
; CHECK: stp x4, x5, [sp, #48]
|
|
; CHECK: stp x2, x3, [sp, #32]
|
|
; CHECK: str x1, [sp, #24]
|
|
; CHECK: str x8, [sp, #8]
|
|
; CHECK: bl other_func
|
|
; CHECK: ldr x30, [sp], #80
|
|
; CHECK: ret
|
|
%ap = alloca i8*, align 8
|
|
%ap1 = bitcast i8** %ap to i8*
|
|
call void @llvm.va_start(i8* %ap1)
|
|
%ap2 = load i8*, i8** %ap, align 8
|
|
call void @other_func(i8* %ap2)
|
|
ret void
|
|
}
|
|
|
|
declare void @other_func(i8*) local_unnamed_addr
|
|
|
|
declare void @llvm.va_start(i8*) nounwind
|
|
declare void @llvm.va_copy(i8*, i8*) nounwind
|
|
|
|
; CHECK-LABEL: f9:
|
|
; CHECK: sub sp, sp, #16
|
|
; CHECK: add x8, sp, #24
|
|
; CHECK: add x0, sp, #24
|
|
; CHECK: str x8, [sp, #8]
|
|
; CHECK: add sp, sp, #16
|
|
; CHECK: ret
|
|
define win64cc i8* @f9(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, ...) nounwind {
|
|
entry:
|
|
%ap = alloca i8*, align 8
|
|
%ap1 = bitcast i8** %ap to i8*
|
|
call void @llvm.va_start(i8* %ap1)
|
|
%ap2 = load i8*, i8** %ap, align 8
|
|
ret i8* %ap2
|
|
}
|
|
|
|
; CHECK-LABEL: f8:
|
|
; CHECK: sub sp, sp, #16
|
|
; CHECK: add x8, sp, #16
|
|
; CHECK: add x0, sp, #16
|
|
; CHECK: str x8, [sp, #8]
|
|
; CHECK: add sp, sp, #16
|
|
; CHECK: ret
|
|
define win64cc i8* @f8(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, ...) nounwind {
|
|
entry:
|
|
%ap = alloca i8*, align 8
|
|
%ap1 = bitcast i8** %ap to i8*
|
|
call void @llvm.va_start(i8* %ap1)
|
|
%ap2 = load i8*, i8** %ap, align 8
|
|
ret i8* %ap2
|
|
}
|
|
|
|
; CHECK-LABEL: f7:
|
|
; CHECK: sub sp, sp, #32
|
|
; CHECK: add x8, sp, #24
|
|
; CHECK: str x7, [sp, #24]
|
|
; CHECK: add x0, sp, #24
|
|
; CHECK: str x8, [sp, #8]
|
|
; CHECK: add sp, sp, #32
|
|
; CHECK: ret
|
|
define win64cc i8* @f7(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, ...) nounwind {
|
|
entry:
|
|
%ap = alloca i8*, align 8
|
|
%ap1 = bitcast i8** %ap to i8*
|
|
call void @llvm.va_start(i8* %ap1)
|
|
%ap2 = load i8*, i8** %ap, align 8
|
|
ret i8* %ap2
|
|
}
|