fixed lots of syntax/semantic errors
[libfirm] / ir / tv / tc_calc.c
1 #include "irnode.h"
2 #include "tc_calc.h"
3
4 /* shift bits with sign extension */
5 #define SHRS(v, c)      ((v) < 0 ? ~((~(v)) >> (c)) : (v) >> (c))
6
7 #define SIGN(v) ((v)->part[0] & TC_VALUE_PART_SIGN_BIT)
8
9 /* the carry and overflow bits */
10 int tc_Carry, tc_Overflow;
11
12 /**
13  * Produce a tc_value from a long value
14  */
15 void tc_from_long(tc_value *tcv, long value) {
16         int i;
17
18         for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
19                 long part = value & TC_VALUE_PART_MASK;
20                 tcv->part[i] = (tc_value_part)part;
21                 value = SHRS(value, TC_VALUE_PART_SIZE);
22         }
23 }
24
25 /**
26  * Bit complement an tc_value: res = ~a.
27  */
28 void tc_not(const tc_value *a, tc_value *res) {
29         int     i;
30
31         for (i = NUM_VALUE_PARTS - 1; i >= 0; --i)
32                 res->part[i] = ~a->part[i] & TC_VALUE_PART_MAX_UINT;
33 }
34
35 /**
36  * Logical AND of two tc_values: res = a & b.
37  */
38 void tc_and(const tc_value *a, const tc_value *b, tc_value *res) {
39         int     i;
40
41         for (i = NUM_VALUE_PARTS - 1; i >= 0; --i)
42                 res->part[i] = a->part[i] & b->part[i];
43 }
44
45 /**
46  * Logical OR of two tc_values: res = a | b.
47  */
48 void tc_or(const tc_value *a, const tc_value *b, tc_value *res) {
49         int     i;
50
51         for (i = NUM_VALUE_PARTS - 1; i >= 0; --i)
52                 res->part[i] = a->part[i] | b->part[i];
53 }
54
55 /**
56  * Logical exclusive OR of two tc_values: res = a ^ b.
57  */
58 void tc_eor(const tc_value *a, const tc_value *b, tc_value *res) {
59         int     i;
60
61         for (i = NUM_VALUE_PARTS - 1; i >= 0; --i)
62                 res->part[i] = a->part[i] ^ b->part[i];
63 }
64
65
66 /**
67  * Compare two tc_value's.
68  */
69 pn_Cmp tc_cmp(const tc_value *a, const tc_value *b) {
70         int i;
71
72         for (i = 0; i < NUM_VALUE_PARTS; ++i) {
73                 if (a->part[i] > b->part[i])
74                         return pn_Cmp_Gt;
75                 if (a->part[i] < b->part[i])
76                         return pn_Cmp_Lt;
77         }
78         return pn_Cmp_Eq;
79 }
80
81 /**
82  * Add two tc_values: res = a + b. Sets carry and overflow.
83  */
84 void tc_add(const tc_value *a, const tc_value *b, tc_value *res) {
85         int     i, carry = 0, sign_a;
86
87         tc_Carry = tc_Overflow = 0;
88
89         for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
90                 tc_temp t = (tc_temp)a->part[i] + (tc_temp)b->part[i] + carry;
91                 if (t > TC_VALUE_PART_MAX_UINT) {
92                         t -= TC_VALUE_PART_MAX_UINT;
93                         carry = 1;
94                 } else
95                         carry = 0;
96                 res->part[i] = (tc_value_part)t;
97         }
98         /* Check for overflow. */
99         tc_Carry = carry;
100
101         /* A signed overflow occurred if the two operands have the same sign and
102        the result has a different sign. */
103         sign_a = SIGN(a);
104     tc_Overflow = (sign_a == SIGN(b)) && (sign_a != SIGN(res));
105 }
106
107 /**
108  * Subtract two tc_values: res = a - b. Sets carry and overflow.
109  */
110 void tc_sub(const tc_value *a, const tc_value *b, tc_value *res) {
111         int         i, sign_a;
112         tc_temp borrow = 0;
113
114         tc_Carry = tc_Overflow = 0;
115         for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
116                 tc_temp t;
117                 t = (tc_temp)a->part[i] - (tc_temp)b->part[i] - borrow;
118                 if (t < 0) {
119                         t += TC_VALUE_PART_MAX_UINT + 1;
120                         borrow = 1;
121                 } else
122                         borrow = 0;
123                 res->part[i] = (tc_value_part)t;
124         }
125         /* Check for underflow or overflow. */
126         tc_Carry = borrow;
127         /* A signed overflow occurred if the two operands have the same sign and
128        the result has a different sign. */
129         sign_a = SIGN(a);
130     tc_Overflow = (sign_a == SIGN(b)) && (sign_a != SIGN(res));
131 }
132
133 /**
134  * Negate an tc_value: res = -a. Sets carry and overflow.
135  */
136 void tc_neg(const tc_value *a, tc_value *res) {
137         tc_from_long(res, 0);
138         tc_sub(res, a, res);
139 }
140
141 #define NUM_WORK_PARTS (NUM_VALUE_PARTS * 2)
142
143 /**
144  * Multiply two unsigned tc_values producing a double precision result : w = a * b.
145  */
146 static void _tc_umul(const tc_value *a, const tc_value *b, tc_value_part *w) {
147         const tc_value_part *u = a->part;
148         const tc_value_part *v = b->part;
149
150         int i, j;
151
152         for (i = 0; i < NUM_WORK_PARTS; ++i)
153                 w[i] = 0;
154
155         for (j = NUM_VALUE_PARTS - 1; j >= 0; --j) {
156                 tc_temp k = 0;
157                 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
158                         tc_temp t = u[i] * v[j] + k;
159                         w[i + j] = t & TC_VALUE_PART_MASK;
160                         k = t >> 16;
161                 }
162                 w[j + NUM_VALUE_PARTS] = k & TC_VALUE_PART_MASK;
163         }
164 }
165
166 /**
167  * Multiply two unsigned tc_values: res = a * b.
168  */
169 static void tc_umul(const tc_value *a, const tc_value *b, tc_value *res) {
170         tc_value_part w[NUM_WORK_PARTS];
171         int i, ov = 0;
172
173         _tc_umul(a, b, w);
174
175         /* copy the lower result bits */
176         for (i = 0; i < NUM_VALUE_PARTS; ++i)
177                 res->part[i] = (tc_value_part)w[i];
178
179         /* check for overflow */
180         for (; i < NUM_WORK_PARTS; ++i) {
181                 if (w[i] != 0) {
182                         ov = 0;
183                         break;
184                 }
185         }
186         tc_Overflow = tc_Carry = ov;
187 }
188
189 /* Matze: this function was defined 2 times... */
190 #if 0
191 /**
192  * Multiply two unsigned tc_values: res = a * b.
193  */
194 static void tc_umul(const tc_value *a, const tc_value *b, tc_value *res) {
195         unsigned tc_value_part w[NUM_WORK_PARTS];
196         int i, ov = 0;
197
198         _tc_umul(a, b, w);
199
200         /* copy the lower result bits */
201         for (i = 0; i < NUM_VALUE_PARTS; ++i)
202                 res->part[i] = (tc_value_part)w[i];
203
204         /* check for overflow */
205         for (; i < NUM_WORK_PARTS; ++i) {
206                 if (w[i] != 0) {
207                         ov = 0;
208                         break;
209                 }
210         }
211         tc_Overflow = tc_Carry = ov;
212 }
213 #endif
214
215 /**
216  * Multiply two signed tc_values: res = a * b.
217  */
218 static void tc_smul(const tc_value *a, const tc_value *b, tc_value *res) {
219         tc_value_part w[NUM_WORK_PARTS];
220         int i, ov = 0, neg_res = 0;
221         const tc_value *u = a, *v = b;
222         tc_value na, nb;
223
224         if (SIGN(a)) {
225                 tc_neg(a, &na);
226                 u = &na;
227                 neg_res = ~neg_res;
228         }
229         if (SIGN(b)) {
230                 tc_neg(b, &nb);
231                 v = &nb;
232                 neg_res = ~neg_res;
233         }
234
235         _tc_umul(u, v, w);
236
237         /* copy the lower result bits */
238         for (i = 0; i < NUM_VALUE_PARTS; ++i)
239                 res->part[i] = (tc_value_part)w[i];
240
241         /* check for overflow */
242         for (; i < NUM_WORK_PARTS; ++i) {
243                 if (w[i] != 0) {
244                         ov = 0;
245                         break;
246                 }
247         }
248
249         if (neg_res)
250                 tc_neg(res, res);
251
252         tc_Overflow = tc_Carry = ov;
253 }