1/* This file tests that we can successfully call each compiler-rt function. It is
2   designed to check that the runtime libraries are available for linking and
3   that they contain the expected contents. It is not designed to test the
4   correctness of the individual functions in compiler-rt.
5
6   This test is assumed to be run on a 10.6 machine. The two environment
7   variables below should be set to 10.4 and 10.5 machines which can be directly
8   ssh/rsync'd to in order to actually test the executables can run on the
9   desired targets.
10*/
11
12// RUN: export TENFOUR_X86_MACHINE=localhost
13// RUN: export TENFIVE_X86_MACHINE=localhost
14// RUN: export ARM_MACHINE=localhost
15// RUN: export ARM_SYSROOT=$(xcodebuild -sdk iphoneos -version Path)
16
17// RUN: echo iPhoneOS, ARM, v6, thumb
18// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -c %s -o %t.o
19// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2
20// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out
21// RUN: ssh $ARM_MACHINE /tmp/a.out
22// RUN: echo
23
24// RUN: echo iPhoneOS, ARM, v6, no-thumb
25// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -c %s -o %t.o
26// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2
27// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out
28// RUN: ssh $ARM_MACHINE /tmp/a.out
29// RUN: echo
30
31// RUN: echo iPhoneOS, ARM, v7, thumb
32// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -c %s -o %t.o
33// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2
34// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out
35// RUN: ssh $ARM_MACHINE /tmp/a.out
36// RUN: echo
37
38// RUN: echo iPhoneOS, ARM, v7, no-thumb
39// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -c %s -o %t.o
40// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2
41// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out
42// RUN: ssh $ARM_MACHINE /tmp/a.out
43// RUN: echo
44
45// RUN: echo 10.4, i386
46// RUN: %clang -arch i386 -mmacosx-version-min=10.4 -c %s -o %t.o
47// RUN: %clang -arch i386 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2
48// RUN: %t
49// RUN: echo
50
51// RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out
52// RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out
53// RUN: echo
54
55// RUX: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out
56// RUX: ssh $TENFIVE_X86_MACHINE /tmp/a.out
57// RUN: echo
58
59// RUN: echo 10.5, i386
60// RUN: %clang -arch i386 -mmacosx-version-min=10.5 -c %s -o %t.o
61// RUN: %clang -arch i386 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2
62// RUN: %t
63// RUN: echo
64
65// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out
66// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out
67// RUN: echo
68
69// RUN: echo 10.6, i386
70// RUN: %clang -arch i386 -mmacosx-version-min=10.6 -c %s -o %t.o
71// RUN: %clang -arch i386 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2
72// RUN: %t
73// RUN: echo
74
75// RUN: echo 10.4, x86_64
76// RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -c %s -o %t.o
77// RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2
78// RUN: %t
79// RUN: echo
80
81// RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out
82// RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out
83// RUN: echo
84
85// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out
86// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out
87// RUN: echo
88
89// RUN: echo 10.5, x86_64
90// RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -c %s -o %t.o
91// RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2
92// RUN: %t
93// RUN: echo
94
95// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out
96// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out
97// RUN: echo
98
99// RUN: echo 10.6, x86_64
100// RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -c %s -o %t.o
101// RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2
102// RUN: %t
103// RUN: echo
104
105#include <assert.h>
106#include <stdio.h>
107#include <sys/utsname.h>
108
109typedef int si_int;
110typedef unsigned su_int;
111
112typedef long long di_int;
113typedef unsigned long long du_int;
114
115// Integral bit manipulation
116
117di_int __ashldi3(di_int a, si_int b);      // a << b
118di_int __ashrdi3(di_int a, si_int b);      // a >> b  arithmetic (sign fill)
119di_int __lshrdi3(di_int a, si_int b);      // a >> b  logical    (zero fill)
120
121si_int __clzsi2(si_int a);  // count leading zeros
122si_int __clzdi2(di_int a);  // count leading zeros
123si_int __ctzsi2(si_int a);  // count trailing zeros
124si_int __ctzdi2(di_int a);  // count trailing zeros
125
126si_int __ffsdi2(di_int a);  // find least significant 1 bit
127
128si_int __paritysi2(si_int a);  // bit parity
129si_int __paritydi2(di_int a);  // bit parity
130
131si_int __popcountsi2(si_int a);  // bit population
132si_int __popcountdi2(di_int a);  // bit population
133
134// Integral arithmetic
135
136di_int __negdi2    (di_int a);                         // -a
137di_int __muldi3    (di_int a, di_int b);               // a * b
138di_int __divdi3    (di_int a, di_int b);               // a / b   signed
139du_int __udivdi3   (du_int a, du_int b);               // a / b   unsigned
140di_int __moddi3    (di_int a, di_int b);               // a % b   signed
141du_int __umoddi3   (du_int a, du_int b);               // a % b   unsigned
142du_int __udivmoddi4(du_int a, du_int b, du_int* rem);  // a / b, *rem = a % b
143
144//  Integral arithmetic with trapping overflow
145
146si_int __absvsi2(si_int a);           // abs(a)
147di_int __absvdi2(di_int a);           // abs(a)
148
149si_int __negvsi2(si_int a);           // -a
150di_int __negvdi2(di_int a);           // -a
151
152si_int __addvsi3(si_int a, si_int b);  // a + b
153di_int __addvdi3(di_int a, di_int b);  // a + b
154
155si_int __subvsi3(si_int a, si_int b);  // a - b
156di_int __subvdi3(di_int a, di_int b);  // a - b
157
158si_int __mulvsi3(si_int a, si_int b);  // a * b
159di_int __mulvdi3(di_int a, di_int b);  // a * b
160
161//  Integral comparison: a  < b -> 0
162//                       a == b -> 1
163//                       a  > b -> 2
164
165si_int __cmpdi2 (di_int a, di_int b);
166si_int __ucmpdi2(du_int a, du_int b);
167
168//  Integral / floating point conversion
169
170di_int __fixsfdi(      float a);
171di_int __fixdfdi(     double a);
172di_int __fixxfdi(long double a);
173
174su_int __fixunssfsi(      float a);
175su_int __fixunsdfsi(     double a);
176su_int __fixunsxfsi(long double a);
177
178du_int __fixunssfdi(      float a);
179du_int __fixunsdfdi(     double a);
180du_int __fixunsxfdi(long double a);
181
182float       __floatdisf(di_int a);
183double      __floatdidf(di_int a);
184long double __floatdixf(di_int a);
185
186float       __floatundisf(du_int a);
187double      __floatundidf(du_int a);
188long double __floatundixf(du_int a);
189
190//  Floating point raised to integer power
191
192float       __powisf2(      float a, si_int b);  // a ^ b
193double      __powidf2(     double a, si_int b);  // a ^ b
194long double __powixf2(long double a, si_int b);  // a ^ b
195
196//  Complex arithmetic
197
198//  (a + ib) * (c + id)
199
200      float _Complex __mulsc3( float a,  float b,  float c,  float d);
201     double _Complex __muldc3(double a, double b, double c, double d);
202long double _Complex __mulxc3(long double a, long double b,
203                              long double c, long double d);
204
205//  (a + ib) / (c + id)
206
207      float _Complex __divsc3( float a,  float b,  float c,  float d);
208     double _Complex __divdc3(double a, double b, double c, double d);
209long double _Complex __divxc3(long double a, long double b,
210                              long double c, long double d);
211
212#ifndef __arm
213#define HAS_LONG_DOUBLE
214#endif
215
216int main(int argc, char **argv) {
217  du_int du_tmp;
218  struct utsname name;
219#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
220  const char *target_name = "OS X";
221  unsigned target_version = __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__;
222  unsigned target_maj = target_version / 100;
223  unsigned target_min = (target_version / 10) % 10;
224  unsigned target_micro = target_version % 10;
225#else
226  const char *target_name = "iPhoneOS";
227  unsigned target_version = __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__;
228  unsigned target_maj = target_version / 10000;
229  unsigned target_min = (target_version / 100) % 100;
230  unsigned target_micro = target_version % 100;
231#endif
232
233  if (uname(&name))
234    return 1;
235
236  fprintf(stderr, "%s: clang_rt test:\n", argv[0]);
237  fprintf(stderr, "  target  : %s %d.%d.%d\n\n", target_name,
238          target_maj, target_min, target_micro);
239  fprintf(stderr, "  sysname : %s\n", name.sysname);
240  fprintf(stderr, "  nodename: %s\n", name.nodename);
241  fprintf(stderr, "  release : %s\n", name.release);
242  fprintf(stderr, "  version : %s\n", name.version);
243  fprintf(stderr, "  machine : %s\n", name.machine);
244
245  assert(__ashldi3(1, 1) == 2);
246  assert(__ashrdi3(2, 1) == 1);
247  assert(__lshrdi3(2, 1) == 1);
248  assert(__clzsi2(1) == 31);
249  assert(__clzdi2(1) == 63);
250  assert(__ctzsi2(2) == 1);
251  assert(__ctzdi2(2) == 1);
252  assert(__ffsdi2(12) == 3);
253  assert(__paritysi2(13) == 1);
254  assert(__paritydi2(13) == 1);
255  assert(__popcountsi2(13) == 3);
256  assert(__popcountdi2(13) == 3);
257  assert(__negdi2(3) == -3);
258  assert(__muldi3(2,2) == 4);
259  assert(__divdi3(-4,2) == -2);
260  assert(__udivdi3(4,2) == 2);
261  assert(__moddi3(3,2) == 1);
262  assert(__umoddi3(3,2) == 1);
263  assert(__udivmoddi4(5,2,&du_tmp) == 2 && du_tmp == 1);
264  assert(__absvsi2(-2) == 2);
265  assert(__absvdi2(-2) == 2);
266  assert(__negvsi2(2) == -2);
267  assert(__negvdi2(2) == -2);
268  assert(__addvsi3(2, 3) == 5);
269  assert(__addvdi3(2, 3) == 5);
270  assert(__subvsi3(2, 3) == -1);
271  assert(__subvdi3(2, 3) == -1);
272  assert(__mulvsi3(2, 3) == 6);
273  assert(__mulvdi3(2, 3) == 6);
274  assert(__cmpdi2(3, 2) == 2);
275  assert(__ucmpdi2(3, 2) == 2);
276  assert(__fixsfdi(2.0) == 2);
277  assert(__fixdfdi(2.0) == 2);
278  assert(__fixunssfsi(2.0) == 2);
279  assert(__fixunsdfsi(2.0) == 2);
280  assert(__fixunssfdi(2.0) == 2);
281  assert(__fixunsdfdi(2.0) == 2);
282  assert(__floatdisf(2) == 2.0);
283  assert(__floatdidf(2) == 2.0);
284  assert(__floatundisf(2) == 2.0);
285  assert(__floatundidf(2) == 2.0);
286  assert(__powisf2(2.0, 2) == 4.0);
287  assert(__powidf2(2.0, 2) == 4.0);
288
289  // FIXME: Clang/LLVM seems to be miscompiling _Complex currently, probably an
290  // ABI issue.
291#ifndef __arm
292  {
293    _Complex float a = __mulsc3(1.0, 2.0, 4.0, 8.0);
294    _Complex float b = (-12.0 + 16.0j);
295    fprintf(stderr, "a: (%f + %f), b: (%f + %f)\n",
296            __real a, __imag a, __real b, __imag b);
297  }
298  assert(__mulsc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j));
299  assert(__muldc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j));
300  assert(__divsc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j));
301  assert(__divdc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j));
302#endif
303
304#ifdef HAS_LONG_DOUBLE
305  assert(__divxc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j));
306  assert(__fixunsxfdi(2.0) == 2);
307  assert(__fixunsxfsi(2.0) == 2);
308  assert(__fixxfdi(2.0) == 2);
309  assert(__floatdixf(2) == 2.0);
310  assert(__floatundixf(2) == 2);
311  assert(__mulxc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j));
312  assert(__powixf2(2.0, 2) == 4.0);
313#endif
314
315  // Test some calls which are used on armv6/thumb. The calls/prototypes are
316  // fake, it would be nice to test correctness, but mostly we just want to
317  // make sure we resolve symbols correctly.
318#if defined(__arm) && defined(__ARM_ARCH_6K__) && defined(__thumb__)
319  if (argc == 100) {
320    extern void __restore_vfp_d8_d15_regs(void), __save_vfp_d8_d15_regs(void);
321    extern void __switch8(void), __switchu8(void),
322      __switch16(void), __switch32(void);
323    extern void __addsf3vfp(void);
324
325    __addsf3vfp();
326    __restore_vfp_d8_d15_regs();
327    __save_vfp_d8_d15_regs();
328    __switch8();
329    __switchu8();
330    __switch16();
331    __switch32();
332  }
333#endif
334
335  fprintf(stderr, "    OK!\n");
336
337  return 0;
338}
339