Viewing file: bcd-4.c (10.82 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* { dg-do run } */ /* { dg-require-effective-target int128 } */ /* { dg-require-effective-target power10_hw } */ /* { dg-options "-mdejagnu-cpu=power10 -O2 -save-temps" } */ /* { dg-final { scan-assembler-times {\mbcdadd\M} 7 } } */ /* { dg-final { scan-assembler-times {\mbcdsub\M} 18 } } */ /* { dg-final { scan-assembler-times {\mbcds\M} 2 } } */ /* { dg-final { scan-assembler-times {\mdenbcdq\M} 1 } } */
#include <altivec.h>
#define DEBUG 0
#if DEBUG #include <stdio.h> #endif
#define BCD_POS0 12 // 0xC #define BCD_POS1 15 // 0xF #define BCD_NEG 13 // 0xD
void abort (void);
union conv_t { _Decimal128 d128; vector unsigned char ch; vector long long unsigned int vllui; } conv; _Decimal128 convert_vec_char (vector unsigned char a) { union conv_t conv; _Decimal128 result; conv.ch = a; result = conv.d128; return result; } vector unsigned char maxbcd(unsigned int sign) { vector unsigned char result; int i;
for (i = 15; i > 0; i--) result[i] = 0x99;
result[0] = sign << 4 | 0x9; }
vector unsigned char num2bcd(long int a, int encoding) { int i; unsigned int hi, low, sign; vector unsigned char result;
if (a > 0) { if (encoding == 0) sign = BCD_POS0; else sign = BCD_POS1;
} else { sign = BCD_NEG; a = -a; }
hi = a % 10; // 1st digit a = a / 10; result[0] = hi << 4| sign;
for (i = 1; i < 16; i++) { low = a % 10; a = a / 10; hi = a % 10; a = a / 10; result[i] = hi << 4 | low; }
return result; }
int main () { int i; long int value_a, value_b, value_result; vector unsigned char a, b, result, exp_result; _Decimal128 result_d128, exp_result_d128;
/* Make a and b positive BCD numbers */ value_a = 1020304; a = num2bcd(value_a, 0);
value_b = 101010; b = num2bcd(value_b, 0); value_result = value_a + value_b; exp_result = num2bcd(value_result, 0); result = __builtin_bcdadd (a, b, 0);
for (i = 0; i < 16; i++) if (exp_result[i] != result[i]) {
#if DEBUG printf("ERROR: __builtin_bcdadd result[%d] = %d does not match " "expected_result[%d] = %d\n", i, result[i], i, exp_result[i]); #else abort(); #endif }
/* result should be positive */ if ((result[0] & 0xF) != BCD_POS0) #if DEBUG printf("ERROR: __builtin_bcdadd sign of result is %d. Does not match " "expected_result = %d\n", result[0] & 0xF, BCD_POS0); #else abort(); #endif
/* Make a and b positive BCD numbers using alternate positive encoding. */ value_a = 1030507; a = num2bcd(value_a, 1);
value_b = 204060; b = num2bcd(value_b, 1);
value_result = value_a + value_b; exp_result = num2bcd(value_result, 1); result = __builtin_bcdadd (a, b, 1);
for (i = 0; i < 16; i++) if (exp_result[i] != result[i]) { #if DEBUG printf("ERROR: __builtin_bcdadd result[%d] = %d does not match " "expected_result[%d] = %d\n", i, result[i], i, exp_result[i]); #else abort(); #endif }
/* Result should be positive, alternate encoding. */ if ((result[0] & 0xF) != BCD_POS1) #if DEBUG printf("ERROR: __builtin_bcdadd sign of result is %d. Does not " "match expected_result = %d\n", result[0] & 0xF, BCD_POS1); #else abort(); #endif
/* Make a and b negative BCD numbers */ value_a = -1030507; a = num2bcd(value_a, 0);
value_b = -1010101; b = num2bcd(value_b, 0);
value_result = value_a + value_b; exp_result = num2bcd(value_result, 0); result = __builtin_bcdadd (a, b, 0);
for (i = 0; i < 16; i++) if (exp_result[i] != result[i]) { #if DEBUG printf("ERROR: __builtin_bcdadd, neg result[%d] = %d does not match " "expected_result[%d] = %d\n", i, result[i], i, exp_result[i]); #else abort(); #endif }
/* result should be negative */ if ((result[0] & 0xF) != BCD_NEG) #if DEBUG printf("ERROR: __builtin_bcdadd sign, neg of result is %d. Does not " "match expected_result = %d\n", result[0] & 0xF, BCD_NEG); #else abort(); #endif
/* Make a negative, b positive BCD numbers */ value_a = -1030507; a = num2bcd(value_a, 0);
value_b = 1010101; b = num2bcd(value_b, 0);
value_result = value_a - value_b; exp_result = num2bcd(value_result, 0); result = __builtin_bcdsub (a, b, 0);
for (i = 0; i < 16; i++) if (exp_result[i] != result[i]) { #if DEBUG printf("ERROR: __builtin_bcdsub, neg result[%d] = %d does not match " "expected_result[%d] = %d\n", i, result[i], i, exp_result[i]); #else abort(); #endif }
/* result should be positive, alt encoding */ if ((result[0] & 0xF) != BCD_NEG) #if DEBUG printf("ERROR: __builtin_bcdadd sign, of result is %d. Does not match " "expected_result = %d\n", result[0] & 0xF, BCD_NEG); #else abort(); #endif
/* Make a and b positive BCD numbers */ value_a = 1030507; a = num2bcd(value_a, 1);
value_b = 1010101; b = num2bcd(value_b, 1);
value_result = value_a - value_b; exp_result = num2bcd(value_result, 1); result = __builtin_bcdsub (a, b, 1);
for (i = 0; i < 16; i++) if (exp_result[i] != result[i]) { #if DEBUG printf("ERROR:carll __builtin_bcdsub, pos result[%d] = %d does not " "match expected_result[%d] = %d\n", i, result[i], i, exp_result[i]); #else abort(); #endif }
/* result should be positive */ if ((result[0] & 0xF) != BCD_POS1) #if DEBUG printf("ERROR: __builtin_bcdsub sign, result is %d. Does not match " "expected_result = %d\n", result[0] & 0xF, BCD_POS1); #else abort(); #endif
/* Test overflow add and subtract. */ a = maxbcd(BCD_POS0); b = maxbcd(BCD_POS0);
if(__builtin_bcdadd_ofl (a, b, 0) == 0) #if DEBUG printf("ERROR: __builtin_bcdadd did not overflow as expected\n"); #else abort(); #endif
value_a = 99999999; a = num2bcd(value_a, 0);
value_b = 999999999; b = num2bcd(value_b, 0);
if(__builtin_bcdadd_ofl (a, b, 0)) #if DEBUG printf("ERROR: __builtin_bcdadd unexpectedly overflowed\n"); #else abort(); #endif
a = maxbcd(BCD_NEG); b = maxbcd(BCD_NEG);
if (__builtin_bcdsub_ofl (a, b, 0) == 0) #if DEBUG printf("ERROR: __builtin_bcdsub did not overflow as expected\n"); #else abort(); #endif
value_a = -99999999; a = num2bcd(value_a, 0);
value_b = -999999999; b = num2bcd(value_b, 0);
if (__builtin_bcdsub_ofl (a, b, 0)) #if DEBUG printf("ERROR: __builtin_bcdsub unexpectedly overflowed\n"); #else abort(); #endif
/* Test arguments for valid/invalid */ if (__builtin_bcdinvalid (a)) #if DEBUG printf("ERROR: __builtin_invalid input is unexpectedly invalid.\n"); #else abort(); #endif
a[3] = 0xBB; /* an invalid BCD digit */ if (!__builtin_bcdinvalid (a)) #if DEBUG printf("ERROR: __builtin_invalid input is unexpectedly valid.\n"); #else abort(); #endif
value_a = 1020304; a = num2bcd(value_a, 0);
value_b = 101010; b = num2bcd(value_b, 0);
/* Test equality */ if (__builtin_bcdcmpeq (a, b)) #if DEBUG printf("ERROR: __builtin__bcdcmpeq result is unexpectedly 1.\n"); #else abort(); #endif
if (!__builtin_bcdcmpeq (a, a)) #if DEBUG printf("ERROR: __builtin__bcdcmpeq result is unexpectedly 0.\n"); #else abort(); #endif
/* Test a greater then b, inputs already setup this way. */ if (!__builtin_bcdcmpgt (a, b)) #if DEBUG printf("ERROR: __builtin__bcdcmpgt result is unexpectedly 0.\n"); #else abort(); #endif
if (__builtin_bcdcmpgt (b, a)) #if DEBUG printf("ERROR: __builtin__bcdcmpgt result is unexpectedly 1.\n"); #else abort(); #endif
if (__builtin_bcdcmpgt (a, a)) #if DEBUG printf("ERROR: __builtin__bcdcmpgt input equal, result is unexpectedly " "1.\n"); #else abort(); #endif
if (!__builtin_bcdcmpge (a, b)) #if DEBUG printf("ERROR: __builtin__bcdcmpge result is unexpectedly 0.\n"); #else abort(); #endif
if (__builtin_bcdcmpge (b, a)) #if DEBUG printf("ERROR: __builtin__bcdcmpge result is unexpectedly 1.\n"); #else abort(); #endif
if (!__builtin_bcdcmpge (b, b)) #if DEBUG printf("ERROR: __builtin__bcdcmpge inputs equal result is unexpectedly " "0.\n"); #else abort(); #endif
/* Test a less then b. */ value_a = 101010; a = num2bcd(value_a, 0); value_b = 1020304; b = num2bcd(value_b, 0);
if (!__builtin_bcdcmplt (a, b)) #if DEBUG printf("ERROR: __builtin__bcdcmplt result is unexpectedly 0.\n"); #else abort(); #endif
if (__builtin_bcdcmplt (b, a)) #if DEBUG printf("ERROR: __builtin__bcdcmplt result is unexpectedly 1.\n"); #else abort(); #endif
if (__builtin_bcdcmplt (b, b)) #if DEBUG printf("ERROR: __builtin__bcdcmplt inputs equal result is unexpectedly " "1.\n"); #else abort(); #endif
if (!__builtin_bcdcmple (a, b)) #if DEBUG printf("ERROR: __builtin__bcdcmple result is unexpectedly 0.\n"); #else abort(); #endif
if (__builtin_bcdcmple (b, a)) #if DEBUG printf("ERROR: __builtin__bcdcmple result is unexpectedly 1.\n"); #else abort(); #endif
if (!__builtin_bcdcmple (a, a)) #if DEBUG printf("ERROR: __builtin__bcdcmple inputs equal result is unexpectedly " "0.\n"); #else abort(); #endif
/* Test multipy 10 */ value_a = 1020304; a = num2bcd(value_a, 0);
value_result = value_a * 10; exp_result = num2bcd(value_result, 0); result = __builtin_bcdmul10 (a);
for (i = 0; i < 16; i++) if (exp_result[i] != result[i]) { #if DEBUG printf("ERROR:carll __builtin_bcdmul10, pos result[%d] = %d does not " "match expected_result[%d] = %d\n", i, result[i], i, exp_result[i]); #else abort(); #endif }
/* result should be positive */ if ((result[0] & 0xF) != BCD_POS0) #if 0 printf("ERROR: __builtin_bcdmul10 sign, result is %d. Does not match " "expected_result = %d\n", result[0] & 0xF, BCD_POS1); #else abort(); #endif
/* Test divide 10 */ value_a = 1020304; a = num2bcd(value_a, 0);
value_result = value_a / 10; exp_result = num2bcd(value_result, 0); result = __builtin_bcddiv10 (a);
for (i = 0; i < 16; i++) if (exp_result[i] != result[i]) { #if DEBUG printf("ERROR:carll __builtin_bcddiv10, pos result[%d] = %d does not " "match expected_result[%d] = %d\n", i, result[i], i, exp_result[i]); #else abort(); #endif }
/* result should be positive */ if ((result[0] & 0xF) != BCD_POS0) #if DEBUG printf("ERROR: __builtin_bcddiv10 sign, result is %d. Does not match " "expected_result = %d\n", result[0] & 0xF, BCD_POS1); #else abort(); #endif
value_a = 1020304; exp_result_d128 = 1020304; a = num2bcd(value_a, 0);
conv.ch = a; conv.d128 = __builtin_bcd2dfp (a); result_d128 = conv.d128; if (result_d128 != exp_result_d128) #if DEBUG printf("ERROR: __builtin_bcd2dfp, result does not match expected_result." "\n"); #else abort(); #endif return 0; }
|