Makefile.in (FPBIT_FUNCS, [...]): Define.
e * Makefile.in (FPBIT_FUNCS, DPBIT_FUNCS): Define. (libgcc2.a): Depend on $(DPBIT) and $(FPBIT). Add rules to generate more fine grained floating point emulation libraries. * config/fp-bit.c: Add protecting #ifdef to all functions so that they can be compiled separately. If !FINE_GRAINED_LIBRARIES, then compile all suitable functions. (pack_d, unpack_d, fpcmp_parts): Add declarations, define with two underscores to avoid namespace pollution. * t-mn10200 (LIB2FUNCS_EXTRA): Remove fp-bit.c (FPBIT): Define. * t-mn10300 (LIB2FUNCS_EXTRA): Remove fp-bit.c and dp-bit.c (FPBIT): Define. (DPBIT): Define. From-SVN: r17164
This commit is contained in:
parent
5198352eea
commit
a018144099
2 changed files with 125 additions and 19 deletions
|
@ -43,6 +43,55 @@ Boston, MA 02111-1307, USA. */
|
|||
/* The intended way to use this file is to make two copies, add `#define FLOAT'
|
||||
to one copy, then compile both copies and add them to libgcc.a. */
|
||||
|
||||
/* 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_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
|
||||
#endif
|
||||
|
||||
/* The following macros can be defined to change the behaviour of this file:
|
||||
FLOAT: Implement a `float', aka SFmode, fp library. If this is not
|
||||
defined, then this file implements a `double', aka DFmode, fp library.
|
||||
|
@ -141,8 +190,9 @@ typedef unsigned int UDItype __attribute__ ((mode (DI)));
|
|||
# define FRAC_NBITS 32
|
||||
# define FRACHIGH 0x80000000L
|
||||
# define FRACHIGH2 0xc0000000L
|
||||
# define pack_d pack_f
|
||||
# define unpack_d unpack_f
|
||||
# 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;
|
||||
|
@ -163,6 +213,9 @@ typedef unsigned int UDItype __attribute__ ((mode (DI)));
|
|||
# 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;
|
||||
|
@ -241,7 +294,7 @@ typedef unsigned int UDItype __attribute__ ((mode (DI)));
|
|||
/* 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::NGARGS-(float::FRAC_BITS-float::NGARDS))
|
||||
(double::FRAC_BITS+double::NGARDS-(float::FRAC_BITS-float::NGARDS))
|
||||
*/
|
||||
#define F_D_BITOFF (52+8-(23+7))
|
||||
|
||||
|
@ -370,7 +423,10 @@ flip_sign ( fp_number_type * x)
|
|||
x->sign = !x->sign;
|
||||
}
|
||||
|
||||
static FLO_type
|
||||
extern FLO_type pack_d ( fp_number_type * );
|
||||
|
||||
#if defined(L_pack_df) || defined(L_pack_sf)
|
||||
FLO_type
|
||||
pack_d ( fp_number_type * src)
|
||||
{
|
||||
FLO_union_type dst;
|
||||
|
@ -456,7 +512,7 @@ pack_d ( fp_number_type * src)
|
|||
}
|
||||
|
||||
/* We previously used bitfields to store the number, but this doesn't
|
||||
handle little/big endian systems conviently, so use shifts and
|
||||
handle little/big endian systems conveniently, so use shifts and
|
||||
masks */
|
||||
#ifdef FLOAT_BIT_ORDER_MISMATCH
|
||||
dst.bits.fraction = fraction;
|
||||
|
@ -478,12 +534,16 @@ pack_d ( fp_number_type * src)
|
|||
|
||||
return dst.value;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
extern void unpack_d (FLO_union_type *, fp_number_type *);
|
||||
|
||||
#if defined(L_unpack_df) || defined(L_unpack_sf)
|
||||
void
|
||||
unpack_d (FLO_union_type * src, fp_number_type * dst)
|
||||
{
|
||||
/* We previously used bitfields to store the number, but this doesn't
|
||||
handle little/big endian systems conviently, so use shifts and
|
||||
handle little/big endian systems conveniently, so use shifts and
|
||||
masks */
|
||||
fractype fraction;
|
||||
int exp;
|
||||
|
@ -566,7 +626,9 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
|
|||
dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_addsub_sf) || defined(L_addsub_df)
|
||||
static fp_number_type *
|
||||
_fpadd_parts (fp_number_type * a,
|
||||
fp_number_type * b,
|
||||
|
@ -734,8 +796,10 @@ sub (FLO_type arg_a, FLO_type arg_b)
|
|||
|
||||
return pack_d (res);
|
||||
}
|
||||
#endif
|
||||
|
||||
static fp_number_type *
|
||||
#if defined(L_mul_sf) || defined(L_mul_df)
|
||||
static INLINE fp_number_type *
|
||||
_fpmul_parts ( fp_number_type * a,
|
||||
fp_number_type * b,
|
||||
fp_number_type * tmp)
|
||||
|
@ -920,8 +984,10 @@ multiply (FLO_type arg_a, FLO_type arg_b)
|
|||
|
||||
return pack_d (res);
|
||||
}
|
||||
#endif
|
||||
|
||||
static fp_number_type *
|
||||
#if defined(L_div_sf) || defined(L_div_df)
|
||||
static INLINE fp_number_type *
|
||||
_fpdiv_parts (fp_number_type * a,
|
||||
fp_number_type * b,
|
||||
fp_number_type * tmp)
|
||||
|
@ -1033,15 +1099,19 @@ divide (FLO_type arg_a, FLO_type arg_b)
|
|||
|
||||
return pack_d (res);
|
||||
}
|
||||
#endif
|
||||
|
||||
int __fpcmp_parts (fp_number_type * a, fp_number_type *b);
|
||||
|
||||
#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df)
|
||||
/* according to the demo, fpcmp returns a comparison with 0... thus
|
||||
a<b -> -1
|
||||
a==b -> 0
|
||||
a>b -> +1
|
||||
*/
|
||||
|
||||
static int
|
||||
_fpcmp_parts (fp_number_type * a, fp_number_type * b)
|
||||
int
|
||||
__fpcmp_parts (fp_number_type * a, fp_number_type * b)
|
||||
{
|
||||
#if 0
|
||||
/* either nan -> unordered. Must be checked outside of this routine. */
|
||||
|
@ -1116,7 +1186,9 @@ _fpcmp_parts (fp_number_type * a, fp_number_type * b)
|
|||
/* after all that, they're equal. */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_compare_sf) || defined(L_compare_df)
|
||||
CMPtype
|
||||
compare (FLO_type arg_a, FLO_type arg_b)
|
||||
{
|
||||
|
@ -1126,13 +1198,15 @@ compare (FLO_type arg_a, FLO_type arg_b)
|
|||
unpack_d ((FLO_union_type *) & arg_a, &a);
|
||||
unpack_d ((FLO_union_type *) & arg_b, &b);
|
||||
|
||||
return _fpcmp_parts (&a, &b);
|
||||
return __fpcmp_parts (&a, &b);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef US_SOFTWARE_GOFAST
|
||||
|
||||
/* These should be optimized for their specific tasks someday. */
|
||||
|
||||
#if defined(L_eq_sf) || defined(L_eq_df)
|
||||
CMPtype
|
||||
_eq_f2 (FLO_type arg_a, FLO_type arg_b)
|
||||
{
|
||||
|
@ -1145,9 +1219,11 @@ _eq_f2 (FLO_type arg_a, FLO_type arg_b)
|
|||
if (isnan (&a) || isnan (&b))
|
||||
return 1; /* false, truth == 0 */
|
||||
|
||||
return _fpcmp_parts (&a, &b) ;
|
||||
return __fpcmp_parts (&a, &b) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_ne_sf) || defined(L_ne_df)
|
||||
CMPtype
|
||||
_ne_f2 (FLO_type arg_a, FLO_type arg_b)
|
||||
{
|
||||
|
@ -1160,9 +1236,11 @@ _ne_f2 (FLO_type arg_a, FLO_type arg_b)
|
|||
if (isnan (&a) || isnan (&b))
|
||||
return 1; /* true, truth != 0 */
|
||||
|
||||
return _fpcmp_parts (&a, &b) ;
|
||||
return __fpcmp_parts (&a, &b) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_gt_sf) || defined(L_gt_df)
|
||||
CMPtype
|
||||
_gt_f2 (FLO_type arg_a, FLO_type arg_b)
|
||||
{
|
||||
|
@ -1175,9 +1253,11 @@ _gt_f2 (FLO_type arg_a, FLO_type arg_b)
|
|||
if (isnan (&a) || isnan (&b))
|
||||
return -1; /* false, truth > 0 */
|
||||
|
||||
return _fpcmp_parts (&a, &b);
|
||||
return __fpcmp_parts (&a, &b);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_ge_sf) || defined(L_ge_df)
|
||||
CMPtype
|
||||
_ge_f2 (FLO_type arg_a, FLO_type arg_b)
|
||||
{
|
||||
|
@ -1189,9 +1269,11 @@ _ge_f2 (FLO_type arg_a, FLO_type arg_b)
|
|||
|
||||
if (isnan (&a) || isnan (&b))
|
||||
return -1; /* false, truth >= 0 */
|
||||
return _fpcmp_parts (&a, &b) ;
|
||||
return __fpcmp_parts (&a, &b) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_lt_sf) || defined(L_lt_df)
|
||||
CMPtype
|
||||
_lt_f2 (FLO_type arg_a, FLO_type arg_b)
|
||||
{
|
||||
|
@ -1204,9 +1286,11 @@ _lt_f2 (FLO_type arg_a, FLO_type arg_b)
|
|||
if (isnan (&a) || isnan (&b))
|
||||
return 1; /* false, truth < 0 */
|
||||
|
||||
return _fpcmp_parts (&a, &b);
|
||||
return __fpcmp_parts (&a, &b);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_le_sf) || defined(L_le_df)
|
||||
CMPtype
|
||||
_le_f2 (FLO_type arg_a, FLO_type arg_b)
|
||||
{
|
||||
|
@ -1219,11 +1303,13 @@ _le_f2 (FLO_type arg_a, FLO_type arg_b)
|
|||
if (isnan (&a) || isnan (&b))
|
||||
return 1; /* false, truth <= 0 */
|
||||
|
||||
return _fpcmp_parts (&a, &b) ;
|
||||
return __fpcmp_parts (&a, &b) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! US_SOFTWARE_GOFAST */
|
||||
|
||||
#if defined(L_si_to_sf) || defined(L_si_to_df)
|
||||
FLO_type
|
||||
si_to_float (SItype arg_a)
|
||||
{
|
||||
|
@ -1259,7 +1345,9 @@ si_to_float (SItype arg_a)
|
|||
}
|
||||
return pack_d (&in);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_sf_to_si) || defined(L_df_to_si)
|
||||
SItype
|
||||
float_to_si (FLO_type arg_a)
|
||||
{
|
||||
|
@ -1282,7 +1370,9 @@ float_to_si (FLO_type arg_a)
|
|||
tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
|
||||
return a.sign ? (-tmp) : (tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(L_sf_to_usi) || defined(L_df_to_usi)
|
||||
#ifdef US_SOFTWARE_GOFAST
|
||||
/* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
|
||||
we also define them for GOFAST because the ones in libgcc2.c have the
|
||||
|
@ -1317,7 +1407,9 @@ float_to_usi (FLO_type arg_a)
|
|||
return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(L_negate_sf) || defined(L_negate_df)
|
||||
FLO_type
|
||||
negate (FLO_type arg_a)
|
||||
{
|
||||
|
@ -1327,9 +1419,11 @@ negate (FLO_type arg_a)
|
|||
flip_sign (&a);
|
||||
return pack_d (&a);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FLOAT
|
||||
|
||||
#if defined(L_make_sf)
|
||||
SFtype
|
||||
__make_fp(fp_class_type class,
|
||||
unsigned int sign,
|
||||
|
@ -1344,6 +1438,7 @@ __make_fp(fp_class_type class,
|
|||
in.fraction.ll = frac;
|
||||
return pack_d (&in);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef FLOAT_ONLY
|
||||
|
||||
|
@ -1354,6 +1449,7 @@ __make_fp(fp_class_type class,
|
|||
|
||||
extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype frac);
|
||||
|
||||
#if defined(L_sf_to_df)
|
||||
DFtype
|
||||
sf_to_df (SFtype arg_a)
|
||||
{
|
||||
|
@ -1363,6 +1459,7 @@ sf_to_df (SFtype arg_a)
|
|||
return __make_dp (in.class, in.sign, in.normal_exp,
|
||||
((UDItype) in.fraction.ll) << F_D_BITOFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1371,6 +1468,7 @@ sf_to_df (SFtype arg_a)
|
|||
|
||||
extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
|
||||
|
||||
#if defined(L_make_df)
|
||||
DFtype
|
||||
__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
|
||||
{
|
||||
|
@ -1382,7 +1480,9 @@ __make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
|
|||
in.fraction.ll = frac;
|
||||
return pack_d (&in);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (L_df_to_sf)
|
||||
SFtype
|
||||
df_to_sf (DFtype arg_a)
|
||||
{
|
||||
|
@ -1400,6 +1500,7 @@ df_to_sf (DFtype arg_a)
|
|||
|
||||
return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* !EXTENDED_FLOAT_STUBS */
|
||||
|
|
|
@ -36,9 +36,14 @@ LIB1ASMFUNCS = _divhi3 \
|
|||
|
||||
# We do not have DF or DI types, so fake out the libgcc2 compilation.
|
||||
TARGET_LIBGCC2_CFLAGS=-DDF=SF -DDI=SI
|
||||
LIB2FUNCS_EXTRA = fp-bit.c $(srcdir)/config/mn10200/udivmodsi4.c \
|
||||
LIB2FUNCS_EXTRA = $(srcdir)/config/mn10200/udivmodsi4.c \
|
||||
$(srcdir)/config/mn10200/divmod.c $(srcdir)/config/mn10200/udivmod.c
|
||||
|
||||
# We want fine grained libraries, so use the new code to build the
|
||||
# floating point emulation libraries. The mn10200 only has single
|
||||
# precision floating point.
|
||||
FPBIT = fp-bit.c
|
||||
|
||||
fp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#define FLOAT' > fp-bit.c
|
||||
echo '#define FLOAT_ONLY' >> fp-bit.c
|
||||
|
|
Loading…
Add table
Reference in a new issue