2017-12-05 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / testsuite / gcc.dg / graphite / id-15.c
blobd1cb2a2519bfc0d9264936106fcf428f0e8345ca
1 /* { dg-require-effective-target int32plus } */
3 typedef long unsigned int size_t;
4 extern void *memset (void *__s, int __c, size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
6 static void
7 encode (words, low, hi)
8 long *words;
9 unsigned long low;
10 long hi;
12 words[0] = ((low) & (((unsigned long) 1 << (sizeof(unsigned long) / 2)) - 1));
13 words[1] = ((unsigned long) (low) >> sizeof(unsigned long) / 2);
14 words[2] = ((hi) & (((unsigned long) 1 << (sizeof(unsigned long) / 2)) - 1));
15 words[3] = ((unsigned long) (hi) >> sizeof(unsigned long) / 2);
18 static void
19 decode (words, low, hi)
20 long *words;
21 unsigned long *low;
22 long *hi;
24 *low = words[0] + words[1] * ((unsigned long) 1 << sizeof(unsigned long) / 2);
25 *hi = words[2] + words[3] * ((unsigned long) 1 << sizeof(unsigned long) / 2);
28 int
29 neg_double (l1, h1, lv, hv)
30 unsigned long l1;
31 long h1;
32 unsigned long *lv;
33 long *hv;
35 if (l1 == 0)
37 *lv = 0;
38 *hv = - h1;
39 return (*hv & h1) < 0;
41 else
43 *lv = -l1;
44 *hv = ~h1;
45 return 0;
49 int
50 add_double (l1, h1, l2, h2, lv, hv)
51 unsigned long l1, l2;
52 long h1, h2;
53 unsigned long *lv;
54 long *hv;
56 unsigned long l;
57 long h;
59 l = l1 + l2;
60 h = h1 + h2 + (l < l1);
62 *lv = l;
63 *hv = h;
64 return ((~((h1) ^ (h2)) & ((h1) ^ (h))) < 0);
67 int
68 mul_double (l1, h1, l2, h2, lv, hv)
69 unsigned long l1, l2;
70 long h1, h2;
71 unsigned long *lv;
72 long *hv;
74 long arg1[4];
75 long arg2[4];
76 long prod[4 * 2];
77 unsigned long carry;
78 int i, j, k;
79 unsigned long toplow, neglow;
80 long tophigh, neghigh;
82 encode (arg1, l1, h1);
83 encode (arg2, l2, h2);
85 memset ((char *) prod, 0, sizeof prod);
87 for (i = 0; i < 4; i++)
89 carry = 0;
90 for (j = 0; j < 4; j++)
92 k = i + j;
94 carry += arg1[i] * arg2[j];
96 carry += prod[k];
97 prod[k] = ((carry) & (((unsigned long) 1 << (sizeof(unsigned long) / 2)) - 1));
98 carry = ((unsigned long) (carry) >> sizeof(unsigned long) / 2);
100 prod[i + 4] = carry;
103 decode (prod, lv, hv);
107 decode (prod + 4, &toplow, &tophigh);
108 if (h1 < 0)
110 neg_double (l2, h2, &neglow, &neghigh);
111 add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
113 if (h2 < 0)
115 neg_double (l1, h1, &neglow, &neghigh);
116 add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
118 return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;