mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-19 01:34:32 +00:00
d7a4f74f15
The AAPCS treats small structs and homogeneous floating (or vector) aggregates specially, and guarantees they either get passed as a contiguous block of registers, or prevent any future use of those registers and get passed on the stack. This concept can fit quite neatly into LLVM's own type system, mapping an HFA to [N x float] and so on, and small structs to [N x i64]. Doing so allows front-ends to emit AAPCS compliant code without having to duplicate the register counting logic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222903 91177308-0d34-0410-b5e6-96231b3b80d8
93 lines
3.1 KiB
LLVM
93 lines
3.1 KiB
LLVM
; RUN: llc -mtriple=aarch64-apple-ios7.0 -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DARWINPCS
|
|
; RUN: llc -mtriple=aarch64-linux-gnu -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AAPCS
|
|
|
|
declare void @callee(...)
|
|
|
|
define float @test_hfa_regs(float, [2 x float] %in) {
|
|
; CHECK-LABEL: test_hfa_regs:
|
|
; CHECK: fadd s0, s1, s2
|
|
|
|
%lhs = extractvalue [2 x float] %in, 0
|
|
%rhs = extractvalue [2 x float] %in, 1
|
|
%sum = fadd float %lhs, %rhs
|
|
ret float %sum
|
|
}
|
|
|
|
; Check that the array gets allocated to a contiguous block on the stack (rather
|
|
; than the default of 2 8-byte slots).
|
|
define float @test_hfa_block([7 x float], [2 x float] %in) {
|
|
; CHECK-LABEL: test_hfa_block:
|
|
; CHECK: ldp [[LHS:s[0-9]+]], [[RHS:s[0-9]+]], [sp]
|
|
; CHECK: fadd s0, [[LHS]], [[RHS]]
|
|
|
|
%lhs = extractvalue [2 x float] %in, 0
|
|
%rhs = extractvalue [2 x float] %in, 1
|
|
%sum = fadd float %lhs, %rhs
|
|
ret float %sum
|
|
}
|
|
|
|
; Check that an HFA prevents backfilling of VFP registers (i.e. %rhs must go on
|
|
; the stack rather than in s7).
|
|
define float @test_hfa_block_consume([7 x float], [2 x float] %in, float %rhs) {
|
|
; CHECK-LABEL: test_hfa_block_consume:
|
|
; CHECK-DAG: ldr [[LHS:s[0-9]+]], [sp]
|
|
; CHECK-DAG: ldr [[RHS:s[0-9]+]], [sp, #8]
|
|
; CHECK: fadd s0, [[LHS]], [[RHS]]
|
|
|
|
%lhs = extractvalue [2 x float] %in, 0
|
|
%sum = fadd float %lhs, %rhs
|
|
ret float %sum
|
|
}
|
|
|
|
define float @test_hfa_stackalign([8 x float], [1 x float], [2 x float] %in) {
|
|
; CHECK-LABEL: test_hfa_stackalign:
|
|
; CHECK-AAPCS: ldp [[LHS:s[0-9]+]], [[RHS:s[0-9]+]], [sp, #8]
|
|
; CHECK-DARWINPCS: ldp [[LHS:s[0-9]+]], [[RHS:s[0-9]+]], [sp, #4]
|
|
; CHECK: fadd s0, [[LHS]], [[RHS]]
|
|
%lhs = extractvalue [2 x float] %in, 0
|
|
%rhs = extractvalue [2 x float] %in, 1
|
|
%sum = fadd float %lhs, %rhs
|
|
ret float %sum
|
|
}
|
|
|
|
; An HFA that ends up on the stack should not have any effect on where
|
|
; integer-based arguments go.
|
|
define i64 @test_hfa_ignores_gprs([7 x float], [2 x float] %in, i64, i64 %res) {
|
|
; CHECK-LABEL: test_hfa_ignores_gprs:
|
|
; CHECK: mov x0, x1
|
|
ret i64 %res
|
|
}
|
|
|
|
; [2 x float] should not be promoted to double by the Darwin varargs handling,
|
|
; but should go in an 8-byte aligned slot.
|
|
define void @test_varargs_stackalign() {
|
|
; CHECK-LABEL: test_varargs_stackalign:
|
|
; CHECK-DARWINPCS: stp {{w[0-9]+}}, {{w[0-9]+}}, [sp, #16]
|
|
|
|
call void(...)* @callee([3 x float] undef, [2 x float] [float 1.0, float 2.0])
|
|
ret void
|
|
}
|
|
|
|
define i64 @test_smallstruct_block([7 x i64], [2 x i64] %in) {
|
|
; CHECK-LABEL: test_smallstruct_block:
|
|
; CHECK: ldp [[LHS:x[0-9]+]], [[RHS:x[0-9]+]], [sp]
|
|
; CHECK: add x0, [[LHS]], [[RHS]]
|
|
%lhs = extractvalue [2 x i64] %in, 0
|
|
%rhs = extractvalue [2 x i64] %in, 1
|
|
%sum = add i64 %lhs, %rhs
|
|
ret i64 %sum
|
|
}
|
|
|
|
; Check that a small struct prevents backfilling of registers (i.e. %rhs
|
|
; must go on the stack rather than in x7).
|
|
define i64 @test_smallstruct_block_consume([7 x i64], [2 x i64] %in, i64 %rhs) {
|
|
; CHECK-LABEL: test_smallstruct_block_consume:
|
|
; CHECK-DAG: ldr [[LHS:x[0-9]+]], [sp]
|
|
; CHECK-DAG: ldr [[RHS:x[0-9]+]], [sp, #16]
|
|
; CHECK: add x0, [[LHS]], [[RHS]]
|
|
|
|
%lhs = extractvalue [2 x i64] %in, 0
|
|
%sum = add i64 %lhs, %rhs
|
|
ret i64 %sum
|
|
}
|