OSDN Git Service

PR middle-end/29274
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.target / arm / eabi1.c
1 /* { dg-do run { target arm*-*-symbianelf* arm*-*-eabi* } } */
2 /* { dg-options "" } */
3
4 /* This file tests most of the non-C++ run-time helper functions
5    described in Section 4 of the "Run-Time ABI for the ARM
6    Architecture".  These are basic tests; they do not try to validate
7    all of the corner cases in these routines.  
8
9    The functions not tested here are:
10
11      __aeabi_cdcmpeq
12      __aeabi_cdcmple
13      __aeabi_cdrcmple
14      __aeabi_cfcmpeq
15      __aeabi_cfcmple
16      __aeabi_cfrcmple
17      __aeabi_ldivmod
18      __aeabi_uldivmod
19      __aeabi_idivmod
20      __aeabi_uidivmod
21
22    These functions have non-standard calling conventions that would
23    require the use of inline assembly to test.  It would be good to
24    add such tests, but they have not yet been implemented.  
25
26    There are also no tests for the "division by zero", "memory copying,
27    clearing, and setting" functions.  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <math.h>
32
33 /* All these functions are defined to use the base ABI, so use the
34    attribute to ensure the tests use the base ABI to call them even
35    when the VFP ABI is otherwise in effect.  */
36 #define PCS __attribute__((pcs("aapcs")))
37
38 #define decl_float(code, type)                                          \
39   extern type __aeabi_ ## code ## add (type, type) PCS;                 \
40   extern type __aeabi_ ## code ## div (type, type) PCS;                 \
41   extern type __aeabi_ ## code ## mul (type, type) PCS;                 \
42   extern type __aeabi_ ## code ## neg (type) PCS;                       \
43   extern type __aeabi_ ## code ## rsub (type, type) PCS;                \
44   extern type __aeabi_ ## code ## sub (type, type) PCS;                 \
45   extern int __aeabi_ ## code ## cmpeq (type, type) PCS;                \
46   extern int __aeabi_ ## code ## cmplt (type, type) PCS;                \
47   extern int __aeabi_ ## code ## cmple (type, type) PCS;                \
48   extern int __aeabi_ ## code ## cmpge (type, type) PCS;                \
49   extern int __aeabi_ ## code ## cmpgt (type, type) PCS;                \
50   extern int __aeabi_ ## code ## cmpun (type, type) PCS;                \
51   extern int __aeabi_ ## code ## 2iz (type) PCS;                        \
52   extern unsigned int __aeabi_ ## code ## 2uiz (type) PCS;              \
53   extern long long __aeabi_ ## code ## 2lz (type) PCS;                  \
54   extern unsigned long long __aeabi_ ## code ## 2ulz (type) PCS;        \
55   extern type __aeabi_i2 ## code (int) PCS;                             \
56   extern type __aeabi_ui2 ## code (int) PCS;                            \
57   extern type __aeabi_l2 ## code (long long) PCS;                       \
58   extern type __aeabi_ul2 ## code (unsigned long long) PCS;             \
59                                                                         \
60   type code ## zero = 0.0;                                              \
61   type code ## one = 1.0;                                               \
62   type code ## two = 2.0;                                               \
63   type code ## four = 4.0;                                              \
64   type code ## minus_one = -1.0;                                        \
65   type code ## minus_two = -2.0;                                        \
66   type code ## minus_four = -4.0;                                       \
67   type code ## epsilon = 1E-32;                                         \
68   type code ## NaN = 0.0 / 0.0;
69
70 decl_float (d, double)
71 decl_float (f, float)
72
73 extern float __aeabi_d2f (double) PCS;
74 extern double __aeabi_f2d (float) PCS;
75 extern long long __aeabi_lmul (long long, long long);
76 extern long long __aeabi_llsl (long long, int);
77 extern long long __aeabi_llsr (long long, int);
78 extern long long __aeabi_lasr (long long, int);
79 extern int __aeabi_lcmp (long long, long long);
80 extern int __aeabi_ulcmp (unsigned long long, unsigned long long);
81 extern int __aeabi_idiv (int, int);
82 extern unsigned int __aeabi_uidiv (unsigned int, unsigned int);
83 extern int __aeabi_uread4 (void *);
84 extern int __aeabi_uwrite4 (int, void *);
85 extern long long __aeabi_uread8 (void *);
86 extern long long __aeabi_uwrite8 (long long, void *);
87
88 #define eq(a, b, type, abs, epsilon, format)                    \
89   {                                                             \
90     type a1;                                                    \
91     type b1;                                                    \
92                                                                 \
93     a1 = a;                                                     \
94     b1 = b;                                                     \
95     if (abs (a1 - b1) > epsilon)                                \
96     {                                                           \
97       fprintf (stderr, "%d: Test %s == %s\n", __LINE__, #a, #b);        \
98       fprintf (stderr, "%d: " format " != " format "\n",        \
99                __LINE__, a1, b1);                               \
100       abort ();                                                 \
101     }                                                           \
102   }
103
104 #define ieq(a, b) eq (a, b, int, abs, 0, "%d")
105 #define ueq(a, b) eq (a, b, unsigned int, abs, 0, "%u")
106 #define leq(a, b) eq (a, b, long long, abs, 0, "%lld")
107 #define uleq(a, b) eq (a, b, unsigned long long, abs, 0, "%llu")
108 #define feq(a, b) eq (a, b, float, fabs, fepsilon, "%f")
109 #define deq(a, b) eq (a, b, double, fabs, depsilon, "%g")
110
111 #define NUM_CMP_VALUES 6
112
113 /* Values picked to cover a range of small, large, positive and negative.  */
114 static unsigned int cmp_val[NUM_CMP_VALUES] = 
115 {
116   0,
117   1,
118   0x40000000,
119   0x80000000,
120   0xc0000000,
121   0xffffffff
122 };
123
124 /* All combinations for each of the above values. */
125 #define ulcmp(l, s, m) \
126     s, l, l, l, l, l,  m, s, l, l, l, l, \
127     m, m, s, l, l, l,  m, m, m, s, l, l, \
128     m, m, m, m, s, l,  m, m, m, m, m, s
129
130 #define lcmp(l, s, m) \
131     s, l, l, m, m, m,  m, s, l, m, m, m, \
132     m, m, s, m, m, m,  l, l, l, s, l, l, \
133     l, l, l, m, s, l,  l, l, l, m, m, s
134
135 /* All combinations of the above for high/low words.  */
136 static int lcmp_results[] =
137 {
138   lcmp(ulcmp(-1, -1, -1), ulcmp(-1, 0, 1), ulcmp(1, 1, 1))
139 };
140
141 static int ulcmp_results[] =
142 {
143   ulcmp(ulcmp(-1, -1, -1), ulcmp(-1, 0, 1), ulcmp(1, 1, 1))
144 };
145
146 static int signof(int i)
147 {
148   if (i < 0)
149     return -1;
150
151   if (i == 0)
152     return 0;
153
154   return 1;
155 }
156
157 int main () {
158   unsigned char bytes[256];
159   int i, j, k, n;
160   int *result;
161
162   /* Table 2.  Double-precision floating-point arithmetic.  */
163   deq (__aeabi_dadd (dzero, done), done);
164   deq (__aeabi_dadd (done, done), dtwo);
165   deq (__aeabi_ddiv (dminus_four, dminus_two), dtwo);
166   deq (__aeabi_ddiv (dminus_two, dtwo), dminus_one);
167   deq (__aeabi_dmul (dtwo, dtwo), dfour);
168   deq (__aeabi_dmul (dminus_one, dminus_two), dtwo);
169   deq (__aeabi_dneg (dminus_one), done);
170   deq (__aeabi_dneg (dfour), dminus_four);
171   deq (__aeabi_drsub (done, dzero), dminus_one);
172   deq (__aeabi_drsub (dtwo, dminus_two), dminus_four);
173   deq (__aeabi_dsub (dzero, done), dminus_one);
174   deq (__aeabi_dsub (dminus_two, dtwo), dminus_four);
175
176   /* Table 3.  Double-precision floating-point comparisons.  */
177   ieq (__aeabi_dcmpeq (done, done), 1);
178   ieq (__aeabi_dcmpeq (done, dzero), 0);
179   ieq (__aeabi_dcmpeq (dNaN, dzero), 0);
180   ieq (__aeabi_dcmpeq (dNaN, dNaN), 0);
181
182   ieq (__aeabi_dcmplt (dzero, done), 1);
183   ieq (__aeabi_dcmplt (done, dzero), 0);
184   ieq (__aeabi_dcmplt (dzero, dzero), 0);
185   ieq (__aeabi_dcmplt (dzero, dNaN), 0);
186   ieq (__aeabi_dcmplt (dNaN, dNaN), 0);
187
188   ieq (__aeabi_dcmple (dzero, done), 1);
189   ieq (__aeabi_dcmple (done, dzero), 0);
190   ieq (__aeabi_dcmple (dzero, dzero), 1);
191   ieq (__aeabi_dcmple (dzero, dNaN), 0);
192   ieq (__aeabi_dcmple (dNaN, dNaN), 0);
193
194   ieq (__aeabi_dcmpge (dzero, done), 0);
195   ieq (__aeabi_dcmpge (done, dzero), 1);
196   ieq (__aeabi_dcmpge (dzero, dzero), 1);
197   ieq (__aeabi_dcmpge (dzero, dNaN), 0);
198   ieq (__aeabi_dcmpge (dNaN, dNaN), 0);
199
200   ieq (__aeabi_dcmpgt (dzero, done), 0);
201   ieq (__aeabi_dcmpgt (done, dzero), 1);
202   ieq (__aeabi_dcmplt (dzero, dzero), 0);
203   ieq (__aeabi_dcmpgt (dzero, dNaN), 0);
204   ieq (__aeabi_dcmpgt (dNaN, dNaN), 0);
205
206   ieq (__aeabi_dcmpun (done, done), 0);
207   ieq (__aeabi_dcmpun (done, dzero), 0);
208   ieq (__aeabi_dcmpun (dNaN, dzero), 1);
209   ieq (__aeabi_dcmpun (dNaN, dNaN), 1);
210
211   /* Table 4.  Single-precision floating-point arithmetic.  */
212   feq (__aeabi_fadd (fzero, fone), fone);
213   feq (__aeabi_fadd (fone, fone), ftwo);
214   feq (__aeabi_fdiv (fminus_four, fminus_two), ftwo);
215   feq (__aeabi_fdiv (fminus_two, ftwo), fminus_one);
216   feq (__aeabi_fmul (ftwo, ftwo), ffour);
217   feq (__aeabi_fmul (fminus_one, fminus_two), ftwo);
218   feq (__aeabi_fneg (fminus_one), fone);
219   feq (__aeabi_fneg (ffour), fminus_four);
220   feq (__aeabi_frsub (fone, fzero), fminus_one);
221   feq (__aeabi_frsub (ftwo, fminus_two), fminus_four);
222   feq (__aeabi_fsub (fzero, fone), fminus_one);
223   feq (__aeabi_fsub (fminus_two, ftwo), fminus_four);
224
225   /* Table 5.  Single-precision floating-point comparisons.  */
226   ieq (__aeabi_fcmpeq (fone, fone), 1);
227   ieq (__aeabi_fcmpeq (fone, fzero), 0);
228   ieq (__aeabi_fcmpeq (fNaN, fzero), 0);
229   ieq (__aeabi_fcmpeq (fNaN, fNaN), 0);
230
231   ieq (__aeabi_fcmplt (fzero, fone), 1);
232   ieq (__aeabi_fcmplt (fone, fzero), 0);
233   ieq (__aeabi_fcmplt (fzero, fzero), 0);
234   ieq (__aeabi_fcmplt (fzero, fNaN), 0);
235   ieq (__aeabi_fcmplt (fNaN, fNaN), 0);
236
237   ieq (__aeabi_fcmple (fzero, fone), 1);
238   ieq (__aeabi_fcmple (fone, fzero), 0);
239   ieq (__aeabi_fcmple (fzero, fzero), 1);
240   ieq (__aeabi_fcmple (fzero, fNaN), 0);
241   ieq (__aeabi_fcmple (fNaN, fNaN), 0);
242
243   ieq (__aeabi_fcmpge (fzero, fone), 0);
244   ieq (__aeabi_fcmpge (fone, fzero), 1);
245   ieq (__aeabi_fcmpge (fzero, fzero), 1);
246   ieq (__aeabi_fcmpge (fzero, fNaN), 0);
247   ieq (__aeabi_fcmpge (fNaN, fNaN), 0);
248
249   ieq (__aeabi_fcmpgt (fzero, fone), 0);
250   ieq (__aeabi_fcmpgt (fone, fzero), 1);
251   ieq (__aeabi_fcmplt (fzero, fzero), 0);
252   ieq (__aeabi_fcmpgt (fzero, fNaN), 0);
253   ieq (__aeabi_fcmpgt (fNaN, fNaN), 0);
254
255   ieq (__aeabi_fcmpun (fone, fone), 0);
256   ieq (__aeabi_fcmpun (fone, fzero), 0);
257   ieq (__aeabi_fcmpun (fNaN, fzero), 1);
258   ieq (__aeabi_fcmpun (fNaN, fNaN), 1);
259
260   /* Table 6.  Floating-point to integer conversions.  */
261   ieq (__aeabi_d2iz (dminus_one), -1);
262   ueq (__aeabi_d2uiz (done), 1);
263   leq (__aeabi_d2lz (dminus_two), -2LL);
264   uleq (__aeabi_d2ulz (dfour), 4LL);
265   ieq (__aeabi_f2iz (fminus_one), -1);
266   ueq (__aeabi_f2uiz (fone), 1);
267   leq (__aeabi_f2lz (fminus_two), -2LL);
268   uleq (__aeabi_f2ulz (ffour), 4LL);
269
270   /* Table 7.  Conversions between floating types.  */
271   feq (__aeabi_d2f (dtwo), ftwo);
272   deq (__aeabi_f2d (fminus_four), dminus_four);
273
274   /* Table 8.  Integer to floating-point conversions.  */
275   deq (__aeabi_i2d (-1), dminus_one);
276   deq (__aeabi_ui2d (2), dtwo);
277   deq (__aeabi_l2d (-1), dminus_one);
278   deq (__aeabi_ul2d (2ULL), dtwo);
279   feq (__aeabi_i2f (-1), fminus_one);
280   feq (__aeabi_ui2f (2), ftwo);
281   feq (__aeabi_l2f (-1), fminus_one);
282   feq (__aeabi_ul2f (2ULL), ftwo);
283
284   /* Table 9.  Long long functions.  */
285   leq (__aeabi_lmul (4LL, -1LL), -4LL);
286   leq (__aeabi_llsl (2LL, 1), 4LL);
287   leq (__aeabi_llsr (-1LL, 63), 1);
288   leq (__aeabi_lasr (-1LL, 63), -1);
289
290   result = lcmp_results;
291   for (i = 0; i < NUM_CMP_VALUES; i++)
292     for (j = 0; j < NUM_CMP_VALUES; j++)
293       for (k = 0; k < NUM_CMP_VALUES; k++)
294         for (n = 0; n < NUM_CMP_VALUES; n++)
295           {
296             ieq (signof (__aeabi_lcmp
297                           (((long long)cmp_val[i] << 32) | cmp_val[k],
298                            ((long long)cmp_val[j] << 32) | cmp_val[n])),
299                            *result);
300             result++;
301           }
302   result = ulcmp_results;
303   for (i = 0; i < NUM_CMP_VALUES; i++)
304     for (j = 0; j < NUM_CMP_VALUES; j++)
305       for (k = 0; k < NUM_CMP_VALUES; k++)
306         for (n = 0; n < NUM_CMP_VALUES; n++)
307           {
308             ieq (signof (__aeabi_ulcmp
309                           (((long long)cmp_val[i] << 32) | cmp_val[k],
310                            ((long long)cmp_val[j] << 32) | cmp_val[n])),
311                            *result);
312             result++;
313           }
314
315   ieq (__aeabi_idiv (-550, 11), -50);
316   ueq (__aeabi_uidiv (4000000000U, 1000000U), 4000U);
317
318   for (i = 0; i < 256; i++)
319     bytes[i] = i;
320
321 #ifdef __ARMEB__
322   ieq (__aeabi_uread4 (bytes + 1), 0x01020304U);
323   leq (__aeabi_uread8 (bytes + 3), 0x030405060708090aLL);
324   ieq (__aeabi_uwrite4 (0x66778899U, bytes + 5), 0x66778899U);
325   leq (__aeabi_uwrite8 (0x2030405060708090LL, bytes + 15),
326        0x2030405060708090LL);
327 #else
328   ieq (__aeabi_uread4 (bytes + 1), 0x04030201U);
329   leq (__aeabi_uread8 (bytes + 3), 0x0a09080706050403LL);
330   ieq (__aeabi_uwrite4 (0x99887766U, bytes + 5), 0x99887766U);
331   leq (__aeabi_uwrite8 (0x9080706050403020LL, bytes + 15),
332        0x9080706050403020LL);
333 #endif
334
335   for (i = 0; i < 4; i++)
336     ieq (bytes[5 + i], (6 + i) * 0x11);
337
338   for (i = 0; i < 8; i++)
339     ieq (bytes[15 + i], (2 + i) * 0x10);
340
341   exit (0);             
342 }