diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg/graphite/id-15.c')
-rw-r--r-- | gcc/testsuite/gcc.dg/graphite/id-15.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/graphite/id-15.c b/gcc/testsuite/gcc.dg/graphite/id-15.c new file mode 100644 index 00000000000..109d5bbdb01 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-15.c @@ -0,0 +1,118 @@ +typedef long unsigned int size_t; +extern void *memset (void *__s, int __c, size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1))); + +static void +encode (words, low, hi) + long *words; + unsigned long low; + long hi; +{ + words[0] = ((low) & (((unsigned long) 1 << ((8 * 8) / 2)) - 1)); + words[1] = ((unsigned long) (low) >> (8 * 8) / 2); + words[2] = ((hi) & (((unsigned long) 1 << ((8 * 8) / 2)) - 1)); + words[3] = ((unsigned long) (hi) >> (8 * 8) / 2); +} + +static void +decode (words, low, hi) + long *words; + unsigned long *low; + long *hi; +{ + *low = words[0] + words[1] * ((unsigned long) 1 << (8 * 8) / 2); + *hi = words[2] + words[3] * ((unsigned long) 1 << (8 * 8) / 2); +} + +int +neg_double (l1, h1, lv, hv) + unsigned long l1; + long h1; + unsigned long *lv; + long *hv; +{ + if (l1 == 0) + { + *lv = 0; + *hv = - h1; + return (*hv & h1) < 0; + } + else + { + *lv = -l1; + *hv = ~h1; + return 0; + } +} + +int +add_double (l1, h1, l2, h2, lv, hv) + unsigned long l1, l2; + long h1, h2; + unsigned long *lv; + long *hv; +{ + unsigned long l; + long h; + + l = l1 + l2; + h = h1 + h2 + (l < l1); + + *lv = l; + *hv = h; + return ((~((h1) ^ (h2)) & ((h1) ^ (h))) < 0); +} + +int +mul_double (l1, h1, l2, h2, lv, hv) + unsigned long l1, l2; + long h1, h2; + unsigned long *lv; + long *hv; +{ + long arg1[4]; + long arg2[4]; + long prod[4 * 2]; + unsigned long carry; + int i, j, k; + unsigned long toplow, neglow; + long tophigh, neghigh; + + encode (arg1, l1, h1); + encode (arg2, l2, h2); + + memset ((char *) prod, 0, sizeof prod); + + for (i = 0; i < 4; i++) + { + carry = 0; + for (j = 0; j < 4; j++) + { + k = i + j; + + carry += arg1[i] * arg2[j]; + + carry += prod[k]; + prod[k] = ((carry) & (((unsigned long) 1 << ((8 * 8) / 2)) - 1)); + carry = ((unsigned long) (carry) >> (8 * 8) / 2); + } + prod[i + 4] = carry; + } + + decode (prod, lv, hv); + + + + decode (prod + 4, &toplow, &tophigh); + if (h1 < 0) + { + neg_double (l2, h2, &neglow, &neghigh); + add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh); + } + if (h2 < 0) + { + neg_double (l1, h1, &neglow, &neghigh); + add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh); + } + return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0; +} + |