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 + -
显示快捷键?