LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/ucpp - arith.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 181 0.0 %
Date: 2012-12-17 Functions: 0 49 0.0 %
Legend: Lines: hit not hit

          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           0 : 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           0 : ARITH_DECL_MONO_ST_US(octconst)
     667             : {
     668           0 :         arith_u z = 0;
     669             : 
     670           0 :         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           0 :         *ru = z;
     684             : #if SIGNED_IS_BIGGER
     685             :         *rs = z;
     686             :         *sp = 1;
     687             : #else
     688           0 :         if (z > NATIVE_SIGNED_MAX) {
     689           0 :                 *sp = 0;
     690             :         } else {
     691           0 :                 *rs = z;
     692           0 :                 *sp = 1;
     693             :         }
     694             : #endif
     695           0 :         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

Generated by: LCOV version 1.10