Branch data Line data Source code
1 : : /*
2 : : * Integer arithmetic evaluation.
3 : : *
4 : : * (c) Thomas Pornin 2002
5 : : *
6 : : * Redistribution and use in source and binary forms, with or without
7 : : * modification, are permitted provided that the following conditions
8 : : * are met:
9 : : * 1. Redistributions of source code must retain the above copyright
10 : : * notice, this list of conditions and the following disclaimer.
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in the
13 : : * documentation and/or other materials provided with the distribution.
14 : : * 4. The name of the authors may not be used to endorse or promote
15 : : * products derived from this software without specific prior written
16 : : * permission.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 : : * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
22 : : * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 : : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24 : : * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 : : * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 : : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 : : * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 : : * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 : : *
30 : : */
31 : :
32 : : #include <limits.h>
33 : : #include "arith.h"
34 : :
35 : : #define ARITH_OCTAL(x) ((x) >= '0' && (x) <= '7')
36 : : #define ARITH_OVAL(x) ((x) - '0')
37 : : #define ARITH_DECIM(x) ((x) >= '0' && (x) <= '9')
38 : : #define ARITH_DVAL(x) ((x) - '0')
39 : : #define ARITH_HEXAD(x) (ARITH_DECIM(x) \
40 : : || (x) == 'a' || (x) == 'A' \
41 : : || (x) == 'b' || (x) == 'B' \
42 : : || (x) == 'c' || (x) == 'C' \
43 : : || (x) == 'd' || (x) == 'D' \
44 : : || (x) == 'e' || (x) == 'E' \
45 : : || (x) == 'f' || (x) == 'F')
46 : : #define ARITH_HVAL(x) (ARITH_DECIM(x) ? ARITH_DVAL(x) \
47 : : : (x) == 'a' || (x) == 'A' ? 10 \
48 : : : (x) == 'b' || (x) == 'B' ? 11 \
49 : : : (x) == 'c' || (x) == 'C' ? 12 \
50 : : : (x) == 'd' || (x) == 'D' ? 13 \
51 : : : (x) == 'e' || (x) == 'E' ? 14 : 15)
52 : :
53 : : #ifdef NATIVE_SIGNED
54 : : /* ====================================================================== */
55 : : /* Arithmetics with native types */
56 : : /* ====================================================================== */
57 : :
58 : : /*
59 : : * The following properties are imposed by the C standard:
60 : : *
61 : : * -- Arithmetics on the unsigned type should never overflow; every
62 : : * result is reduced modulo some power of 2. The macro NATIVE_UNSIGNED_BITS
63 : : * should have been defined to that specific exponent.
64 : : *
65 : : * -- The signed type should use either two's complement, one's complement
66 : : * or a sign bit and a magnitude. There should be an integer N such that
67 : : * the maximum signed value is (2^N)-1 and the minimum signed value is
68 : : * either -(2^N) or -((2^N)-1). -(2^N) is possible only for two's complement.
69 : : *
70 : : * -- The maximum signed value is at most equal to the maximum unsigned
71 : : * value.
72 : : *
73 : : * -- Trap representations can only be:
74 : : * ** In two's complement, 1 as sign bit and 0 for all value bits.
75 : : * This can happen only if the minimum signed value is -((2^N)-1).
76 : : * ** In one's complement, all bits set to 1.
77 : : * ** In mantissa + sign, sign bit to 1 and 0 for all value bits.
78 : : * Unsigned values have no trap representation achievable with numerical
79 : : * operators. Only signed values can have such representations, with
80 : : * operators &, |, ^, ~, << and >>. If trap representations are possible,
81 : : * such occurrences are reported as warnings.
82 : : *
83 : : * -- The operators +, -, * and << may overflow or underflow on signed
84 : : * quantities, which is potentially an error. A warning is emitted.
85 : : *
86 : : * -- The operator >> yields an implementation-defined result on
87 : : * signed negative quantities. Usually, the sign is extended, but this
88 : : * is not guaranteed. A warning is emitted.
89 : : *
90 : : * -- The operators / and % used with a second operand of 0 cannot work.
91 : : * An error is emitted when such a call is performed. Furthermore, in
92 : : * two's complemement representation, with NATIVE_SIGNED_MIN == -(2^N)
93 : : * for some N, the expression `NATIVE_SIGNED_MIN / (-1)' yields an
94 : : * unrepresentable result, which is also an error.
95 : : *
96 : : *
97 : : * For the value checks, we need to consider those different cases. So
98 : : * we calculate the following macros:
99 : : * -- TWOS_COMPLEMENT: is 1 if representation is two's complement, 0
100 : : * otherwise.
101 : : * -- ONES_COMPLEMENT: is 1 if representation is one's complement, 0
102 : : * otherwise.
103 : : * -- SIGNED_IS_BIGGER: 1 if the maximum signed value is equal to the
104 : : * maximum unsigned value, 0 otherwise. NATIVE_SIGNED_MAX cannot
105 : : * exceed the maximum unsigned value. If SIGNED_IS_BIGGER is 0, then
106 : : * the maximum unsigned value is strictly superior to twice the
107 : : * value of NATIVE_SIGNED_MAX (e.g. 65535 to 32767).
108 : : * -- TRAP_REPRESENTATION: 1 if a trap representation is possible, 0
109 : : * otherwise. The only way trap representations are guaranteed
110 : : * impossible is when TWOS_COMPLEMENT is set, and NATIVE_SIGNED_MIN
111 : : * is equal to -NATIVE_SIGNED_MAX - 1.
112 : : *
113 : : * Those macros are calculated by some preprocessor directives. This
114 : : * supposes that the implementation conforms to C99. Rules on preprocessing
115 : : * were quite looser in C90, and it could be that an old compiler, used
116 : : * for a cross-compiling task, does not get those right. Therefore, if
117 : : * ARCH_DEFINED is defined prior to the inclusion of this file, those
118 : : * four macros are supposed to be already defined. Otherwise they are
119 : : * (re)defined. The macro ARCH_TRAP_DEFINED has the same meaning, but
120 : : * is limited to the TRAP_REPRESENTATION macro (if ARCH_TRAP_DEFINED is
121 : : * defined, the macro TRAP_REPRESENTATION is supposed to be already
122 : : * defined; the three other macros are recalculated).
123 : : *
124 : : *
125 : : * To sum up:
126 : : * -- Whenever a division operator (/ or %) is invoked and would yield
127 : : * an unrepresentable result, ARITH_ERROR() is invoked.
128 : : * -- With ARITHMETIC_CHECKS undefined, ARITH_WARNING() is never invoked.
129 : : * -- With ARITHMETIC_CHECKS defined:
130 : : * ** If ARCH_DEFINED is defined, the including context must provide
131 : : * the macros TWOS_COMPLEMENT, ONES_COMPLEMENT, SIGNED_IS_BIGGER
132 : : * and TRAP_REPRESENTATION.
133 : : * ** Otherwise, if ARCH_TRAP_DEFINED is defined, the including context
134 : : * must provide the macro TRAP_REPRESENTATION.
135 : : * The code then detects all operator invokations that would yield an
136 : : * overflow, underflow, trap representation, or any implementation
137 : : * defined result or undefined behaviour. The macro ARITH_WARNING() is
138 : : * invoked for each detection.
139 : : * -- Trap representation detection code supposes that the operands are
140 : : * _not_ trap representation.
141 : : */
142 : :
143 : : #ifndef ARCH_DEFINED
144 : :
145 : : #undef TWOS_COMPLEMENT
146 : : #undef ONES_COMPLEMENT
147 : : #undef SIGNED_IS_BIGGER
148 : : #ifndef ARCH_TRAP_DEFINED
149 : : #undef TRAP_REPRESENTATION
150 : : #endif
151 : :
152 : : #if (-1) & 3 == 3
153 : : /*
154 : : * Two's complement.
155 : : */
156 : : #define TWOS_COMPLEMENT 1
157 : : #define ONES_COMPLEMENT 0
158 : : #ifndef ARCH_TRAP_DEFINED
159 : : #if NATIVE_SIGNED_MIN < -NATIVE_SIGNED_MAX
160 : : #define TRAP_REPRESENTATION 0
161 : : #else
162 : : #define TRAP_REPRESENTATION 1
163 : : #endif
164 : : #endif
165 : :
166 : : #elif (-1) & 3 == 2
167 : : /*
168 : : * One's complement.
169 : : */
170 : : #define TWOS_COMPLEMENT 0
171 : : #define ONES_COMPLEMENT 1
172 : : #ifndef ARCH_TRAP_DEFINED
173 : : #define TRAP_REPRESENTATION 1
174 : : #endif
175 : :
176 : : #else
177 : : /*
178 : : * Mantissa + sign.
179 : : */
180 : : #define TWOS_COMPLEMENT 0
181 : : #define ONES_COMPLEMENT 0
182 : : #ifndef ARCH_TRAP_DEFINED
183 : : #define TRAP_REPRESENTATION 1
184 : : #endif
185 : :
186 : : #endif
187 : :
188 : : /*
189 : : * Maximum native unsigned value. The first macro is for #if directives,
190 : : * the second macro is for use as constant expression in C code.
191 : : */
192 : : #define NATIVE_UNSIGNED_MAX ((((1U << (NATIVE_UNSIGNED_BITS - 1)) - 1U) \
193 : : << 1) + 1U)
194 : : #define NATIVE_UNSIGNED_MAX_A (((((arith_u)1 << (NATIVE_UNSIGNED_BITS - 1)) \
195 : : - (arith_u)1) << 1) + (arith_u)1)
196 : :
197 : : #if NATIVE_SIGNED_MAX == NATIVE_UNSIGNED_MAX
198 : : #define SIGNED_IS_BIGGER 1
199 : : #else
200 : : #define SIGNED_IS_BIGGER 0
201 : : #endif
202 : :
203 : : #endif
204 : :
205 : : #undef NEGATIVE_IS_BIGGER
206 : : #if NATIVE_SIGNED_MIN < -NATIVE_SIGNED_MAX
207 : : #define NEGATIVE_IS_BIGGER 1
208 : : #else
209 : : #define NEGATIVE_IS_BIGGER 0
210 : : #endif
211 : :
212 : : /* sanity check: we cannot have a trap representation if we have
213 : : two's complement with NATIVE_SIGNED_MIN < -NATIVE_SIGNED_MAX */
214 : : #if TRAP_REPRESENTATION && NEGATIVE_IS_BIGGER
215 : : #error Impossible to get trap representations.
216 : : #endif
217 : :
218 : : /* operations on the unsigned type */
219 : :
220 : 0 : ARITH_DECL_MONO_S_U(to_u) { return (arith_u)x; }
221 : : ARITH_DECL_MONO_I_U(fromint) { return (arith_u)x; }
222 : 0 : ARITH_DECL_MONO_L_U(fromulong) { return (arith_u)x; }
223 : :
224 : 0 : ARITH_DECL_MONO_U_I(toint)
225 : : {
226 : : #if NATIVE_UNSIGNED_MAX > INT_MAX
227 [ # # ]: 0 : if (x > (arith_u)INT_MAX) return INT_MAX;
228 : : #endif
229 : 0 : return (int)x;
230 : : }
231 : :
232 : 0 : ARITH_DECL_MONO_U_L(toulong)
233 : : {
234 : : #if NATIVE_UNSIGNED_MAX > LONG_MAX
235 [ # # ]: 0 : if (x > (arith_u)LONG_MAX) return LONG_MAX;
236 : : #endif
237 : 0 : return (long)x;
238 : : }
239 : :
240 : 0 : ARITH_DECL_MONO_U_U(neg) { return -x; }
241 : 0 : ARITH_DECL_MONO_U_U(not) { return ~x; }
242 : : ARITH_DECL_MONO_U_I(lnot) { return !x; }
243 : 0 : ARITH_DECL_MONO_U_I(lval) { return x != 0; }
244 : :
245 : 0 : ARITH_DECL_BI_UU_U(plus) { return x + y; }
246 : 0 : ARITH_DECL_BI_UU_U(minus) { return x - y; }
247 : 0 : ARITH_DECL_BI_UU_I(lt) { return x < y; }
248 : 0 : ARITH_DECL_BI_UU_I(leq) { return x <= y; }
249 : 0 : ARITH_DECL_BI_UU_I(gt) { return x > y; }
250 : 0 : ARITH_DECL_BI_UU_I(geq) { return x >= y; }
251 : 0 : ARITH_DECL_BI_UU_I(same) { return x == y; }
252 : 0 : ARITH_DECL_BI_UU_I(neq) { return x != y; }
253 : 0 : ARITH_DECL_BI_UU_U(and) { return x & y; }
254 : 0 : ARITH_DECL_BI_UU_U(xor) { return x ^ y; }
255 : 0 : ARITH_DECL_BI_UU_U(or) { return x | y; }
256 : 0 : ARITH_DECL_BI_UU_U(star) { return x * y; }
257 : :
258 : 0 : ARITH_DECL_BI_UI_U(lsh)
259 : : {
260 : : #ifdef ARITHMETIC_CHECKS
261 [ # # ]: 0 : if (y >= NATIVE_UNSIGNED_BITS)
262 : 0 : ARITH_WARNING(ARITH_EXCEP_LSH_W);
263 [ # # ]: 0 : else if (y < 0)
264 : 0 : ARITH_WARNING(ARITH_EXCEP_LSH_C);
265 : : #endif
266 : 0 : return x << y;
267 : : }
268 : :
269 : 0 : ARITH_DECL_BI_UI_U(rsh)
270 : : {
271 : : #ifdef ARITHMETIC_CHECKS
272 [ # # ]: 0 : if (y >= NATIVE_UNSIGNED_BITS)
273 : 0 : ARITH_WARNING(ARITH_EXCEP_RSH_W);
274 [ # # ]: 0 : else if (y < 0)
275 : 0 : ARITH_WARNING(ARITH_EXCEP_RSH_C);
276 : : #endif
277 : 0 : return x >> y;
278 : : }
279 : :
280 : 0 : ARITH_DECL_BI_UU_U(slash)
281 : : {
282 [ # # ]: 0 : if (y == 0) ARITH_ERROR(ARITH_EXCEP_SLASH_D);
283 : 0 : return x / y;
284 : : }
285 : :
286 : 0 : ARITH_DECL_BI_UU_U(pct)
287 : : {
288 [ # # ]: 0 : if (y == 0) ARITH_ERROR(ARITH_EXCEP_PCT_D);
289 : 0 : return x % y;
290 : : }
291 : :
292 : : /* operations on the signed type */
293 : :
294 : : ARITH_DECL_MONO_U_S(to_s)
295 : : {
296 : : #ifdef ARITHMETIC_CHECKS
297 : : #if !SIGNED_IS_BIGGER
298 : : if (x > (arith_u)NATIVE_SIGNED_MAX)
299 : : ARITH_WARNING(ARITH_EXCEP_CONV_O);
300 : : #endif
301 : : #endif
302 : : return (arith_s)x;
303 : : }
304 : :
305 : 0 : ARITH_DECL_MONO_I_S(fromint) { return (arith_s)x; }
306 : 0 : ARITH_DECL_MONO_L_S(fromlong) { return (arith_s)x; }
307 : :
308 : 0 : ARITH_DECL_MONO_S_I(toint)
309 : : {
310 : : #if NATIVE_SIGNED_MIN < INT_MIN
311 [ # # ]: 0 : if (x < (arith_s)INT_MIN) return INT_MIN;
312 : : #endif
313 : : #if NATIVE_SIGNED_MAX > INT_MAX
314 [ # # ]: 0 : if (x > (arith_s)INT_MAX) return INT_MAX;
315 : : #endif
316 : 0 : return (int)x;
317 : : }
318 : :
319 : : ARITH_DECL_MONO_S_L(tolong)
320 : : {
321 : : #if NATIVE_SIGNED_MIN < LONG_MIN
322 : : if (x < (arith_s)LONG_MIN) return LONG_MIN;
323 : : #endif
324 : : #if NATIVE_SIGNED_MAX > LONG_MAX
325 : : if (x > (arith_s)LONG_MAX) return LONG_MAX;
326 : : #endif
327 : : return (long)x;
328 : : }
329 : :
330 : 0 : ARITH_DECL_MONO_S_S(neg)
331 : : {
332 : : #ifdef ARITHMETIC_CHECKS
333 : : #if NEGATIVE_IS_BIGGER
334 [ # # ]: 0 : if (x == NATIVE_SIGNED_MIN)
335 : 0 : ARITH_WARNING(ARITH_EXCEP_NEG_O);
336 : : #endif
337 : : #endif
338 : 0 : return -x;
339 : : }
340 : :
341 : 0 : ARITH_DECL_MONO_S_S(not)
342 : : {
343 : : #ifdef ARITHMETIC_CHECKS
344 : : #if TRAP_REPRESENTATION
345 : : if (
346 : : #if TWOS_COMPLEMENT
347 : : (x == NATIVE_SIGNED_MAX)
348 : : #elif ONES_COMPLEMENT
349 : : (x == 0)
350 : : #else
351 : : (x == NATIVE_SIGNED_MAX)
352 : : #endif
353 : : ) ARITH_WARNING(ARITH_EXCEP_NOT_T);
354 : : #endif
355 : : #endif
356 : 0 : return ~x;
357 : : }
358 : :
359 : 0 : ARITH_DECL_MONO_S_I(lnot) { return !x; }
360 : 2 : ARITH_DECL_MONO_S_I(lval) { return x != 0; }
361 : :
362 : : /*
363 : : * Addition of signed values:
364 : : * -- overflows occur only when both operands are strictly positive
365 : : * -- underflows occur only when both operands are strictly negative
366 : : * -- overflow check (both operands > 0):
367 : : * ** if SIGNED_IS_BIGGER == 1, overflows are kept as such in the
368 : : * unsigned world (if the signed addition overflows, so does the
369 : : * unsigned, and vice versa)
370 : : * ** if SIGNED_IS_BIGGER == 0, no overflow can happen in the unsigned
371 : : * world
372 : : * -- underflow check (both operands < 0):
373 : : * ** if NEGATIVE_IS_BIGGER == 1 (must be two's complement)
374 : : * ++ we have a guaranteed underflow if one of the operand is equal
375 : : * to NATIVE_SIGNED_MIN; otherwise, -x and -y are valid integers,
376 : : * and we cast them into the unsigned world
377 : : * ++ if SIGNED_IS_BIGGER == 1, underflows become unsigned overflows
378 : : * with a non-zero result
379 : : * ++ if SIGNED_IS_BIGGER == 0, no overflow happens in the unsigned
380 : : * world; we use the fact that -NATIVE_SIGNED_MIN is then
381 : : * exaxctly 1 more than NATIVE_SIGNED_MAX
382 : : * ** if NEGATIVE_IS_BIGGER == 0, underflow check is identical to
383 : : * overflow check on (signed) -x and -y.
384 : : */
385 : 0 : ARITH_DECL_BI_SS_S(plus)
386 : : {
387 : : #ifdef ARITHMETIC_CHECKS
388 [ # # ][ # # ]: 0 : if (x > 0 && y > 0 && (
[ # # ]
389 : : #if SIGNED_IS_BIGGER
390 : : ((arith_u)((arith_u)x + (arith_u)y) < (arith_u)x)
391 : : #else
392 : 0 : (((arith_u)x + (arith_u)y) > (arith_u)NATIVE_SIGNED_MAX)
393 : : #endif
394 : 0 : )) ARITH_WARNING(ARITH_EXCEP_PLUS_O);
395 [ # # ][ # # ]: 0 : else if (x < 0 && y < 0 && (
[ # # ]
396 : : #if NEGATIVE_IS_BIGGER
397 [ # # ][ # # ]: 0 : (x == NATIVE_SIGNED_MIN || y == NATIVE_SIGNED_MIN) ||
398 : : #if SIGNED_IS_BIGGER
399 : : (((arith_u)(-x) + (arith_u)(-y) != 0)
400 : : && (arith_u)((arith_u)(-x) + (arith_u)(-y))
401 : : < (arith_u)(-x))
402 : : #else
403 : 0 : (((arith_u)(-x) + (arith_u)(-y))
404 : : > ((arith_u)1 + (arith_u)NATIVE_SIGNED_MAX))
405 : : #endif
406 : : #else
407 : : #if SIGNED_IS_BIGGER
408 : : ((arith_u)((arith_u)(-x) + (arith_u)(-y)) < (arith_u)(-x))
409 : : #else
410 : : (((arith_u)(-x) + (arith_u)(-y))
411 : : > (arith_u)NATIVE_SIGNED_MAX)
412 : : #endif
413 : : #endif
414 : 0 : )) ARITH_WARNING(ARITH_EXCEP_PLUS_U);
415 : : #endif
416 : 0 : return x + y;
417 : : }
418 : :
419 : : /*
420 : : * Subtraction of signed values:
421 : : * -- overflow: only if x > 0 and y < 0
422 : : * ** if NEGATIVE_IS_BIGGER == 1 (must be two's complement) and
423 : : * y == NATIVE_SIGNED_MIN then overflow
424 : : * ** otherwise, cast x and -y to unsigned, then add and check
425 : : * for overflows
426 : : * -- underflow: only if x < 0 and y > 0
427 : : * ** if NEGATIVE_IS_BIGGER == 1 (must be two's complement):
428 : : * ++ if x == NATIVE_SIGNED_MIN then underflow
429 : : * ++ cast -x and y to unsigned, then add. If SIGNED_IS_BIGGER == 0,
430 : : * just check. Otherwise, check for overflow with non-zero result.
431 : : * ** if NEGATIVE_IS_BIGGER == 0: cast -x and y to unsigned, then
432 : : * add. Overflow check as in addition.
433 : : */
434 : 0 : ARITH_DECL_BI_SS_S(minus)
435 : : {
436 : : #ifdef ARITHMETIC_CHECKS
437 [ # # ][ # # ]: 0 : if (x > 0 && y < 0 && (
[ # # ]
438 : : #if NEGATIVE_IS_BIGGER
439 [ # # ]: 0 : (y == NATIVE_SIGNED_MIN) ||
440 : : #endif
441 : : #if SIGNED_IS_BIGGER
442 : : ((arith_u)((arith_u)x + (arith_u)(-y)) < (arith_u)x)
443 : : #else
444 : 0 : (((arith_u)x + (arith_u)(-y)) > (arith_u)NATIVE_SIGNED_MAX)
445 : : #endif
446 : 0 : )) ARITH_WARNING(ARITH_EXCEP_MINUS_O);
447 [ # # ][ # # ]: 0 : else if (x < 0 && y > 0 && (
[ # # ]
448 : : #if NEGATIVE_IS_BIGGER
449 [ # # ]: 0 : (x == NATIVE_SIGNED_MIN) ||
450 : : #if SIGNED_IS_BIGGER
451 : : ((((arith_u)(-x) + (arith_u)y) != 0) &&
452 : : ((arith_u)((arith_u)(-x) + (arith_u)y) < (arith_u)(-x)))
453 : : #else
454 : 0 : (((arith_u)(-x) + (arith_u)y) >
455 : : ((arith_u)1 + (arith_u)NATIVE_SIGNED_MAX))
456 : : #endif
457 : : #else
458 : : #if SIGNED_IS_BIGGER
459 : : ((arith_u)((arith_u)(-x) + (arith_u)y) < (arith_u)(-x))
460 : : #else
461 : : (((arith_u)(-x) + (arith_u)y) > (arith_u)NATIVE_SIGNED_MAX)
462 : : #endif
463 : : #endif
464 : 0 : )) ARITH_WARNING(ARITH_EXCEP_MINUS_U);
465 : : #endif
466 : 0 : return x - y;
467 : : }
468 : :
469 : 0 : ARITH_DECL_BI_SS_I(lt) { return x < y; }
470 : 0 : ARITH_DECL_BI_SS_I(leq) { return x <= y; }
471 : 0 : ARITH_DECL_BI_SS_I(gt) { return x > y; }
472 : 0 : ARITH_DECL_BI_SS_I(geq) { return x >= y; }
473 : 0 : ARITH_DECL_BI_SS_I(same) { return x == y; }
474 : 0 : ARITH_DECL_BI_SS_I(neq) { return x != y; }
475 : :
476 : : /*
477 : : * Provided neither x nor y is a trap representation:
478 : : * -- one's complement: impossible to get a trap representation
479 : : * -- two's complement and sign + mantissa: trap representation if and
480 : : * only if x and y are strictly negative and (-x) & (-y) == 0
481 : : * (in two's complement, -x is safe because overflow would occur only
482 : : * if x was already a trap representation).
483 : : */
484 : 0 : ARITH_DECL_BI_SS_S(and)
485 : : {
486 : : #ifdef ARITHMETIC_CHECKS
487 : : #if TRAP_REPRESENTATION && !ONES_COMPLEMENT
488 : : if (x < 0 && y < 0 && ((-x) & (-y)) == 0)
489 : : ARITH_WARNING(ARITH_EXCEP_AND_T);
490 : : #endif
491 : : #endif
492 : 0 : return x & y;
493 : : }
494 : :
495 : : /*
496 : : * Provided neither x nor y is a trap representation:
497 : : * -- two's complement: trap if and only if x != NATIVE_SIGNED_MAX && ~x == y
498 : : * -- one's complement: trap if and only if x != 0 && ~x == y
499 : : * -- mantissa + sign: trap if and only if x != 0 && -x == y
500 : : */
501 : 0 : ARITH_DECL_BI_SS_S(xor)
502 : : {
503 : : #ifdef ARITHMETIC_CHECKS
504 : : #if TRAP_REPRESENTATION
505 : : if (
506 : : #if TWOS_COMPLEMENT
507 : : (x != NATIVE_SIGNED_MAX && ~x == y)
508 : : #elif ONES_COMPLEMENT
509 : : (x != 0 && ~x == y)
510 : : #else
511 : : (x != 0 && -x == y)
512 : : #endif
513 : : ) ARITH_WARNING(ARITH_EXCEP_XOR_T);
514 : : #endif
515 : : #endif
516 : 0 : return x ^ y;
517 : : }
518 : :
519 : : /*
520 : : * Provided neither x nor y is a trap representation:
521 : : * -- two's complement: impossible to trap
522 : : * -- one's complement: trap if and only if x != 0 && y != 0 && (~x & ~y) == 0
523 : : * -- mantissa + sign: impossible to trap
524 : : */
525 : 0 : ARITH_DECL_BI_SS_S(or)
526 : : {
527 : : #ifdef ARITHMETIC_CHECKS
528 : : #if TRAP_REPRESENTATION
529 : : #if ONES_COMPLEMENT
530 : : if (x != 0 && y != 0 && (~x & ~y) == 0)
531 : : ARITH_WARNING(ARITH_EXCEP_OR_T);
532 : : #endif
533 : : #endif
534 : : #endif
535 : 0 : return x | y;
536 : : }
537 : :
538 : : /*
539 : : * Left-shifting by a negative or greater than type width count is
540 : : * forbidden. Left-shifting a negative value is forbidden (underflow).
541 : : * Left-shifting a positive value can trigger an overflow. We check it
542 : : * by casting into the unsigned world and simulating a truncation.
543 : : *
544 : : * If SIGNED_IS_BIGGER is set, then the signed type width is 1 more
545 : : * than the unsigned type width (the sign bit is included in the width);
546 : : * otherwise, if W is the signed type width, 1U << (W-1) is equal to
547 : : * NATIVE_SIGNED_MAX + 1.
548 : : */
549 : 0 : ARITH_DECL_BI_SI_S(lsh)
550 : : {
551 : : #ifdef ARITHMETIC_CHECKS
552 [ # # ]: 0 : if (y < 0) ARITH_WARNING(ARITH_EXCEP_LSH_C);
553 [ # # ]: 0 : else if (
554 : : #if SIGNED_IS_BIGGER
555 : : y > NATIVE_UNSIGNED_BITS
556 : : #else
557 : : y >= NATIVE_UNSIGNED_BITS
558 [ # # ][ # # ]: 0 : || (y > 0 && (((arith_u)1 << (y - 1))
559 : 0 : > (arith_u)NATIVE_SIGNED_MAX))
560 : : #endif
561 : 0 : ) ARITH_WARNING(ARITH_EXCEP_LSH_W);
562 [ # # ]: 0 : else if (x < 0) ARITH_WARNING(ARITH_EXCEP_LSH_U);
563 [ # # ][ # # ]: 0 : else if (x > 0 && ((((arith_u)x << y) & NATIVE_SIGNED_MAX) >> y)
564 : 0 : != (arith_u)x) ARITH_WARNING(ARITH_EXCEP_LSH_O);
565 : : #endif
566 : 0 : return x << y;
567 : : }
568 : :
569 : : /*
570 : : * Right-shifting is handled as left-shifting, except that the problem
571 : : * is somehow simpler: there is no possible overflow or underflow. Only
572 : : * right-shifting a negative value yields an implementation defined
573 : : * result (_not_ an undefined behaviour).
574 : : */
575 : 0 : ARITH_DECL_BI_SI_S(rsh)
576 : : {
577 : : #ifdef ARITHMETIC_CHECKS
578 [ # # ]: 0 : if (y < 0) ARITH_WARNING(ARITH_EXCEP_RSH_C);
579 [ # # ]: 0 : else if (
580 : : #if SIGNED_IS_BIGGER
581 : : y > NATIVE_UNSIGNED_BITS
582 : : #else
583 : : y >= NATIVE_UNSIGNED_BITS
584 [ # # ][ # # ]: 0 : || (y > 0 && (((arith_u)1 << (y - 1))
585 : 0 : > (arith_u)NATIVE_SIGNED_MAX))
586 : : #endif
587 : 0 : ) ARITH_WARNING(ARITH_EXCEP_RSH_W);
588 [ # # ]: 0 : else if (x < 0) ARITH_WARNING(ARITH_EXCEP_RSH_N);
589 : : #endif
590 : 0 : return x >> y;
591 : : }
592 : :
593 : : /*
594 : : * Overflow can happen only if both operands have the same sign.
595 : : * Underflow can happen only if both operands have opposite signs.
596 : : *
597 : : * Overflow checking: this is done quite inefficiently by performing
598 : : * a division on the result and check if it matches the initial operand.
599 : : */
600 : 0 : ARITH_DECL_BI_SS_S(star)
601 : : {
602 : : #ifdef ARITHMETIC_CHECKS
603 [ # # ][ # # ]: 0 : if (x == 0 || y == 0) return 0;
604 [ # # ][ # # ]: 0 : if (x > 0 && y > 0) {
605 [ # # ]: 0 : if ((((arith_u)x * (arith_u)y) & (arith_u)NATIVE_SIGNED_MAX)
606 : 0 : / (arith_u)y != (arith_u)x)
607 : 0 : ARITH_WARNING(ARITH_EXCEP_STAR_O);
608 [ # # ][ # # ]: 0 : } else if (x < 0 && y < 0) {
609 [ # # ]: 0 : if (
610 : : #if NEGATIVE_IS_BIGGER
611 [ # # ][ # # ]: 0 : (x == NATIVE_SIGNED_MIN || y == NATIVE_SIGNED_MIN) ||
612 : : #endif
613 : 0 : (((arith_u)(-x) * (arith_u)(-y))
614 : 0 : & (arith_u)NATIVE_SIGNED_MAX) / (arith_u)(-y)
615 : 0 : != (arith_u)(-x))
616 : 0 : ARITH_WARNING(ARITH_EXCEP_STAR_O);
617 [ # # ][ # # ]: 0 : } else if (x > 0 && y < 0) {
618 [ # # ][ # # ]: 0 : if ((arith_u)x > (arith_u)1 && (
619 : : #if NEGATIVE_IS_BIGGER
620 [ # # ]: 0 : y == NATIVE_SIGNED_MIN ||
621 : : #endif
622 : 0 : (((arith_u)x * (arith_u)(-y)) & (arith_u)NATIVE_SIGNED_MAX)
623 : 0 : / (arith_u)(-y) != (arith_u)x))
624 : 0 : ARITH_WARNING(ARITH_EXCEP_STAR_U);
625 : : } else {
626 [ # # ][ # # ]: 0 : if ((arith_u)y > (arith_u)1 && (
627 : : #if NEGATIVE_IS_BIGGER
628 [ # # ]: 0 : x == NATIVE_SIGNED_MIN ||
629 : : #endif
630 : 0 : (((arith_u)y * (arith_u)(-x)) & (arith_u)NATIVE_SIGNED_MAX)
631 : 0 : / (arith_u)(-x) != (arith_u)y))
632 : 0 : ARITH_WARNING(ARITH_EXCEP_STAR_U);
633 : : }
634 : : #endif
635 : 0 : return x * y;
636 : : }
637 : :
638 : : /*
639 : : * Division by 0 is an error. The only other possible problem is an
640 : : * overflow of the result. Such an overflow can only happen in two's
641 : : * complement representation, when NEGATIVE_IS_BIGGER is set, and
642 : : * one attempts to divide NATIVE_SIGNED_MIN by -1: the result is then
643 : : * -NATIVE_SIGNED_MIN, which is not representable by the type. This is
644 : : * considered as an error, not a warning, because it actually triggers
645 : : * an exception on modern Pentium-based PC.
646 : : */
647 : 0 : ARITH_DECL_BI_SS_S(slash)
648 : : {
649 [ # # ]: 0 : if (y == 0) ARITH_ERROR(ARITH_EXCEP_SLASH_D);
650 : : #if NEGATIVE_IS_BIGGER
651 [ # # ][ # # ]: 0 : else if (x == NATIVE_SIGNED_MIN && y == (arith_s)(-1))
652 : 0 : ARITH_ERROR(ARITH_EXCEP_SLASH_O);
653 : : #endif
654 : 0 : return x / y;
655 : : }
656 : :
657 : : /*
658 : : * Only division by 0 needs to be checked.
659 : : */
660 : 0 : ARITH_DECL_BI_SS_S(pct)
661 : : {
662 [ # # ]: 0 : if (y == 0) ARITH_ERROR(ARITH_EXCEP_PCT_D);
663 : 0 : return x % y;
664 : : }
665 : :
666 : 2 : ARITH_DECL_MONO_ST_US(octconst)
667 : : {
668 : 2 : arith_u z = 0;
669 : :
670 [ - + ][ # # ]: 2 : for (; ARITH_OCTAL(*c); c ++) {
671 : 0 : arith_u w = ARITH_OVAL(*c);
672 [ # # ]: 0 : if (z > (NATIVE_UNSIGNED_MAX_A / 8))
673 : 0 : ARITH_ERROR(ARITH_EXCEP_CONST_O);
674 : 0 : z *= 8;
675 : : #if 0
676 : : /* obsolete */
677 : : /* NATIVE_UNSIGNED_MAX_A is 2^N - 1, 0 <= w <= 7 and 8 divides z */
678 : : if (z > (NATIVE_UNSIGNED_MAX_A - w))
679 : : ARITH_ERROR(ARITH_EXCEP_CONST_O);
680 : : #endif
681 : 0 : z += w;
682 : : }
683 : 2 : *ru = z;
684 : : #if SIGNED_IS_BIGGER
685 : : *rs = z;
686 : : *sp = 1;
687 : : #else
688 [ - + ]: 2 : if (z > NATIVE_SIGNED_MAX) {
689 : 0 : *sp = 0;
690 : : } else {
691 : 2 : *rs = z;
692 : 2 : *sp = 1;
693 : : }
694 : : #endif
695 : 2 : return c;
696 : : }
697 : :
698 : 0 : ARITH_DECL_MONO_ST_US(decconst)
699 : : {
700 : 0 : arith_u z = 0;
701 : :
702 [ # # ][ # # ]: 0 : for (; ARITH_DECIM(*c); c ++) {
703 : 0 : arith_u w = ARITH_DVAL(*c);
704 [ # # ]: 0 : if (z > (NATIVE_UNSIGNED_MAX_A / 10))
705 : 0 : ARITH_ERROR(ARITH_EXCEP_CONST_O);
706 : 0 : z *= 10;
707 [ # # ]: 0 : if (z > (NATIVE_UNSIGNED_MAX_A - w))
708 : 0 : ARITH_ERROR(ARITH_EXCEP_CONST_O);
709 : 0 : z += w;
710 : : }
711 : 0 : *ru = z;
712 : : #if SIGNED_IS_BIGGER
713 : : *rs = z;
714 : : *sp = 1;
715 : : #else
716 [ # # ]: 0 : if (z > NATIVE_SIGNED_MAX) {
717 : 0 : *sp = 0;
718 : : } else {
719 : 0 : *rs = z;
720 : 0 : *sp = 1;
721 : : }
722 : : #endif
723 : 0 : return c;
724 : : }
725 : :
726 : 0 : ARITH_DECL_MONO_ST_US(hexconst)
727 : : {
728 : 0 : arith_u z = 0;
729 : :
730 [ # # ][ # # ]: 0 : for (; ARITH_HEXAD(*c); c ++) {
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
731 [ # # ][ # # ]: 0 : arith_u w = ARITH_HVAL(*c);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
732 [ # # ]: 0 : if (z > (NATIVE_UNSIGNED_MAX_A / 16))
733 : 0 : ARITH_ERROR(ARITH_EXCEP_CONST_O);
734 : 0 : z *= 16;
735 : : #if 0
736 : : /* obsolete */
737 : : /* NATIVE_UNSIGNED_MAX_A is 2^N - 1, 0 <= w <= 15 and 16 divides z */
738 : : if (z > (NATIVE_UNSIGNED_MAX_A - w))
739 : : ARITH_ERROR(ARITH_EXCEP_CONST_O);
740 : : #endif
741 : 0 : z += w;
742 : : }
743 : 0 : *ru = z;
744 : : #if SIGNED_IS_BIGGER
745 : : *rs = z;
746 : : *sp = 1;
747 : : #else
748 [ # # ]: 0 : if (z > NATIVE_SIGNED_MAX) {
749 : 0 : *sp = 0;
750 : : } else {
751 : 0 : *rs = z;
752 : 0 : *sp = 1;
753 : : }
754 : : #endif
755 : 0 : return c;
756 : : }
757 : :
758 : : #else
759 : : /* ====================================================================== */
760 : : /* Arithmetics with a simple simulated type */
761 : : /* ====================================================================== */
762 : :
763 : : /*
764 : : * We simulate a type with the following characteristics:
765 : : * -- the signed type width is equal to the unsigned type width (which
766 : : * means that there is one less value bit in the signed type);
767 : : * -- the signed type uses two's complement representation;
768 : : * -- there is no trap representation;
769 : : * -- overflows and underflows are truncated (but a warning is emitted
770 : : * if ARITHMETIC_CHECKS is defined);
771 : : * -- overflow on integer division is still an error;
772 : : * -- right-shifting of a negative value extends the sign;
773 : : * -- the shift count value is first cast to unsigned, then reduced modulo
774 : : * the type size.
775 : : *
776 : : * These characteristics follow what is usually found on modern
777 : : * architectures.
778 : : *
779 : : * The maximum emulated type size is twice the size of the unsigned native
780 : : * type which is used to emulate the type.
781 : : */
782 : :
783 : : #undef SIMUL_ONE_TMP
784 : : #undef SIMUL_MSW_TMP1
785 : : #undef SIMUL_MSW_MASK
786 : : #undef SIMUL_LSW_TMP1
787 : : #undef SIMUL_LSW_MASK
788 : :
789 : : #define SIMUL_ONE_TMP ((SIMUL_ARITH_SUBTYPE)1)
790 : : #define SIMUL_MSW_TMP1 (SIMUL_ONE_TMP << (SIMUL_MSW_WIDTH - 1))
791 : : #define SIMUL_MSW_MASK (SIMUL_MSW_TMP1 | (SIMUL_MSW_TMP1 - SIMUL_ONE_TMP))
792 : : #define SIMUL_LSW_TMP1 (SIMUL_ONE_TMP << (SIMUL_LSW_WIDTH - 1))
793 : : #define SIMUL_LSW_MASK (SIMUL_LSW_TMP1 | (SIMUL_LSW_TMP1 - SIMUL_ONE_TMP))
794 : :
795 : : #undef TMSW
796 : : #undef TLSW
797 : :
798 : : #define TMSW(x) ((x) & SIMUL_MSW_MASK)
799 : : #define TLSW(x) ((x) & SIMUL_LSW_MASK)
800 : :
801 : : #undef SIMUL_ZERO
802 : : #undef SIMUL_ONE
803 : :
804 : : #define SIMUL_ZERO arith_strc(ARITH_TYPENAME, _zero)
805 : : #define SIMUL_ONE arith_strc(ARITH_TYPENAME, _one)
806 : :
807 : : static arith_u SIMUL_ZERO = { 0, 0 };
808 : : static arith_u SIMUL_ONE = { 0, 1 };
809 : :
810 : : /*
811 : : * We use the fact that both the signed and unsigned type are the same
812 : : * structure. The difference between the signed and the unsigned type
813 : : * is a type information, and, as such, is considered compile-time and
814 : : * not maintained in the value structure itself. This is a job for
815 : : * the programmer / compiler.
816 : : */
817 : : ARITH_DECL_MONO_S_U(to_u) { return x; }
818 : :
819 : : ARITH_DECL_MONO_I_U(fromint)
820 : : {
821 : : arith_u z;
822 : :
823 : : if (x < 0) return arith_op_u(neg)(arith_op_u(fromint)(-x));
824 : : /*
825 : : * This code works because types smaller than int are promoted
826 : : * by the C compiler before evaluating the >> operator.
827 : : */
828 : : z.msw = TMSW(((SIMUL_ARITH_SUBTYPE)x >> (SIMUL_LSW_WIDTH - 1)) >> 1);
829 : : z.lsw = TLSW((SIMUL_ARITH_SUBTYPE)x);
830 : : return z;
831 : : }
832 : :
833 : : ARITH_DECL_MONO_L_U(fromulong)
834 : : {
835 : : arith_u z;
836 : :
837 : : #if (ULONG_MAX >> (SIMUL_LSW_WIDTH - 1)) >> 1 == 0
838 : : z.msw = 0;
839 : : z.lsw = x;
840 : : #else
841 : : z.msw = TMSW(x >> SIMUL_LSW_WIDTH);
842 : : z.lsw = TLSW((SIMUL_ARITH_SUBTYPE)x);
843 : : #endif
844 : : return z;
845 : : }
846 : :
847 : : ARITH_DECL_MONO_U_I(toint)
848 : : {
849 : : #if ((INT_MAX >> (SIMUL_LSW_WIDTH - 1)) >> 1) == 0
850 : : if (x.msw != 0 || x.lsw > (SIMUL_ARITH_SUBTYPE)INT_MAX)
851 : : return INT_MAX;
852 : : return (int)x.lsw;
853 : : #else
854 : : #if (INT_MAX >> (SIMUL_SUBTYPE_BITS - 1)) == 0
855 : : if (x.msw > (SIMUL_ARITH_SUBTYPE)(INT_MAX >> SIMUL_LSW_WIDTH))
856 : : return INT_MAX;
857 : : #endif
858 : : return ((int)x.msw << SIMUL_LSW_WIDTH) | (int)x.lsw;
859 : : #endif
860 : : }
861 : :
862 : : ARITH_DECL_MONO_U_L(toulong)
863 : : {
864 : : #if ((ULONG_MAX >> (SIMUL_LSW_WIDTH - 1)) >> 1) == 0
865 : : if (x.msw != 0 || x.lsw > (SIMUL_ARITH_SUBTYPE)ULONG_MAX)
866 : : return ULONG_MAX;
867 : : return (unsigned long)x.lsw;
868 : : #else
869 : : #if (ULONG_MAX >> (SIMUL_SUBTYPE_BITS - 1)) == 0
870 : : if (x.msw > (SIMUL_ARITH_SUBTYPE)(ULONG_MAX >> SIMUL_LSW_WIDTH))
871 : : return ULONG_MAX;
872 : : #endif
873 : : return ((unsigned long)x.msw << SIMUL_LSW_WIDTH) | (unsigned long)x.lsw;
874 : : #endif
875 : : }
876 : :
877 : : ARITH_DECL_MONO_U_U(neg)
878 : : {
879 : : x = arith_op_u(not)(x);
880 : : return arith_op_u(plus)(x, SIMUL_ONE);
881 : : }
882 : :
883 : : ARITH_DECL_MONO_U_U(not)
884 : : {
885 : : x.msw = TMSW(~x.msw);
886 : : x.lsw = TLSW(~x.lsw);
887 : : return x;
888 : : }
889 : :
890 : : ARITH_DECL_MONO_U_I(lnot)
891 : : {
892 : : return x.msw == 0 && x.lsw == 0;
893 : : }
894 : :
895 : : ARITH_DECL_MONO_U_I(lval)
896 : : {
897 : : return x.msw != 0 || x.lsw != 0;
898 : : }
899 : :
900 : : ARITH_DECL_BI_UU_U(plus)
901 : : {
902 : : x.lsw = TLSW(x.lsw + y.lsw);
903 : : x.msw = TMSW(x.msw + y.msw);
904 : : if (x.lsw < y.lsw) x.msw = TMSW(x.msw + 1);
905 : : return x;
906 : : }
907 : :
908 : : ARITH_DECL_BI_UU_U(minus)
909 : : {
910 : : return arith_op_u(plus)(x, arith_op_u(neg)(y));
911 : : }
912 : :
913 : : ARITH_DECL_BI_UI_U(lsh)
914 : : {
915 : : if (y == 0) return x;
916 : : #ifdef ARITHMETIC_CHECKS
917 : : if (y < 0) ARITH_WARNING(ARITH_EXCEP_LSH_C);
918 : : else if (y >= SIMUL_NUMBITS) ARITH_WARNING(ARITH_EXCEP_LSH_W);
919 : : #endif
920 : : y = (unsigned)y % SIMUL_NUMBITS;
921 : : if (y >= SIMUL_LSW_WIDTH) {
922 : : /*
923 : : * We use here the fact that the LSW size is always
924 : : * equal to or greater than the MSW size.
925 : : */
926 : : x.msw = TMSW(x.lsw << (y - SIMUL_LSW_WIDTH));
927 : : x.lsw = 0;
928 : : return x;
929 : : }
930 : : x.msw = TMSW((x.msw << y) | (x.lsw >> (SIMUL_LSW_WIDTH - y)));
931 : : x.lsw = TLSW(x.lsw << y);
932 : : return x;
933 : : }
934 : :
935 : : ARITH_DECL_BI_UI_U(rsh)
936 : : {
937 : : #ifdef ARITHMETIC_CHECKS
938 : : if (y < 0) ARITH_WARNING(ARITH_EXCEP_RSH_C);
939 : : else if (y >= SIMUL_NUMBITS) ARITH_WARNING(ARITH_EXCEP_RSH_W);
940 : : #endif
941 : : y = (unsigned)y % SIMUL_NUMBITS;
942 : : if (y >= SIMUL_LSW_WIDTH) {
943 : : x.lsw = x.msw >> (y - SIMUL_LSW_WIDTH);
944 : : x.msw = 0;
945 : : return x;
946 : : }
947 : : x.lsw = TLSW((x.lsw >> y) | (x.msw << (SIMUL_LSW_WIDTH - y)));
948 : : x.msw >>= y;
949 : : return x;
950 : : }
951 : :
952 : : ARITH_DECL_BI_UU_I(lt)
953 : : {
954 : : return x.msw < y.msw || (x.msw == y.msw && x.lsw < y.lsw);
955 : : }
956 : :
957 : : ARITH_DECL_BI_UU_I(leq)
958 : : {
959 : : return x.msw < y.msw || (x.msw == y.msw && x.lsw <= y.lsw);
960 : : }
961 : :
962 : : ARITH_DECL_BI_UU_I(gt)
963 : : {
964 : : return arith_op_u(lt)(y, x);
965 : : }
966 : :
967 : : ARITH_DECL_BI_UU_I(geq)
968 : : {
969 : : return arith_op_u(leq)(y, x);
970 : : }
971 : :
972 : : ARITH_DECL_BI_UU_I(same)
973 : : {
974 : : return x.msw == y.msw && x.lsw == y.lsw;
975 : : }
976 : :
977 : : ARITH_DECL_BI_UU_I(neq)
978 : : {
979 : : return !arith_op_u(same)(x, y);
980 : : }
981 : :
982 : : ARITH_DECL_BI_UU_U(and)
983 : : {
984 : : x.msw &= y.msw;
985 : : x.lsw &= y.lsw;
986 : : return x;
987 : : }
988 : :
989 : : ARITH_DECL_BI_UU_U(xor)
990 : : {
991 : : x.msw ^= y.msw;
992 : : x.lsw ^= y.lsw;
993 : : return x;
994 : : }
995 : :
996 : : ARITH_DECL_BI_UU_U(or)
997 : : {
998 : : x.msw |= y.msw;
999 : : x.lsw |= y.lsw;
1000 : : return x;
1001 : : }
1002 : :
1003 : : #undef SIMUL_LSW_ODDLEN
1004 : : #undef SIMUL_LSW_HALFLEN
1005 : : #undef SIMUL_LSW_HALFMASK
1006 : :
1007 : : #define SIMUL_LSW_ODDLEN (SIMUL_LSW_WIDTH & 1)
1008 : : #define SIMUL_LSW_HALFLEN (SIMUL_LSW_WIDTH / 2)
1009 : : #define SIMUL_LSW_HALFMASK (~(~(SIMUL_ARITH_SUBTYPE)0 << SIMUL_LSW_HALFLEN))
1010 : :
1011 : : ARITH_DECL_BI_UU_U(star)
1012 : : {
1013 : : arith_u z;
1014 : : SIMUL_ARITH_SUBTYPE a = x.lsw, b = y.lsw, t00, t01, t10, t11, c = 0, t;
1015 : : #if SIMUL_LSW_ODDLEN
1016 : : SIMUL_ARITH_SUBTYPE bms = b & (SIMUL_ONE_TMP << (SIMUL_LSW_WIDTH - 1));
1017 : :
1018 : : b &= ~(SIMUL_ONE_TMP << (SIMUL_LSW_WIDTH - 1));
1019 : : #endif
1020 : :
1021 : : t00 = (a & SIMUL_LSW_HALFMASK) * (b & SIMUL_LSW_HALFMASK);
1022 : : t01 = (a & SIMUL_LSW_HALFMASK) * (b >> SIMUL_LSW_HALFLEN);
1023 : : t10 = (a >> SIMUL_LSW_HALFLEN) * (b & SIMUL_LSW_HALFMASK);
1024 : : t11 = (a >> SIMUL_LSW_HALFLEN) * (b >> SIMUL_LSW_HALFLEN);
1025 : : t = z.lsw = t00;
1026 : : z.lsw = TLSW(z.lsw + (t01 << SIMUL_LSW_HALFLEN));
1027 : : if (t > z.lsw) c ++;
1028 : : t = z.lsw;
1029 : : z.lsw = TLSW(z.lsw + (t10 << SIMUL_LSW_HALFLEN));
1030 : : if (t > z.lsw) c ++;
1031 : : #if SIMUL_LSW_ODDLEN
1032 : : t = z.lsw;
1033 : : z.lsw = TLSW(z.lsw + (t11 << (2 * SIMUL_LSW_HALFLEN)));
1034 : : if (t > z.lsw) c ++;
1035 : : if (bms && (a & SIMUL_ONE_TMP)) {
1036 : : t = z.lsw;
1037 : : z.lsw = TLSW(z.lsw + b);
1038 : : if (t > z.lsw) c ++;
1039 : : }
1040 : : #endif
1041 : : z.msw = TMSW(x.lsw * y.msw + x.msw * y.lsw + c
1042 : : + (t01 >> (SIMUL_LSW_WIDTH - SIMUL_LSW_HALFLEN))
1043 : : + (t10 >> (SIMUL_LSW_WIDTH - SIMUL_LSW_HALFLEN))
1044 : : + (t11 >> (SIMUL_LSW_WIDTH - (2 * SIMUL_LSW_HALFLEN))));
1045 : : return z;
1046 : : }
1047 : :
1048 : : /*
1049 : : * This function calculates the unsigned integer division, yielding
1050 : : * both quotient and remainder. The divider (y) MUST be non-zero.
1051 : : */
1052 : : static void arith_op_u(udiv)(arith_u x, arith_u y, arith_u *q, arith_u *r)
1053 : : {
1054 : : int i, j;
1055 : : arith_u a;
1056 : :
1057 : : *q = SIMUL_ZERO;
1058 : : for (i = SIMUL_NUMBITS - 1; i >= 0; i --) {
1059 : : if (i >= (int)SIMUL_LSW_WIDTH
1060 : : && (y.msw & (SIMUL_ONE_TMP << (i - SIMUL_LSW_WIDTH))))
1061 : : break;
1062 : : if (i < (int)SIMUL_LSW_WIDTH && (y.lsw & (SIMUL_ONE_TMP << i)))
1063 : : break;
1064 : : }
1065 : : a = arith_op_u(lsh)(y, SIMUL_NUMBITS - 1 - i);
1066 : : for (j = SIMUL_NUMBITS - 1 - i; j >= SIMUL_LSW_WIDTH; j --) {
1067 : : if (arith_op_u(leq)(a, x)) {
1068 : : x = arith_op_u(minus)(x, a);
1069 : : q->msw |= SIMUL_ONE_TMP << (j - SIMUL_LSW_WIDTH);
1070 : : }
1071 : : a = arith_op_u(rsh)(a, 1);
1072 : : }
1073 : : for (; j >= 0; j --) {
1074 : : if (arith_op_u(leq)(a, x)) {
1075 : : x = arith_op_u(minus)(x, a);
1076 : : q->lsw |= SIMUL_ONE_TMP << j;
1077 : : }
1078 : : a = arith_op_u(rsh)(a, 1);
1079 : : }
1080 : : *r = x;
1081 : : }
1082 : :
1083 : : ARITH_DECL_BI_UU_U(slash)
1084 : : {
1085 : : arith_u q, r;
1086 : :
1087 : : if (arith_op_u(same)(y, SIMUL_ZERO))
1088 : : ARITH_ERROR(ARITH_EXCEP_SLASH_D);
1089 : : arith_op_u(udiv)(x, y, &q, &r);
1090 : : return q;
1091 : : }
1092 : :
1093 : : ARITH_DECL_BI_UU_U(pct)
1094 : : {
1095 : : arith_u q, r;
1096 : :
1097 : : if (arith_op_u(same)(y, SIMUL_ZERO))
1098 : : ARITH_ERROR(ARITH_EXCEP_PCT_D);
1099 : : arith_op_u(udiv)(x, y, &q, &r);
1100 : : return r;
1101 : : }
1102 : :
1103 : : #undef SIMUL_TRAP
1104 : : #undef SIMUL_TRAPL
1105 : : #define SIMUL_TRAP (SIMUL_ONE_TMP << (SIMUL_MSW_WIDTH - 1))
1106 : : #define SIMUL_TRAPL (SIMUL_ONE_TMP << (SIMUL_LSW_WIDTH - 1))
1107 : :
1108 : : ARITH_DECL_MONO_U_S(to_s)
1109 : : {
1110 : : #ifdef ARITHMETIC_CHECKS
1111 : : if (x.msw & SIMUL_TRAP) ARITH_WARNING(ARITH_EXCEP_CONV_O);
1112 : : #endif
1113 : : return x;
1114 : : }
1115 : :
1116 : : ARITH_DECL_MONO_I_S(fromint) { return arith_op_u(fromint)(x); }
1117 : : ARITH_DECL_MONO_L_S(fromlong)
1118 : : {
1119 : : if (x < 0) return arith_op_u(neg)(
1120 : : arith_op_u(fromulong)((unsigned long)(-x)));
1121 : : return arith_op_u(fromulong)((unsigned long)x);
1122 : : }
1123 : :
1124 : : ARITH_DECL_MONO_S_I(toint)
1125 : : {
1126 : : if (x.msw & SIMUL_TRAP) return -arith_op_u(toint)(arith_op_u(neg)(x));
1127 : : return arith_op_u(toint)(x);
1128 : : }
1129 : :
1130 : : ARITH_DECL_MONO_S_L(tolong)
1131 : : {
1132 : : if (x.msw & SIMUL_TRAP)
1133 : : return -(long)arith_op_u(toulong)(arith_op_u(neg)(x));
1134 : : return (long)arith_op_u(toulong)(x);
1135 : : }
1136 : :
1137 : : ARITH_DECL_MONO_S_S(neg)
1138 : : {
1139 : : #ifdef ARITHMETIC_CHECKS
1140 : : if (x.lsw == 0 && x.msw == SIMUL_TRAP)
1141 : : ARITH_WARNING(ARITH_EXCEP_NEG_O);
1142 : : #endif
1143 : : return arith_op_u(neg)(x);
1144 : : }
1145 : :
1146 : : ARITH_DECL_MONO_S_S(not) { return arith_op_u(not)(x); }
1147 : : ARITH_DECL_MONO_S_I(lnot) { return arith_op_u(lnot)(x); }
1148 : : ARITH_DECL_MONO_S_I(lval) { return arith_op_u(lval)(x); }
1149 : :
1150 : : ARITH_DECL_BI_SS_S(plus)
1151 : : {
1152 : : arith_u z = arith_op_u(plus)(x, y);
1153 : :
1154 : : #ifdef ARITHMETIC_CHECKS
1155 : : if (x.msw & y.msw & ~z.msw & SIMUL_TRAP)
1156 : : ARITH_WARNING(ARITH_EXCEP_PLUS_U);
1157 : : else if (~x.msw & ~y.msw & z.msw & SIMUL_TRAP)
1158 : : ARITH_WARNING(ARITH_EXCEP_PLUS_O);
1159 : : #endif
1160 : : return z;
1161 : : }
1162 : :
1163 : : ARITH_DECL_BI_SS_S(minus)
1164 : : {
1165 : : arith_s z = arith_op_u(minus)(x, y);
1166 : :
1167 : : #ifdef ARITHMETIC_CHECKS
1168 : : if (x.msw & ~y.msw & ~z.msw & SIMUL_TRAP)
1169 : : ARITH_WARNING(ARITH_EXCEP_MINUS_U);
1170 : : else if (~x.msw & y.msw & z.msw & SIMUL_TRAP)
1171 : : ARITH_WARNING(ARITH_EXCEP_MINUS_O);
1172 : : #endif
1173 : : return z;
1174 : : }
1175 : :
1176 : : /*
1177 : : * Since signed and unsigned widths are equal for the simulated type,
1178 : : * we can use the unsigned left shift function, which performs the
1179 : : * the checks on the type width.
1180 : : */
1181 : : ARITH_DECL_BI_SI_S(lsh)
1182 : : {
1183 : : arith_s z = arith_op_u(lsh)(x, y);
1184 : :
1185 : : #ifdef ARITHMETIC_CHECKS
1186 : : if (x.msw & SIMUL_TRAP) ARITH_WARNING(ARITH_EXCEP_LSH_U);
1187 : : else {
1188 : : /*
1189 : : * To check for possible overflow, we right shift the
1190 : : * result. We need to make the shift count proper so that
1191 : : * we do not emit a double-warning. Besides, the left shift
1192 : : * could have been untruncated but yet affet the sign bit,
1193 : : * so we must test this explicitly.
1194 : : */
1195 : : arith_s w = arith_op_u(rsh)(z, (unsigned)y % SIMUL_NUMBITS);
1196 : :
1197 : : if ((z.msw & SIMUL_TRAP) || w.msw != x.msw || w.lsw != x.lsw)
1198 : : ARITH_WARNING(ARITH_EXCEP_LSH_O);
1199 : : }
1200 : : #endif
1201 : : return z;
1202 : : }
1203 : :
1204 : : /*
1205 : : * We define that right shifting a negative value, besides being worth a
1206 : : * warning, duplicates the sign bit. This is the most useful and most
1207 : : * usually encountered behaviour, and the standard allows it.
1208 : : */
1209 : : ARITH_DECL_BI_SI_S(rsh)
1210 : : {
1211 : : int xn = (x.msw & SIMUL_TRAP) != 0;
1212 : : arith_s z = arith_op_u(rsh)(x, y);
1213 : : int gy = (unsigned)y % SIMUL_NUMBITS;
1214 : :
1215 : : #ifdef ARITHMETIC_CHECKS
1216 : : if (xn) ARITH_WARNING(ARITH_EXCEP_RSH_N);
1217 : : #endif
1218 : : if (xn && gy > 0) {
1219 : : if (gy <= SIMUL_MSW_WIDTH) {
1220 : : z.msw |= TMSW(~(SIMUL_MSW_MASK >> gy));
1221 : : } else {
1222 : : z.msw = SIMUL_MSW_MASK;
1223 : : z.lsw |= TLSW(~(SIMUL_LSW_MASK
1224 : : >> (gy - SIMUL_MSW_WIDTH)));
1225 : : }
1226 : : }
1227 : : return z;
1228 : : }
1229 : :
1230 : : ARITH_DECL_BI_SS_I(lt)
1231 : : {
1232 : : int xn = (x.msw & SIMUL_TRAP) != 0;
1233 : : int yn = (y.msw & SIMUL_TRAP) != 0;
1234 : :
1235 : : if (xn == yn) {
1236 : : return x.msw < y.msw || (x.msw == y.msw && x.lsw < y.lsw);
1237 : : } else {
1238 : : return xn;
1239 : : }
1240 : : }
1241 : :
1242 : : ARITH_DECL_BI_SS_I(leq)
1243 : : {
1244 : : int xn = (x.msw & SIMUL_TRAP) != 0;
1245 : : int yn = (y.msw & SIMUL_TRAP) != 0;
1246 : :
1247 : : if (xn == yn) {
1248 : : return x.msw < y.msw || (x.msw == y.msw && x.lsw <= y.lsw);
1249 : : } else {
1250 : : return xn;
1251 : : }
1252 : : }
1253 : :
1254 : : ARITH_DECL_BI_SS_I(gt)
1255 : : {
1256 : : return arith_op_s(lt)(y, x);
1257 : : }
1258 : :
1259 : : ARITH_DECL_BI_SS_I(geq)
1260 : : {
1261 : : return arith_op_s(leq)(y, x);
1262 : : }
1263 : :
1264 : : ARITH_DECL_BI_SS_I(same)
1265 : : {
1266 : : return x.msw == y.msw && x.lsw == y.lsw;
1267 : : }
1268 : :
1269 : : ARITH_DECL_BI_SS_I(neq)
1270 : : {
1271 : : return !arith_op_s(same)(x, y);
1272 : : }
1273 : :
1274 : : ARITH_DECL_BI_SS_S(and)
1275 : : {
1276 : : return arith_op_u(and)(x, y);
1277 : : }
1278 : :
1279 : : ARITH_DECL_BI_SS_S(xor)
1280 : : {
1281 : : return arith_op_u(xor)(x, y);
1282 : : }
1283 : :
1284 : : ARITH_DECL_BI_SS_S(or)
1285 : : {
1286 : : return arith_op_u(or)(x, y);
1287 : : }
1288 : :
1289 : : /*
1290 : : * This function calculates the signed integer division, yielding
1291 : : * both quotient and remainder. The divider (y) MUST be non-zero.
1292 : : */
1293 : : static void arith_op_s(sdiv)(arith_s x, arith_s y, arith_s *q, arith_s *r)
1294 : : {
1295 : : arith_u a = x, b = y, c, d;
1296 : : int xn = 0, yn = 0;
1297 : :
1298 : : if (x.msw & SIMUL_TRAP) { a = arith_op_u(neg)(x); xn = 1; }
1299 : : if (y.msw & SIMUL_TRAP) { b = arith_op_u(neg)(y); yn = 1; }
1300 : : arith_op_u(udiv)(a, b, &c, &d);
1301 : : if (xn != yn) *q = arith_op_u(neg)(c); else *q = c;
1302 : : if (xn != yn) *r = arith_op_u(neg)(d); else *r = d;
1303 : : }
1304 : :
1305 : : /*
1306 : : * Overflow/underflow check is done the following way: obvious cases
1307 : : * are checked (both upper words non-null, both upper words null...)
1308 : : * and border-line occurrences are verified with an unsigned division
1309 : : * (which is quite computationaly expensive).
1310 : : */
1311 : : ARITH_DECL_BI_SS_S(star)
1312 : : {
1313 : : #ifdef ARITHMETIC_CHECKS
1314 : : arith_s z = arith_op_u(star)(x, y);
1315 : : int warn = 0;
1316 : :
1317 : : if (x.msw > 0) {
1318 : : if (y.msw > 0
1319 : : #if SIMUL_LSW_ODDLEN
1320 : : || (y.lsw & SIMUL_TRAPL)
1321 : : #endif
1322 : : ) warn = 1;
1323 : : }
1324 : : #if SIMUL_LSW_ODDLEN
1325 : : else if (y.msw > 0 && (x.lsw & SIMUL_TRAPL)) warn = 1;
1326 : : #endif
1327 : : if (!warn && (x.msw > 0 || y.msw > 0
1328 : : #if SIMUL_LSW_ODDLEN
1329 : : || ((x.lsw | y.lsw) & SIMUL_TRAPL)
1330 : : #endif
1331 : : )) {
1332 : : if (x.msw == SIMUL_MSW_MASK && x.lsw == SIMUL_LSW_MASK) {
1333 : : if (y.msw == SIMUL_TRAP && y.lsw == 0) warn = 1;
1334 : : } else if (!(x.msw == 0 && x.lsw == 0)
1335 : : && !arith_op_s(same)(arith_op_s(slash)(z, x), y)) {
1336 : : } warn = 1;
1337 : : }
1338 : : if (warn) ARITH_WARNING(((x.msw ^ y.msw) & SIMUL_TRAP)
1339 : : ? ARITH_EXCEP_STAR_U : ARITH_EXCEP_STAR_O);
1340 : : return z;
1341 : : #else
1342 : : return arith_op_u(star)(x, y);
1343 : : #endif
1344 : : }
1345 : :
1346 : : ARITH_DECL_BI_SS_S(slash)
1347 : : {
1348 : : arith_s q, r;
1349 : :
1350 : : if (arith_op_s(same)(y, SIMUL_ZERO))
1351 : : ARITH_ERROR(ARITH_EXCEP_SLASH_D);
1352 : : else if (x.msw == SIMUL_TRAP && x.lsw == 0
1353 : : && y.msw == SIMUL_MSW_MASK && y.lsw == SIMUL_LSW_MASK)
1354 : : ARITH_ERROR(ARITH_EXCEP_SLASH_O);
1355 : : arith_op_s(sdiv)(x, y, &q, &r);
1356 : : return q;
1357 : : }
1358 : :
1359 : : ARITH_DECL_BI_SS_S(pct)
1360 : : {
1361 : : arith_s q, r;
1362 : :
1363 : : if (arith_op_s(same)(y, SIMUL_ZERO))
1364 : : ARITH_ERROR(ARITH_EXCEP_PCT_D);
1365 : : arith_op_s(sdiv)(x, y, &q, &r);
1366 : : return r;
1367 : : }
1368 : :
1369 : : ARITH_DECL_MONO_ST_US(octconst)
1370 : : {
1371 : : arith_u z = { 0, 0 };
1372 : :
1373 : : for (; ARITH_OCTAL(*c); c ++) {
1374 : : unsigned w = ARITH_OVAL(*c);
1375 : : if (z.msw > (SIMUL_MSW_MASK / 8))
1376 : : ARITH_ERROR(ARITH_EXCEP_CONST_O);
1377 : : z = arith_op_u(lsh)(z, 3);
1378 : : z.lsw |= w;
1379 : : }
1380 : : *ru = z;
1381 : : if (z.msw & SIMUL_TRAP) {
1382 : : *sp = 0;
1383 : : } else {
1384 : : *rs = z;
1385 : : *sp = 1;
1386 : : }
1387 : : return c;
1388 : : }
1389 : :
1390 : : ARITH_DECL_MONO_ST_US(decconst)
1391 : : {
1392 : : #define ARITH_ALPHA_TRAP (1U << (SIMUL_MSW_WIDTH - 1))
1393 : : #define ARITH_ALPHA_MASK (ARITH_ALPHA_TRAP | (ARITH_ALPHA_TRAP - 1))
1394 : : #define ARITH_ALPHA ((ARITH_ALPHA_MASK - 10 * (ARITH_ALPHA_TRAP / 5)) + 1)
1395 : : #define ARITH_ALPHA_A ((SIMUL_MSW_MASK - 10 * (SIMUL_TRAP / 5)) + 1)
1396 : :
1397 : : arith_u z = { 0, 0 };
1398 : :
1399 : : for (; ARITH_DECIM(*c); c ++) {
1400 : : unsigned w = ARITH_DVAL(*c);
1401 : : SIMUL_ARITH_SUBTYPE t;
1402 : :
1403 : : if (z.msw > (SIMUL_MSW_MASK / 10)
1404 : : || (z.msw == (SIMUL_MSW_MASK / 10) &&
1405 : : /* ARITH_ALPHA is between 1 and 9, inclusive. */
1406 : : #if ARITH_ALPHA == 5
1407 : : z.lsw >= SIMUL_TRAPL
1408 : : #else
1409 : : z.lsw > ((SIMUL_TRAPL / 5) * ARITH_ALPHA_A
1410 : : + ((SIMUL_TRAPL % 5) * ARITH_ALPHA_A) / 5)
1411 : : #endif
1412 : : )) ARITH_ERROR(ARITH_EXCEP_CONST_O);
1413 : : z = arith_op_u(plus)(arith_op_u(lsh)(z, 3),
1414 : : arith_op_u(lsh)(z, 1));
1415 : : t = TLSW(z.lsw + w);
1416 : : if (t < z.lsw) z.msw ++;
1417 : : z.lsw = t;
1418 : : }
1419 : : *ru = z;
1420 : : if (z.msw & SIMUL_TRAP) {
1421 : : *sp = 0;
1422 : : } else {
1423 : : *rs = z;
1424 : : *sp = 1;
1425 : : }
1426 : : return c;
1427 : :
1428 : : #undef ARITH_ALPHA_A
1429 : : #undef ARITH_ALPHA
1430 : : #undef ARITH_ALPHA_TRAP
1431 : : #undef ARITH_ALPHA_MASK
1432 : : }
1433 : :
1434 : : ARITH_DECL_MONO_ST_US(hexconst)
1435 : : {
1436 : : arith_u z = { 0, 0 };
1437 : :
1438 : : for (; ARITH_HEXAD(*c); c ++) {
1439 : : unsigned w = ARITH_HVAL(*c);
1440 : : if (z.msw > (SIMUL_MSW_MASK / 16))
1441 : : ARITH_ERROR(ARITH_EXCEP_CONST_O);
1442 : : z = arith_op_u(lsh)(z, 4);
1443 : : z.lsw |= w;
1444 : : }
1445 : : *ru = z;
1446 : : if (z.msw & SIMUL_TRAP) {
1447 : : *sp = 0;
1448 : : } else {
1449 : : *rs = z;
1450 : : *sp = 1;
1451 : : }
1452 : : return c;
1453 : : }
1454 : :
1455 : : #endif
1456 : :
1457 : : #undef ARITH_HVAL
1458 : : #undef ARITH_HEXAD
1459 : : #undef ARITH_DVAL
1460 : : #undef ARITH_DECIM
1461 : : #undef ARITH_OVAL
1462 : : #undef ARITH_OCTAL
|