[testsuite] require sqrt_insn effective target where needed
[official-gcc.git] / gcc / testsuite / gcc.target / powerpc / bcd-4.c
blob6d2c59ef792e032f464e05584f30af00cc3c7bd9
1 /* { dg-do run } */
2 /* { dg-require-effective-target int128 } */
3 /* { dg-require-effective-target p9vector_hw } */
4 /* { dg-options "-mdejagnu-cpu=power9 -O2 -save-temps" } */
5 /* { dg-final { scan-assembler-times {\mbcdadd\M} 5 } } */
6 /* { dg-final { scan-assembler-times {\mbcdsub\M} 20 } } */
7 /* { dg-final { scan-assembler-times {\mbcds\M} 2 } } */
8 /* { dg-final { scan-assembler-times {\mdenbcdq\M} 1 } } */
10 #include <altivec.h>
12 #define DEBUG 0
14 #if DEBUG
15 #include <stdio.h>
16 #endif
19 #define BCD_POS0 12 // 0xC
20 #define BCD_POS1 15 // 0xF
21 #define BCD_NEG 13 // 0xD
23 void abort (void);
25 union conv_t
27 _Decimal128 d128;
28 vector unsigned char ch;
29 vector long long unsigned int vllui;
30 } conv;
32 _Decimal128 convert_vec_char (vector unsigned char a)
34 union conv_t conv;
35 _Decimal128 result;
37 conv.ch = a;
38 result = conv.d128;
39 return result;
42 vector unsigned char maxbcd(unsigned int sign)
44 vector unsigned char result;
45 int i;
47 #ifdef __BIG_ENDIAN__
48 for (i = 0; i < 15; i++)
49 #else
50 for (i = 15; i > 0; i--)
51 #endif
52 result[i] = 0x99;
54 #ifdef __BIG_ENDIAN__
55 result[15] = 0x90 | sign;
56 #else
57 result[0] = 0x90 | sign;
58 #endif
60 return result;
63 vector unsigned char num2bcd(long int a, int encoding)
65 int i;
66 unsigned int hi, low, sign;
68 vector unsigned char result;
70 if (a > 0) {
71 if (encoding == 0)
72 sign = BCD_POS0;
73 else
74 sign = BCD_POS1;
76 } else {
77 sign = BCD_NEG;
78 a = -a;
81 hi = a % 10; // 1st digit
82 a = a / 10;
83 #ifdef __BIG_ENDIAN__
84 result[15] = hi << 4| sign;
85 #else
86 result[0] = hi << 4| sign;
87 #endif
89 #ifdef __BIG_ENDIAN__
90 for (i = 14; i >= 0; i--)
91 #else
92 for (i = 1; i < 16; i++)
93 #endif
95 low = a % 10;
96 a = a / 10;
97 hi = a % 10;
98 a = a / 10;
99 result[i] = hi << 4 | low;
103 return result;
106 int main ()
108 int i;
109 long int value_a, value_b, value_result;
110 vector unsigned char a, b, result, exp_result;
111 _Decimal128 result_d128, exp_result_d128;
113 /* Make a and b positive BCD numbers */
114 value_a = 1020304;
115 a = num2bcd(value_a, 0);
117 value_b = 101010;
118 b = num2bcd(value_b, 0);
120 value_result = value_a + value_b;
121 exp_result = num2bcd(value_result, 0);
123 result = __builtin_bcdadd (a, b, 0);
125 for (i = 0; i < 16; i++)
126 if (exp_result[i] != result[i]) {
128 #if DEBUG
129 printf("ERROR: __builtin_bcdadd result[%d] = %d does not match "
130 "expected_result[%d] = %d\n",
131 i, result[i], i, exp_result[i]);
132 #else
133 abort();
134 #endif
137 /* result should be positive */
138 #ifdef __BIG_ENDIAN__
139 if ((result[15] & 0xF) != BCD_POS0)
140 #else
141 if ((result[0] & 0xF) != BCD_POS0)
142 #endif
143 #if DEBUG
144 printf("ERROR: __builtin_bcdadd sign of result is %d. Does not match "
145 "expected_result = %d\n",
146 result[0] & 0xF, BCD_POS0);
147 #else
148 abort();
149 #endif
151 /* Make a and b positive BCD numbers using alternate positive encoding. */
152 value_a = 1030507;
153 a = num2bcd(value_a, 1);
155 value_b = 204060;
156 b = num2bcd(value_b, 1);
158 value_result = value_a + value_b;
159 exp_result = num2bcd(value_result, 1);
161 result = __builtin_bcdadd (a, b, 1);
163 for (i = 0; i < 16; i++)
164 if (exp_result[i] != result[i]) {
165 #if DEBUG
166 printf("ERROR: __builtin_bcdadd result[%d] = %d does not match "
167 "expected_result[%d] = %d\n",
168 i, result[i], i, exp_result[i]);
169 #else
170 abort();
171 #endif
174 /* Result should be positive, alternate encoding. */
175 #ifdef __BIG_ENDIAN__
176 if ((result[15] & 0xF) != BCD_POS1)
177 #else
178 if ((result[0] & 0xF) != BCD_POS1)
179 #endif
180 #if DEBUG
181 printf("ERROR: __builtin_bcdadd sign of result is %d. Does not "
182 "match expected_result = %d\n",
183 result[0] & 0xF, BCD_POS1);
184 #else
185 abort();
186 #endif
188 /* Make a and b negative BCD numbers */
189 value_a = -1030507;
190 a = num2bcd(value_a, 0);
192 value_b = -1010101;
193 b = num2bcd(value_b, 0);
195 value_result = value_a + value_b;
196 exp_result = num2bcd(value_result, 0);
198 result = __builtin_bcdadd (a, b, 0);
200 for (i = 0; i < 16; i++)
201 if (exp_result[i] != result[i]) {
202 #if DEBUG
203 printf("ERROR: __builtin_bcdadd, neg result[%d] = %d does not match "
204 "expected_result[%d] = %d\n",
205 i, result[i], i, exp_result[i]);
206 #else
207 abort();
208 #endif
211 /* result should be negative */
212 #ifdef __BIG_ENDIAN__
213 if ((result[15] & 0xF) != BCD_NEG)
214 #else
215 if ((result[0] & 0xF) != BCD_NEG)
216 #endif
217 #if DEBUG
218 printf("ERROR: __builtin_bcdadd sign, neg of result is %d. Does not "
219 "match expected_result = %d\n",
220 result[0] & 0xF, BCD_NEG);
221 #else
222 abort();
223 #endif
226 /* Make a negative, b positive BCD numbers */
227 value_a = -1030507;
228 a = num2bcd(value_a, 0);
230 value_b = 1010101;
231 b = num2bcd(value_b, 0);
233 value_result = value_a - value_b;
234 exp_result = num2bcd(value_result, 0);
236 result = __builtin_bcdsub (a, b, 0);
238 for (i = 0; i < 16; i++)
239 if (exp_result[i] != result[i]) {
240 #if DEBUG
241 printf("ERROR: __builtin_bcdsub, neg result[%d] = %d does not match "
242 "expected_result[%d] = %d\n",
243 i, result[i], i, exp_result[i]);
244 #else
245 abort();
246 #endif
249 /* result should be positive */
250 #ifdef __BIG_ENDIAN__
251 if ((result[15] & 0xF) != BCD_NEG)
252 #else
253 if ((result[0] & 0xF) != BCD_NEG)
254 #endif
255 #if DEBUG
256 printf("ERROR: __builtin_bcdadd sign, of result is %d. Does not match "
257 "expected_result = %d\n",
258 result[0] & 0xF, BCD_NEG);
259 #else
260 abort();
261 #endif
263 /* Make a and b positive BCD numbers */
264 value_a = 1030507;
265 a = num2bcd(value_a, 1);
267 value_b = 1010101;
268 b = num2bcd(value_b, 1);
270 value_result = value_a - value_b;
271 exp_result = num2bcd(value_result, 1);
273 result = __builtin_bcdsub (a, b, 1);
275 for (i = 0; i < 16; i++)
276 if (exp_result[i] != result[i]) {
277 #if DEBUG
278 printf("ERROR:carll __builtin_bcdsub, pos result[%d] = %d does not "
279 "match expected_result[%d] = %d\n",
280 i, result[i], i, exp_result[i]);
281 #else
282 abort();
283 #endif
286 /* result should be positive */
287 #ifdef __BIG_ENDIAN__
288 if ((result[15] & 0xF) != BCD_POS1)
289 #else
290 if ((result[0] & 0xF) != BCD_POS1)
291 #endif
292 #if DEBUG
293 printf("ERROR: __builtin_bcdsub sign, result is %d. Does not match "
294 "expected_result = %d\n",
295 result[0] & 0xF, BCD_POS1);
296 #else
297 abort();
298 #endif
300 /* Test overflow add and subtract. */
301 a = maxbcd(BCD_POS0);
302 b = maxbcd(BCD_POS0);
304 if(__builtin_bcdadd_ofl (a, b, 0) == 0)
305 #if DEBUG
306 printf("ERROR: __builtin_bcdadd did not overflow as expected\n");
307 #else
308 abort();
309 #endif
311 value_a = 99999999;
312 a = num2bcd(value_a, 0);
314 value_b = 999999999;
315 b = num2bcd(value_b, 0);
317 if(__builtin_bcdadd_ofl (a, b, 0))
318 #if DEBUG
319 printf("ERROR: __builtin_bcdadd unexpectedly overflowed\n");
320 #else
321 abort();
322 #endif
324 a = maxbcd(BCD_POS0);
325 b = maxbcd(BCD_NEG);
327 if (__builtin_bcdsub_ofl (a, b, 0) == 0)
328 #if DEBUG
329 printf("ERROR: __builtin_bcdsub did not overflow as expected\n");
330 #else
331 abort();
332 #endif
334 value_a = -99999999;
335 a = num2bcd(value_a, 0);
337 value_b = -999999999;
338 b = num2bcd(value_b, 0);
340 if (__builtin_bcdsub_ofl (a, b, 0))
341 #if DEBUG
342 printf("ERROR: __builtin_bcdsub unexpectedly overflowed\n");
343 #else
344 abort();
345 #endif
347 /* Test arguments for valid/invalid */
348 if (__builtin_bcdinvalid (a))
349 #if DEBUG
350 printf("ERROR: __builtin_invalid input is unexpectedly invalid.\n");
351 #else
352 abort();
353 #endif
355 a[3] = 0xBB; /* an invalid BCD digit */
356 if (!__builtin_bcdinvalid (a))
357 #if DEBUG
358 printf("ERROR: __builtin_invalid input is unexpectedly valid.\n");
359 #else
360 abort();
361 #endif
363 value_a = 1020304;
364 a = num2bcd(value_a, 0);
366 value_b = 101010;
367 b = num2bcd(value_b, 0);
369 /* Test equality */
370 if (__builtin_bcdcmpeq (a, b))
371 #if DEBUG
372 printf("ERROR: __builtin__bcdcmpeq result is unexpectedly 1.\n");
373 #else
374 abort();
375 #endif
377 if (!__builtin_bcdcmpeq (a, a))
378 #if DEBUG
379 printf("ERROR: __builtin__bcdcmpeq result is unexpectedly 0.\n");
380 #else
381 abort();
382 #endif
385 /* Test a greater then b, inputs already setup this way. */
386 if (!__builtin_bcdcmpgt (a, b))
387 #if DEBUG
388 printf("ERROR: __builtin__bcdcmpgt result is unexpectedly 0.\n");
389 #else
390 abort();
391 #endif
393 if (__builtin_bcdcmpgt (b, a))
394 #if DEBUG
395 printf("ERROR: __builtin__bcdcmpgt result is unexpectedly 1.\n");
396 #else
397 abort();
398 #endif
400 if (__builtin_bcdcmpgt (a, a))
401 #if DEBUG
402 printf("ERROR: __builtin__bcdcmpgt input equal, result is unexpectedly "
403 "1.\n");
404 #else
405 abort();
406 #endif
409 if (!__builtin_bcdcmpge (a, b))
410 #if DEBUG
411 printf("ERROR: __builtin__bcdcmpge result is unexpectedly 0.\n");
412 #else
413 abort();
414 #endif
416 if (__builtin_bcdcmpge (b, a))
417 #if DEBUG
418 printf("ERROR: __builtin__bcdcmpge result is unexpectedly 1.\n");
419 #else
420 abort();
421 #endif
423 if (!__builtin_bcdcmpge (b, b))
424 #if DEBUG
425 printf("ERROR: __builtin__bcdcmpge inputs equal result is unexpectedly "
426 "0.\n");
427 #else
428 abort();
429 #endif
431 /* Test a less then b. */
432 value_a = 101010;
433 a = num2bcd(value_a, 0);
434 value_b = 1020304;
435 b = num2bcd(value_b, 0);
437 if (!__builtin_bcdcmplt (a, b))
438 #if DEBUG
439 printf("ERROR: __builtin__bcdcmplt result is unexpectedly 0.\n");
440 #else
441 abort();
442 #endif
444 if (__builtin_bcdcmplt (b, a))
445 #if DEBUG
446 printf("ERROR: __builtin__bcdcmplt result is unexpectedly 1.\n");
447 #else
448 abort();
449 #endif
451 if (__builtin_bcdcmplt (b, b))
452 #if DEBUG
453 printf("ERROR: __builtin__bcdcmplt inputs equal result is unexpectedly "
454 "1.\n");
455 #else
456 abort();
457 #endif
460 if (!__builtin_bcdcmple (a, b))
461 #if DEBUG
462 printf("ERROR: __builtin__bcdcmple result is unexpectedly 0.\n");
463 #else
464 abort();
465 #endif
467 if (__builtin_bcdcmple (b, a))
468 #if DEBUG
469 printf("ERROR: __builtin__bcdcmple result is unexpectedly 1.\n");
470 #else
471 abort();
472 #endif
474 if (!__builtin_bcdcmple (a, a))
475 #if DEBUG
476 printf("ERROR: __builtin__bcdcmple inputs equal result is unexpectedly "
477 "0.\n");
478 #else
479 abort();
480 #endif
482 /* Test multipy 10 */
483 value_a = 1020304;
484 a = num2bcd(value_a, 0);
486 value_result = value_a * 10;
487 exp_result = num2bcd(value_result, 0);
489 result = __builtin_bcdmul10 (a);
491 for (i = 0; i < 16; i++)
492 if (exp_result[i] != result[i]) {
493 #if DEBUG
494 printf("ERROR:carll __builtin_bcdmul10, pos result[%d] = %d does not "
495 "match expected_result[%d] = %d\n",
496 i, result[i], i, exp_result[i]);
497 #else
498 abort();
499 #endif
502 /* result should be positive */
503 #ifdef __BIG_ENDIAN__
504 if ((result[15] & 0xF) != BCD_POS0)
505 #else
506 if ((result[0] & 0xF) != BCD_POS0)
507 #endif
508 #if DEBUG
509 printf("ERROR: __builtin_bcdmul10 sign, result is %d. Does not match "
510 "expected_result = %d\n",
511 result[0] & 0xF, BCD_POS1);
512 #else
513 abort();
514 #endif
516 /* Test divide 10 */
517 value_a = 1020304;
518 a = num2bcd(value_a, 0);
520 value_result = value_a / 10;
521 exp_result = num2bcd(value_result, 0);
523 result = __builtin_bcddiv10 (a);
525 for (i = 0; i < 16; i++)
526 if (exp_result[i] != result[i]) {
527 #if DEBUG
528 printf("ERROR:carll __builtin_bcddiv10, pos result[%d] = %d does not "
529 "match expected_result[%d] = %d\n",
530 i, result[i], i, exp_result[i]);
531 #else
532 abort();
533 #endif
536 /* result should be positive */
537 #ifdef __BIG_ENDIAN__
538 if ((result[15] & 0xF) != BCD_POS0)
539 #else
540 if ((result[0] & 0xF) != BCD_POS0)
541 #endif
542 #if DEBUG
543 printf("ERROR: __builtin_bcddiv10 sign, result is %d. Does not match "
544 "expected_result = %d\n",
545 result[0] & 0xF, BCD_POS1);
546 #else
547 abort();
548 #endif
550 value_a = 1020304;
551 exp_result_d128 = 1020304;
552 a = num2bcd(value_a, 0);
554 conv.ch = a;
555 conv.d128 = __builtin_bcd2dfp (a);
556 result_d128 = conv.d128;
558 if (result_d128 != exp_result_d128)
559 #if DEBUG
560 printf("ERROR: __builtin_bcd2dfp, result does not match expected_result."
561 "\n");
562 #else
563 abort();
564 #endif
565 return 0;