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