1 /* { dg-do run { target 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
signof(int i)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
main()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 }
343