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