sm64

A Super Mario 64 decompilation
Log | Files | Refs | README | LICENSE

longlong.h (8107B)


      1 // This file is copied from gcc 2.95.2
      2 // Asm code except mips has been removed
      3 
      4 /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
      5    Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
      6 
      7    This definition file is free software; you can redistribute it
      8    and/or modify it under the terms of the GNU General Public
      9    License as published by the Free Software Foundation; either
     10    version 2, or (at your option) any later version.
     11 
     12    This definition file is distributed in the hope that it will be
     13    useful, but WITHOUT ANY WARRANTY; without even the implied
     14    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     15    See the GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the Free Software
     19    Foundation, Inc., 59 Temple Place - Suite 330,
     20    Boston, MA 02111-1307, USA.  */
     21 
     22 #ifndef SI_TYPE_SIZE
     23 #define SI_TYPE_SIZE 32
     24 #endif
     25 
     26 #define __BITS4 (SI_TYPE_SIZE / 4)
     27 #define __ll_B (1L << (SI_TYPE_SIZE / 2))
     28 #define __ll_lowpart(t) ((USItype) (t) % __ll_B)
     29 #define __ll_highpart(t) ((USItype) (t) / __ll_B)
     30 
     31 /* Define auxiliary asm macros.
     32 
     33    1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
     34    multiplies two USItype integers MULTIPLER and MULTIPLICAND,
     35    and generates a two-part USItype product in HIGH_PROD and
     36    LOW_PROD.
     37 
     38    2) __umulsidi3(a,b) multiplies two USItype integers A and B,
     39    and returns a UDItype product.  This is just a variant of umul_ppmm.
     40 
     41    3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
     42    denominator) divides a two-word unsigned integer, composed by the
     43    integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
     44    places the quotient in QUOTIENT and the remainder in REMAINDER.
     45    HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
     46    If, in addition, the most significant bit of DENOMINATOR must be 1,
     47    then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
     48 
     49    4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
     50    denominator).  Like udiv_qrnnd but the numbers are signed.  The
     51    quotient is rounded towards 0.
     52 
     53    5) count_leading_zeros(count, x) counts the number of zero-bits from
     54    the msb to the first non-zero bit.  This is the number of steps X
     55    needs to be shifted left to set the msb.  Undefined for X == 0.
     56 
     57    6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
     58    high_addend_2, low_addend_2) adds two two-word unsigned integers,
     59    composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
     60    LOW_ADDEND_2 respectively.  The result is placed in HIGH_SUM and
     61    LOW_SUM.  Overflow (i.e. carry out) is not stored anywhere, and is
     62    lost.
     63 
     64    7) sub_ddmmss(high_difference, low_difference, high_minuend,
     65    low_minuend, high_subtrahend, low_subtrahend) subtracts two
     66    two-word unsigned integers, composed by HIGH_MINUEND_1 and
     67    LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
     68    respectively.  The result is placed in HIGH_DIFFERENCE and
     69    LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
     70    and is lost.
     71 
     72    If any of these macros are left undefined for a particular CPU,
     73    C macros are used.  */
     74 
     75 /* The CPUs come in alphabetical order below.
     76 
     77    Please add support for more CPUs here, or improve the current support
     78    for the CPUs below!
     79    (E.g. WE32100, IBM360.)  */
     80 
     81 #if defined (__GNUC__) && !defined (NO_ASM)
     82 
     83 /* We sometimes need to clobber "cc" with gcc2, but that would not be
     84    understood by gcc1.  Use cpp to avoid major code duplication.  */
     85 #if __GNUC__ < 2
     86 #define __CLOBBER_CC
     87 #define __AND_CLOBBER_CC
     88 #else /* __GNUC__ >= 2 */
     89 #define __CLOBBER_CC : "cc"
     90 #define __AND_CLOBBER_CC , "cc"
     91 #endif /* __GNUC__ < 2 */
     92 
     93 #if defined (__mips__)
     94 #define umul_ppmm(w1, w0, u, v) \
     95   __asm__ ("multu %2,%3"						\
     96 	   : "=l" ((USItype) (w0)),					\
     97 	     "=h" ((USItype) (w1))					\
     98 	   : "d" ((USItype) (u)),					\
     99 	     "d" ((USItype) (v)))
    100 #define UMUL_TIME 10
    101 #define UDIV_TIME 100
    102 #endif /* __mips__ */
    103 
    104 #endif /* __GNUC__ */
    105 
    106 /* If this machine has no inline assembler, use C macros.  */
    107 
    108 #if !defined (add_ssaaaa)
    109 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
    110   do {									\
    111     USItype __x;							\
    112     __x = (al) + (bl);							\
    113     (sh) = (ah) + (bh) + (__x < (al));					\
    114     (sl) = __x;								\
    115   } while (0)
    116 #endif
    117 
    118 #if !defined (sub_ddmmss)
    119 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
    120   do {									\
    121     USItype __x;							\
    122     __x = (al) - (bl);							\
    123     (sh) = (ah) - (bh) - (__x > (al));					\
    124     (sl) = __x;								\
    125   } while (0)
    126 #endif
    127 
    128 #if !defined (umul_ppmm)
    129 #define umul_ppmm(w1, w0, u, v)						\
    130   do {									\
    131     USItype __x0, __x1, __x2, __x3;					\
    132     USItype __ul, __vl, __uh, __vh;					\
    133 									\
    134     __ul = __ll_lowpart (u);						\
    135     __uh = __ll_highpart (u);						\
    136     __vl = __ll_lowpart (v);						\
    137     __vh = __ll_highpart (v);						\
    138 									\
    139     __x0 = (USItype) __ul * __vl;					\
    140     __x1 = (USItype) __ul * __vh;					\
    141     __x2 = (USItype) __uh * __vl;					\
    142     __x3 = (USItype) __uh * __vh;					\
    143 									\
    144     __x1 += __ll_highpart (__x0);/* this can't give carry */		\
    145     __x1 += __x2;		/* but this indeed can */		\
    146     if (__x1 < __x2)		/* did we get it? */			\
    147       __x3 += __ll_B;		/* yes, add it in the proper pos. */	\
    148 									\
    149     (w1) = __x3 + __ll_highpart (__x1);					\
    150     (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
    151   } while (0)
    152 #endif
    153 
    154 #if !defined (__umulsidi3)
    155 #define __umulsidi3(u, v) \
    156   ({DIunion __w;							\
    157     umul_ppmm (__w.s.high, __w.s.low, u, v);				\
    158     __w.ll; })
    159 #endif
    160 
    161 /* Define this unconditionally, so it can be used for debugging.  */
    162 #define __udiv_qrnnd_c(q, r, n1, n0, d) \
    163   do {									\
    164     USItype __d1, __d0, __q1, __q0;					\
    165     USItype __r1, __r0, __m;						\
    166     __d1 = __ll_highpart (d);						\
    167     __d0 = __ll_lowpart (d);						\
    168 									\
    169     __r1 = (n1) % __d1;							\
    170     __q1 = (n1) / __d1;							\
    171     __m = (USItype) __q1 * __d0;					\
    172     __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
    173     if (__r1 < __m)							\
    174       {									\
    175 	__q1--, __r1 += (d);						\
    176 	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
    177 	  if (__r1 < __m)						\
    178 	    __q1--, __r1 += (d);					\
    179       }									\
    180     __r1 -= __m;							\
    181 									\
    182     __r0 = __r1 % __d1;							\
    183     __q0 = __r1 / __d1;							\
    184     __m = (USItype) __q0 * __d0;					\
    185     __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
    186     if (__r0 < __m)							\
    187       {									\
    188 	__q0--, __r0 += (d);						\
    189 	if (__r0 >= (d))						\
    190 	  if (__r0 < __m)						\
    191 	    __q0--, __r0 += (d);					\
    192       }									\
    193     __r0 -= __m;							\
    194 									\
    195     (q) = (USItype) __q1 * __ll_B | __q0;				\
    196     (r) = __r0;								\
    197   } while (0)
    198 
    199 /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
    200    __udiv_w_sdiv (defined in libgcc or elsewhere).  */
    201 #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
    202 #define udiv_qrnnd(q, r, nh, nl, d) \
    203   do {									\
    204     USItype __r;							\
    205     (q) = __udiv_w_sdiv (&__r, nh, nl, d);				\
    206     (r) = __r;								\
    207   } while (0)
    208 #endif
    209 
    210 /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c.  */
    211 #if !defined (udiv_qrnnd)
    212 #define UDIV_NEEDS_NORMALIZATION 1
    213 #define udiv_qrnnd __udiv_qrnnd_c
    214 #endif
    215 
    216 #if !defined (count_leading_zeros)
    217 //extern const UQItype __clz_tab[];
    218 #define count_leading_zeros(count, x) \
    219   do {									\
    220     USItype __xr = (x);							\
    221     USItype __a;							\
    222 									\
    223     if (SI_TYPE_SIZE <= 32)						\
    224       {									\
    225 	__a = __xr < ((USItype)1<<2*__BITS4)				\
    226 	  ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4)		\
    227 	  : (__xr < ((USItype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);	\
    228       }									\
    229     else								\
    230       {									\
    231 	for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8)			\
    232 	  if (((__xr >> __a) & 0xff) != 0)				\
    233 	    break;							\
    234       }									\
    235 									\
    236     (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);		\
    237   } while (0)
    238 #endif
    239 
    240 #ifndef UDIV_NEEDS_NORMALIZATION
    241 #define UDIV_NEEDS_NORMALIZATION 0
    242 #endif