|  | /* Header file for fp-bit.c.  */ | 
|  | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | 
|  |  | 
|  | This file is part of GCC. | 
|  |  | 
|  | GCC is free software; you can redistribute it and/or modify it under | 
|  | the terms of the GNU General Public License as published by the Free | 
|  | Software Foundation; either version 3, or (at your option) any later | 
|  | version. | 
|  |  | 
|  | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | 
|  | WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|  | FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|  | for more details. | 
|  |  | 
|  | Under Section 7 of GPL version 3, you are granted additional | 
|  | permissions described in the GCC Runtime Library Exception, version | 
|  | 3.1, as published by the Free Software Foundation. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License and | 
|  | a copy of the GCC Runtime Library Exception along with this program; | 
|  | see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see | 
|  | <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | #ifndef GCC_FP_BIT_H | 
|  | #define GCC_FP_BIT_H | 
|  |  | 
|  | /* Defining FINE_GRAINED_LIBRARIES allows one to select which routines | 
|  | from this file are compiled via additional -D options. | 
|  |  | 
|  | This avoids the need to pull in the entire fp emulation library | 
|  | when only a small number of functions are needed. | 
|  |  | 
|  | If FINE_GRAINED_LIBRARIES is not defined, then compile every | 
|  | suitable routine.  */ | 
|  | #ifndef FINE_GRAINED_LIBRARIES | 
|  | #define L_pack_df | 
|  | #define L_unpack_df | 
|  | #define L_pack_sf | 
|  | #define L_unpack_sf | 
|  | #define L_addsub_sf | 
|  | #define L_addsub_df | 
|  | #define L_mul_sf | 
|  | #define L_mul_df | 
|  | #define L_div_sf | 
|  | #define L_div_df | 
|  | #define L_fpcmp_parts_sf | 
|  | #define L_fpcmp_parts_df | 
|  | #define L_compare_sf | 
|  | #define L_compare_df | 
|  | #define L_eq_sf | 
|  | #define L_eq_df | 
|  | #define L_ne_sf | 
|  | #define L_ne_df | 
|  | #define L_gt_sf | 
|  | #define L_gt_df | 
|  | #define L_ge_sf | 
|  | #define L_ge_df | 
|  | #define L_lt_sf | 
|  | #define L_lt_df | 
|  | #define L_le_sf | 
|  | #define L_le_df | 
|  | #define L_unord_sf | 
|  | #define L_unord_df | 
|  | #define L_usi_to_sf | 
|  | #define L_usi_to_df | 
|  | #define L_si_to_sf | 
|  | #define L_si_to_df | 
|  | #define L_sf_to_si | 
|  | #define L_df_to_si | 
|  | #define L_f_to_usi | 
|  | #define L_df_to_usi | 
|  | #define L_negate_sf | 
|  | #define L_negate_df | 
|  | #define L_make_sf | 
|  | #define L_make_df | 
|  | #define L_sf_to_df | 
|  | #define L_df_to_sf | 
|  | #ifdef FLOAT | 
|  | #define L_thenan_sf | 
|  | #else | 
|  | #define L_thenan_df | 
|  | #endif | 
|  | #endif /* ! FINE_GRAINED_LIBRARIES */ | 
|  |  | 
|  | #if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106 | 
|  | # if defined(TFLOAT) || defined(L_sf_to_tf) || defined(L_df_to_tf) | 
|  | #  define TMODES | 
|  | # endif | 
|  | #endif | 
|  |  | 
|  | typedef float SFtype __attribute__ ((mode (SF))); | 
|  | typedef float DFtype __attribute__ ((mode (DF))); | 
|  | #ifdef TMODES | 
|  | typedef float TFtype __attribute__ ((mode (TF))); | 
|  | #endif | 
|  |  | 
|  | typedef int HItype __attribute__ ((mode (HI))); | 
|  | typedef int SItype __attribute__ ((mode (SI))); | 
|  | typedef int DItype __attribute__ ((mode (DI))); | 
|  | #ifdef TMODES | 
|  | typedef int TItype __attribute__ ((mode (TI))); | 
|  | #endif | 
|  |  | 
|  | /* The type of the result of a floating point comparison.  This must | 
|  | match `__libgcc_cmp_return__' in GCC for the target.  */ | 
|  | #ifndef CMPtype | 
|  | typedef int CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); | 
|  | #endif | 
|  |  | 
|  | typedef unsigned int UHItype __attribute__ ((mode (HI))); | 
|  | typedef unsigned int USItype __attribute__ ((mode (SI))); | 
|  | typedef unsigned int UDItype __attribute__ ((mode (DI))); | 
|  | #ifdef TMODES | 
|  | typedef unsigned int UTItype __attribute__ ((mode (TI))); | 
|  | #endif | 
|  |  | 
|  | #define MAX_USI_INT  (~(USItype)0) | 
|  | #define MAX_SI_INT   ((SItype) (MAX_USI_INT >> 1)) | 
|  | #define BITS_PER_SI  (4 * __CHAR_BIT__) | 
|  | #ifdef TMODES | 
|  | #define MAX_UDI_INT  (~(UDItype)0) | 
|  | #define MAX_DI_INT   ((DItype) (MAX_UDI_INT >> 1)) | 
|  | #define BITS_PER_DI  (8 * __CHAR_BIT__) | 
|  | #endif | 
|  |  | 
|  | #ifdef FLOAT_ONLY | 
|  | #define NO_DI_MODE | 
|  | #endif | 
|  |  | 
|  | #if __BYTE_ORDER__ != __FLOAT_WORD_ORDER__ | 
|  | #define FLOAT_WORD_ORDER_MISMATCH | 
|  | #endif | 
|  |  | 
|  | #ifdef TFLOAT | 
|  | # ifndef TMODES | 
|  | #  error "TFLOAT requires long double to have 113 bits of mantissa" | 
|  | # endif | 
|  |  | 
|  | #	define PREFIXFPDP tp | 
|  | #	define PREFIXSFDF tf | 
|  | #	define NGARDS 10L /* Is this right? */ | 
|  | #	define GARDROUND 0x1ff | 
|  | #	define GARDMASK  0x3ff | 
|  | #	define GARDMSB   0x200 | 
|  | #	define FRAC_NBITS 128 | 
|  |  | 
|  | # if __LDBL_MANT_DIG__ == 113 /* IEEE quad */ | 
|  | #	define EXPBITS 15 | 
|  | #	define EXPBIAS 16383 | 
|  | #	define EXPMAX (0x7fff) | 
|  | #	define QUIET_NAN ((TItype)0x8 << 108) | 
|  | #	define FRACHIGH  ((TItype)0x8 << 124) | 
|  | #	define FRACHIGH2 ((TItype)0xc << 124) | 
|  | #	define FRACBITS 112 | 
|  | # endif | 
|  |  | 
|  | # if __LDBL_MANT_DIG__ == 106 /* IBM extended (double+double) */ | 
|  | #	define EXPBITS 11 | 
|  | #	define EXPBIAS 1023 | 
|  | #	define EXPMAX (0x7ff) | 
|  | #	define QUIET_NAN ((TItype)0x8 << (48 + 64)) | 
|  | #	define FRACHIGH  ((TItype)0x8 << 124) | 
|  | #	define FRACHIGH2 ((TItype)0xc << 124) | 
|  | #	define FRACBITS 105 | 
|  | #	define HALFFRACBITS 52 | 
|  | #	define HALFSHIFT 64 | 
|  | # endif | 
|  |  | 
|  | #	define pack_d __pack_t | 
|  | #	define unpack_d __unpack_t | 
|  | #	define __fpcmp_parts __fpcmp_parts_t | 
|  | typedef UTItype fractype; | 
|  | typedef UDItype halffractype; | 
|  | typedef USItype qrtrfractype; | 
|  | #define qrtrfractype qrtrfractype | 
|  | typedef TFtype FLO_type; | 
|  | typedef TItype intfrac; | 
|  | #elif defined FLOAT | 
|  | #	define NGARDS    7L | 
|  | #	define GARDROUND 0x3f | 
|  | #	define GARDMASK  0x7f | 
|  | #	define GARDMSB   0x40 | 
|  | #	define EXPBITS 8 | 
|  | #	define EXPBIAS 127 | 
|  | #	define FRACBITS 23 | 
|  | #	define EXPMAX (0xff) | 
|  | #	define QUIET_NAN 0x400000L | 
|  | #	define FRAC_NBITS 32 | 
|  | #	define FRACHIGH  0x80000000L | 
|  | #	define FRACHIGH2 0xc0000000L | 
|  | #	define pack_d __pack_f | 
|  | #	define unpack_d __unpack_f | 
|  | #	define __fpcmp_parts __fpcmp_parts_f | 
|  | typedef USItype fractype; | 
|  | typedef UHItype halffractype; | 
|  | typedef SFtype FLO_type; | 
|  | typedef SItype intfrac; | 
|  |  | 
|  | #else | 
|  | #	define PREFIXFPDP dp | 
|  | #	define PREFIXSFDF df | 
|  | #	define NGARDS 8L | 
|  | #	define GARDROUND 0x7f | 
|  | #	define GARDMASK  0xff | 
|  | #	define GARDMSB   0x80 | 
|  | #	define EXPBITS 11 | 
|  | #	define EXPBIAS 1023 | 
|  | #	define FRACBITS 52 | 
|  | #	define EXPMAX (0x7ff) | 
|  | #	define QUIET_NAN 0x8000000000000LL | 
|  | #	define FRAC_NBITS 64 | 
|  | #	define FRACHIGH  0x8000000000000000LL | 
|  | #	define FRACHIGH2 0xc000000000000000LL | 
|  | #	define pack_d __pack_d | 
|  | #	define unpack_d __unpack_d | 
|  | #	define __fpcmp_parts __fpcmp_parts_d | 
|  | typedef UDItype fractype; | 
|  | typedef USItype halffractype; | 
|  | typedef DFtype FLO_type; | 
|  | typedef DItype intfrac; | 
|  | #endif /* FLOAT */ | 
|  |  | 
|  | #ifdef TFLOAT | 
|  | #	define add 		__addtf3 | 
|  | #	define sub 		__subtf3 | 
|  | #	define multiply 	__multf3 | 
|  | #	define divide 		__divtf3 | 
|  | #	define compare 		__cmptf2 | 
|  | #	define _eq_f2 		__eqtf2 | 
|  | #	define _ne_f2 		__netf2 | 
|  | #	define _gt_f2 		__gttf2 | 
|  | #	define _ge_f2 		__getf2 | 
|  | #	define _lt_f2 		__lttf2 | 
|  | #	define _le_f2 		__letf2 | 
|  | #	define _unord_f2	__unordtf2 | 
|  | #	define usi_to_float 	__floatunsitf | 
|  | #	define si_to_float 	__floatsitf | 
|  | #	define float_to_si 	__fixtfsi | 
|  | #	define float_to_usi 	__fixunstfsi | 
|  | #	define negate 		__negtf2 | 
|  | #	define tf_to_sf		__trunctfsf2 | 
|  | #	define tf_to_df		__trunctfdf2 | 
|  | #elif defined FLOAT | 
|  | #	define add 		__addsf3 | 
|  | #	define sub 		__subsf3 | 
|  | #	define multiply 	__mulsf3 | 
|  | #	define divide 		__divsf3 | 
|  | #	define compare 		__cmpsf2 | 
|  | #	define _eq_f2 		__eqsf2 | 
|  | #	define _ne_f2 		__nesf2 | 
|  | #	define _gt_f2 		__gtsf2 | 
|  | #	define _ge_f2 		__gesf2 | 
|  | #	define _lt_f2 		__ltsf2 | 
|  | #	define _le_f2 		__lesf2 | 
|  | #	define _unord_f2	__unordsf2 | 
|  | #	define usi_to_float 	__floatunsisf | 
|  | #	define si_to_float 	__floatsisf | 
|  | #	define float_to_si 	__fixsfsi | 
|  | #	define float_to_usi 	__fixunssfsi | 
|  | #	define negate 		__negsf2 | 
|  | #	define sf_to_df		__extendsfdf2 | 
|  | #	define sf_to_tf		__extendsftf2 | 
|  | #else | 
|  | #	define add 		__adddf3 | 
|  | #	define sub 		__subdf3 | 
|  | #	define multiply 	__muldf3 | 
|  | #	define divide 		__divdf3 | 
|  | #	define compare 		__cmpdf2 | 
|  | #	define _eq_f2 		__eqdf2 | 
|  | #	define _ne_f2 		__nedf2 | 
|  | #	define _gt_f2 		__gtdf2 | 
|  | #	define _ge_f2 		__gedf2 | 
|  | #	define _lt_f2 		__ltdf2 | 
|  | #	define _le_f2 		__ledf2 | 
|  | #	define _unord_f2	__unorddf2 | 
|  | #	define usi_to_float 	__floatunsidf | 
|  | #	define si_to_float 	__floatsidf | 
|  | #	define float_to_si 	__fixdfsi | 
|  | #	define float_to_usi 	__fixunsdfsi | 
|  | #	define negate 		__negdf2 | 
|  | #	define df_to_sf		__truncdfsf2 | 
|  | #	define df_to_tf		__extenddftf2 | 
|  | #endif /* FLOAT */ | 
|  |  | 
|  | #ifndef INLINE | 
|  | #define INLINE __inline__ | 
|  | #endif | 
|  |  | 
|  | /* Preserve the sticky-bit when shifting fractions to the right.  */ | 
|  | #define LSHIFT(a, s) { a = (a >> s) | !!(a & (((fractype) 1 << s) - 1)); } | 
|  |  | 
|  | /* numeric parameters */ | 
|  | /* F_D_BITOFF is the number of bits offset between the MSB of the mantissa | 
|  | of a float and of a double. Assumes there are only two float types. | 
|  | (double::FRAC_BITS+double::NGARDS-(float::FRAC_BITS+float::NGARDS)) | 
|  | */ | 
|  | #define F_D_BITOFF (52+8-(23+7)) | 
|  |  | 
|  | #ifdef TMODES | 
|  | # define F_T_BITOFF (__LDBL_MANT_DIG__-1+10-(23+7)) | 
|  | # define D_T_BITOFF (__LDBL_MANT_DIG__-1+10-(52+8)) | 
|  | #endif | 
|  |  | 
|  |  | 
|  | #define NORMAL_EXPMIN (-(EXPBIAS)+1) | 
|  | #define IMPLICIT_1 ((fractype)1<<(FRACBITS+NGARDS)) | 
|  | #define IMPLICIT_2 ((fractype)1<<(FRACBITS+1+NGARDS)) | 
|  |  | 
|  | /* common types */ | 
|  |  | 
|  | typedef enum | 
|  | { | 
|  | CLASS_SNAN, | 
|  | CLASS_QNAN, | 
|  | CLASS_ZERO, | 
|  | CLASS_NUMBER, | 
|  | CLASS_INFINITY | 
|  | } fp_class_type; | 
|  |  | 
|  | typedef struct | 
|  | { | 
|  | #ifdef SMALL_MACHINE | 
|  | char class; | 
|  | unsigned char sign; | 
|  | short normal_exp; | 
|  | #else | 
|  | fp_class_type class; | 
|  | unsigned int sign; | 
|  | int normal_exp; | 
|  | #endif | 
|  |  | 
|  | union | 
|  | { | 
|  | fractype ll; | 
|  | halffractype l[2]; | 
|  | } fraction; | 
|  | } fp_number_type; | 
|  |  | 
|  | typedef union | 
|  | { | 
|  | FLO_type value; | 
|  | fractype value_raw; | 
|  |  | 
|  | #ifndef FLOAT | 
|  | # ifdef qrtrfractype | 
|  | qrtrfractype qwords[4]; | 
|  | # else | 
|  | halffractype words[2]; | 
|  | # endif | 
|  | #endif | 
|  |  | 
|  | #ifdef _DEBUG_BITFLOAT | 
|  | struct | 
|  | { | 
|  | unsigned int sign:1 __attribute__ ((packed)); | 
|  | unsigned int exp:EXPBITS __attribute__ ((packed)); | 
|  | fractype fraction:FRACBITS __attribute__ ((packed)); | 
|  | } | 
|  | bits_big_endian; | 
|  |  | 
|  | struct | 
|  | { | 
|  | fractype fraction:FRACBITS __attribute__ ((packed)); | 
|  | unsigned int exp:EXPBITS __attribute__ ((packed)); | 
|  | unsigned int sign:1 __attribute__ ((packed)); | 
|  | } | 
|  | bits_little_endian; | 
|  | #endif | 
|  | } | 
|  | FLO_union_type; | 
|  |  | 
|  | /* Prototypes.  */ | 
|  |  | 
|  | #if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf) | 
|  | extern FLO_type pack_d (const fp_number_type *); | 
|  | #endif | 
|  |  | 
|  | extern void unpack_d (FLO_union_type *, fp_number_type *); | 
|  |  | 
|  | #if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf) | 
|  | extern FLO_type add (FLO_type, FLO_type); | 
|  | extern FLO_type sub (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf) | 
|  | extern FLO_type multiply (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf) | 
|  | extern FLO_type divide (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | extern int __fpcmp_parts (fp_number_type *, fp_number_type *); | 
|  |  | 
|  | #if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compare_tf) | 
|  | extern CMPtype compare (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf) | 
|  | extern CMPtype _eq_f2 (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf) | 
|  | extern CMPtype _ne_f2 (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf) | 
|  | extern CMPtype _gt_f2 (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf) | 
|  | extern CMPtype _ge_f2 (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf) | 
|  | extern CMPtype _lt_f2 (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf) | 
|  | extern CMPtype _le_f2 (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf) | 
|  | extern CMPtype _unord_f2 (FLO_type, FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf) | 
|  | extern FLO_type si_to_float (SItype); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si) | 
|  | extern SItype float_to_si (FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_tf_to_usi) | 
|  | extern USItype float_to_usi (FLO_type); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf) | 
|  | extern FLO_type usi_to_float (USItype); | 
|  | #endif | 
|  |  | 
|  | #if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf) | 
|  | extern FLO_type negate (FLO_type); | 
|  | #endif | 
|  |  | 
|  | #ifdef FLOAT | 
|  | #if defined(L_make_sf) | 
|  | extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype); | 
|  | #endif | 
|  | #ifndef FLOAT_ONLY | 
|  | extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype); | 
|  | #if defined(L_sf_to_df) | 
|  | extern DFtype sf_to_df (SFtype); | 
|  | #endif | 
|  | #if defined(L_sf_to_tf) && defined(TMODES) | 
|  | extern TFtype sf_to_tf (SFtype); | 
|  | #endif | 
|  | #endif /* ! FLOAT_ONLY */ | 
|  | #endif /* FLOAT */ | 
|  |  | 
|  | #ifndef FLOAT | 
|  | extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype); | 
|  | #if defined(L_make_df) | 
|  | extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype); | 
|  | #endif | 
|  | #if defined(L_df_to_sf) | 
|  | extern SFtype df_to_sf (DFtype); | 
|  | #endif | 
|  | #if defined(L_df_to_tf) && defined(TMODES) | 
|  | extern TFtype df_to_tf (DFtype); | 
|  | #endif | 
|  | #endif /* ! FLOAT */ | 
|  |  | 
|  | #ifdef TMODES | 
|  | extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype); | 
|  | extern TFtype __make_tp (fp_class_type, unsigned int, int, UTItype); | 
|  | #ifdef TFLOAT | 
|  | #if defined(L_tf_to_sf) | 
|  | extern SFtype tf_to_sf (TFtype); | 
|  | #endif | 
|  | #if defined(L_tf_to_df) | 
|  | extern DFtype tf_to_df (TFtype); | 
|  | #endif | 
|  | #if defined(L_di_to_tf) | 
|  | extern TFtype di_to_df (DItype); | 
|  | #endif | 
|  | #endif /* TFLOAT */ | 
|  | #endif /* TMODES */ | 
|  |  | 
|  | #endif /* ! GCC_FP_BIT_H */ |