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 
ARITH_DECL_MONO_S_U(to_u)220 ARITH_DECL_MONO_S_U(to_u) { return (arith_u)x; }
ARITH_DECL_MONO_I_U(fromint)221 ARITH_DECL_MONO_I_U(fromint) { return (arith_u)x; }
ARITH_DECL_MONO_L_U(fromulong)222 ARITH_DECL_MONO_L_U(fromulong) { return (arith_u)x; }
223 
ARITH_DECL_MONO_U_I(toint)224 ARITH_DECL_MONO_U_I(toint)
225 {
226 #if NATIVE_UNSIGNED_MAX > INT_MAX
227 	if (x > (arith_u)INT_MAX) return INT_MAX;
228 #endif
229 	return (int)x;
230 }
231 
ARITH_DECL_MONO_U_L(toulong)232 ARITH_DECL_MONO_U_L(toulong)
233 {
234 #if NATIVE_UNSIGNED_MAX > LONG_MAX
235 	if (x > (arith_u)LONG_MAX) return LONG_MAX;
236 #endif
237 	return (long)x;
238 }
239 
ARITH_DECL_MONO_U_U(neg)240 ARITH_DECL_MONO_U_U(neg) { return -x; }
ARITH_DECL_MONO_U_U(not)241 ARITH_DECL_MONO_U_U(not) { return ~x; }
ARITH_DECL_MONO_U_I(lnot)242 ARITH_DECL_MONO_U_I(lnot) { return !x; }
ARITH_DECL_MONO_U_I(lval)243 ARITH_DECL_MONO_U_I(lval) { return x != 0; }
244 
ARITH_DECL_BI_UU_U(plus)245 ARITH_DECL_BI_UU_U(plus) { return x + y; }
ARITH_DECL_BI_UU_U(minus)246 ARITH_DECL_BI_UU_U(minus) { return x - y; }
ARITH_DECL_BI_UU_I(lt)247 ARITH_DECL_BI_UU_I(lt) { return x < y; }
ARITH_DECL_BI_UU_I(leq)248 ARITH_DECL_BI_UU_I(leq) { return x <= y; }
ARITH_DECL_BI_UU_I(gt)249 ARITH_DECL_BI_UU_I(gt) { return x > y; }
ARITH_DECL_BI_UU_I(geq)250 ARITH_DECL_BI_UU_I(geq) { return x >= y; }
ARITH_DECL_BI_UU_I(same)251 ARITH_DECL_BI_UU_I(same) { return x == y; }
ARITH_DECL_BI_UU_I(neq)252 ARITH_DECL_BI_UU_I(neq) { return x != y; }
ARITH_DECL_BI_UU_U(and)253 ARITH_DECL_BI_UU_U(and) { return x & y; }
ARITH_DECL_BI_UU_U(xor)254 ARITH_DECL_BI_UU_U(xor) { return x ^ y; }
ARITH_DECL_BI_UU_U(or)255 ARITH_DECL_BI_UU_U(or) { return x | y; }
ARITH_DECL_BI_UU_U(star)256 ARITH_DECL_BI_UU_U(star) { return x * y; }
257 
ARITH_DECL_BI_UI_U(lsh)258 ARITH_DECL_BI_UI_U(lsh)
259 {
260 #ifdef ARITHMETIC_CHECKS
261 	if (y >= NATIVE_UNSIGNED_BITS)
262 		ARITH_WARNING(ARITH_EXCEP_LSH_W);
263 	else if (y < 0)
264 		ARITH_WARNING(ARITH_EXCEP_LSH_C);
265 #endif
266 	return x << y;
267 }
268 
ARITH_DECL_BI_UI_U(rsh)269 ARITH_DECL_BI_UI_U(rsh)
270 {
271 #ifdef ARITHMETIC_CHECKS
272 	if (y >= NATIVE_UNSIGNED_BITS)
273 		ARITH_WARNING(ARITH_EXCEP_RSH_W);
274 	else if (y < 0)
275 		ARITH_WARNING(ARITH_EXCEP_RSH_C);
276 #endif
277 	return x >> y;
278 }
279 
ARITH_DECL_BI_UU_U(slash)280 ARITH_DECL_BI_UU_U(slash)
281 {
282 	if (y == 0) ARITH_ERROR(ARITH_EXCEP_SLASH_D);
283 	return x / y;
284 }
285 
ARITH_DECL_BI_UU_U(pct)286 ARITH_DECL_BI_UU_U(pct)
287 {
288 	if (y == 0) ARITH_ERROR(ARITH_EXCEP_PCT_D);
289 	return x % y;
290 }
291 
292 /* operations on the signed type */
293 
ARITH_DECL_MONO_U_S(to_s)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 
ARITH_DECL_MONO_I_S(fromint)305 ARITH_DECL_MONO_I_S(fromint) { return (arith_s)x; }
ARITH_DECL_MONO_L_S(fromlong)306 ARITH_DECL_MONO_L_S(fromlong) { return (arith_s)x; }
307 
ARITH_DECL_MONO_S_I(toint)308 ARITH_DECL_MONO_S_I(toint)
309 {
310 #if NATIVE_SIGNED_MIN < INT_MIN
311 	if (x < (arith_s)INT_MIN) return INT_MIN;
312 #endif
313 #if NATIVE_SIGNED_MAX > INT_MAX
314 	if (x > (arith_s)INT_MAX) return INT_MAX;
315 #endif
316 	return (int)x;
317 }
318 
ARITH_DECL_MONO_S_L(tolong)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 
ARITH_DECL_MONO_S_S(neg)330 ARITH_DECL_MONO_S_S(neg)
331 {
332 #ifdef ARITHMETIC_CHECKS
333 #if NEGATIVE_IS_BIGGER
334 	if (x == NATIVE_SIGNED_MIN)
335 		ARITH_WARNING(ARITH_EXCEP_NEG_O);
336 #endif
337 #endif
338 	return -x;
339 }
340 
ARITH_DECL_MONO_S_S(not)341 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 	return ~x;
357 }
358 
ARITH_DECL_MONO_S_I(lnot)359 ARITH_DECL_MONO_S_I(lnot) { return !x; }
ARITH_DECL_MONO_S_I(lval)360 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  */
ARITH_DECL_BI_SS_S(plus)385 ARITH_DECL_BI_SS_S(plus)
386 {
387 #ifdef ARITHMETIC_CHECKS
388 	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 		(((arith_u)x + (arith_u)y) > (arith_u)NATIVE_SIGNED_MAX)
393 #endif
394 		)) ARITH_WARNING(ARITH_EXCEP_PLUS_O);
395 	else if (x < 0 && y < 0 && (
396 #if NEGATIVE_IS_BIGGER
397 		(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 		(((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 		)) ARITH_WARNING(ARITH_EXCEP_PLUS_U);
415 #endif
416 	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  */
ARITH_DECL_BI_SS_S(minus)434 ARITH_DECL_BI_SS_S(minus)
435 {
436 #ifdef ARITHMETIC_CHECKS
437 	if (x > 0 && y < 0 && (
438 #if NEGATIVE_IS_BIGGER
439 	(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 	(((arith_u)x + (arith_u)(-y)) > (arith_u)NATIVE_SIGNED_MAX)
445 #endif
446 	)) ARITH_WARNING(ARITH_EXCEP_MINUS_O);
447 	else if (x < 0 && y > 0 && (
448 #if NEGATIVE_IS_BIGGER
449 	(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 	(((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 	)) ARITH_WARNING(ARITH_EXCEP_MINUS_U);
465 #endif
466 	return x - y;
467 }
468 
ARITH_DECL_BI_SS_I(lt)469 ARITH_DECL_BI_SS_I(lt) { return x < y; }
ARITH_DECL_BI_SS_I(leq)470 ARITH_DECL_BI_SS_I(leq) { return x <= y; }
ARITH_DECL_BI_SS_I(gt)471 ARITH_DECL_BI_SS_I(gt) { return x > y; }
ARITH_DECL_BI_SS_I(geq)472 ARITH_DECL_BI_SS_I(geq) { return x >= y; }
ARITH_DECL_BI_SS_I(same)473 ARITH_DECL_BI_SS_I(same) { return x == y; }
ARITH_DECL_BI_SS_I(neq)474 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  */
ARITH_DECL_BI_SS_S(and)484 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 	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  */
ARITH_DECL_BI_SS_S(xor)501 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 	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  */
ARITH_DECL_BI_SS_S(or)525 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 	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  */
ARITH_DECL_BI_SI_S(lsh)549 ARITH_DECL_BI_SI_S(lsh)
550 {
551 #ifdef ARITHMETIC_CHECKS
552 	if (y < 0) ARITH_WARNING(ARITH_EXCEP_LSH_C);
553 	else if (
554 #if SIGNED_IS_BIGGER
555 		y > NATIVE_UNSIGNED_BITS
556 #else
557 		y >= NATIVE_UNSIGNED_BITS
558 		|| (y > 0 && (((arith_u)1 << (y - 1))
559 			> (arith_u)NATIVE_SIGNED_MAX))
560 #endif
561 		) ARITH_WARNING(ARITH_EXCEP_LSH_W);
562 	else if (x < 0) ARITH_WARNING(ARITH_EXCEP_LSH_U);
563 	else if (x > 0 && ((((arith_u)x << y) & NATIVE_SIGNED_MAX) >> y)
564 		!= (arith_u)x) ARITH_WARNING(ARITH_EXCEP_LSH_O);
565 #endif
566 	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  */
ARITH_DECL_BI_SI_S(rsh)575 ARITH_DECL_BI_SI_S(rsh)
576 {
577 #ifdef ARITHMETIC_CHECKS
578 	if (y < 0) ARITH_WARNING(ARITH_EXCEP_RSH_C);
579 	else if (
580 #if SIGNED_IS_BIGGER
581 		y > NATIVE_UNSIGNED_BITS
582 #else
583 		y >= NATIVE_UNSIGNED_BITS
584 		|| (y > 0 && (((arith_u)1 << (y - 1))
585 			> (arith_u)NATIVE_SIGNED_MAX))
586 #endif
587 		) ARITH_WARNING(ARITH_EXCEP_RSH_W);
588 	else if (x < 0) ARITH_WARNING(ARITH_EXCEP_RSH_N);
589 #endif
590 	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  */
ARITH_DECL_BI_SS_S(star)600 ARITH_DECL_BI_SS_S(star)
601 {
602 #ifdef ARITHMETIC_CHECKS
603 	if (x == 0 || y == 0) return 0;
604 	if (x > 0 && y > 0) {
605 		if ((((arith_u)x * (arith_u)y) & (arith_u)NATIVE_SIGNED_MAX)
606 			/ (arith_u)y != (arith_u)x)
607 			ARITH_WARNING(ARITH_EXCEP_STAR_O);
608 	} else if (x < 0 && y < 0) {
609 		if (
610 #if NEGATIVE_IS_BIGGER
611 			(x == NATIVE_SIGNED_MIN || y == NATIVE_SIGNED_MIN) ||
612 #endif
613 			(((arith_u)(-x) * (arith_u)(-y))
614 			& (arith_u)NATIVE_SIGNED_MAX) / (arith_u)(-y)
615 			!= (arith_u)(-x))
616 			ARITH_WARNING(ARITH_EXCEP_STAR_O);
617 	} else if (x > 0 && y < 0) {
618 		if ((arith_u)x > (arith_u)1 && (
619 #if NEGATIVE_IS_BIGGER
620 		y == NATIVE_SIGNED_MIN ||
621 #endif
622 		(((arith_u)x * (arith_u)(-y)) & (arith_u)NATIVE_SIGNED_MAX)
623 		/ (arith_u)(-y) != (arith_u)x))
624 		ARITH_WARNING(ARITH_EXCEP_STAR_U);
625 	} else {
626 		if ((arith_u)y > (arith_u)1 && (
627 #if NEGATIVE_IS_BIGGER
628 		x == NATIVE_SIGNED_MIN ||
629 #endif
630 		(((arith_u)y * (arith_u)(-x)) & (arith_u)NATIVE_SIGNED_MAX)
631 		/ (arith_u)(-x) != (arith_u)y))
632 		ARITH_WARNING(ARITH_EXCEP_STAR_U);
633 	}
634 #endif
635 	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  */
ARITH_DECL_BI_SS_S(slash)647 ARITH_DECL_BI_SS_S(slash)
648 {
649 	if (y == 0) ARITH_ERROR(ARITH_EXCEP_SLASH_D);
650 #if NEGATIVE_IS_BIGGER
651 	else if (x == NATIVE_SIGNED_MIN && y == (arith_s)(-1))
652 		ARITH_ERROR(ARITH_EXCEP_SLASH_O);
653 #endif
654 	return x / y;
655 }
656 
657 /*
658  * Only division by 0 needs to be checked.
659  */
ARITH_DECL_BI_SS_S(pct)660 ARITH_DECL_BI_SS_S(pct)
661 {
662 	if (y == 0) ARITH_ERROR(ARITH_EXCEP_PCT_D);
663 	return x % y;
664 }
665 
ARITH_DECL_MONO_ST_US(octconst)666 ARITH_DECL_MONO_ST_US(octconst)
667 {
668 	arith_u z = 0;
669 
670 	for (; ARITH_OCTAL(*c); c ++) {
671 		arith_u w = ARITH_OVAL(*c);
672 		if (z > (NATIVE_UNSIGNED_MAX_A / 8))
673 			ARITH_ERROR(ARITH_EXCEP_CONST_O);
674 		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 		z += w;
682 	}
683 	*ru = z;
684 #if SIGNED_IS_BIGGER
685 	*rs = z;
686 	*sp = 1;
687 #else
688 	if (z > NATIVE_SIGNED_MAX) {
689 		*sp = 0;
690 	} else {
691 		*rs = z;
692 		*sp = 1;
693 	}
694 #endif
695 	return c;
696 }
697 
ARITH_DECL_MONO_ST_US(decconst)698 ARITH_DECL_MONO_ST_US(decconst)
699 {
700 	arith_u z = 0;
701 
702 	for (; ARITH_DECIM(*c); c ++) {
703 		arith_u w = ARITH_DVAL(*c);
704 		if (z > (NATIVE_UNSIGNED_MAX_A / 10))
705 			ARITH_ERROR(ARITH_EXCEP_CONST_O);
706 		z *= 10;
707 		if (z > (NATIVE_UNSIGNED_MAX_A - w))
708 			ARITH_ERROR(ARITH_EXCEP_CONST_O);
709 		z += w;
710 	}
711 	*ru = z;
712 #if SIGNED_IS_BIGGER
713 	*rs = z;
714 	*sp = 1;
715 #else
716 	if (z > NATIVE_SIGNED_MAX) {
717 		*sp = 0;
718 	} else {
719 		*rs = z;
720 		*sp = 1;
721 	}
722 #endif
723 	return c;
724 }
725 
ARITH_DECL_MONO_ST_US(hexconst)726 ARITH_DECL_MONO_ST_US(hexconst)
727 {
728 	arith_u z = 0;
729 
730 	for (; ARITH_HEXAD(*c); c ++) {
731 		arith_u w = ARITH_HVAL(*c);
732 		if (z > (NATIVE_UNSIGNED_MAX_A / 16))
733 			ARITH_ERROR(ARITH_EXCEP_CONST_O);
734 		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 		z += w;
742 	}
743 	*ru = z;
744 #if SIGNED_IS_BIGGER
745 	*rs = z;
746 	*sp = 1;
747 #else
748 	if (z > NATIVE_SIGNED_MAX) {
749 		*sp = 0;
750 	} else {
751 		*rs = z;
752 		*sp = 1;
753 	}
754 #endif
755 	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  */
ARITH_DECL_MONO_S_U(to_u)817 ARITH_DECL_MONO_S_U(to_u) { return x; }
818 
ARITH_DECL_MONO_I_U(fromint)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 
ARITH_DECL_MONO_L_U(fromulong)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 
ARITH_DECL_MONO_U_I(toint)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 
ARITH_DECL_MONO_U_L(toulong)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 
ARITH_DECL_MONO_U_U(neg)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 
ARITH_DECL_MONO_U_U(not)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 
ARITH_DECL_MONO_U_I(lnot)890 ARITH_DECL_MONO_U_I(lnot)
891 {
892 	return x.msw == 0 && x.lsw == 0;
893 }
894 
ARITH_DECL_MONO_U_I(lval)895 ARITH_DECL_MONO_U_I(lval)
896 {
897 	return x.msw != 0 || x.lsw != 0;
898 }
899 
ARITH_DECL_BI_UU_U(plus)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 
ARITH_DECL_BI_UU_U(minus)908 ARITH_DECL_BI_UU_U(minus)
909 {
910 	return arith_op_u(plus)(x, arith_op_u(neg)(y));
911 }
912 
ARITH_DECL_BI_UI_U(lsh)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 
ARITH_DECL_BI_UI_U(rsh)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 
ARITH_DECL_BI_UU_I(lt)952 ARITH_DECL_BI_UU_I(lt)
953 {
954 	return x.msw < y.msw || (x.msw == y.msw && x.lsw < y.lsw);
955 }
956 
ARITH_DECL_BI_UU_I(leq)957 ARITH_DECL_BI_UU_I(leq)
958 {
959 	return x.msw < y.msw || (x.msw == y.msw && x.lsw <= y.lsw);
960 }
961 
ARITH_DECL_BI_UU_I(gt)962 ARITH_DECL_BI_UU_I(gt)
963 {
964 	return arith_op_u(lt)(y, x);
965 }
966 
ARITH_DECL_BI_UU_I(geq)967 ARITH_DECL_BI_UU_I(geq)
968 {
969 	return arith_op_u(leq)(y, x);
970 }
971 
ARITH_DECL_BI_UU_I(same)972 ARITH_DECL_BI_UU_I(same)
973 {
974 	return x.msw == y.msw && x.lsw == y.lsw;
975 }
976 
ARITH_DECL_BI_UU_I(neq)977 ARITH_DECL_BI_UU_I(neq)
978 {
979 	return !arith_op_u(same)(x, y);
980 }
981 
ARITH_DECL_BI_UU_U(and)982 ARITH_DECL_BI_UU_U(and)
983 {
984 	x.msw &= y.msw;
985 	x.lsw &= y.lsw;
986 	return x;
987 }
988 
ARITH_DECL_BI_UU_U(xor)989 ARITH_DECL_BI_UU_U(xor)
990 {
991 	x.msw ^= y.msw;
992 	x.lsw ^= y.lsw;
993 	return x;
994 }
995 
ARITH_DECL_BI_UU_U(or)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 
ARITH_DECL_BI_UU_U(star)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  */
arith_op_u(udiv)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 
ARITH_DECL_BI_UU_U(slash)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 
ARITH_DECL_BI_UU_U(pct)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 
ARITH_DECL_MONO_U_S(to_s)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 
ARITH_DECL_MONO_I_S(fromint)1116 ARITH_DECL_MONO_I_S(fromint) { return arith_op_u(fromint)(x); }
ARITH_DECL_MONO_L_S(fromlong)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 
ARITH_DECL_MONO_S_I(toint)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 
ARITH_DECL_MONO_S_L(tolong)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 
ARITH_DECL_MONO_S_S(neg)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 
ARITH_DECL_MONO_S_S(not)1146 ARITH_DECL_MONO_S_S(not) { return arith_op_u(not)(x); }
ARITH_DECL_MONO_S_I(lnot)1147 ARITH_DECL_MONO_S_I(lnot) { return arith_op_u(lnot)(x); }
ARITH_DECL_MONO_S_I(lval)1148 ARITH_DECL_MONO_S_I(lval) { return arith_op_u(lval)(x); }
1149 
ARITH_DECL_BI_SS_S(plus)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 
ARITH_DECL_BI_SS_S(minus)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  */
ARITH_DECL_BI_SI_S(lsh)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  */
ARITH_DECL_BI_SI_S(rsh)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 
ARITH_DECL_BI_SS_I(lt)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 
ARITH_DECL_BI_SS_I(leq)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 
ARITH_DECL_BI_SS_I(gt)1254 ARITH_DECL_BI_SS_I(gt)
1255 {
1256 	return arith_op_s(lt)(y, x);
1257 }
1258 
ARITH_DECL_BI_SS_I(geq)1259 ARITH_DECL_BI_SS_I(geq)
1260 {
1261 	return arith_op_s(leq)(y, x);
1262 }
1263 
ARITH_DECL_BI_SS_I(same)1264 ARITH_DECL_BI_SS_I(same)
1265 {
1266 	return x.msw == y.msw && x.lsw == y.lsw;
1267 }
1268 
ARITH_DECL_BI_SS_I(neq)1269 ARITH_DECL_BI_SS_I(neq)
1270 {
1271 	return !arith_op_s(same)(x, y);
1272 }
1273 
ARITH_DECL_BI_SS_S(and)1274 ARITH_DECL_BI_SS_S(and)
1275 {
1276 	return arith_op_u(and)(x, y);
1277 }
1278 
ARITH_DECL_BI_SS_S(xor)1279 ARITH_DECL_BI_SS_S(xor)
1280 {
1281 	return arith_op_u(xor)(x, y);
1282 }
1283 
ARITH_DECL_BI_SS_S(or)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  */
arith_op_s(sdiv)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  */
ARITH_DECL_BI_SS_S(star)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 
ARITH_DECL_BI_SS_S(slash)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 
ARITH_DECL_BI_SS_S(pct)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 
ARITH_DECL_MONO_ST_US(octconst)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 
ARITH_DECL_MONO_ST_US(decconst)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 
ARITH_DECL_MONO_ST_US(hexconst)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
1463