LCOV - code coverage report
Current view: top level - workdir/unxlngi6.pro/CustomTarget/ucpp/source - arith.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 9 181 5.0 %
Date: 2012-08-25 Functions: 2 49 4.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 196 1.0 %

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

Generated by: LCOV version 1.10