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 } } */
19 #define BCD_POS0 12 // 0xC
20 #define BCD_POS1 15 // 0xF
21 #define BCD_NEG 13 // 0xD
28 vector
unsigned char ch
;
29 vector
long long unsigned int vllui
;
32 _Decimal128
convert_vec_char (vector
unsigned char a
)
42 vector
unsigned char maxbcd(unsigned int sign
)
44 vector
unsigned char result
;
48 for (i
= 0; i
< 15; i
++)
50 for (i
= 15; i
> 0; i
--)
55 result
[15] = 0x90 | sign
;
57 result
[0] = 0x90 | sign
;
63 vector
unsigned char num2bcd(long int a
, int encoding
)
66 unsigned int hi
, low
, sign
;
68 vector
unsigned char result
;
81 hi
= a
% 10; // 1st digit
84 result
[15] = hi
<< 4| sign
;
86 result
[0] = hi
<< 4| sign
;
90 for (i
= 14; i
>= 0; i
--)
92 for (i
= 1; i
< 16; i
++)
99 result
[i
] = hi
<< 4 | low
;
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 */
115 a
= num2bcd(value_a
, 0);
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
]) {
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
]);
137 /* result should be positive */
138 #ifdef __BIG_ENDIAN__
139 if ((result
[15] & 0xF) != BCD_POS0
)
141 if ((result
[0] & 0xF) != BCD_POS0
)
144 printf("ERROR: __builtin_bcdadd sign of result is %d. Does not match "
145 "expected_result = %d\n",
146 result
[0] & 0xF, BCD_POS0
);
151 /* Make a and b positive BCD numbers using alternate positive encoding. */
153 a
= num2bcd(value_a
, 1);
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
]) {
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
]);
174 /* Result should be positive, alternate encoding. */
175 #ifdef __BIG_ENDIAN__
176 if ((result
[15] & 0xF) != BCD_POS1
)
178 if ((result
[0] & 0xF) != BCD_POS1
)
181 printf("ERROR: __builtin_bcdadd sign of result is %d. Does not "
182 "match expected_result = %d\n",
183 result
[0] & 0xF, BCD_POS1
);
188 /* Make a and b negative BCD numbers */
190 a
= num2bcd(value_a
, 0);
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
]) {
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
]);
211 /* result should be negative */
212 #ifdef __BIG_ENDIAN__
213 if ((result
[15] & 0xF) != BCD_NEG
)
215 if ((result
[0] & 0xF) != BCD_NEG
)
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
);
226 /* Make a negative, b positive BCD numbers */
228 a
= num2bcd(value_a
, 0);
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
]) {
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
]);
249 /* result should be positive */
250 #ifdef __BIG_ENDIAN__
251 if ((result
[15] & 0xF) != BCD_NEG
)
253 if ((result
[0] & 0xF) != BCD_NEG
)
256 printf("ERROR: __builtin_bcdadd sign, of result is %d. Does not match "
257 "expected_result = %d\n",
258 result
[0] & 0xF, BCD_NEG
);
263 /* Make a and b positive BCD numbers */
265 a
= num2bcd(value_a
, 1);
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
]) {
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
]);
286 /* result should be positive */
287 #ifdef __BIG_ENDIAN__
288 if ((result
[15] & 0xF) != BCD_POS1
)
290 if ((result
[0] & 0xF) != BCD_POS1
)
293 printf("ERROR: __builtin_bcdsub sign, result is %d. Does not match "
294 "expected_result = %d\n",
295 result
[0] & 0xF, BCD_POS1
);
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)
306 printf("ERROR: __builtin_bcdadd did not overflow as expected\n");
312 a
= num2bcd(value_a
, 0);
315 b
= num2bcd(value_b
, 0);
317 if(__builtin_bcdadd_ofl (a
, b
, 0))
319 printf("ERROR: __builtin_bcdadd unexpectedly overflowed\n");
324 a
= maxbcd(BCD_POS0
);
327 if (__builtin_bcdsub_ofl (a
, b
, 0) == 0)
329 printf("ERROR: __builtin_bcdsub did not overflow as expected\n");
335 a
= num2bcd(value_a
, 0);
337 value_b
= -999999999;
338 b
= num2bcd(value_b
, 0);
340 if (__builtin_bcdsub_ofl (a
, b
, 0))
342 printf("ERROR: __builtin_bcdsub unexpectedly overflowed\n");
347 /* Test arguments for valid/invalid */
348 if (__builtin_bcdinvalid (a
))
350 printf("ERROR: __builtin_invalid input is unexpectedly invalid.\n");
355 a
[3] = 0xBB; /* an invalid BCD digit */
356 if (!__builtin_bcdinvalid (a
))
358 printf("ERROR: __builtin_invalid input is unexpectedly valid.\n");
364 a
= num2bcd(value_a
, 0);
367 b
= num2bcd(value_b
, 0);
370 if (__builtin_bcdcmpeq (a
, b
))
372 printf("ERROR: __builtin__bcdcmpeq result is unexpectedly 1.\n");
377 if (!__builtin_bcdcmpeq (a
, a
))
379 printf("ERROR: __builtin__bcdcmpeq result is unexpectedly 0.\n");
385 /* Test a greater then b, inputs already setup this way. */
386 if (!__builtin_bcdcmpgt (a
, b
))
388 printf("ERROR: __builtin__bcdcmpgt result is unexpectedly 0.\n");
393 if (__builtin_bcdcmpgt (b
, a
))
395 printf("ERROR: __builtin__bcdcmpgt result is unexpectedly 1.\n");
400 if (__builtin_bcdcmpgt (a
, a
))
402 printf("ERROR: __builtin__bcdcmpgt input equal, result is unexpectedly "
409 if (!__builtin_bcdcmpge (a
, b
))
411 printf("ERROR: __builtin__bcdcmpge result is unexpectedly 0.\n");
416 if (__builtin_bcdcmpge (b
, a
))
418 printf("ERROR: __builtin__bcdcmpge result is unexpectedly 1.\n");
423 if (!__builtin_bcdcmpge (b
, b
))
425 printf("ERROR: __builtin__bcdcmpge inputs equal result is unexpectedly "
431 /* Test a less then b. */
433 a
= num2bcd(value_a
, 0);
435 b
= num2bcd(value_b
, 0);
437 if (!__builtin_bcdcmplt (a
, b
))
439 printf("ERROR: __builtin__bcdcmplt result is unexpectedly 0.\n");
444 if (__builtin_bcdcmplt (b
, a
))
446 printf("ERROR: __builtin__bcdcmplt result is unexpectedly 1.\n");
451 if (__builtin_bcdcmplt (b
, b
))
453 printf("ERROR: __builtin__bcdcmplt inputs equal result is unexpectedly "
460 if (!__builtin_bcdcmple (a
, b
))
462 printf("ERROR: __builtin__bcdcmple result is unexpectedly 0.\n");
467 if (__builtin_bcdcmple (b
, a
))
469 printf("ERROR: __builtin__bcdcmple result is unexpectedly 1.\n");
474 if (!__builtin_bcdcmple (a
, a
))
476 printf("ERROR: __builtin__bcdcmple inputs equal result is unexpectedly "
482 /* Test multipy 10 */
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
]) {
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
]);
502 /* result should be positive */
503 #ifdef __BIG_ENDIAN__
504 if ((result
[15] & 0xF) != BCD_POS0
)
506 if ((result
[0] & 0xF) != BCD_POS0
)
509 printf("ERROR: __builtin_bcdmul10 sign, result is %d. Does not match "
510 "expected_result = %d\n",
511 result
[0] & 0xF, BCD_POS1
);
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
]) {
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
]);
536 /* result should be positive */
537 #ifdef __BIG_ENDIAN__
538 if ((result
[15] & 0xF) != BCD_POS0
)
540 if ((result
[0] & 0xF) != BCD_POS0
)
543 printf("ERROR: __builtin_bcddiv10 sign, result is %d. Does not match "
544 "expected_result = %d\n",
545 result
[0] & 0xF, BCD_POS1
);
551 exp_result_d128
= 1020304;
552 a
= num2bcd(value_a
, 0);
555 conv
.d128
= __builtin_bcd2dfp (a
);
556 result_d128
= conv
.d128
;
558 if (result_d128
!= exp_result_d128
)
560 printf("ERROR: __builtin_bcd2dfp, result does not match expected_result."