mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-28 06:29:45 +00:00
The ELFv2 ABI reduces the amount of stack required to implement an ABI-compliant function call in two ways: * the "linkage area" is reduced from 48 bytes to 32 bytes by eliminating two unused doublewords * the 64-byte "parameter save area" is now optional and need not be present in certain cases (it remains mandatory in functions with variable arguments, and functions that have any parameter that is passed on the stack) The following patch implements this required changes: - reducing the linkage area, and associated relocation of the TOC save slot, in getLinkageSize / getTOCSaveOffset (this requires updating all callers of these routines to pass in the isELFv2ABI flag). - (partially) handling the case where the parameter save are is optional This latter part requires some extra explanation: Currently, we still always allocate the parameter save area when *calling* a function. That is certainly always compliant with the ABI, but may cause code to allocate stack unnecessarily. This can be addressed by a follow-on optimization patch. On the *callee* side, in LowerFormalArguments, we *must* track correctly whether the ABI guarantees that the caller has allocated the parameter save area for our use, and the patch does so. However, there is one complication: the code that handles incoming "byval" arguments will currently *always* write to the parameter save area, because it has to force incoming register arguments to the stack since it must return an *address* to implement the byval semantics. To fix this, the patch changes the LowerFormalArguments code to write arguments to a freshly allocated stack slot on the function's own stack frame instead of the argument save area in those cases where that area is not present. Reviewed by Hal Finkel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213490 91177308-0d34-0410-b5e6-96231b3b80d8
60 lines
2.1 KiB
LLVM
60 lines
2.1 KiB
LLVM
; Verify that small structures and float arguments are passed in the
|
|
; least significant part of a stack slot doubleword.
|
|
|
|
; RUN: llc < %s | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-i64:64-n32:64"
|
|
target triple = "powerpc64le-unknown-linux-gnu"
|
|
|
|
%struct.large_arg = type { [8 x i64] }
|
|
%struct.small_arg = type { i16, i8 }
|
|
|
|
@gl = common global %struct.large_arg zeroinitializer, align 8
|
|
@gs = common global %struct.small_arg zeroinitializer, align 2
|
|
@gf = common global float 0.000000e+00, align 4
|
|
|
|
define void @callee1(%struct.small_arg* noalias nocapture sret %agg.result, %struct.large_arg* byval nocapture readnone %pad, %struct.small_arg* byval nocapture readonly %x) {
|
|
entry:
|
|
%0 = bitcast %struct.small_arg* %x to i32*
|
|
%1 = bitcast %struct.small_arg* %agg.result to i32*
|
|
%2 = load i32* %0, align 2
|
|
store i32 %2, i32* %1, align 2
|
|
ret void
|
|
}
|
|
; CHECK: @callee1
|
|
; CHECK: lwz {{[0-9]+}}, 104(1)
|
|
; CHECK: blr
|
|
|
|
define void @caller1() {
|
|
entry:
|
|
%tmp = alloca %struct.small_arg, align 2
|
|
call void @test1(%struct.small_arg* sret %tmp, %struct.large_arg* byval @gl, %struct.small_arg* byval @gs)
|
|
ret void
|
|
}
|
|
; CHECK: @caller1
|
|
; CHECK: stw {{[0-9]+}}, 104(1)
|
|
; CHECK: bl test1
|
|
|
|
declare void @test1(%struct.small_arg* sret, %struct.large_arg* byval, %struct.small_arg* byval)
|
|
|
|
define float @callee2(float %pad1, float %pad2, float %pad3, float %pad4, float %pad5, float %pad6, float %pad7, float %pad8, float %pad9, float %pad10, float %pad11, float %pad12, float %pad13, float %x) {
|
|
entry:
|
|
ret float %x
|
|
}
|
|
; CHECK: @callee2
|
|
; CHECK: lfs {{[0-9]+}}, 136(1)
|
|
; CHECK: blr
|
|
|
|
define void @caller2() {
|
|
entry:
|
|
%0 = load float* @gf, align 4
|
|
%call = tail call float @test2(float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float %0)
|
|
ret void
|
|
}
|
|
; CHECK: @caller2
|
|
; CHECK: stfs {{[0-9]+}}, 136(1)
|
|
; CHECK: bl test2
|
|
|
|
declare float @test2(float, float, float, float, float, float, float, float, float, float, float, float, float, float)
|
|
|