longlong.h
来自「一个C源代码分析器」· C头文件 代码 · 共 1,296 行 · 第 1/3 页
H
1,296 行
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.This file is free software; you can redistribute it and/or modifyit under the terms of the GNU Library General Public License as published bythe Free Software Foundation; either version 2 of the License, or (at youroption) any later version.This file is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITYor FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General PublicLicense for more details.You should have received a copy of the GNU Library General Public Licensealong with this file; see the file COPYING.LIB. If not, write tothe Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* You have to define the following before including this file: UWtype -- An unsigned type, default type for operations (typically a "word") UHWtype -- An unsigned type, at least half the size of UWtype. UDWtype -- An unsigned type, at least twice as large a UWtype W_TYPE_SIZE -- size in bits of UWtype SItype, USItype -- Signed and unsigned 32 bit types. DItype, UDItype -- Signed and unsigned 64 bit types. On a 32 bit machine UWtype should typically be USItype; on a 64 bit machine, UWtype should typically be UDItype.*/#define __BITS4 (W_TYPE_SIZE / 4)#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))/* Define auxiliary asm macros. 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype word product in HIGH_PROD and LOW_PROD. 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a UDWtype product. This is just a variant of umul_ppmm. 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator) divides a UDWtype, composed by the UWtype integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less than DENOMINATOR for correct operation. If, in addition, the most significant bit of DENOMINATOR must be 1, then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1. 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator). Like udiv_qrnnd but the numbers are signed. The quotient is rounded towards 0. 5) count_leading_zeros(count, x) counts the number of zero-bits from the msb to the first non-zero bit in the UWtype X. This is the number of steps X needs to be shifted left to set the msb. Undefined for X == 0, unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts from the least significant end. 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, high_addend_2, low_addend_2) adds two UWtype integers, composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is lost. 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, and is lost. If any of these macros are left undefined for a particular CPU, C macros are used. *//* The CPUs come in alphabetical order below. Please add support for more CPUs here, or improve the current support for the CPUs below! */#if defined (__GNUC__) && !defined (NO_ASM)/* We sometimes need to clobber "cc" with gcc2, but that would not be understood by gcc1. Use cpp to avoid major code duplication. */#if __GNUC__ < 2#define __CLOBBER_CC#define __AND_CLOBBER_CC#else /* __GNUC__ >= 2 */#define __CLOBBER_CC : "cc"#define __AND_CLOBBER_CC , "cc"#endif /* __GNUC__ < 2 */#if (defined (__a29k__) || defined (___AM29K__)) && W_TYPE_SIZE == 32#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %1,%4,%5 addc %0,%2,%3" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "%r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "%r" ((USItype)(al)), \ "rI" ((USItype)(bl)))#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %1,%4,%5 subc %0,%2,%3" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "r" ((USItype)(al)), \ "rI" ((USItype)(bl)))#define umul_ppmm(xh, xl, m0, m1) \ do { \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ("multiplu %0,%1,%2" \ : "=r" ((USItype)(xl)) \ : "r" (__m0), \ "r" (__m1)); \ __asm__ ("multmu %0,%1,%2" \ : "=r" ((USItype)(xh)) \ : "r" (__m0), \ "r" (__m1)); \ } while (0)#define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("dividu %0,%3,%4" \ : "=r" ((USItype)(q)), \ "=q" ((USItype)(r)) \ : "1" ((USItype)(n1)), \ "r" ((USItype)(n0)), \ "r" ((USItype)(d)))#define count_leading_zeros(count, x) \ __asm__ ("clz %0,%1" \ : "=r" ((USItype)(count)) \ : "r" ((USItype)(x)))#endif /* __a29k__ */#if defined (__alpha__) && W_TYPE_SIZE == 64#define umul_ppmm(ph, pl, m0, m1) \ do { \ UDItype __m0 = (m0), __m1 = (m1); \ __asm__ ("umulh %r1,%2,%0" \ : "=r" ((UDItype) ph) \ : "%rJ" (__m0), \ "rI" (__m1)); \ (pl) = __m0 * __m1; \ } while (0)#define UMUL_TIME 46#define udiv_qrnnd(q, r, n1, n0, d) \ do { UDItype __r; \ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ (r) = __r; \ } while (0)extern UDItype __udiv_qrnnd ();#define UDIV_TIME 220#endif#if defined (__arm__) && W_TYPE_SIZE == 32#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("adds %1,%4,%5 adc %0,%2,%3" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "%r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "%r" ((USItype)(al)), \ "rI" ((USItype)(bl)))#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subs %1,%4,%5 sbc %0,%2,%3" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "r" ((USItype)(ah)), \ "rI" ((USItype)(bh)), \ "r" ((USItype)(al)), \ "rI" ((USItype)(bl)))#define umul_ppmm(xh, xl, a, b) \ __asm__ ("; Inlined umul_ppmm mov r0,%2 lsr 16 mov r2,%3 lsr 16 bic r1,%2,r0 lsl 16 bic r2,%3,r2 lsl 16 mul %1,r1,r2 mul r2,r0,r2 mul r1,%0,r1 mul %0,r0,%0 adds r1,r2,r1 addcs %0,%0,0x10000 adds %1,%1,r1 lsl 16 adc %0,%0,r1 lsr 16" \ : "=&r" ((USItype)(xh)), \ "=r" ((USItype)(xl)) \ : "r" ((USItype)(a)), \ "r" ((USItype)(b)) \ : "r0", "r1", "r2")#define UMUL_TIME 20#define UDIV_TIME 100#endif /* __arm__ */#if defined (__clipper__) && W_TYPE_SIZE == 32#define umul_ppmm(w1, w0, u, v) \ ({union {UDItype __ll; \ struct {USItype __l, __h;} __i; \ } __xx; \ __asm__ ("mulwux %2,%0" \ : "=r" (__xx.__ll) \ : "%0" ((USItype)(u)), \ "r" ((USItype)(v))); \ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})#define smul_ppmm(w1, w0, u, v) \ ({union {DItype __ll; \ struct {SItype __l, __h;} __i; \ } __xx; \ __asm__ ("mulwx %2,%0" \ : "=r" (__xx.__ll) \ : "%0" ((SItype)(u)), \ "r" ((SItype)(v))); \ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})#define __umulsidi3(u, v) \ ({UDItype __w; \ __asm__ ("mulwux %2,%0" \ : "=r" (__w) \ : "%0" ((USItype)(u)), \ "r" ((USItype)(v))); \ __w; })#endif /* __clipper__ */#if defined (__gmicro__) && W_TYPE_SIZE == 32#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add.w %5,%1 addx %3,%0" \ : "=g" ((USItype)(sh)), \ "=&g" ((USItype)(sl)) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ "g" ((USItype)(bl)))#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub.w %5,%1 subx %3,%0" \ : "=g" ((USItype)(sh)), \ "=&g" ((USItype)(sl)) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ "g" ((USItype)(bl)))#define umul_ppmm(ph, pl, m0, m1) \ __asm__ ("mulx %3,%0,%1" \ : "=g" ((USItype)(ph)), \ "=r" ((USItype)(pl)) \ : "%0" ((USItype)(m0)), \ "g" ((USItype)(m1)))#define udiv_qrnnd(q, r, nh, nl, d) \ __asm__ ("divx %4,%0,%1" \ : "=g" ((USItype)(q)), \ "=r" ((USItype)(r)) \ : "1" ((USItype)(nh)), \ "0" ((USItype)(nl)), \ "g" ((USItype)(d)))#define count_leading_zeros(count, x) \ __asm__ ("bsch/1 %1,%0" \ : "=g" (count) \ : "g" ((USItype)(x)), \ "0" ((USItype)0))#endif#if defined (__hppa) && W_TYPE_SIZE == 32#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %4,%5,%1 addc %2,%3,%0" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "%rM" ((USItype)(ah)), \ "rM" ((USItype)(bh)), \ "%rM" ((USItype)(al)), \ "rM" ((USItype)(bl)))#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %4,%5,%1 subb %2,%3,%0" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "rM" ((USItype)(ah)), \ "rM" ((USItype)(bh)), \ "rM" ((USItype)(al)), \ "rM" ((USItype)(bl)))#if defined (_PA_RISC1_1)#define umul_ppmm(wh, wl, u, v) \ do { \ union {UDItype __ll; \ struct {USItype __h, __l;} __i; \ } __xx; \ __asm__ ("xmpyu %1,%2,%0" \ : "=x" (__xx.__ll) \ : "x" ((USItype)(u)), \ "x" ((USItype)(v))); \ (wh) = __xx.__i.__h; \ (wl) = __xx.__i.__l; \ } while (0)#define UMUL_TIME 8#define UDIV_TIME 60#else#define UMUL_TIME 40#define UDIV_TIME 80#endif#define udiv_qrnnd(q, r, n1, n0, d) \ do { USItype __r; \ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ (r) = __r; \ } while (0)extern USItype __udiv_qrnnd ();#define count_leading_zeros(count, x) \ do { \ USItype __tmp; \ __asm__ ( \ "ldi 1,%0 extru,= %1,15,16,%%r0 ; Bits 31..16 zero? extru,tr %1,15,16,%1 ; No. Shift down, skip add. ldo 16(%0),%0 ; Yes. Perform add. extru,= %1,23,8,%%r0 ; Bits 15..8 zero? extru,tr %1,23,8,%1 ; No. Shift down, skip add. ldo 8(%0),%0 ; Yes. Perform add. extru,= %1,27,4,%%r0 ; Bits 7..4 zero? extru,tr %1,27,4,%1 ; No. Shift down, skip add. ldo 4(%0),%0 ; Yes. Perform add. extru,= %1,29,2,%%r0 ; Bits 3..2 zero? extru,tr %1,29,2,%1 ; No. Shift down, skip add. ldo 2(%0),%0 ; Yes. Perform add. extru %1,30,1,%1 ; Extract bit 1. sub %0,%1,%0 ; Subtract it. " : "=r" (count), "=r" (__tmp) : "1" (x)); \ } while (0)#endif#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32#define umul_ppmm(xh, xl, m0, m1) \ do { \ union {UDItype __ll; \ struct {USItype __h, __l;} __i; \ } __xx; \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ("mr %0,%3" \ : "=r" (__xx.__i.__h), \ "=r" (__xx.__i.__l) \ : "%1" (__m0), \ "r" (__m1)); \ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ (xh) += ((((SItype) __m0 >> 31) & __m1) \ + (((SItype) __m1 >> 31) & __m0)); \ } while (0)#define smul_ppmm(xh, xl, m0, m1) \ do { \ union {DItype __ll; \ struct {USItype __h, __l;} __i; \ } __xx; \ __asm__ ("mr %0,%3" \ : "=r" (__xx.__i.__h), \ "=r" (__xx.__i.__l) \ : "%1" (m0), \ "r" (m1)); \ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ } while (0)#define sdiv_qrnnd(q, r, n1, n0, d) \ do { \ union {DItype __ll; \ struct {USItype __h, __l;} __i; \ } __xx; \ __xx.__i.__h = n1; __xx.__i.__l = n0; \ __asm__ ("dr %0,%2" \ : "=r" (__xx.__ll) \ : "0" (__xx.__ll), "r" (d)); \ (q) = __xx.__i.__l; (r) = __xx.__i.__h; \ } while (0)#endif#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addl %5,%1 adcl %3,%0" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "%0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ "g" ((USItype)(bl)))#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subl %5,%1 sbbl %3,%0" \ : "=r" ((USItype)(sh)), \ "=&r" ((USItype)(sl)) \ : "0" ((USItype)(ah)), \ "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ "g" ((USItype)(bl)))#define umul_ppmm(w1, w0, u, v) \ __asm__ ("mull %3" \ : "=a" ((USItype)(w0)), \ "=d" ((USItype)(w1)) \ : "%0" ((USItype)(u)), \ "rm" ((USItype)(v)))#define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divl %4" \ : "=a" ((USItype)(q)), \ "=d" ((USItype)(r)) \ : "0" ((USItype)(n0)), \ "1" ((USItype)(n1)), \ "rm" ((USItype)(d)))#define count_leading_zeros(count, x) \ do { \ USItype __cbtmp; \ __asm__ ("bsrl %1,%0" \ : "=r" (__cbtmp) : "rm" ((USItype)(x))); \ (count) = __cbtmp ^ 31; \ } while (0)#define count_trailing_zeros(count, x) \ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))#define UMUL_TIME 40#define UDIV_TIME 40#endif /* 80x86 */#if defined (__i960__) && W_TYPE_SIZE == 32#define umul_ppmm(w1, w0, u, v) \ ({union {UDItype __ll; \ struct {USItype __l, __h;} __i; \ } __xx; \ __asm__ ("emul %2,%1,%0" \ : "=d" (__xx.__ll) \
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?