mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
libgcc _BitInt helper documentation [PR102989]
On Mon, Aug 21, 2023 at 05:32:04PM +0000, Joseph Myers wrote: > I think the libgcc functions (i.e. those exported by libgcc, to which > references are generated by the compiler) need documenting in libgcc.texi. > Internal functions or macros in the libgcc patch need appropriate comments > specifying their semantics; especially FP_TO_BITINT and FP_FROM_BITINT > which have a lot of arguments and no comments saying what the semantics of > the macros and their arguments are supposed to me. Here is an incremental patch which does that. 2023-09-06 Jakub Jelinek <jakub@redhat.com> PR c/102989 gcc/ * doc/libgcc.texi (Bit-precise integer arithmetic functions): Document general rules for _BitInt support library functions and document __mulbitint3 and __divmodbitint4. (Conversion functions): Document __fix{s,d,x,t}fbitint, __floatbitint{s,d,x,t,h,b}f, __bid_fix{s,d,t}dbitint and __bid_floatbitint{s,d,t}d. libgcc/ * libgcc2.c (bitint_negate): Add function comment. * soft-fp/bitint.h (bitint_negate): Add function comment. (FP_TO_BITINT, FP_FROM_BITINT): Add comment explaining the macros.
This commit is contained in:
parent
f76ae4369c
commit
f6e0ec5696
@ -218,6 +218,51 @@ These functions return the number of bits set in @var{a}.
|
||||
These functions return the @var{a} byteswapped.
|
||||
@end deftypefn
|
||||
|
||||
@subsection Bit-precise integer arithmetic functions
|
||||
|
||||
@code{_BitInt(@var{n})} library functions operate on arrays of limbs, where
|
||||
each limb has @code{__LIBGCC_BITINT_LIMB_WIDTH__} bits and the limbs are
|
||||
ordered according to @code{__LIBGCC_BITINT_ORDER__} ordering. The most
|
||||
significant limb if @var{n} is not divisible by
|
||||
@code{__LIBGCC_BITINT_LIMB_WIDTH__} contains padding bits which should be
|
||||
ignored on read (sign or zero extended), but extended on write. For the
|
||||
library functions, all bit-precise integers regardless of @var{n} are
|
||||
represented like that, even when the target ABI says that for some small
|
||||
@var{n} they should be represented differently in memory. A pointer
|
||||
to the array of limbs argument is always accompanied with a bit size
|
||||
argument. If that argument is positive, it is number of bits and the
|
||||
number is assumed to be zero-extended to infinite precision, if that
|
||||
argument is negative, it is negated number of bits above which all bits
|
||||
are assumed to be sign-extended to infinite precision. These number of bits
|
||||
arguments don't need to match actual @var{n} for the operation used in the
|
||||
source, they could be lowered because of sign or zero extensions on the
|
||||
input or because value-range optimization figures value will need certain
|
||||
lower number of bits. For big-endian ordering of limbs, when lowering
|
||||
the bit size argument the pointer argument needs to be adjusted as well.
|
||||
Negative bit size argument should be always smaller or equal to @code{-2},
|
||||
because @code{signed _BitInt(1)} is not valid.
|
||||
For output arguments, either the corresponding bit size argument should
|
||||
be always positive (for multiplication and division), or is negative when
|
||||
the output of conversion from floating-point value is signed and positive
|
||||
when unsigned. The arrays of limbs output arguments point to should not
|
||||
overlap any inputs, while input arrays of limbs can overlap.
|
||||
@code{UBILtype} below stands for unsigned integer type with
|
||||
@code{__LIBGCC_BITINT_LIMB_WIDTH__} bit precision.
|
||||
|
||||
@deftypefn {Runtime Function} void __mulbitint3 (@code{UBILtype} *@var{ret}, int32_t @var{retprec}, const @code{UBILtype} *u, int32_t @var{uprec}, const @code{UBILtype} *v, int32_t @var{vprec})
|
||||
This function multiplies bit-precise integer operands @var{u} and @var{v} and stores
|
||||
result into @var{retprec} precision bit-precise integer result @var{ret}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Runtime Function} void __divmodbitint4 (@code{UBILtype} *@var{q}, int32_t @var{qprec}, @code{UBILtype} *@var{r}, int32_t @var{rprec}, const @code{UBILtype} *u, int32_t @var{uprec}, const @code{UBILtype} *v, int32_t @var{vprec})
|
||||
This function divides bit-precise integer operands @var{u} and @var{v} and stores
|
||||
quotient into @var{qprec} precision bit-precise integer result @var{q}
|
||||
(unless @var{q} is @code{NULL} and @var{qprec} is 0, in that case quotient
|
||||
is not stored anywhere) and remainder into @var{rprec} precision bit-precise
|
||||
integer result @var{r} (similarly, unless @var{r} is @code{NULL} and @var{rprec}
|
||||
is 0).
|
||||
@end deftypefn
|
||||
|
||||
@node Soft float library routines
|
||||
@section Routines for floating point emulation
|
||||
@cindex soft float library
|
||||
@ -384,6 +429,27 @@ These functions convert @var{i}, an unsigned long, to floating point.
|
||||
These functions convert @var{i}, an unsigned long long, to floating point.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Runtime Function} void __fixsfbitint (@code{UBILtype} *@var{r}, int32_t @var{rprec}, float @var{a})
|
||||
@deftypefnx {Runtime Function} void __fixdfbitint (@code{UBILtype} *@var{r}, int32_t @var{rprec}, double @var{a})
|
||||
@deftypefnx {Runtime Function} void __fixxfbitint (@code{UBILtype} *@var{r}, int32_t @var{rprec}, __float80 @var{a})
|
||||
@deftypefnx {Runtime Function} void __fixtfbitint (@code{UBILtype} *@var{r}, int32_t @var{rprec}, _Float128 @var{a})
|
||||
These functions convert @var{a} to bit-precise integer @var{r}, rounding toward zero.
|
||||
If @var{rprec} is positive, it converts to unsigned bit-precise integer and
|
||||
negative values all become zero, if @var{rprec} is negative, it converts
|
||||
to signed bit-precise integer.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Runtime Function} float __floatbitintsf (@code{UBILtype} *@var{i}, int32_t @var{iprec})
|
||||
@deftypefnx {Runtime Function} double __floatbitintdf (@code{UBILtype} *@var{i}, int32_t @var{iprec})
|
||||
@deftypefnx {Runtime Function} __float80 __floatbitintxf (@code{UBILtype} *@var{i}, int32_t @var{iprec})
|
||||
@deftypefnx {Runtime Function} _Float128 __floatbitinttf (@code{UBILtype} *@var{i}, int32_t @var{iprec})
|
||||
@deftypefnx {Runtime Function} _Float16 __floatbitinthf (@code{UBILtype} *@var{i}, int32_t @var{iprec})
|
||||
@deftypefnx {Runtime Function} __bf16 __floatbitintbf (@code{UBILtype} *@var{i}, int32_t @var{iprec})
|
||||
These functions convert bit-precise integer @var{i} to floating point. If
|
||||
@var{iprec} is positive, it is conversion from unsigned bit-precise integer,
|
||||
otherwise from signed bit-precise integer.
|
||||
@end deftypefn
|
||||
|
||||
@subsection Comparison functions
|
||||
|
||||
There are two sets of basic comparison functions.
|
||||
@ -707,6 +773,23 @@ These functions convert @var{i}, an unsigned integer, to decimal floating point.
|
||||
These functions convert @var{i}, an unsigned long, to decimal floating point.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Runtime Function} void __bid_fixsdbitint (@code{UBILtype} *@var{r}, int32_t @var{rprec}, _Decimal32 @var{a})
|
||||
@deftypefnx {Runtime Function} void __bid_fixddbitint (@code{UBILtype} *@var{r}, int32_t @var{rprec}, _Decimal64 @var{a})
|
||||
@deftypefnx {Runtime Function} void __bid_fixtdbitint (@code{UBILtype} *@var{r}, int32_t @var{rprec}, _Decimal128 @var{a})
|
||||
These functions convert @var{a} to bit-precise integer @var{r}, rounding toward zero.
|
||||
If @var{rprec} is positive, it converts to unsigned bit-precise integer and
|
||||
negative values all become zero, if @var{rprec} is negative, it converts
|
||||
to signed bit-precise integer. So far implemented for BID format only.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Runtime Function} _Decimal32 __bid_floatbitintsd (@code{UBILtype} *@var{i}, int32_t @var{iprec})
|
||||
@deftypefnx {Runtime Function} _Decimal64 __bid_floatbitintdd (@code{UBILtype} *@var{i}, int32_t @var{iprec})
|
||||
@deftypefnx {Runtime Function} _Decimal128 __bid_floatbitinttd (@code{UBILtype} *@var{i}, int32_t @var{iprec})
|
||||
These functions convert bit-precise integer @var{i} to decimal floating point. If
|
||||
@var{iprec} is positive, it is conversion from unsigned bit-precise integer,
|
||||
otherwise from signed bit-precise integer. So far implemented for BID format only.
|
||||
@end deftypefn
|
||||
|
||||
@subsection Comparison functions
|
||||
|
||||
@deftypefn {Runtime Function} int __dpd_unordsd2 (_Decimal32 @var{a}, _Decimal32 @var{b})
|
||||
|
@ -1640,6 +1640,8 @@ __mulbitint3 (UWtype *ret, SItype retprec,
|
||||
#endif
|
||||
|
||||
#ifdef L_divmodbitint4
|
||||
/* D = -S. */
|
||||
|
||||
static void
|
||||
bitint_negate (UWtype *d, const UWtype *s, SItype n)
|
||||
{
|
||||
|
@ -160,6 +160,9 @@ bitint_reduce_prec (const UBILtype **p, SItype prec)
|
||||
# define BITINT_END(be, le) (le)
|
||||
#endif
|
||||
|
||||
/* Negate N limbs from S into D. D and S should point to
|
||||
the least significant limb. */
|
||||
|
||||
static inline __attribute__((__always_inline__)) void
|
||||
bitint_negate (UBILtype *d, const UBILtype *s, SItype n)
|
||||
{
|
||||
@ -175,6 +178,19 @@ bitint_negate (UBILtype *d, const UBILtype *s, SItype n)
|
||||
while (--n);
|
||||
}
|
||||
|
||||
/* Common final part of __fix?fbitint conversion functions.
|
||||
The A floating point value should have been converted using
|
||||
soft-fp macros into RV, U##DI##type DI##_BITS precise normal
|
||||
integral type and SHIFT, how many bits should that value be
|
||||
shifted to the left. R is pointer to limbs array passed to the
|
||||
function, RN number of limbs in it, ARPREC absolute value of
|
||||
RPREC argument passed to it, RSIZE number of significant bits in RV.
|
||||
RSIGNED is non-zero if the result is signed bit-precise integer,
|
||||
otherwise zero. If OVF is true, instead of storing RV shifted left
|
||||
by SHIFT bits and zero or sign extended store minimum or maximum
|
||||
of the signed or unsigned bit-precise integer type or zero depending on if
|
||||
RV contains the minimum or maximum signed or unsigned value or zero. */
|
||||
|
||||
#define FP_TO_BITINT(r, rn, arprec, shift, rv, rsize, rsigned, ovf, DI) \
|
||||
if (ovf) \
|
||||
{ \
|
||||
@ -232,6 +248,16 @@ bitint_negate (UBILtype *d, const UBILtype *s, SItype n)
|
||||
* sizeof (UBILtype)); \
|
||||
}
|
||||
|
||||
/* Common initial part of __floatbitint?f conversion functions.
|
||||
I and IPREC are arguments passed to those functions, convert that
|
||||
into a pair of DI##type IV integer and SHIFT, such that converting
|
||||
IV to floating point and multiplicating that by pow (2, SHIFT)
|
||||
gives the expected result. IV size needs to be chosen such that
|
||||
it is larger than number of bits in floating-point mantissa and
|
||||
contains there even at least a two bits below the mantissa for
|
||||
rounding purposes. If any of the SHIFT bits shifted out is non-zero,
|
||||
the least significant bit should be non-zero. */
|
||||
|
||||
#define FP_FROM_BITINT(i, iprec, iv, shift, DI) \
|
||||
do \
|
||||
{ \
|
||||
|
Loading…
Reference in New Issue
Block a user