mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-19 00:18:51 +09:00
![Tom Rini](/assets/img/avatar_default.png)
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
251 lines
8.4 KiB
C
251 lines
8.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
|
|
Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004,
|
|
2005 Free Software Foundation, Inc.
|
|
*/
|
|
|
|
/* 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
|
|
|
|
UQItype -- Unsigned 8 bit type.
|
|
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))
|
|
|
|
#ifndef W_TYPE_SIZE
|
|
#define W_TYPE_SIZE 32
|
|
#define UWtype USItype
|
|
#define UHWtype USItype
|
|
#define UDWtype UDItype
|
|
#endif
|
|
|
|
extern const UQItype __clz_tab[256];
|
|
|
|
/* Define auxiliary asm macros.
|
|
|
|
1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
|
|
UWtype integers MULTIPLIER 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 nonzero 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!
|
|
(E.g. WE32100, IBM360.) */
|
|
|
|
/* Snipped per CPU support */
|
|
|
|
/* If this machine has no inline assembler, use C macros. */
|
|
|
|
#if !defined (add_ssaaaa)
|
|
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
|
|
do { \
|
|
UWtype __x; \
|
|
__x = (al) + (bl); \
|
|
(sh) = (ah) + (bh) + (__x < (al)); \
|
|
(sl) = __x; \
|
|
} while (0)
|
|
#endif
|
|
|
|
#if !defined (sub_ddmmss)
|
|
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
|
|
do { \
|
|
UWtype __x; \
|
|
__x = (al) - (bl); \
|
|
(sh) = (ah) - (bh) - (__x > (al)); \
|
|
(sl) = __x; \
|
|
} while (0)
|
|
#endif
|
|
|
|
/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of
|
|
smul_ppmm. */
|
|
#if !defined (umul_ppmm) && defined (smul_ppmm)
|
|
#define umul_ppmm(w1, w0, u, v) \
|
|
do { \
|
|
UWtype __w1; \
|
|
UWtype __xm0 = (u), __xm1 = (v); \
|
|
smul_ppmm (__w1, w0, __xm0, __xm1); \
|
|
(w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \
|
|
+ (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \
|
|
} while (0)
|
|
#endif
|
|
|
|
/* If we still don't have umul_ppmm, define it using plain C. */
|
|
#if !defined (umul_ppmm)
|
|
#define umul_ppmm(w1, w0, u, v) \
|
|
do { \
|
|
UWtype __x0, __x1, __x2, __x3; \
|
|
UHWtype __ul, __vl, __uh, __vh; \
|
|
\
|
|
__ul = __ll_lowpart (u); \
|
|
__uh = __ll_highpart (u); \
|
|
__vl = __ll_lowpart (v); \
|
|
__vh = __ll_highpart (v); \
|
|
\
|
|
__x0 = (UWtype) __ul * __vl; \
|
|
__x1 = (UWtype) __ul * __vh; \
|
|
__x2 = (UWtype) __uh * __vl; \
|
|
__x3 = (UWtype) __uh * __vh; \
|
|
\
|
|
__x1 += __ll_highpart (__x0);/* this can't give carry */ \
|
|
__x1 += __x2; /* but this indeed can */ \
|
|
if (__x1 < __x2) /* did we get it? */ \
|
|
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
|
|
\
|
|
(w1) = __x3 + __ll_highpart (__x1); \
|
|
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
|
|
} while (0)
|
|
#endif
|
|
|
|
#if !defined (__umulsidi3)
|
|
#define __umulsidi3(u, v) \
|
|
({DWunion __w; \
|
|
umul_ppmm (__w.s.high, __w.s.low, u, v); \
|
|
__w.ll; })
|
|
#endif
|
|
|
|
/* Define this unconditionally, so it can be used for debugging. */
|
|
#define __udiv_qrnnd_c(q, r, n1, n0, d) \
|
|
do { \
|
|
UWtype __d1, __d0, __q1, __q0; \
|
|
UWtype __r1, __r0, __m; \
|
|
__d1 = __ll_highpart (d); \
|
|
__d0 = __ll_lowpart (d); \
|
|
\
|
|
__r1 = (n1) % __d1; \
|
|
__q1 = (n1) / __d1; \
|
|
__m = (UWtype) __q1 * __d0; \
|
|
__r1 = __r1 * __ll_B | __ll_highpart (n0); \
|
|
if (__r1 < __m) \
|
|
{ \
|
|
__q1--, __r1 += (d); \
|
|
if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
|
|
if (__r1 < __m) \
|
|
__q1--, __r1 += (d); \
|
|
} \
|
|
__r1 -= __m; \
|
|
\
|
|
__r0 = __r1 % __d1; \
|
|
__q0 = __r1 / __d1; \
|
|
__m = (UWtype) __q0 * __d0; \
|
|
__r0 = __r0 * __ll_B | __ll_lowpart (n0); \
|
|
if (__r0 < __m) \
|
|
{ \
|
|
__q0--, __r0 += (d); \
|
|
if (__r0 >= (d)) \
|
|
if (__r0 < __m) \
|
|
__q0--, __r0 += (d); \
|
|
} \
|
|
__r0 -= __m; \
|
|
\
|
|
(q) = (UWtype) __q1 * __ll_B | __q0; \
|
|
(r) = __r0; \
|
|
} while (0)
|
|
|
|
/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
|
|
__udiv_w_sdiv (defined in libgcc or elsewhere). */
|
|
#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
|
|
#define udiv_qrnnd(q, r, nh, nl, d) \
|
|
do { \
|
|
USItype __r; \
|
|
(q) = __udiv_w_sdiv (&__r, nh, nl, d); \
|
|
(r) = __r; \
|
|
} while (0)
|
|
#endif
|
|
|
|
/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
|
|
#if !defined (udiv_qrnnd)
|
|
#define UDIV_NEEDS_NORMALIZATION 1
|
|
#define udiv_qrnnd __udiv_qrnnd_c
|
|
#endif
|
|
|
|
#if !defined (count_leading_zeros)
|
|
#define count_leading_zeros(count, x) \
|
|
do { \
|
|
UWtype __xr = (x); \
|
|
UWtype __a; \
|
|
\
|
|
if (W_TYPE_SIZE <= 32) \
|
|
{ \
|
|
__a = __xr < ((UWtype)1<<2*__BITS4) \
|
|
? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \
|
|
: (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
|
|
} \
|
|
else \
|
|
{ \
|
|
for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
|
|
if (((__xr >> __a) & 0xff) != 0) \
|
|
break; \
|
|
} \
|
|
\
|
|
(count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
|
|
} while (0)
|
|
#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
|
|
#endif
|
|
|
|
#if !defined (count_trailing_zeros)
|
|
/* Define count_trailing_zeros using count_leading_zeros. The latter might be
|
|
defined in asm, but if it is not, the C version above is good enough. */
|
|
#define count_trailing_zeros(count, x) \
|
|
do { \
|
|
UWtype __ctz_x = (x); \
|
|
UWtype __ctz_c; \
|
|
count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
|
|
(count) = W_TYPE_SIZE - 1 - __ctz_c; \
|
|
} while (0)
|
|
#endif
|
|
|
|
#ifndef UDIV_NEEDS_NORMALIZATION
|
|
#define UDIV_NEEDS_NORMALIZATION 0
|
|
#endif
|