blob: 5d21088eba8e8227950880084c8b05dece86198c [file] [log] [blame]
Jim Grosbachf7947052012-07-09 18:34:21 +00001// REQUIRES: arm-registered-target
Anton Korobeynikov00000b02012-04-13 11:23:39 +00002// RUN: %clang_cc1 -triple armv7---eabi -target-abi aapcs -mfloat-abi hard -emit-llvm %s -o - | FileCheck %s
Anton Korobeynikova8063c32012-04-23 09:02:13 +00003
4typedef long long int64_t;
5typedef unsigned int uint32_t;
Anton Korobeynikov00000b02012-04-13 11:23:39 +00006
7/* This is not a homogenous aggregate - fundamental types are different */
8typedef union {
9 float f[4];
10 uint32_t i[4];
11} union_with_first_floats;
12union_with_first_floats g_u_f;
13
14extern void takes_union_with_first_floats(union_with_first_floats a);
15extern union_with_first_floats returns_union_with_first_floats(void);
16
17void test_union_with_first_floats(void) {
18 takes_union_with_first_floats(g_u_f);
19}
20// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_first_floats([4 x i32])
21
22void test_return_union_with_first_floats(void) {
23 g_u_f = returns_union_with_first_floats();
24}
25// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(%union.union_with_first_floats* sret)
26
27/* This is not a homogenous aggregate - fundamental types are different */
28typedef union {
29 uint32_t i[4];
30 float f[4];
31} union_with_non_first_floats;
32union_with_non_first_floats g_u_nf_f;
33
34extern void takes_union_with_non_first_floats(union_with_non_first_floats a);
35extern union_with_non_first_floats returns_union_with_non_first_floats(void);
36
37void test_union_with_non_first_floats(void) {
38 takes_union_with_non_first_floats(g_u_nf_f);
39}
40// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_non_first_floats([4 x i32])
41
42void test_return_union_with_non_first_floats(void) {
43 g_u_nf_f = returns_union_with_non_first_floats();
44}
45// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(%union.union_with_non_first_floats* sret)
46
47/* This is not a homogenous aggregate - fundamental types are different */
48typedef struct {
49 float a;
50 union_with_first_floats b;
51} struct_with_union_with_first_floats;
52struct_with_union_with_first_floats g_s_f;
53
54extern void takes_struct_with_union_with_first_floats(struct_with_union_with_first_floats a);
55extern struct_with_union_with_first_floats returns_struct_with_union_with_first_floats(void);
56
57void test_struct_with_union_with_first_floats(void) {
58 takes_struct_with_union_with_first_floats(g_s_f);
59}
60// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_first_floats([5 x i32])
61
62void test_return_struct_with_union_with_first_floats(void) {
63 g_s_f = returns_struct_with_union_with_first_floats();
64}
65// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(%struct.struct_with_union_with_first_floats* sret)
66
67/* This is not a homogenous aggregate - fundamental types are different */
68typedef struct {
69 float a;
70 union_with_non_first_floats b;
71} struct_with_union_with_non_first_floats;
72struct_with_union_with_non_first_floats g_s_nf_f;
73
74extern void takes_struct_with_union_with_non_first_floats(struct_with_union_with_non_first_floats a);
75extern struct_with_union_with_non_first_floats returns_struct_with_union_with_non_first_floats(void);
76
77void test_struct_with_union_with_non_first_floats(void) {
78 takes_struct_with_union_with_non_first_floats(g_s_nf_f);
79}
80// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_non_first_floats([5 x i32])
81
82void test_return_struct_with_union_with_non_first_floats(void) {
83 g_s_nf_f = returns_struct_with_union_with_non_first_floats();
84}
85// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(%struct.struct_with_union_with_non_first_floats* sret)
86
87/* Plain array is not a homogenous aggregate */
88extern void takes_array_of_floats(float a[4]);
89void test_array_of_floats(void) {
90 float a[4] = {1.0, 2.0, 3.0, 4.0};
91 takes_array_of_floats(a);
92}
93// CHECK: declare arm_aapcs_vfpcc void @takes_array_of_floats(float*)
94
95/* Struct-type homogenous aggregate */
96typedef struct {
97 float x, y, z, w;
98} struct_with_fundamental_elems;
99struct_with_fundamental_elems g_s;
100
101extern void takes_struct_with_fundamental_elems(struct_with_fundamental_elems a);
102extern struct_with_fundamental_elems returns_struct_with_fundamental_elems(void);
103
104void test_struct_with_fundamental_elems(void) {
105 takes_struct_with_fundamental_elems(g_s);
106// CHECK: call arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float{{.*}}, float {{.*}})
107}
108// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(float, float, float, float)
109
110void test_return_struct_with_fundamental_elems(void) {
111 g_s = returns_struct_with_fundamental_elems();
112// CHECK: call arm_aapcs_vfpcc %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems()
113}
114// CHECK: declare arm_aapcs_vfpcc %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems()
115
116/* Array-type homogenous aggregate */
117typedef struct {
118 float xyzw[4];
119} struct_with_array;
120struct_with_array g_s_a;
121
122extern void takes_struct_with_array(struct_with_array a);
123extern struct_with_array returns_struct_with_array(void);
124
125void test_struct_with_array(void) {
126 takes_struct_with_array(g_s_a);
127// CHECK: call arm_aapcs_vfpcc void @takes_struct_with_array(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}})
128}
129// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_array(float, float, float, float)
130
131void test_return_struct_with_array(void) {
132 g_s_a = returns_struct_with_array();
133// CHECK: call arm_aapcs_vfpcc %struct.struct_with_array @returns_struct_with_array()
134}
135// CHECK: declare arm_aapcs_vfpcc %struct.struct_with_array @returns_struct_with_array()
136
137/* This union is a homogenous aggregate. Check that it's passed properly */
138typedef union {
139 struct_with_fundamental_elems xyzw;
140 float a[3];
141} union_with_struct_with_fundamental_elems;
142union_with_struct_with_fundamental_elems g_u_s_fe;
143
144extern void takes_union_with_struct_with_fundamental_elems(union_with_struct_with_fundamental_elems a);
145extern union_with_struct_with_fundamental_elems returns_union_with_struct_with_fundamental_elems(void);
146
147void test_union_with_struct_with_fundamental_elems(void) {
148 takes_union_with_struct_with_fundamental_elems(g_u_s_fe);
149// CHECK: call arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}})
150}
151// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(float, float, float, float)
152
153void test_return_union_with_struct_with_fundamental_elems(void) {
154 g_u_s_fe = returns_union_with_struct_with_fundamental_elems();
155// CHECK: call arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems()
156}
157// CHECK: declare arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems()
158
Manman Renb3fa55f2012-10-30 23:21:41 +0000159// Make sure HAs that can be partially fit into VFP registers will be allocated
160// on stack and that later VFP candidates will go on stack as well.
161typedef struct {
162 double x;
163 double a2;
164 double a3;
165 double a4;
166} struct_of_four_doubles;
167extern void takes_struct_of_four_doubles(double a, struct_of_four_doubles b, struct_of_four_doubles c, double d);
168struct_of_four_doubles g_s4d;
169
170void test_struct_of_four_doubles(void) {
171// CHECK: test_struct_of_four_doubles
172// CHECK: call arm_aapcs_vfpcc void @takes_struct_of_four_doubles(double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [6 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
173 takes_struct_of_four_doubles(3.0, g_s4d, g_s4d, 4.0);
174}
175
Manman Ren710c5172012-10-31 19:02:26 +0000176extern void takes_struct_with_backfill(float f1, double a, float f2, struct_of_four_doubles b, struct_of_four_doubles c, double d);
177void test_struct_with_backfill(void) {
178// CHECK: test_struct_with_backfill
179// CHECK: call arm_aapcs_vfpcc void @takes_struct_with_backfill(float {{.*}}, double {{.*}}, float {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [4 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
180 takes_struct_with_backfill(3.0, 3.1, 3.2, g_s4d, g_s4d, 4.0);
181}
182
Manman Renb3fa55f2012-10-30 23:21:41 +0000183typedef __attribute__(( ext_vector_type(8) )) char __char8;
184typedef __attribute__(( ext_vector_type(4) )) short __short4;
185typedef struct {
186 __char8 a1;
187 __short4 a2;
188 __char8 a3;
189 __short4 a4;
190} struct_of_vecs;
191extern void takes_struct_of_vecs(double a, struct_of_vecs b, struct_of_vecs c, double d);
192struct_of_vecs g_vec;
193
194void test_struct_of_vecs(void) {
195// CHECK: test_struct_of_vecs
196// CHECK: call arm_aapcs_vfpcc void @takes_struct_of_vecs(double {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, [6 x float] undef, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, double {{.*}})
197 takes_struct_of_vecs(3.0, g_vec, g_vec, 4.0);
198}
199
Anton Korobeynikov00000b02012-04-13 11:23:39 +0000200// FIXME: Tests necessary:
201// - Vectors
Jim Grosbachf7947052012-07-09 18:34:21 +0000202// - C++ stuff