OSDN Git Service

2009-08-14 Paolo Bonzini <bonzini@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.dg / graphite / id-15.c
1 typedef long unsigned int size_t;
2 extern void *memset (void *__s, int __c, size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));
3
4 static void
5 encode (words, low, hi)
6      long *words;
7      unsigned long low;
8      long hi;
9 {
10   words[0] = ((low) & (((unsigned long) 1 << ((8 * 8) / 2)) - 1));
11   words[1] = ((unsigned long) (low) >> (8 * 8) / 2);
12   words[2] = ((hi) & (((unsigned long) 1 << ((8 * 8) / 2)) - 1));
13   words[3] = ((unsigned long) (hi) >> (8 * 8) / 2);
14 }
15
16 static void
17 decode (words, low, hi)
18      long *words;
19      unsigned long *low;
20      long *hi;
21 {
22   *low = words[0] + words[1] * ((unsigned long) 1 << (8 * 8) / 2);
23   *hi = words[2] + words[3] * ((unsigned long) 1 << (8 * 8) / 2);
24 }
25
26 int
27 neg_double (l1, h1, lv, hv)
28      unsigned long l1;
29      long h1;
30      unsigned long *lv;
31      long *hv;
32 {
33   if (l1 == 0)
34     {
35       *lv = 0;
36       *hv = - h1;
37       return (*hv & h1) < 0;
38     }
39   else
40     {
41       *lv = -l1;
42       *hv = ~h1;
43       return 0;
44     }
45 }
46
47 int
48 add_double (l1, h1, l2, h2, lv, hv)
49      unsigned long l1, l2;
50      long h1, h2;
51      unsigned long *lv;
52      long *hv;
53 {
54   unsigned long l;
55   long h;
56
57   l = l1 + l2;
58   h = h1 + h2 + (l < l1);
59
60   *lv = l;
61   *hv = h;
62   return ((~((h1) ^ (h2)) & ((h1) ^ (h))) < 0);
63 }
64
65 int
66 mul_double (l1, h1, l2, h2, lv, hv)
67      unsigned long l1, l2;
68      long h1, h2;
69      unsigned long *lv;
70      long *hv;
71 {
72   long arg1[4];
73   long arg2[4];
74   long prod[4 * 2];
75   unsigned long carry;
76   int i, j, k;
77   unsigned long toplow, neglow;
78   long tophigh, neghigh;
79
80   encode (arg1, l1, h1);
81   encode (arg2, l2, h2);
82
83   memset ((char *) prod, 0, sizeof prod);
84
85   for (i = 0; i < 4; i++)
86     {
87       carry = 0;
88       for (j = 0; j < 4; j++)
89         {
90           k = i + j;
91
92           carry += arg1[i] * arg2[j];
93
94           carry += prod[k];
95           prod[k] = ((carry) & (((unsigned long) 1 << ((8 * 8) / 2)) - 1));
96           carry = ((unsigned long) (carry) >> (8 * 8) / 2);
97         }
98       prod[i + 4] = carry;
99     }
100
101   decode (prod, lv, hv);
102
103
104
105   decode (prod + 4, &toplow, &tophigh);
106   if (h1 < 0)
107     {
108       neg_double (l2, h2, &neglow, &neghigh);
109       add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
110     }
111   if (h2 < 0)
112     {
113       neg_double (l1, h1, &neglow, &neghigh);
114       add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
115     }
116   return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;
117 }
118