xref: /aosp_15_r20/external/llvm/test/CodeGen/ARM/v7k-abi-align.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=thumbv7k-apple-watchos2.0 -o - %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker%struct = type { i8, i64, i8, double, i8, <2 x float>, i8, <4 x float> }
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workerdefine i32 @test_i64_align() {
6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_i64_align:
7*9880d681SAndroid Build Coastguard Worker; CHECL: movs r0, #8
8*9880d681SAndroid Build Coastguard Worker  ret i32 ptrtoint(i64* getelementptr(%struct, %struct* null, i32 0, i32 1) to i32)
9*9880d681SAndroid Build Coastguard Worker}
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Workerdefine i32 @test_f64_align() {
12*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_f64_align:
13*9880d681SAndroid Build Coastguard Worker; CHECL: movs r0, #24
14*9880d681SAndroid Build Coastguard Worker  ret i32 ptrtoint(double* getelementptr(%struct, %struct* null, i32 0, i32 3) to i32)
15*9880d681SAndroid Build Coastguard Worker}
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Workerdefine i32 @test_v2f32_align() {
18*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v2f32_align:
19*9880d681SAndroid Build Coastguard Worker; CHECL: movs r0, #40
20*9880d681SAndroid Build Coastguard Worker  ret i32 ptrtoint(<2 x float>* getelementptr(%struct, %struct* null, i32 0, i32 5) to i32)
21*9880d681SAndroid Build Coastguard Worker}
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Workerdefine i32 @test_v4f32_align() {
24*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v4f32_align:
25*9880d681SAndroid Build Coastguard Worker; CHECL: movs r0, #64
26*9880d681SAndroid Build Coastguard Worker  ret i32 ptrtoint(<4 x float>* getelementptr(%struct, %struct* null, i32 0, i32 7) to i32)
27*9880d681SAndroid Build Coastguard Worker}
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker; Key point here is than an extra register has to be saved so that the DPRs end
30*9880d681SAndroid Build Coastguard Worker; up in an aligned location (as prologue/epilogue inserter had calculated).
31*9880d681SAndroid Build Coastguard Workerdefine void @test_dpr_unwind_align() {
32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_dpr_unwind_align:
33*9880d681SAndroid Build Coastguard Worker; CHECK: push {r5, r6, r7, lr}
34*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: sub sp
35*9880d681SAndroid Build Coastguard Worker; CHECK: vpush {d8, d9}
36*9880d681SAndroid Build Coastguard Worker; CHECK: .cfi_offset d9, -24
37*9880d681SAndroid Build Coastguard Worker; CHECK: .cfi_offset d8, -32
38*9880d681SAndroid Build Coastguard Worker; [...]
39*9880d681SAndroid Build Coastguard Worker; CHECK: bl _test_i64_align
40*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add sp,
41*9880d681SAndroid Build Coastguard Worker; CHECK: vpop {d8, d9}
42*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add sp,
43*9880d681SAndroid Build Coastguard Worker; CHECK: pop {r5, r6, r7, pc}
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker  call void asm sideeffect "", "~{r6},~{d8},~{d9}"()
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker  ; Whatever
48*9880d681SAndroid Build Coastguard Worker  call i32 @test_i64_align()
49*9880d681SAndroid Build Coastguard Worker  ret void
50*9880d681SAndroid Build Coastguard Worker}
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker; This time, there's no viable way to tack CS-registers onto the list: a real SP
53*9880d681SAndroid Build Coastguard Worker; adjustment needs to be performed to put d8 and d9 where they should be.
54*9880d681SAndroid Build Coastguard Workerdefine void @test_dpr_unwind_align_manually() {
55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_dpr_unwind_align_manually:
56*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, r5, r6, r7, lr}
57*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: sub sp
58*9880d681SAndroid Build Coastguard Worker; CHECK: push.w {r8, r11}
59*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, #4
60*9880d681SAndroid Build Coastguard Worker; CHECK: vpush {d8, d9}
61*9880d681SAndroid Build Coastguard Worker; CHECK: .cfi_offset d9, -40
62*9880d681SAndroid Build Coastguard Worker; CHECK: .cfi_offset d8, -48
63*9880d681SAndroid Build Coastguard Worker; [...]
64*9880d681SAndroid Build Coastguard Worker; CHECK: bl _test_i64_align
65*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add sp,
66*9880d681SAndroid Build Coastguard Worker; CHECK: vpop {d8, d9}
67*9880d681SAndroid Build Coastguard Worker; CHECK: add sp, #4
68*9880d681SAndroid Build Coastguard Worker; CHECK: pop.w {r8, r11}
69*9880d681SAndroid Build Coastguard Worker; CHECK: pop {r4, r5, r6, r7, pc}
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker  call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{d8},~{d9}"()
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker  ; Whatever
74*9880d681SAndroid Build Coastguard Worker  call i32 @test_i64_align()
75*9880d681SAndroid Build Coastguard Worker  ret void
76*9880d681SAndroid Build Coastguard Worker}
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker; If there's only a CS1 area, the sub should be in the right place:
79*9880d681SAndroid Build Coastguard Workerdefine void @test_dpr_unwind_align_just_cs1() {
80*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_dpr_unwind_align_just_cs1:
81*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, r5, r6, r7, lr}
82*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, #4
83*9880d681SAndroid Build Coastguard Worker; CHECK: vpush {d8, d9}
84*9880d681SAndroid Build Coastguard Worker; CHECK: .cfi_offset d9, -32
85*9880d681SAndroid Build Coastguard Worker; CHECK: .cfi_offset d8, -40
86*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, #8
87*9880d681SAndroid Build Coastguard Worker; [...]
88*9880d681SAndroid Build Coastguard Worker; CHECK: bl _test_i64_align
89*9880d681SAndroid Build Coastguard Worker; CHECK: add sp, #8
90*9880d681SAndroid Build Coastguard Worker; CHECK: vpop {d8, d9}
91*9880d681SAndroid Build Coastguard Worker; CHECK: add sp, #4
92*9880d681SAndroid Build Coastguard Worker; CHECK: pop {r4, r5, r6, r7, pc}
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker  call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{d8},~{d9}"()
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker  ; Whatever
97*9880d681SAndroid Build Coastguard Worker  call i32 @test_i64_align()
98*9880d681SAndroid Build Coastguard Worker  ret void
99*9880d681SAndroid Build Coastguard Worker}
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker; If there are no DPRs, we shouldn't try to align the stack in stages anyway
102*9880d681SAndroid Build Coastguard Workerdefine void @test_dpr_unwind_align_no_dprs() {
103*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_dpr_unwind_align_no_dprs:
104*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, r5, r6, r7, lr}
105*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, #12
106*9880d681SAndroid Build Coastguard Worker; [...]
107*9880d681SAndroid Build Coastguard Worker; CHECK: bl _test_i64_align
108*9880d681SAndroid Build Coastguard Worker; CHECK: add sp, #12
109*9880d681SAndroid Build Coastguard Worker; CHECK: pop {r4, r5, r6, r7, pc}
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker  call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7}"()
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker  ; Whatever
114*9880d681SAndroid Build Coastguard Worker  call i32 @test_i64_align()
115*9880d681SAndroid Build Coastguard Worker  ret void
116*9880d681SAndroid Build Coastguard Worker}
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker; 128-bit vectors should use 128-bit (i.e. correctly aligned) slots on
119*9880d681SAndroid Build Coastguard Worker; the stack.
120*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @test_v128_stack_pass([8 x double], float, <4 x float> %in) {
121*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v128_stack_pass:
122*9880d681SAndroid Build Coastguard Worker; CHECK: add r[[ADDR:[0-9]+]], sp, #16
123*9880d681SAndroid Build Coastguard Worker; CHECK: vld1.64 {d0, d1}, [r[[ADDR]]:128]
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %in
126*9880d681SAndroid Build Coastguard Worker}
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Workerdeclare void @varargs(i32, ...)
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker; When varargs are enabled, we go down a different route. Still want 128-bit
131*9880d681SAndroid Build Coastguard Worker; alignment though.
132*9880d681SAndroid Build Coastguard Workerdefine void @test_v128_stack_pass_varargs(<4 x float> %in) {
133*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v128_stack_pass_varargs:
134*9880d681SAndroid Build Coastguard Worker; CHECK: add r[[ADDR:[0-9]+]], sp, #16
135*9880d681SAndroid Build Coastguard Worker; CHECK: vst1.64 {d0, d1}, [r[[ADDR]]:128]
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker  call void(i32, ...) @varargs(i32 undef, [3 x i32] undef, float undef, <4 x float> %in)
138*9880d681SAndroid Build Coastguard Worker  ret void
139*9880d681SAndroid Build Coastguard Worker}
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker; To be compatible with AAPCS's va_start model (store r0-r3 at incoming SP, give
142*9880d681SAndroid Build Coastguard Worker; a single pointer), 64-bit quantities must be pass
143*9880d681SAndroid Build Coastguard Workerdefine i64 @test_64bit_gpr_align(i32, i64 %r2_r3, i32 %sp) {
144*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_64bit_gpr_align:
145*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[RHS:r[0-9]+]], [sp]
146*9880d681SAndroid Build Coastguard Worker; CHECK: adds r0, [[RHS]], r2
147*9880d681SAndroid Build Coastguard Worker; CHECK: adc r1, r3, #0
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker  %ext = zext i32 %sp to i64
150*9880d681SAndroid Build Coastguard Worker  %sum = add i64 %ext, %r2_r3
151*9880d681SAndroid Build Coastguard Worker  ret i64 %sum
152*9880d681SAndroid Build Coastguard Worker}
153