xref: /llvm-project/llvm/test/CodeGen/ARM/aapcs-hfa-code.ll (revision 22df0886a1575439d0bf595f2b3a31c5255e9de6)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; RUN: llc < %s -mtriple=armv7-linux-gnueabihf -o - | FileCheck %s
3; RUN: llc < %s -mtriple=thumbv7em-none-eabi -mcpu=cortex-m4 | FileCheck %s --check-prefix=CHECK-M4F
4
5target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
6
7define arm_aapcs_vfpcc void @test_1float({ float } %a) {
8; CHECK-LABEL: test_1float:
9; CHECK:       @ %bb.0:
10; CHECK-NEXT:    .save {r11, lr}
11; CHECK-NEXT:    push {r11, lr}
12; CHECK-NEXT:    vmov.f32 s0, #1.000000e+00
13; CHECK-NEXT:    bl test_1float
14; CHECK-NEXT:    pop {r11, pc}
15;
16; CHECK-M4F-LABEL: test_1float:
17; CHECK-M4F:       @ %bb.0:
18; CHECK-M4F-NEXT:    .save {r7, lr}
19; CHECK-M4F-NEXT:    push {r7, lr}
20; CHECK-M4F-NEXT:    vmov.f32 s0, #1.000000e+00
21; CHECK-M4F-NEXT:    bl test_1float
22; CHECK-M4F-NEXT:    pop {r7, pc}
23  call arm_aapcs_vfpcc void @test_1float({ float } { float 1.0 })
24  ret void
25}
26
27define arm_aapcs_vfpcc void @test_2float({ float, float } %a) {
28; CHECK-LABEL: test_2float:
29; CHECK:       @ %bb.0:
30; CHECK-NEXT:    .save {r11, lr}
31; CHECK-NEXT:    push {r11, lr}
32; CHECK-NEXT:    vmov.f32 s0, #1.000000e+00
33; CHECK-NEXT:    vmov.f32 s1, #2.000000e+00
34; CHECK-NEXT:    bl test_2float
35; CHECK-NEXT:    pop {r11, pc}
36;
37; CHECK-M4F-LABEL: test_2float:
38; CHECK-M4F:       @ %bb.0:
39; CHECK-M4F-NEXT:    .save {r7, lr}
40; CHECK-M4F-NEXT:    push {r7, lr}
41; CHECK-M4F-NEXT:    vmov.f32 s0, #1.000000e+00
42; CHECK-M4F-NEXT:    vmov.f32 s1, #2.000000e+00
43; CHECK-M4F-NEXT:    bl test_2float
44; CHECK-M4F-NEXT:    pop {r7, pc}
45  call arm_aapcs_vfpcc void @test_2float({ float, float } { float 1.0, float 2.0 })
46  ret void
47}
48
49define arm_aapcs_vfpcc void @test_3float({ float, float, float } %a) {
50; CHECK-LABEL: test_3float:
51; CHECK:       @ %bb.0:
52; CHECK-NEXT:    .save {r11, lr}
53; CHECK-NEXT:    push {r11, lr}
54; CHECK-NEXT:    vmov.f32 s0, #1.000000e+00
55; CHECK-NEXT:    vmov.f32 s1, #2.000000e+00
56; CHECK-NEXT:    vmov.f32 s2, #3.000000e+00
57; CHECK-NEXT:    bl test_3float
58; CHECK-NEXT:    pop {r11, pc}
59;
60; CHECK-M4F-LABEL: test_3float:
61; CHECK-M4F:       @ %bb.0:
62; CHECK-M4F-NEXT:    .save {r7, lr}
63; CHECK-M4F-NEXT:    push {r7, lr}
64; CHECK-M4F-NEXT:    vmov.f32 s0, #1.000000e+00
65; CHECK-M4F-NEXT:    vmov.f32 s1, #2.000000e+00
66; CHECK-M4F-NEXT:    vmov.f32 s2, #3.000000e+00
67; CHECK-M4F-NEXT:    bl test_3float
68; CHECK-M4F-NEXT:    pop {r7, pc}
69  call arm_aapcs_vfpcc void @test_3float({ float, float, float } { float 1.0, float 2.0, float 3.0 })
70  ret void
71}
72
73define arm_aapcs_vfpcc void @test_1double({ double } %a) {
74; CHECK-LABEL: test_1double:
75; CHECK:       @ %bb.0:
76; CHECK-NEXT:    .save {r11, lr}
77; CHECK-NEXT:    push {r11, lr}
78; CHECK-NEXT:    vmov.f64 d0, #1.000000e+00
79; CHECK-NEXT:    bl test_1double
80; CHECK-NEXT:    pop {r11, pc}
81;
82; CHECK-M4F-LABEL: test_1double:
83; CHECK-M4F:       @ %bb.0:
84; CHECK-M4F-NEXT:    .save {r7, lr}
85; CHECK-M4F-NEXT:    push {r7, lr}
86; CHECK-M4F-NEXT:    vldr d0, .LCPI3_0
87; CHECK-M4F-NEXT:    bl test_1double
88; CHECK-M4F-NEXT:    pop {r7, pc}
89; CHECK-M4F-NEXT:    .p2align 3
90; CHECK-M4F-NEXT:  @ %bb.1:
91; CHECK-M4F-NEXT:  .LCPI3_0:
92; CHECK-M4F-NEXT:    .long 0 @ double 1
93; CHECK-M4F-NEXT:    .long 1072693248
94  call arm_aapcs_vfpcc void @test_1double({ double } { double 1.0 })
95  ret void
96}
97
98; Final double argument might be put in s15 & [sp] if we're careless. It should
99; go all on the stack.
100define arm_aapcs_vfpcc void @test_1double_nosplit([4 x float], [4 x double], [3 x float], double %a) {
101; CHECK-LABEL: test_1double_nosplit:
102; CHECK:       @ %bb.0:
103; CHECK-NEXT:    .save {r11, lr}
104; CHECK-NEXT:    push {r11, lr}
105; CHECK-NEXT:    .pad #8
106; CHECK-NEXT:    sub sp, sp, #8
107; CHECK-NEXT:    vmov.f64 d16, #1.000000e+00
108; CHECK-NEXT:    vstr d16, [sp]
109; CHECK-NEXT:    bl test_1double_nosplit
110; CHECK-NEXT:    add sp, sp, #8
111; CHECK-NEXT:    pop {r11, pc}
112;
113; CHECK-M4F-LABEL: test_1double_nosplit:
114; CHECK-M4F:       @ %bb.0:
115; CHECK-M4F-NEXT:    .save {r7, lr}
116; CHECK-M4F-NEXT:    push {r7, lr}
117; CHECK-M4F-NEXT:    .pad #8
118; CHECK-M4F-NEXT:    sub sp, #8
119; CHECK-M4F-NEXT:    movs r0, #0
120; CHECK-M4F-NEXT:    movt r0, #16368
121; CHECK-M4F-NEXT:    movs r1, #0
122; CHECK-M4F-NEXT:    strd r1, r0, [sp]
123; CHECK-M4F-NEXT:    bl test_1double_nosplit
124; CHECK-M4F-NEXT:    add sp, #8
125; CHECK-M4F-NEXT:    pop {r7, pc}
126  call arm_aapcs_vfpcc void @test_1double_nosplit([4 x float] undef, [4 x double] undef, [3 x float] undef, double 1.0)
127  ret void
128}
129
130; Final double argument might go at [sp, #4] if we're careless. Should go at
131; [sp, #8] to preserve alignment.
132define arm_aapcs_vfpcc void @test_1double_misaligned([4 x double], [4 x double], float, double) {
133; CHECK-LABEL: test_1double_misaligned:
134; CHECK:       @ %bb.0:
135; CHECK-NEXT:    .save {r11, lr}
136; CHECK-NEXT:    push {r11, lr}
137; CHECK-NEXT:    .pad #16
138; CHECK-NEXT:    sub sp, sp, #16
139; CHECK-NEXT:    vmov.f64 d16, #1.000000e+00
140; CHECK-NEXT:    vstr d16, [sp, #8]
141; CHECK-NEXT:    bl test_1double_misaligned
142; CHECK-NEXT:    add sp, sp, #16
143; CHECK-NEXT:    pop {r11, pc}
144;
145; CHECK-M4F-LABEL: test_1double_misaligned:
146; CHECK-M4F:       @ %bb.0:
147; CHECK-M4F-NEXT:    .save {r7, lr}
148; CHECK-M4F-NEXT:    push {r7, lr}
149; CHECK-M4F-NEXT:    .pad #16
150; CHECK-M4F-NEXT:    sub sp, #16
151; CHECK-M4F-NEXT:    movs r0, #0
152; CHECK-M4F-NEXT:    movt r0, #16368
153; CHECK-M4F-NEXT:    movs r1, #0
154; CHECK-M4F-NEXT:    strd r1, r0, [sp, #8]
155; CHECK-M4F-NEXT:    bl test_1double_misaligned
156; CHECK-M4F-NEXT:    add sp, #16
157; CHECK-M4F-NEXT:    pop {r7, pc}
158  call arm_aapcs_vfpcc void @test_1double_misaligned([4 x double] undef, [4 x double] undef, float undef, double 1.0)
159
160  ret void
161}
162