Add BID decimal support

Co-Authored-By: H.J. Lu <hongjiu.lu@intel.com>
Co-Authored-By: Marius Cornea <marius.cornea@intel.com>

From-SVN: r123185
This commit is contained in:
Michael Meissner 2007-03-24 17:04:47 +00:00 committed by Michael Meissner
parent cca643862d
commit 79b87c74d7
42 changed files with 12547 additions and 160 deletions

View File

@ -1,3 +1,68 @@
2007-03-23 Michael Meissner <michael.meissner@amd.com>
H.J. Lu <hongjiu.lu@intel.com>
* config/dfp-bit.h (DPD_BID_NAME): New macro to give either the
DPD or BID name.
(name macros): Use DPD_BID_NAME to convert names properly.
* optabs.c (DECIMAL_PREFIX): Prefix string to use for the current
decimal floating point format.
(init_floating_libfuncs): Change decimal functions so that they
have a "bid_" prefix if the decimal system uses the BID format,
and "dpd_" prefix if the decimal system uses the DPD format.
(init_interclass_conv_libfuncs): Ditto.
(init_intraclass_conv_libfuncs): Ditto.
* config.in (ENABLE_DECIMAL_BID_FORMAT): New macro to say we are
using the BID format.
* configure.ac (ENABLE_DECIMAL_BID_FORMAT): Set to 1/0 to say
whether we are using the BID decimal format.
* configure: Regenerate.
* c-cppbuiltin.c (c_cpp_builtins): Define __STDC_WANT_DEC_FP__ if
the compiler has decimal floating point enabled. Define
__DECIMAL_BID_FORMAT__ if BID decimal floating point is used
instead of DPD.
* config.in (ENABLE_DECIMAL_BID_FORMAT): New macro to say we are
using the BID format.
* configure.ac (ENABLE_DECIMAL_BID_FORMAT): Set to 1/0 to say
whether we are using the BID decimal format.
* configure: Regenerate.
* c-cppbuiltin.c (c_cpp_builtins): Define __STDC_WANT_DEC_FP__ if
the compiler has decimal floating point enabled. Define
__DECIMAL_BID_FORMAT__ if BID decimal floating point is used
instead of DPD.
* doc/install.texi (--enable-decimal-float): Document BID and DPD
options, and that it is enabled for i386/x86_64 systems.
* Makefile.in (enable_decimal_float): New.
(DECNUMFMT): New.
(DECNUMINC): Add -I$(DECNUMFMT).
(DECNUM_H): Mov decimal32.h, decimal64.h and decimal128.h
to $(DECNUMFMT) from $(DECNUM).
* configure.ac: Support * --enable-decimal-float={no,yes,bid,dpd}.
Substitute enable_decimal_float.
* configure: Regenerated.
PR other/30529
* config/dfp-bit.c (__dec_byte_swap): Use uint32_t instead of
unsigned long.
* configure.ac: Enable decimal float for x86_64-*-linux*.
* configure: Regenerated.
PR other/30530
* dfp.c (decimal_real_arithmetic): Use decimal128FlipSign and
decimal128ClearSign to flip and clear the sign bit in decimal128.
(decimal_real_maxval): Set decimal128SetSign to set the sign
bit in decimal128.
2007-03-23 Ian Lance Taylor <iant@google.com>
* fold-const.c (fold_binary): Correct warning for X - c >= X.

View File

@ -289,8 +289,10 @@ CPPLIB = ../libcpp/libcpp.a
CPPINC = -I$(srcdir)/../libcpp/include
# Where to find decNumber
enable_decimal_float = @enable_decimal_float@
DECNUM = $(srcdir)/../libdecnumber
DECNUMINC = -I$(DECNUM) -I../libdecnumber
DECNUMFMT = $(srcdir)/../libdecnumber/$(enable_decimal_float)
DECNUMINC = -I$(DECNUM) -I$(DECNUMFMT) -I../libdecnumber
LIBDECNUMBER = ../libdecnumber/libdecnumber.a
# Substitution type for target's getgroups 2nd arg.
@ -770,7 +772,7 @@ PREDICT_H = predict.h predict.def
CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \
$(srcdir)/../libcpp/include/cpplib.h
DECNUM_H = $(DECNUM)/decContext.h $(DECNUM)/decDPD.h $(DECNUM)/decNumber.h \
$(DECNUM)/decimal32.h $(DECNUM)/decimal64.h $(DECNUM)/decimal128.h
$(DECNUMFMT)/decimal32.h $(DECNUMFMT)/decimal64.h $(DECNUMFMT)/decimal128.h
MKDEPS_H = $(srcdir)/../libcpp/include/mkdeps.h
SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h
CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h

View File

@ -605,6 +605,17 @@ c_cpp_builtins (cpp_reader *pfile)
new appearance would clobber any existing args. */
if (TARGET_DECLSPEC)
builtin_define ("__declspec(x)=__attribute__((x))");
/* Tell the user whether decimal floating point is supported,
and if it is supported, whether the alternate format (BID)
is used over the standard (DPD) format. */
if (ENABLE_DECIMAL_FLOAT)
{
cpp_define (pfile, "__STDC_WANT_DEC_FP__");
if (ENABLE_DECIMAL_BID_FORMAT)
cpp_define (pfile, "__DECIMAL_BID_FORMAT__");
}
}
/* Pass an object-like macro. If it doesn't lie in the user's

View File

@ -52,6 +52,12 @@
#endif
/* Define to 1 to say we are using the BID decimal format */
#ifndef USED_FOR_TARGET
#undef ENABLE_DECIMAL_BID_FORMAT
#endif
/* Define if you want fold checked that it never destructs its argument. This
is quite expensive. */
#ifndef USED_FOR_TARGET

View File

@ -1,5 +1,5 @@
/* This is a software decimal floating point library.
Copyright (C) 2005, 2006 Free Software Foundation, Inc.
Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC.
@ -66,7 +66,7 @@ typedef decNumber* (*dfp_unary_func)
typedef decNumber* (*dfp_binary_func)
(decNumber *, const decNumber *, const decNumber *, decContext *);
extern unsigned long __dec_byte_swap (unsigned long);
extern uint32_t __dec_byte_swap (uint32_t);
/* Unary operations. */

View File

@ -1,5 +1,5 @@
/* Header file for dfp-bit.c.
Copyright (C) 2005, 2006 Free Software Foundation, Inc.
Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC.
@ -288,63 +288,69 @@ extern float strtof (const char *, char **);
/* Names of arithmetic functions. */
#if ENABLE_DECIMAL_BID_FORMAT
#define DPD_BID_NAME(DPD,BID) BID
#else
#define DPD_BID_NAME(DPD,BID) DPD
#endif
#if WIDTH == 32
#define DFP_ADD __addsd3
#define DFP_SUB __subsd3
#define DFP_MULTIPLY __mulsd3
#define DFP_DIVIDE __divsd3
#define DFP_EQ __eqsd2
#define DFP_NE __nesd2
#define DFP_LT __ltsd2
#define DFP_GT __gtsd2
#define DFP_LE __lesd2
#define DFP_GE __gesd2
#define DFP_UNORD __unordsd2
#define DFP_ADD DPD_BID_NAME(__dpd_addsd3,__bid_addsd3)
#define DFP_SUB DPD_BID_NAME(__dpd_subsd3,__bid_subsd3)
#define DFP_MULTIPLY DPD_BID_NAME(__dpd_mulsd3,__bid_mulsd3)
#define DFP_DIVIDE DPD_BID_NAME(__dpd_divsd3,__bid_divsd3)
#define DFP_EQ DPD_BID_NAME(__dpd_eqsd2,__bid_eqsd2)
#define DFP_NE DPD_BID_NAME(__dpd_nesd2,__bid_nesd2)
#define DFP_LT DPD_BID_NAME(__dpd_ltsd2,__bid_ltsd2)
#define DFP_GT DPD_BID_NAME(__dpd_gtsd2,__bid_gtsd2)
#define DFP_LE DPD_BID_NAME(__dpd_lesd2,__bid_lesd2)
#define DFP_GE DPD_BID_NAME(__dpd_gesd2,__bid_gesd2)
#define DFP_UNORD DPD_BID_NAME(__dpd_unordsd2,__bid_unordsd2)
#elif WIDTH == 64
#define DFP_ADD __adddd3
#define DFP_SUB __subdd3
#define DFP_MULTIPLY __muldd3
#define DFP_DIVIDE __divdd3
#define DFP_EQ __eqdd2
#define DFP_NE __nedd2
#define DFP_LT __ltdd2
#define DFP_GT __gtdd2
#define DFP_LE __ledd2
#define DFP_GE __gedd2
#define DFP_UNORD __unorddd2
#define DFP_ADD DPD_BID_NAME(__dpd_adddd3,__bid_adddd3)
#define DFP_SUB DPD_BID_NAME(__dpd_subdd3,__bid_subdd3)
#define DFP_MULTIPLY DPD_BID_NAME(__dpd_muldd3,__bid_muldd3)
#define DFP_DIVIDE DPD_BID_NAME(__dpd_divdd3,__bid_divdd3)
#define DFP_EQ DPD_BID_NAME(__dpd_eqdd2,__bid_eqdd2)
#define DFP_NE DPD_BID_NAME(__dpd_nedd2,__bid_nedd2)
#define DFP_LT DPD_BID_NAME(__dpd_ltdd2,__bid_ltdd2)
#define DFP_GT DPD_BID_NAME(__dpd_gtdd2,__bid_gtdd2)
#define DFP_LE DPD_BID_NAME(__dpd_ledd2,__bid_ledd2)
#define DFP_GE DPD_BID_NAME(__dpd_gedd2,__bid_gedd2)
#define DFP_UNORD DPD_BID_NAME(__dpd_unorddd2,__bid_unorddd2)
#elif WIDTH == 128
#define DFP_ADD __addtd3
#define DFP_SUB __subtd3
#define DFP_MULTIPLY __multd3
#define DFP_DIVIDE __divtd3
#define DFP_EQ __eqtd2
#define DFP_NE __netd2
#define DFP_LT __lttd2
#define DFP_GT __gttd2
#define DFP_LE __letd2
#define DFP_GE __getd2
#define DFP_UNORD __unordtd2
#define DFP_ADD DPD_BID_NAME(__dpd_addtd3,__bid_addtd3)
#define DFP_SUB DPD_BID_NAME(__dpd_subtd3,__bid_subtd3)
#define DFP_MULTIPLY DPD_BID_NAME(__dpd_multd3,__bid_multd3)
#define DFP_DIVIDE DPD_BID_NAME(__dpd_divtd3,__bid_divtd3)
#define DFP_EQ DPD_BID_NAME(__dpd_eqtd2,__bid_eqtd2)
#define DFP_NE DPD_BID_NAME(__dpd_netd2,__bid_netd2)
#define DFP_LT DPD_BID_NAME(__dpd_lttd2,__bid_lttd2)
#define DFP_GT DPD_BID_NAME(__dpd_gttd2,__bid_gttd2)
#define DFP_LE DPD_BID_NAME(__dpd_letd2,__bid_letd2)
#define DFP_GE DPD_BID_NAME(__dpd_getd2,__bid_getd2)
#define DFP_UNORD DPD_BID_NAME(__dpd_unordtd2,__bid_unordtd2)
#endif
/* Names of functions to convert between different decimal float types. */
#if WIDTH == 32
#if WIDTH_TO == 64
#define DFP_TO_DFP __extendsddd2
#define DFP_TO_DFP DPD_BID_NAME(__dpd_extendsddd2,__bid_extendsddd2)
#elif WIDTH_TO == 128
#define DFP_TO_DFP __extendsdtd2
#define DFP_TO_DFP DPD_BID_NAME(__dpd_extendsdtd2,__bid_extendsdtd2)
#endif
#elif WIDTH == 64
#if WIDTH_TO == 32
#define DFP_TO_DFP __truncddsd2
#define DFP_TO_DFP DPD_BID_NAME(__dpd_truncddsd2,__bid_truncddsd2)
#elif WIDTH_TO == 128
#define DFP_TO_DFP __extendddtd2
#define DFP_TO_DFP DPD_BID_NAME(__dpd_extendddtd2,__bid_extendddtd2)
#endif
#elif WIDTH == 128
#if WIDTH_TO == 32
#define DFP_TO_DFP __trunctdsd2
#define DFP_TO_DFP DPD_BID_NAME(__dpd_trunctdsd2,__bid_trunctdsd2)
#elif WIDTH_TO == 64
#define DFP_TO_DFP __trunctddd2
#define DFP_TO_DFP DPD_BID_NAME(__dpd_trunctddd2,__bid_trunctddd2)
#endif
#endif
@ -352,45 +358,45 @@ extern float strtof (const char *, char **);
#if WIDTH == 32
#if INT_KIND == 1
#define INT_TO_DFP __floatsisd
#define DFP_TO_INT __fixsdsi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatsisd,__bid_floatsisd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixsdsi,__bid_fixsdsi)
#elif INT_KIND == 2
#define INT_TO_DFP __floatdisd
#define DFP_TO_INT __fixsddi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatdisd,__bid_floatdisd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixsddi,__bid_fixsddi)
#elif INT_KIND == 3
#define INT_TO_DFP __floatunssisd
#define DFP_TO_INT __fixunssdsi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatunssisd,__bid_floatunssisd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixunssdsi,__bid_fixunssdsi)
#elif INT_KIND == 4
#define INT_TO_DFP __floatunsdisd
#define DFP_TO_INT __fixunssddi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatunsdisd,__bid_floatunsdisd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixunssddi,__bid_fixunssddi)
#endif
#elif WIDTH == 64
#if INT_KIND == 1
#define INT_TO_DFP __floatsidd
#define DFP_TO_INT __fixddsi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatsidd,__bid_floatsidd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixddsi,__bid_fixddsi)
#elif INT_KIND == 2
#define INT_TO_DFP __floatdidd
#define DFP_TO_INT __fixdddi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatdidd,__bid_floatdidd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixdddi,__bid_fixdddi)
#elif INT_KIND == 3
#define INT_TO_DFP __floatunssidd
#define DFP_TO_INT __fixunsddsi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatunssidd,__bid_floatunssidd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixunsddsi,__bid_fixunsddsi)
#elif INT_KIND == 4
#define INT_TO_DFP __floatunsdidd
#define DFP_TO_INT __fixunsdddi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatunsdidd,__bid_floatunsdidd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixunsdddi,__bid_fixunsdddi)
#endif
#elif WIDTH == 128
#if INT_KIND == 1
#define INT_TO_DFP __floatsitd
#define DFP_TO_INT __fixtdsi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatsitd,__bid_floatsitd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixtdsi,__bid_fixtdsi)
#elif INT_KIND == 2
#define INT_TO_DFP __floatditd
#define DFP_TO_INT __fixtddi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatditd,__bid_floatditd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixtddi,__bid_fixtddi)
#elif INT_KIND == 3
#define INT_TO_DFP __floatunssitd
#define DFP_TO_INT __fixunstdsi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatunssitd,__bid_floatunssitd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixunstdsi,__bid_fixunstdsi)
#elif INT_KIND == 4
#define INT_TO_DFP __floatunsditd
#define DFP_TO_INT __fixunstddi
#define INT_TO_DFP DPD_BID_NAME(__dpd_floatunsditd,__bid_floatunsditd)
#define DFP_TO_INT DPD_BID_NAME(__dpd_fixunstddi,__bid_fixunstddi)
#endif
#endif
@ -398,38 +404,38 @@ extern float strtof (const char *, char **);
#if WIDTH == 32
#if BFP_KIND == 1
#define BFP_TO_DFP __extendsfsd
#define DFP_TO_BFP __truncsdsf
#define BFP_TO_DFP DPD_BID_NAME(__dpd_extendsfsd,__bid_extendsfsd)
#define DFP_TO_BFP DPD_BID_NAME(__dpd_truncsdsf,__bid_truncsdsf)
#elif BFP_KIND == 2
#define BFP_TO_DFP __truncdfsd
#define DFP_TO_BFP __extendsddf
#define BFP_TO_DFP DPD_BID_NAME(__dpd_truncdfsd,__bid_truncdfsd)
#define DFP_TO_BFP DPD_BID_NAME(__dpd_extendsddf,__bid_extendsddf)
#elif BFP_KIND == 3
#define BFP_TO_DFP __truncxfsd
#define DFP_TO_BFP __extendsdxf
#define BFP_TO_DFP DPD_BID_NAME(__dpd_truncxfsd,__bid_truncxfsd)
#define DFP_TO_BFP DPD_BID_NAME(__dpd_extendsdxf,__bid_extendsdxf)
#endif /* BFP_KIND */
#elif WIDTH == 64
#if BFP_KIND == 1
#define BFP_TO_DFP __extendsfdd
#define DFP_TO_BFP __truncddsf
#define BFP_TO_DFP DPD_BID_NAME(__dpd_extendsfdd,__bid_extendsfdd)
#define DFP_TO_BFP DPD_BID_NAME(__dpd_truncddsf,__bid_truncddsf)
#elif BFP_KIND == 2
#define BFP_TO_DFP __extenddfdd
#define DFP_TO_BFP __truncdddf
#define BFP_TO_DFP DPD_BID_NAME(__dpd_extenddfdd,__bid_extenddfdd)
#define DFP_TO_BFP DPD_BID_NAME(__dpd_truncdddf,__bid_truncdddf)
#elif BFP_KIND == 3
#define BFP_TO_DFP __truncxfdd
#define DFP_TO_BFP __extendddxf
#define BFP_TO_DFP DPD_BID_NAME(__dpd_truncxfdd,__bid_truncxfdd)
#define DFP_TO_BFP DPD_BID_NAME(__dpd_extendddxf,__bid_extendddxf)
#endif /* BFP_KIND */
#elif WIDTH == 128
#if BFP_KIND == 1
#define BFP_TO_DFP __extendsftd
#define DFP_TO_BFP __trunctdsf
#define BFP_TO_DFP DPD_BID_NAME(__dpd_extendsftd,__bid_extendsftd)
#define DFP_TO_BFP DPD_BID_NAME(__dpd_trunctdsf,__bid_trunctdsf)
#elif BFP_KIND == 2
#define BFP_TO_DFP __extenddftd
#define DFP_TO_BFP __trunctddf
#define BFP_TO_DFP DPD_BID_NAME(__dpd_extenddftd,__bid_extenddftd)
#define DFP_TO_BFP DPD_BID_NAME(__dpd_trunctddf,__bid_trunctddf)
#elif BFP_KIND == 3
#define BFP_TO_DFP __extendxftd
#define DFP_TO_BFP __trunctdxf
#define BFP_TO_DFP DPD_BID_NAME(__dpd_extendxftd,__bid_extendxftd)
#define DFP_TO_BFP DPD_BID_NAME(__dpd_trunctdxf,__bid_trunctdxf)
#endif /* BFP_KIND */
#endif /* WIDTH */

59
gcc/configure vendored
View File

@ -879,7 +879,10 @@ Optional Features:
--enable-gather-detailed-mem-stats enable detailed memory allocation stats gathering
--enable-multilib enable library support for multiple ABIs
--enable-__cxa_atexit enable __cxa_atexit for C++
--enable-decimal-float enable decimal float extension to C
--enable-decimal-float={no,yes,bid,dpd}
enable decimal float extension to C. Selecting 'bid'
or 'dpd' choses which decimal floating point format
to use
--enable-threads enable thread usage for target GCC
--enable-threads=LIB use LIB thread package for target GCC
--enable-tls enable or disable generation of tls code
@ -7012,9 +7015,19 @@ fi;
if test "${enable_decimal_float+set}" = set; then
enableval="$enable_decimal_float"
if test x$enablevar = xyes ; then
case $target in
powerpc*-*-linux* | i?86*-*-linux*)
case $enable_decimal_float in
yes | no | bid | dpd) ;;
*) { { echo "$as_me:$LINENO: error: '$enable_decimal_float' is an invalid value for --enable-decimal-float.
Valid choices are 'yes', 'bid', 'dpd', and 'no'." >&5
echo "$as_me: error: '$enable_decimal_float' is an invalid value for --enable-decimal-float.
Valid choices are 'yes', 'bid', 'dpd', and 'no'." >&2;}
{ (exit 1); exit 1; }; } ;;
esac
else
case $target in
powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=yes
;;
*)
@ -7022,22 +7035,44 @@ if test "${enable_decimal_float+set}" = set; then
echo "$as_me: WARNING: decimal float is not supported for this target" >&2;}
enable_decimal_float=no
;;
esac
fi
esac
else
enable_decimal_float=no
fi;
dfp=`if test $enable_decimal_float = yes; then echo 1; else echo 0; fi`
dfp=`if test $enable_decimal_float != no; then echo 1; else echo 0; fi`
cat >>confdefs.h <<_ACEOF
#define ENABLE_DECIMAL_FLOAT $dfp
_ACEOF
# x86's use BID format instead of DPD
case x$enable_decimal_float in
xyes)
case $target in
i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=bid
;;
*)
enable_decimal_float=dpd
;;
esac
;;
xno)
# ENABLE_DECIMAL_FLOAT is set to 0. But we have to have proper
# dependency on libdecnumber.
enable_decimal_float=dpd
;;
esac
bid=`if test $enable_decimal_float = bid; then echo 1; else echo 0; fi`
cat >>confdefs.h <<_ACEOF
#define ENABLE_DECIMAL_BID_FORMAT $bid
_ACEOF
# Enable threads
# Pass with no value to take the default
# Pass with a value to specify a thread package
@ -7630,7 +7665,7 @@ if test "${gcc_cv_prog_makeinfo_modern+set}" = set; then
else
ac_prog_version=`$MAKEINFO --version 2>&1 |
sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
echo "configure:7633: version of makeinfo is $ac_prog_version" >&5
echo "configure:7668: version of makeinfo is $ac_prog_version" >&5
case $ac_prog_version in
'') gcc_cv_prog_makeinfo_modern=no;;
4.[4-9]*)

View File

@ -667,27 +667,58 @@ AC_ARG_ENABLE(__cxa_atexit,
# Enable C extension for decimal float if target supports it.
AC_ARG_ENABLE(decimal-float,
[ --enable-decimal-float enable decimal float extension to C],
[ --enable-decimal-float={no,yes,bid,dpd}
enable decimal float extension to C. Selecting 'bid'
or 'dpd' choses which decimal floating point format
to use],
[
if test x$enablevar = xyes ; then
case $target in
powerpc*-*-linux* | i?86*-*-linux*)
case $enable_decimal_float in
yes | no | bid | dpd) ;;
*) AC_MSG_ERROR(['$enable_decimal_float' is an invalid value for --enable-decimal-float.
Valid choices are 'yes', 'bid', 'dpd', and 'no'.]) ;;
esac
],
[
case $target in
powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=yes
;;
*)
AC_MSG_WARN(decimal float is not supported for this target, ignored)
enable_decimal_float=no
;;
esac
fi
], [enable_decimal_float=no])
esac
])
AC_SUBST(enable_decimal_float)
dfp=`if test $enable_decimal_float = yes; then echo 1; else echo 0; fi`
dfp=`if test $enable_decimal_float != no; then echo 1; else echo 0; fi`
AC_DEFINE_UNQUOTED(ENABLE_DECIMAL_FLOAT, $dfp,
[Define to 1 to enable decimal float extension to C.])
# x86's use BID format instead of DPD
case x$enable_decimal_float in
xyes)
case $target in
i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=bid
;;
*)
enable_decimal_float=dpd
;;
esac
;;
xno)
# ENABLE_DECIMAL_FLOAT is set to 0. But we have to have proper
# dependency on libdecnumber.
enable_decimal_float=dpd
;;
esac
AC_SUBST(enable_decimal_float)
bid=`if test $enable_decimal_float = bid; then echo 1; else echo 0; fi`
AC_DEFINE_UNQUOTED(ENABLE_DECIMAL_BID_FORMAT, $bid,
[Define to 1 to specify that we are using the BID decimal floating
point format instead of DPD])
# Enable threads
# Pass with no value to take the default
# Pass with a value to specify a thread package

View File

@ -1,5 +1,5 @@
/* Decimal floating point support.
Copyright (C) 2005, 2006 Free Software Foundation, Inc.
Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC.
@ -656,11 +656,9 @@ decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code,
case NEGATE_EXPR:
{
decimal128 *d128;
*r = *op0;
d128 = (decimal128 *) r->sig;
/* Flip high bit. */
d128->bytes[0] ^= 1 << 7;
/* Flip sign bit. */
decimal128FlipSign ((decimal128 *) r->sig);
/* Keep sign field in sync. */
r->sign ^= 1;
}
@ -668,11 +666,9 @@ decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code,
case ABS_EXPR:
{
decimal128 *d128;
*r = *op0;
d128 = (decimal128 *) r->sig;
/* Clear high bit. */
d128->bytes[0] &= 0x7f;
/* Clear sign bit. */
decimal128ClearSign ((decimal128 *) r->sig);
/* Keep sign field in sync. */
r->sign = 0;
}
@ -712,5 +708,5 @@ decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
decimal_real_from_string (r, max);
if (sign)
r->sig[0] |= 0x80000000;
decimal128SetSign ((decimal128 *) r->sig, 1);
}

View File

@ -1304,11 +1304,20 @@ is removed entirely in the next major release, unless someone steps
forward to maintain the port.
@item --enable-decimal-float
@itemx --enable-decimal-float=yes
@itemx --enable-decimal-float=no
@itemx --enable-decimal-float=bid
@itemx --enable-decimal-float=dpd
@itemx --disable-decimal-float
Enable (or disable) support for the C decimal floating point
extension. This is enabled by default only on PowerPC GNU/Linux
systems. Other systems may also support it, but require the user to
specifically enable it.
Enable (or disable) support for the C decimal floating point extension
that is in the IEEE 754R extension to the IEEE754 floating point
standard. This is enabled by default only on PowerPC, i386, and
x86_64 GNU/Linux systems. Other systems may also support it, but
require the user to specifically enable it. You can optionally
control which decimal floating point format is used (either @samp{bid}
or @samp{dpd}). The @samp{bid} (binary integer decimal) format is
default on i386 and x86_64 systems, and the @samp{dpd} (densely packed
decimal) format is default on PowerPC systems.
@item --with-long-double-128
Specify if @code{long double} type should be 128-bit by default on selected

View File

@ -130,6 +130,14 @@ static rtx vector_compare_rtx (tree, bool, enum insn_code);
#define HAVE_conditional_trap 0
#define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
#endif
/* Prefixes for the current version of decimal floating point (BID vs. DPD) */
#if ENABLE_DECIMAL_BID_FORMAT
#define DECIMAL_PREFIX "bid_"
#else
#define DECIMAL_PREFIX "dpd_"
#endif
/* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
the result of operation CODE applied to OP0 (and OP1 if it is a binary
@ -5177,9 +5185,16 @@ init_integral_libfuncs (optab optable, const char *opname, int suffix)
static void
init_floating_libfuncs (optab optable, const char *opname, int suffix)
{
char *dec_opname = alloca (sizeof (DECIMAL_PREFIX) + strlen (opname));
/* For BID support, change the name to have either a bid_ or dpd_ prefix
depending on the low level floating format used. */
memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
init_libfuncs (optable, MIN_MODE_DECIMAL_FLOAT, MAX_MODE_DECIMAL_FLOAT,
opname, suffix);
dec_opname, suffix);
}
/* Initialize the libfunc fields of an entire group of entries of an
@ -5201,8 +5216,13 @@ init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
const char *fname, *tname;
const char *q;
char *libfunc_name, *suffix;
char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
char *p;
/* If this is a decimal conversion, add the current BID vs. DPD prefix that
depends on which underlying decimal floating point format is used. */
const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
for (fmode = first_from_mode;
fmode != VOIDmode;
fmode = GET_MODE_WIDER_MODE (fmode))
@ -5213,11 +5233,18 @@ init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
tmode = GET_MODE_WIDER_MODE (tmode))
max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
libfunc_name[0] = '_';
libfunc_name[1] = '_';
memcpy (&libfunc_name[2], opname, opname_len);
suffix = libfunc_name + opname_len + 2;
nondec_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
nondec_name[0] = '_';
nondec_name[1] = '_';
memcpy (&nondec_name[2], opname, opname_len);
nondec_suffix = nondec_name + opname_len + 2;
dec_name = alloca (2 + dec_len + opname_len + 2*max_mname_len + 1 + 1);
dec_name[0] = '_';
dec_name[1] = '_';
memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
memcpy (&dec_name[2+dec_len], opname, opname_len);
dec_suffix = dec_name + dec_len + opname_len + 2;
for (fmode = first_from_mode; fmode != VOIDmode;
fmode = GET_MODE_WIDER_MODE (fmode))
@ -5227,6 +5254,17 @@ init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
fname = GET_MODE_NAME (fmode);
tname = GET_MODE_NAME (tmode);
if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
{
libfunc_name = dec_name;
suffix = dec_suffix;
}
else
{
libfunc_name = nondec_name;
suffix = nondec_suffix;
}
p = suffix;
for (q = fname; *q; p++, q++)
*p = TOLOWER (*q);
@ -5257,18 +5295,30 @@ init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
enum machine_mode nmode, wmode;
const char *nname, *wname;
const char *q;
char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
char *libfunc_name, *suffix;
char *p;
/* If this is a decimal conversion, add the current BID vs. DPD prefix that
depends on which underlying decimal floating point format is used. */
const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
for (nmode = first_mode; nmode != VOIDmode;
nmode = GET_MODE_WIDER_MODE (nmode))
max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
libfunc_name[0] = '_';
libfunc_name[1] = '_';
memcpy (&libfunc_name[2], opname, opname_len);
suffix = libfunc_name + opname_len + 2;
nondec_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
nondec_name[0] = '_';
nondec_name[1] = '_';
memcpy (&nondec_name[2], opname, opname_len);
nondec_suffix = nondec_name + opname_len + 2;
dec_name = alloca (2 + dec_len + opname_len + 2*max_mname_len + 1 + 1);
dec_name[0] = '_';
dec_name[1] = '_';
memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
memcpy (&dec_name[2 + dec_len], opname, opname_len);
dec_suffix = dec_name + dec_len + opname_len + 2;
for (nmode = first_mode; nmode != VOIDmode;
nmode = GET_MODE_WIDER_MODE (nmode))
@ -5278,6 +5328,17 @@ init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
nname = GET_MODE_NAME (nmode);
wname = GET_MODE_NAME (wmode);
if (DECIMAL_FLOAT_MODE_P(nmode) || DECIMAL_FLOAT_MODE_P(wmode))
{
libfunc_name = dec_name;
suffix = dec_suffix;
}
else
{
libfunc_name = nondec_name;
suffix = nondec_suffix;
}
p = suffix;
for (q = widening ? nname : wname; *q; p++, q++)
*p = TOLOWER (*q);

View File

@ -1,3 +1,10 @@
2007-03-23 Michael Meissner <michael.meissner@amd.com>
* gcc.dg/dfp/convert-dfp.c: Wrap __STDC_WANT_DEC_FP__ with
#ifndef/#endif.
* gcc.dg/dfp/convert-int-saturate.c: Ditto.
* gcc.dg/dfp/decfloat-constants.c: Ditto.
2007-03-24 Paul Thomas <pault@gcc.gnu.org>
PR fortran/31209

View File

@ -6,7 +6,10 @@
Test various conversions involving decimal floating types. */
#ifndef __STDC_WANT_DEC_FP__
#define __STDC_WANT_DEC_FP__ 1
#endif
#include <float.h>
extern void abort (void);

View File

@ -4,7 +4,10 @@
C99 6.3.1.4(1a) New.
Test integer saturation. */
#ifndef __STDC_WANT_DEC_FP__
#define __STDC_WANT_DEC_FP__ 1
#endif
#include <float.h>
#include <limits.h>

View File

@ -7,7 +7,10 @@
decimal float defined in float.h. */
/* Make sure we are exporting the right values to float.h. */
#ifndef __STDC_WANT_DEC_FP__
#define __STDC_WANT_DEC_FP__ 1
#endif
#include <float.h>
extern void abort (void);

View File

@ -1,3 +1,60 @@
2007-03-23 Michael Meissner <michael.meissner@amd.com>
H.J. Lu <hongjiu.lu@intel.com>
Marius Cornea <marius.cornea@intel.com>
* Makefile.in (enable_decimal_float): New.
(libdecnumber_a_OBJS): Add bid2dpd_dpd2bid.o, host-ieee32.o,
host-ieee64.o and host-ieee128.o for BID.
(libdecnumber_a_SOURCES): Support DPD and BID.
(decimal32.o): Support dependency for both DPD and BID.
(decimal64.o): Likewise.
(decimal128.o): Likewise.
(bid2dpd_dpd2bid.o): New target.
(host-ieee32.o): Likewise.
(host-ieee64.o): Likewise.
(host-ieee128.o): Likewise.
* bid/bid-dpd.h: New file.
* bid/decimal128.c: Likewise.
* bid/decimal128.h: Likewise.
* bid/decimal32.c: Likewise.
* bid/decimal32.h: Likewise.
* bid/decimal64.c: Likewise.
* bid/decimal64.h: Likewise.
* bid/host-ieee128.c: Likewise.
* bid/host-ieee32.c: Likewise.
* bid/host-ieee64.c: Likewise.
* bid/bid2dpd_dpd2bid.c: Likewise.
* bid/bid2dpd_dpd2bid.h: Likewise.
* decimal128.c: Moved to ...
* dpd/decimal128.c: This.
* decimal128.h: Moved to ...
* dpd/decimal128.h: This.
* decimal32.c: Moved to ...
* dpd/decimal32.c: This.
* decimal32.h: Moved to ...
* dpd/decimal32.h: This.
* decimal64.c: Moved to ...
* dpd/decimal64.c: This.
* decimal64.h: Moved to ...
* dpd/decimal64.h: This.
* configure.ac: Support * --enable-decimal-float={no,yes,bid,dpd}.
Add AC_C_BIGENDIAN. Substitute enable_decimal_float.
* config.in: Add decimal support variables.
* configure: Regenerate.
PR other/30530
* decimal128.h (decimal128ClearSign): New.
(decimal128FlipSign): Likewise.
* decimal32.h: (decimal32ClearSign): New.
(decimal32FlipSign): Likewise.
* decimal64.h (decimal64ClearSign): New.
(decimal64FlipSign): Likewise.
2007-03-08 Ben Elliston <bje@au.ibm.com>
* decContext.c, decContext.h, decDPD.h, decimal128.c,

View File

@ -1,7 +1,7 @@
# @configure_input@
# Makefile for libdecnumber. Run 'configure' to generate Makefile from Makefile.in
# Copyright (C) 2005 Free Software Foundation, Inc.
# Copyright (C) 2005, 2007 Free Software Foundation, Inc.
#This file is part of GCC.
@ -50,6 +50,8 @@ libdir = @libdir@
localedir = $(datadir)/locale
prefix = @prefix@
enable_decimal_float= @enable_decimal_float@
INCLUDES = -I$(srcdir) -I.
ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS)
@ -57,11 +59,20 @@ ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS)
libdecnumber_a_OBJS = decNumber.o decContext.o decUtility.o \
decimal32.o decimal64.o decimal128.o
ifeq ($(enable_decimal_float),bid)
libdecnumber_a_OBJS+=bid2dpd_dpd2bid.o host-ieee32.o host-ieee64.o \
host-ieee128.o
endif
libdecnumber_a_SOURCES = decContext.c decContext.h decDPD.h \
decNumber.c decNumber.h decNumberLocal.h \
decUtility.c decUtility.h \
decimal128.c decimal128.h decimal32.c decimal32.h \
decimal64.c decimal64.h
dpd/decimal128.c dpd/decimal128.h \
dpd/decimal32.c dpd/decimal32.h \
dpd/decimal64.c dpd/decimal64.h \
bid/decimal128.c bid/decimal128.h \
bid/decimal32.c bid/decimal32.h \
bid/decimal64.c bid/decimal64.h
all: libdecnumber.a
@ -104,13 +115,26 @@ $(srcdir)/config.in: @MAINT@ $(srcdir)/configure
decContext.o: decContext.c decContext.h decNumberLocal.h
decNumber.o: decNumber.c decNumber.h decContext.h decNumberLocal.h
decimal32.o: decimal32.c decNumber.h decContext.h decNumberLocal.h \
decimal32.h decUtility.h
decimal64.o: decimal64.c decNumber.h decContext.h decNumberLocal.h \
decimal64.h decUtility.h
decimal128.o: decimal128.c decNumber.h decNumberLocal.h decimal128.h \
decUtility.h
decimal32.o: $(enable_decimal_float)/decimal32.c \
$(enable_decimal_float)/decimal32.h \
decNumber.h decContext.h decNumberLocal.h decUtility.h
$(COMPILE) $<
decimal64.o: $(enable_decimal_float)/decimal64.c \
$(enable_decimal_float)/decimal64.h \
decNumber.h decContext.h decNumberLocal.h decUtility.h
$(COMPILE) $<
decimal128.o: $(enable_decimal_float)/decimal128.c \
$(enable_decimal_float)/decimal128.h \
decNumber.h decContext.h decNumberLocal.h decUtility.h
$(COMPILE) $<
bid2dpd_dpd2bid.o : bid/bid2dpd_dpd2bid.c bid/bid2dpd_dpd2bid.h
$(COMPILE) $<
host-ieee32.o : bid/host-ieee32.c bid/decimal32.h
$(COMPILE) $<
host-ieee64.o : bid/host-ieee64.c bid/decimal64.h
$(COMPILE) $<
host-ieee128.o : bid/host-ieee128.c bid/decimal128.h
$(COMPILE) $<
# Other miscellaneous targets.
mostlyclean:

View File

@ -0,0 +1,43 @@
/* Copyright (C) 2007
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 2, 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
typedef unsigned int UINT32;
typedef unsigned long long UINT64;
typedef struct { UINT64 w[2]; } UINT128;
#ifndef IN_LIBGCC2
#define _Decimal32 UINT32
#define _Decimal64 UINT64
#define _Decimal128 UINT128
#endif
void _bid_to_dpd32 (_Decimal32 *, _Decimal32 *);
void _dpd_to_bid32 (_Decimal32 *, _Decimal32 *);
void _bid_to_dpd64 (_Decimal64 *, _Decimal64 *);
void _dpd_to_bid64 (_Decimal64 *, _Decimal64 *);
void _bid_to_dpd128 (_Decimal128 *, _Decimal128 *);
void _dpd_to_bid128 (_Decimal128 *, _Decimal128 *);

View File

@ -0,0 +1,428 @@
/* Copyright (C) 2007 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
#undef IN_LIBGCC2
#include "bid-dpd.h"
/* get full 64x64bit product */
#define __mul_64x64_to_128(P, CX, CY) \
{ \
UINT64 CXH, CXL, CYH,CYL,PL,PH,PM,PM2; \
CXH = (CX) >> 32; \
CXL = (UINT32)(CX); \
CYH = (CY) >> 32; \
CYL = (UINT32)(CY); \
\
PM = CXH*CYL; \
PH = CXH*CYH; \
PL = CXL*CYL; \
PM2 = CXL*CYH; \
PH += (PM>>32); \
PM = (UINT64)((UINT32)PM)+PM2+(PL>>32); \
\
(P).w[1] = PH + (PM>>32); \
(P).w[0] = (PM<<32)+(UINT32)PL; \
}
/* add 64-bit value to 128-bit */
#define __add_128_64(R128, A128, B64) \
{ \
UINT64 R64H; \
R64H = (A128).w[1]; \
(R128).w[0] = (B64) + (A128).w[0]; \
if((R128).w[0] < (B64)) R64H ++; \
(R128).w[1] = R64H; \
}
/* add 128-bit value to 128-bit (assume no carry-out) */
#define __add_128_128(R128, A128, B128) \
{ \
UINT128 Q128; \
Q128.w[1] = (A128).w[1]+(B128).w[1]; \
Q128.w[0] = (B128).w[0] + (A128).w[0]; \
if(Q128.w[0] < (B128).w[0]) Q128.w[1] ++; \
(R128).w[1] = Q128.w[1]; \
(R128).w[0] = Q128.w[0]; \
}
#define __mul_128x128_high(Q, A, B) \
{ \
UINT128 ALBL, ALBH, AHBL, AHBH, QM, QM2; \
\
__mul_64x64_to_128(ALBH, (A).w[0], (B).w[1]); \
__mul_64x64_to_128(AHBL, (B).w[0], (A).w[1]); \
__mul_64x64_to_128(ALBL, (A).w[0], (B).w[0]); \
__mul_64x64_to_128(AHBH, (A).w[1],(B).w[1]); \
\
__add_128_128(QM, ALBH, AHBL); \
__add_128_64(QM2, QM, ALBL.w[1]); \
__add_128_64((Q), AHBH, QM2.w[1]); \
}
#include "bid2dpd_dpd2bid.h"
static const unsigned int dm103[] =
{ 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000 };
void _bid_to_dpd32 (_Decimal32 *, _Decimal32 *);
void
_bid_to_dpd32 (_Decimal32 *pres, _Decimal32 *px) {
unsigned int sign, coefficient_x, exp, dcoeff;
unsigned int b2, b1, b0, b01, res;
_Decimal32 x = *px;
sign = (x & 0x80000000);
if ((x & 0x60000000ul) == 0x60000000ul) {
/* special encodings */
if ((x & 0x78000000ul) == 0x78000000ul) {
*pres = x; /* NaN or Infinity */
return;
}
/* coefficient */
coefficient_x = (x & 0x001ffffful) | 0x00800000ul;
if (coefficient_x >= 10000000) coefficient_x = 0;
/* get exponent */
exp = (x >> 21) & 0xff;
} else {
exp = (x >> 23) & 0xff;
coefficient_x = (x & 0x007ffffful);
}
b01 = coefficient_x / 1000;
b2 = coefficient_x - 1000 * b01;
b0 = b01 / 1000;
b1 = b01 - 1000 * b0;
dcoeff = b2d[b2] | b2d2[b1];
if (b0 >= 8) { /* is b0 8 or 9? */
res = sign | ((0x600 | ((exp >> 6) << 7) |
((b0 & 1) << 6) | (exp & 0x3f)) << 20) | dcoeff;
} else { /* else b0 is 0..7 */
res = sign | ((((exp >> 6) << 9) | (b0 << 6) |
(exp & 0x3f)) << 20) | dcoeff;
}
*pres = res;
}
void _dpd_to_bid32 (_Decimal32 *, _Decimal32 *);
void
_dpd_to_bid32 (_Decimal32 *pres, _Decimal32 *px) {
unsigned int r;
unsigned int sign, exp, bcoeff;
UINT64 trailing;
unsigned int d0, d1, d2;
_Decimal32 x = *px;
sign = (x & 0x80000000);
trailing = (x & 0x000fffff);
if ((x & 0x78000000) == 0x78000000) {
*pres = x;
return;
} else { /* normal number */
if ((x & 0x60000000) == 0x60000000) { /* G0..G1 = 11 -> d0 = 8 + G4 */
d0 = d2b3[((x >> 26) & 1) | 8]; /* d0 = (comb & 0x0100 ? 9 : 8); */
exp = (x >> 27) & 3; /* exp leading bits are G2..G3 */
} else {
d0 = d2b3[(x >> 26) & 0x7];
exp = (x >> 29) & 3; /* exp loading bits are G0..G1 */
}
d1 = d2b2[(trailing >> 10) & 0x3ff];
d2 = d2b[(trailing) & 0x3ff];
bcoeff = d2 + d1 + d0;
exp = (exp << 6) + ((x >> 20) & 0x3f);
if (bcoeff < (1 << 23)) {
r = exp;
r <<= 23;
r |= (bcoeff | sign);
} else {
r = exp;
r <<= 21;
r |= (sign | 0x60000000ul);
/* add coeff, without leading bits */
r |= (((unsigned int) bcoeff) & 0x1fffff);
}
}
*pres = r;
}
void _bid_to_dpd64 (_Decimal64 *, _Decimal64 *);
void
_bid_to_dpd64 (_Decimal64 *pres, _Decimal64 *px) {
UINT64 res;
UINT64 sign, comb, exp, B34, B01;
UINT64 d103, D61;
UINT64 b0, b2, b3, b5;
unsigned int b1, b4;
UINT64 bcoeff;
UINT64 dcoeff;
unsigned int yhi, ylo;
_Decimal64 x = *px;
sign = (x & 0x8000000000000000ull);
comb = (x & 0x7ffc000000000000ull) >> 51;
if ((comb & 0xf00) == 0xf00) {
*pres = x;
return;
} else { /* Normal number */
if ((comb & 0xc00) == 0xc00) { /* G0..G1 = 11 -> exp is G2..G11 */
exp = (comb) & 0x3ff;
bcoeff = (x & 0x0007ffffffffffffull) | 0x0020000000000000ull;
} else {
exp = (comb >> 2) & 0x3ff;
bcoeff = (x & 0x001fffffffffffffull);
}
D61 = 2305843009ull; /* Floor(2^61 / 10^9) */
/* Multiply the binary coefficient by ceil(2^64 / 1000), and take the upper
64-bits in order to compute a division by 1000. */
yhi = (D61 * (UINT64)(bcoeff >> (UINT64)27)) >> (UINT64)34;
ylo = bcoeff - 1000000000ull * yhi;
if (ylo >= 1000000000) {
ylo = ylo - 1000000000;
yhi = yhi + 1;
}
d103 = 0x4189374c;
B34 = ((UINT64) ylo * d103) >> (32 + 8);
B01 = ((UINT64) yhi * d103) >> (32 + 8);
b5 = ylo - B34 * 1000;
b2 = yhi - B01 * 1000;
b3 = ((UINT64) B34 * d103) >> (32 + 8);
b0 = ((UINT64) B01 * d103) >> (32 + 8);
b4 = (unsigned int) B34 - (unsigned int) b3 *1000;
b1 = (unsigned int) B01 - (unsigned int) dm103[b0];
dcoeff = b2d[b5] | b2d2[b4] | b2d3[b3] | b2d4[b2] | b2d5[b1];
if (b0 >= 8) /* is b0 8 or 9? */
res = sign | ((0x1800 | ((exp >> 8) << 9) | ((b0 & 1) << 8) |
(exp & 0xff)) << 50) | dcoeff;
else /* else b0 is 0..7 */
res = sign | ((((exp >> 8) << 11) | (b0 << 8) |
(exp & 0xff)) << 50) | dcoeff;
}
*pres = res;
}
void _dpd_to_bid64 (_Decimal64 *, _Decimal64 *);
void
_dpd_to_bid64 (_Decimal64 *pres, _Decimal64 *px) {
UINT64 res;
UINT64 sign, comb, exp;
UINT64 trailing;
UINT64 d0, d1, d2;
unsigned int d3, d4, d5;
UINT64 bcoeff, mask;
_Decimal64 x = *px;
sign = (x & 0x8000000000000000ull);
comb = (x & 0x7ffc000000000000ull) >> 50;
trailing = (x & 0x0003ffffffffffffull);
if ((comb & 0x1e00) == 0x1e00) {
if ((comb & 0x1f00) == 0x1f00) { /* G0..G4 = 11111 -> NaN */
if (comb & 0x0100) { /* G5 = 1 -> sNaN */
*pres = x;
} else { /* G5 = 0 -> qNaN */
*pres = x;
}
} else { /*if ((comb & 0x1e00) == 0x1e00); G0..G4 = 11110 -> INF */
*pres = x;
}
return;
} else { /* normal number */
if ((comb & 0x1800) == 0x1800) { /* G0..G1 = 11 -> d0 = 8 + G4 */
d0 = d2b6[((comb >> 8) & 1) | 8]; /* d0 = (comb & 0x0100 ? 9 : 8); */
exp = (comb & 0x600) >> 1; /* exp = (comb & 0x0400 ? 1 : 0) * 0x200 +
(comb & 0x0200 ? 1 : 0) * 0x100; exp leading bits are G2..G3 */
} else {
d0 = d2b6[(comb >> 8) & 0x7];
exp = (comb & 0x1800) >> 3; /* exp = (comb & 0x1000 ? 1 : 0) * 0x200 +
(comb & 0x0800 ? 1 : 0) * 0x100; exp loading bits are G0..G1 */
}
d1 = d2b5[(trailing >> 40) & 0x3ff];
d2 = d2b4[(trailing >> 30) & 0x3ff];
d3 = d2b3[(trailing >> 20) & 0x3ff];
d4 = d2b2[(trailing >> 10) & 0x3ff];
d5 = d2b[(trailing) & 0x3ff];
bcoeff = (d5 + d4 + d3) + d2 + d1 + d0;
exp += (comb & 0xff);
mask = 1;
mask <<= 53;
if (bcoeff < mask) { /* check whether coefficient fits in 10*5+3 bits */
res = exp;
res <<= 53;
res |= (bcoeff | sign);
*pres = res;
return;
}
/* special format */
res = (exp << 51) | (sign | 0x6000000000000000ull);
/* add coeff, without leading bits */
mask = (mask >> 2) - 1;
bcoeff &= mask;
res |= bcoeff;
}
*pres = res;
}
void _bid_to_dpd128 (_Decimal128 *, _Decimal128 *);
void
_bid_to_dpd128 (_Decimal128 *pres, _Decimal128 *px) {
UINT128 res;
UINT128 sign;
unsigned int comb;
UINT128 bcoeff;
UINT128 dcoeff;
UINT128 BH, d1018, BT2, BT1;
UINT64 exp, BL, d109;
UINT64 d106, d103;
UINT64 k1, k2, k4, k5, k7, k8, k10, k11;
unsigned int BHH32, BLL32, BHL32, BLH32, k0, k3, k6, k9, amount;
_Decimal128 x = *px;
sign.w[1] = (x.w[1] & 0x8000000000000000ull);
sign.w[0] = 0;
comb = (x.w[1] /*& 0x7fffc00000000000ull */ ) >> 46;
exp = 0;
if ((comb & 0x1e000) == 0x1e000) {
if ((comb & 0x1f000) == 0x1f000) { /* G0..G4 = 11111 -> NaN */
if (comb & 0x01000) { /* G5 = 1 -> sNaN */
res = x;
} else { /* G5 = 0 -> qNaN */
res = x;
}
} else { /* G0..G4 = 11110 -> INF */
res = x;
}
} else { /* normal number */
exp = ((x.w[1] & 0x7fff000000000000ull) >> 49) & 0x3fff;
bcoeff.w[1] = (x.w[1] & 0x0001ffffffffffffull);
bcoeff.w[0] = x.w[0];
d1018 = reciprocals10_128[18];
__mul_128x128_high (BH, bcoeff, d1018);
amount = recip_scale[18];
BH.w[0] = (BH.w[0] >> amount) | (BH.w[1] << (64 - amount));
BL = bcoeff.w[0] - BH.w[0] * 1000000000000000000ull;
d109 = reciprocals10_64[9];
__mul_64x64_to_128 (BT1, BH.w[0], d109);
BHH32 = (unsigned int) (BT1.w[1] >> short_recip_scale[9]);
BHL32 = (unsigned int) BH.w[0] - BHH32 * 1000000000;
__mul_64x64_to_128 (BT2, BL, d109);
BLH32 = (unsigned int) (BT2.w[1] >> short_recip_scale[9]);
BLL32 = (unsigned int) BL - BLH32 * 1000000000;
d106 = 0x431BDE83;
d103 = 0x4189374c;
k0 = ((UINT64) BHH32 * d106) >> (32 + 18);
BHH32 -= (unsigned int) k0 *1000000;
k1 = ((UINT64) BHH32 * d103) >> (32 + 8);
k2 = BHH32 - (unsigned int) k1 *1000;
k3 = ((UINT64) BHL32 * d106) >> (32 + 18);
BHL32 -= (unsigned int) k3 *1000000;
k4 = ((UINT64) BHL32 * d103) >> (32 + 8);
k5 = BHL32 - (unsigned int) k4 *1000;
k6 = ((UINT64) BLH32 * d106) >> (32 + 18);
BLH32 -= (unsigned int) k6 *1000000;
k7 = ((UINT64) BLH32 * d103) >> (32 + 8);
k8 = BLH32 - (unsigned int) k7 *1000;
k9 = ((UINT64) BLL32 * d106) >> (32 + 18);
BLL32 -= (unsigned int) k9 *1000000;
k10 = ((UINT64) BLL32 * d103) >> (32 + 8);
k11 = BLL32 - (unsigned int) k10 *1000;
dcoeff.w[1] = (b2d[k5] >> 4) | (b2d[k4] << 6) | (b2d[k3] << 16) |
(b2d[k2] << 26) | (b2d[k1] << 36);
dcoeff.w[0] = b2d[k11] | (b2d[k10] << 10) | (b2d[k9] << 20) |
(b2d[k8] << 30) | (b2d[k7] << 40) | (b2d[k6] << 50) | (b2d[k5] << 60);
res.w[0] = dcoeff.w[0];
if (k0 >= 8) {
res.w[1] = sign.w[1] | ((0x18000 | ((exp >> 12) << 13) |
((k0 & 1) << 12) | (exp & 0xfff)) << 46) | dcoeff.w[1];
} else {
res.w[1] = sign.w[1] | ((((exp >> 12) << 15) | (k0 << 12) |
(exp & 0xfff)) << 46) | dcoeff.w[1];
}
}
*pres = res;
}
void _dpd_to_bid128 (_Decimal128 *, _Decimal128 *);
void
_dpd_to_bid128 (_Decimal128 *pres, _Decimal128 *px) {
UINT128 res;
UINT128 sign;
UINT64 exp, comb;
UINT128 trailing;
UINT64 d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11;
UINT128 bcoeff;
UINT64 tl, th;
_Decimal128 x = *px;
sign.w[1] = (x.w[1] & 0x8000000000000000ull);
sign.w[0] = 0;
comb = (x.w[1] & 0x7fffc00000000000ull) >> 46;
trailing.w[1] = x.w[1];
trailing.w[0] = x.w[0];
if ((comb & 0x1e000) == 0x1e000) {
if ((comb & 0x1f000) == 0x1f000) { /* G0..G4 = 11111 -> NaN */
if (comb & 0x01000) { /* G5 = 1 -> sNaN */
*pres = x;
} else { /* G5 = 0 -> qNaN */
*pres = x;
}
} else { /* G0..G4 = 11110 -> INF */
*pres = x;
}
return;
} else { /* Normal number */
if ((comb & 0x18000) == 0x18000) { /* G0..G1 = 11 -> d0 = 8 + G4 */
d0 = d2b6[8 + ((comb & 0x01000) >> 12)];
exp = (comb & 0x06000) >> 1; /* exp leading bits are G2..G3 */
} else {
d0 = d2b6[((comb & 0x07000) >> 12)];
exp = (comb & 0x18000) >> 3; /* exp loading bits are G0..G1 */
}
d11 = d2b[(trailing.w[0]) & 0x3ff];
d10 = d2b2[(trailing.w[0] >> 10) & 0x3ff];
d9 = d2b3[(trailing.w[0] >> 20) & 0x3ff];
d8 = d2b4[(trailing.w[0] >> 30) & 0x3ff];
d7 = d2b5[(trailing.w[0] >> 40) & 0x3ff];
d6 = d2b6[(trailing.w[0] >> 50) & 0x3ff];
d5 = d2b[(trailing.w[0] >> 60) | ((trailing.w[1] & 0x3f) << 4)];
d4 = d2b2[(trailing.w[1] >> 6) & 0x3ff];
d3 = d2b3[(trailing.w[1] >> 16) & 0x3ff];
d2 = d2b4[(trailing.w[1] >> 26) & 0x3ff];
d1 = d2b5[(trailing.w[1] >> 36) & 0x3ff];
tl = d11 + d10 + d9 + d8 + d7 + d6;
th = d5 + d4 + d3 + d2 + d1 + d0;
__mul_64x64_to_128 (bcoeff, th, 1000000000000000000ull);
__add_128_64 (bcoeff, bcoeff, tl);
exp += (comb & 0xfff);
res.w[0] = bcoeff.w[0];
res.w[1] = (exp << 49) | sign.w[1] | bcoeff.w[1];
}
*pres = res;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,148 @@
/* Copyright (C) 2007
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 2, 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#define decimal128FromString __dpd128FromString
#define decimal128ToString __dpd128ToString
#define decimal128ToEngString __dpd128ToEngString
#define decimal128FromNumber __dpd128FromNumber
#define decimal128ToNumber __dpd128ToNumber
#include "dpd/decimal128.c"
#undef decimal128FromString
#undef decimal128ToString
#undef decimal128ToEngString
#undef decimal128FromNumber
#undef decimal128ToNumber
#include "bid-dpd.h"
#ifdef IN_LIBGCC2
#define decimal128FromString __decimal128FromString
#define decimal128ToString __decimal128ToString
#define decimal128ToEngString __decimal128ToEngString
#define decimal128FromNumber __decimal128FromNumber
#define decimal128ToNumber __decimal128ToNumber
#endif
decimal128 *decimal128FromString (decimal128 *, const char *, decContext *);
char *decimal128ToString (const decimal128 *, char *);
char *decimal128ToEngString (const decimal128 *, char *);
decimal128 *decimal128FromNumber (decimal128 *, const decNumber *, decContext *);
decNumber *decimal128ToNumber (const decimal128 *, decNumber *);
void __host_to_ieee_128 (_Decimal128 in, decimal128 *out);
void __ieee_to_host_128 (decimal128 in, _Decimal128 *out);
decimal128 *
decimal128FromNumber (decimal128 *d128, const decNumber *dn,
decContext *set)
{
/* decimal128 and _Decimal128 are different types. */
union
{
_Decimal128 _Dec;
decimal128 dec;
} u;
__dpd128FromNumber (d128, dn, set);
/* __dpd128FromNumber returns in big endian. But _dpd_to_bid128 takes
host endian. */
__ieee_to_host_128 (*d128, &u._Dec);
/* Convert DPD to BID. */
_dpd_to_bid128 (&u._Dec, &u._Dec);
/* dfp.c is in bid endian. */
__host_to_ieee_128 (u._Dec, &u.dec);
/* d128 is returned as a pointer to _Decimal128 here. */
*d128 = u.dec;
return d128;
}
decNumber *
decimal128ToNumber (const decimal128 *bid128, decNumber *dn)
{
/* decimal128 and _Decimal128 are different types. */
union
{
_Decimal128 _Dec;
decimal128 dec;
} u;
/* bid128 is a pointer to _Decimal128 in bid endian. But _bid_to_dpd128
takes host endian. */
__ieee_to_host_128 (*bid128, &u._Dec);
/* Convert BID to DPD. */
_bid_to_dpd128 (&u._Dec, &u._Dec);
/* __dpd128ToNumber is in bid endian. */
__host_to_ieee_128 (u._Dec, &u.dec);
return __dpd128ToNumber (&u.dec, dn);
}
char *
decimal128ToString (const decimal128 *d128, char *string)
{
decNumber dn; /* work */
decimal128ToNumber (d128, &dn);
decNumberToString (&dn, string);
return string;
}
char *
decimal128ToEngString (const decimal128 *d128, char *string)
{
decNumber dn; /* work */
decimal128ToNumber (d128, &dn);
decNumberToEngString (&dn, string);
return string;
}
decimal128 *
decimal128FromString (decimal128 *result, const char *string,
decContext *set)
{
decContext dc; /* work */
decNumber dn; /* .. */
decContextDefault (&dc, DEC_INIT_DECIMAL128); /* no traps, please */
dc.round = set->round; /* use supplied rounding */
decNumberFromString (&dn, string, &dc); /* will round if needed */
decimal128FromNumber (result, &dn, &dc);
if (dc.status != 0)
{ /* something happened */
decContextSetStatus (set, dc.status); /* .. pass it on */
}
return result;
}

View File

@ -0,0 +1 @@
#include "dpd/decimal128.h"

View File

@ -0,0 +1,148 @@
/* Copyright (C) 2007
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 2, 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#define decimal32FromString __dpd32FromString
#define decimal32ToString __dpd32ToString
#define decimal32ToEngString __dpd32ToEngString
#define decimal32FromNumber __dpd32FromNumber
#define decimal32ToNumber __dpd32ToNumber
#include "dpd/decimal32.c"
#undef decimal32FromString
#undef decimal32ToString
#undef decimal32ToEngString
#undef decimal32FromNumber
#undef decimal32ToNumber
#include "bid-dpd.h"
#ifdef IN_LIBGCC2
#define decimal32FromString __decimal32FromString
#define decimal32ToString __decimal32ToString
#define decimal32ToEngString __decimal32ToEngString
#define decimal32FromNumber __decimal32FromNumber
#define decimal32ToNumber __decimal32ToNumber
#endif
decimal32 *decimal32FromString (decimal32 *, const char *, decContext *);
char *decimal32ToString (const decimal32 *, char *);
char *decimal32ToEngString (const decimal32 *, char *);
decimal32 *decimal32FromNumber (decimal32 *, const decNumber *, decContext *);
decNumber *decimal32ToNumber (const decimal32 *, decNumber *);
void __host_to_ieee_32 (_Decimal32 in, decimal32 *out);
void __ieee_to_host_32 (decimal32 in, _Decimal32 *out);
decimal32 *
decimal32FromNumber (decimal32 *d32, const decNumber *dn,
decContext *set)
{
/* decimal32 and _Decimal32 are different types. */
union
{
_Decimal32 _Dec;
decimal32 dec;
} u;
__dpd32FromNumber (d32, dn, set);
/* __dpd32FromNumber returns in big endian. But _dpd_to_bid32 takes
host endian. */
__ieee_to_host_32 (*d32, &u._Dec);
/* Convert DPD to BID. */
_dpd_to_bid32 (&u._Dec, &u._Dec);
/* dfp.c is in bid endian. */
__host_to_ieee_32 (u._Dec, &u.dec);
/* d32 is returned as a pointer to _Decimal32 here. */
*d32 = u.dec;
return d32;
}
decNumber *
decimal32ToNumber (const decimal32 *bid32, decNumber *dn)
{
/* decimal32 and _Decimal32 are different types. */
union
{
_Decimal32 _Dec;
decimal32 dec;
} u;
/* bid32 is a pointer to _Decimal32 in bid endian. But _bid_to_dpd32
takes host endian. */
__ieee_to_host_32 (*bid32, &u._Dec);
/* Convert BID to DPD. */
_bid_to_dpd32 (&u._Dec, &u._Dec);
/* __dpd32ToNumber is in bid endian. */
__host_to_ieee_32 (u._Dec, &u.dec);
return __dpd32ToNumber (&u.dec, dn);
}
char *
decimal32ToString (const decimal32 *d32, char *string)
{
decNumber dn; /* work */
decimal32ToNumber (d32, &dn);
decNumberToString (&dn, string);
return string;
}
char *
decimal32ToEngString (const decimal32 *d32, char *string)
{
decNumber dn; /* work */
decimal32ToNumber (d32, &dn);
decNumberToEngString (&dn, string);
return string;
}
decimal32 *
decimal32FromString (decimal32 *result, const char *string,
decContext *set)
{
decContext dc; /* work */
decNumber dn; /* .. */
decContextDefault (&dc, DEC_INIT_DECIMAL32); /* no traps, please */
dc.round = set->round; /* use supplied rounding */
decNumberFromString (&dn, string, &dc); /* will round if needed */
decimal32FromNumber (result, &dn, &dc);
if (dc.status != 0)
{ /* something happened */
decContextSetStatus (set, dc.status); /* .. pass it on */
}
return result;
}

View File

@ -0,0 +1 @@
#include "dpd/decimal32.h"

View File

@ -0,0 +1,148 @@
/* Copyright (C) 2007
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 2, 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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#define decimal64FromString __dpd64FromString
#define decimal64ToString __dpd64ToString
#define decimal64ToEngString __dpd64ToEngString
#define decimal64FromNumber __dpd64FromNumber
#define decimal64ToNumber __dpd64ToNumber
#include "dpd/decimal64.c"
#undef decimal64FromString
#undef decimal64ToString
#undef decimal64ToEngString
#undef decimal64FromNumber
#undef decimal64ToNumber
#include "bid-dpd.h"
#ifdef IN_LIBGCC2
#define decimal64FromString __decimal64FromString
#define decimal64ToString __decimal64ToString
#define decimal64ToEngString __decimal64ToEngString
#define decimal64FromNumber __decimal64FromNumber
#define decimal64ToNumber __decimal64ToNumber
#endif
decimal64 *decimal64FromString (decimal64 *, const char *, decContext *);
char *decimal64ToString (const decimal64 *, char *);
char *decimal64ToEngString (const decimal64 *, char *);
decimal64 *decimal64FromNumber (decimal64 *, const decNumber *, decContext *);
decNumber *decimal64ToNumber (const decimal64 *, decNumber *);
void __host_to_ieee_64 (_Decimal64 in, decimal64 *out);
void __ieee_to_host_64 (decimal64 in, _Decimal64 *out);
decimal64 *
decimal64FromNumber (decimal64 *d64, const decNumber *dn,
decContext *set)
{
/* decimal64 and _Decimal64 are different types. */
union
{
_Decimal64 _Dec;
decimal64 dec;
} u;
__dpd64FromNumber (d64, dn, set);
/* __dpd64FromNumber returns in big endian. But _dpd_to_bid64 takes
host endian. */
__ieee_to_host_64 (*d64, &u._Dec);
/* Convert DPD to BID. */
_dpd_to_bid64 (&u._Dec, &u._Dec);
/* dfp.c is in bid endian. */
__host_to_ieee_64 (u._Dec, &u.dec);
/* d64 is returned as a pointer to _Decimal64 here. */
*d64 = u.dec;
return d64;
}
decNumber *
decimal64ToNumber (const decimal64 *bid64, decNumber *dn)
{
/* decimal64 and _Decimal64 are different types. */
union
{
_Decimal64 _Dec;
decimal64 dec;
} u;
/* bid64 is a pointer to _Decimal64 in bid endian. But _bid_to_dpd64
takes host endian. */
__ieee_to_host_64 (*bid64, &u._Dec);
/* Convert BID to DPD. */
_bid_to_dpd64 (&u._Dec, &u._Dec);
/* __dpd64ToNumber is in bid endian. */
__host_to_ieee_64 (u._Dec, &u.dec);
return __dpd64ToNumber (&u.dec, dn);
}
char *
decimal64ToString (const decimal64 *d64, char *string)
{
decNumber dn; /* work */
decimal64ToNumber (d64, &dn);
decNumberToString (&dn, string);
return string;
}
char *
decimal64ToEngString (const decimal64 *d64, char *string)
{
decNumber dn; /* work */
decimal64ToNumber (d64, &dn);
decNumberToEngString (&dn, string);
return string;
}
decimal64 *
decimal64FromString (decimal64 *result, const char *string,
decContext *set)
{
decContext dc; /* work */
decNumber dn; /* .. */
decContextDefault (&dc, DEC_INIT_DECIMAL64); /* no traps, please */
dc.round = set->round; /* use supplied rounding */
decNumberFromString (&dn, string, &dc); /* will round if needed */
decimal64FromNumber (result, &dn, &dc);
if (dc.status != 0)
{ /* something happened */
decContextSetStatus (set, dc.status); /* .. pass it on */
}
return result;
}

View File

@ -0,0 +1 @@
#include "dpd/decimal64.h"

View File

@ -0,0 +1,82 @@
/* This is a software decimal floating point library.
Copyright (C) 2007 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "config.h"
#include "gstdint.h"
#include "bid-dpd.h"
#include "decimal128.h"
extern uint32_t __dec_byte_swap (uint32_t);
void __host_to_ieee_128 (_Decimal128 in, decimal128 *out);
void __ieee_to_host_128 (decimal128 in, _Decimal128 *out);
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN 0
#endif
static void
__swap128 (char *src, char *dst)
{
uint32_t t1, t2, t3, t4;
if (!WORDS_BIGENDIAN)
{
memcpy (&t1, src, 4);
memcpy (&t2, src + 4, 4);
memcpy (&t3, src + 8, 4);
memcpy (&t4, src + 12, 4);
t1 = __dec_byte_swap (t1);
t2 = __dec_byte_swap (t2);
t3 = __dec_byte_swap (t3);
t4 = __dec_byte_swap (t4);
memcpy (dst, &t4, 4);
memcpy (dst + 4, &t3, 4);
memcpy (dst + 8, &t2, 4);
memcpy (dst + 12, &t1, 4);
}
else
memcpy (dst, src, 16);
}
void
__host_to_ieee_128 (_Decimal128 in, decimal128 *out)
{
__swap128 ((char *) &in, (char *) out);
}
void
__ieee_to_host_128 (decimal128 in, _Decimal128 *out)
{
__swap128 ((char *) &in, (char *) out);
}

View File

@ -0,0 +1,105 @@
/* This is a software decimal floating point library.
Copyright (C) 2007 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* This implements IEEE 754R decimal floating point arithmetic, but
does not provide a mechanism for setting the rounding mode, or for
generating or handling exceptions. Conversions between decimal
floating point types and other types depend on C library functions.
Contributed by Ben Elliston <bje@au.ibm.com>. */
/* The intended way to use this file is to make two copies, add `#define '
to one copy, then compile both copies and add them to libgcc.a. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "config.h"
#include "gstdint.h"
#include "bid-dpd.h"
#include "decimal32.h"
uint32_t __dec_byte_swap (uint32_t);
void __host_to_ieee_32 (_Decimal32 in, decimal32 *out);
void __ieee_to_host_32 (decimal32 in, _Decimal32 *out);
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN 0
#endif
uint32_t
__dec_byte_swap (uint32_t in)
{
uint32_t out = 0;
unsigned char *p = (unsigned char *) &out;
union {
uint32_t i;
unsigned char b[4];
} u;
u.i = in;
p[0] = u.b[3];
p[1] = u.b[2];
p[2] = u.b[1];
p[3] = u.b[0];
return out;
}
void
__host_to_ieee_32 (_Decimal32 in, decimal32 *out)
{
uint32_t t;
if (!WORDS_BIGENDIAN)
{
memcpy (&t, &in, 4);
t = __dec_byte_swap (t);
memcpy (out, &t, 4);
}
else
memcpy (out, &in, 4);
}
void
__ieee_to_host_32 (decimal32 in, _Decimal32 *out)
{
uint32_t t;
if (!WORDS_BIGENDIAN)
{
memcpy (&t, &in, 4);
t = __dec_byte_swap (t);
memcpy (out, &t, 4);
}
else
memcpy (out, &in, 4);
}

View File

@ -0,0 +1,86 @@
/* This is a software decimal floating point library.
Copyright (C) 2007 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 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
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.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* This implements IEEE 754R decimal floating point arithmetic, but
does not provide a mechanism for setting the rounding mode, or for
generating or handling exceptions. Conversions between decimal
floating point types and other types depend on C library functions.
Contributed by Ben Elliston <bje@au.ibm.com>. */
/* The intended way to use this file is to make two copies, add `#define '
to one copy, then compile both copies and add them to libgcc.a. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "config.h"
#include "gstdint.h"
#include "bid-dpd.h"
#include "decimal64.h"
uint32_t __dec_byte_swap (uint32_t);
void __host_to_ieee_64 (_Decimal64 in, decimal64 *out);
void __ieee_to_host_64 (decimal64 in, _Decimal64 *out);
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN 0
#endif
static void
__swap64 (char *src, char *dst)
{
uint32_t t1, t2;
if (!WORDS_BIGENDIAN)
{
memcpy (&t1, src, 4);
memcpy (&t2, src + 4, 4);
t1 = __dec_byte_swap (t1);
t2 = __dec_byte_swap (t2);
memcpy (dst, &t2, 4);
memcpy (dst + 4, &t1, 4);
}
else
memcpy (dst, src, 8);
}
void
__host_to_ieee_64 (_Decimal64 in, decimal64 *out)
{
__swap64 ((char *) &in, (char *) out);
}
void
__ieee_to_host_64 (decimal64 in, _Decimal64 *out)
{
__swap64 ((char *) &in, (char *) out);
}

View File

@ -69,6 +69,10 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to empty if `const' does not conform to ANSI C. */
#undef const

291
libdecnumber/configure vendored
View File

@ -311,7 +311,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB ACLOCAL AUTOCONF AUTOHEADER WARN_CFLAGS WARN_PEDANTIC WERROR CPP EGREP MAINT LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB ACLOCAL AUTOCONF AUTOHEADER WARN_CFLAGS WARN_PEDANTIC WERROR CPP EGREP MAINT enable_decimal_float LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@ -846,6 +846,10 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-werror-always enable -Werror despite compiler version
--enable-maintainer-mode enable rules only needed by maintainers
--enable-decimal-float={no,yes,bid,dpd}
enable decimal float extension to C. Selecting 'bid'
or 'dpd' choses which decimal floating point format
to use
Some influential environment variables:
CC C compiler command
@ -2616,7 +2620,7 @@ fi
echo "$as_me:$LINENO: result: $acx_cv_prog_cc_pedantic__Wno_long_long" >&5
echo "${ECHO_T}$acx_cv_prog_cc_pedantic__Wno_long_long" >&6
if test $acx_cv_prog_cc_pedantic__Wno_long_long = yes; then
WARN_PEDANTIC="-pedantic -Wno-long-long"
WARN_PEDANTIC="$WARN_PEDANTIC${WARN_PEDANTIC:+ }-pedantic -Wno-long-long"
fi
@ -2635,11 +2639,12 @@ else
enable_werror_always=no
fi;
if test $enable_werror_always = yes; then
WERROR=-Werror
WERROR="$WERROR${WERROR:+ }-Werror"
fi
# Checks for header files.
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@ -7316,6 +7321,285 @@ else
fi
# Default decimal format
# If you change the defaults here, be sure to change them in the GCC directory also
echo "$as_me:$LINENO: checking for decimal floating point" >&5
echo $ECHO_N "checking for decimal floating point... $ECHO_C" >&6
# Check whether --enable-decimal-float or --disable-decimal-float was given.
if test "${enable_decimal_float+set}" = set; then
enableval="$enable_decimal_float"
case $enable_decimal_float in
yes | no | bid | dpd) ;;
*) { { echo "$as_me:$LINENO: error: '$enable_decimal_float' is an invalid value for --enable-decimal-float.
Valid choices are 'yes', 'bid', 'dpd', and 'no'." >&5
echo "$as_me: error: '$enable_decimal_float' is an invalid value for --enable-decimal-float.
Valid choices are 'yes', 'bid', 'dpd', and 'no'." >&2;}
{ (exit 1); exit 1; }; } ;;
esac
else
case $target in
powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=yes
;;
*)
enable_decimal_float=no
;;
esac
fi;
# x86's use BID format instead of DPD
# In theory --enable-decimal-float=no should not compile anything
# For the sake of simplicity, just use the default format in this directory
if test x$enable_decimal_float = xyes -o x$enable_decimal_float = xno; then
case $target in
i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=bid
;;
*)
enable_decimal_float=dpd
;;
esac
fi
echo "$as_me:$LINENO: result: $enable_decimal_float" >&5
echo "${ECHO_T}$enable_decimal_float" >&6
echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
if test "${ac_cv_c_bigendian+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
# See if sys/param.h defines the BYTE_ORDER macro.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
#include <sys/param.h>
int
main ()
{
#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
bogus endian macros
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
# It does; now see whether it defined to BIG_ENDIAN or not.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
#include <sys/param.h>
int
main ()
{
#if BYTE_ORDER != BIG_ENDIAN
not big endian
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_c_bigendian=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_c_bigendian=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
# It does not; compile a test program.
if test "$cross_compiling" = yes; then
# try to guess the endianness by grepping values into an object file
ac_cv_c_bigendian=unknown
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
int
main ()
{
_ascii (); _ebcdic ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
ac_cv_c_bigendian=yes
fi
if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
if test "$ac_cv_c_bigendian" = unknown; then
ac_cv_c_bigendian=no
else
# finding both strings is unlikely to happen, but who knows?
ac_cv_c_bigendian=unknown
fi
fi
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int
main ()
{
/* Are we little or big endian? From Harbison&Steele. */
union
{
long l;
char c[sizeof (long)];
} u;
u.l = 1;
exit (u.c[sizeof (long) - 1] == 1);
}
_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_c_bigendian=no
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
ac_cv_c_bigendian=yes
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
echo "${ECHO_T}$ac_cv_c_bigendian" >&6
case $ac_cv_c_bigendian in
yes)
cat >>confdefs.h <<\_ACEOF
#define WORDS_BIGENDIAN 1
_ACEOF
;;
no)
;;
*)
{ { echo "$as_me:$LINENO: error: unknown endianness
presetting ac_cv_c_bigendian=no (or yes) will help" >&5
echo "$as_me: error: unknown endianness
presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
{ (exit 1); exit 1; }; } ;;
esac
# Output.
ac_config_headers="$ac_config_headers config.h:config.in"
@ -7980,6 +8264,7 @@ s,@WERROR@,$WERROR,;t t
s,@CPP@,$CPP,;t t
s,@EGREP@,$EGREP,;t t
s,@MAINT@,$MAINT,;t t
s,@enable_decimal_float@,$enable_decimal_float,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF

View File

@ -71,6 +71,51 @@ else
fi
AC_SUBST(MAINT)
# Default decimal format
# If you change the defaults here, be sure to change them in the GCC directory also
AC_MSG_CHECKING([for decimal floating point])
AC_ARG_ENABLE(decimal-float,
[ --enable-decimal-float={no,yes,bid,dpd}
enable decimal float extension to C. Selecting 'bid'
or 'dpd' choses which decimal floating point format
to use],
[
case $enable_decimal_float in
yes | no | bid | dpd) ;;
*) AC_MSG_ERROR(['$enable_decimal_float' is an invalid value for --enable-decimal-float.
Valid choices are 'yes', 'bid', 'dpd', and 'no'.]) ;;
esac
],
[
case $target in
powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=yes
;;
*)
enable_decimal_float=no
;;
esac
])
# x86's use BID format instead of DPD
# In theory --enable-decimal-float=no should not compile anything
# For the sake of simplicity, just use the default format in this directory
if test x$enable_decimal_float = xyes -o x$enable_decimal_float = xno; then
case $target in
i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=bid
;;
*)
enable_decimal_float=dpd
;;
esac
fi
AC_MSG_RESULT($enable_decimal_float)
AC_SUBST(enable_decimal_float)
AC_C_BIGENDIAN
# Output.
AC_CONFIG_HEADERS(config.h:config.in, [echo timestamp > stamp-h1])

View File

@ -90,6 +90,12 @@ typedef struct
#define decimal128SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Clear sign */
#define decimal128ClearSign(d) {(d)->bytes[0]&=~0x80;}
/* Flip sign */
#define decimal128FlipSign(d) {(d)->bytes[0]^=0x80;}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
@ -103,11 +109,13 @@ typedef struct
/* ------------------------------------------------------------------ */
#ifdef IN_LIBGCC2
#ifndef decimal128FromString
#define decimal128FromString __decimal128FromString
#define decimal128ToString __decimal128ToString
#define decimal128ToEngString __decimal128ToEngString
#define decimal128FromNumber __decimal128FromNumber
#define decimal128ToNumber __decimal128ToNumber
#endif
#endif
/* String conversions */

View File

@ -81,6 +81,12 @@ typedef struct
#define decimal32SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Clear sign */
#define decimal32ClearSign(d) {(d)->bytes[0]&=~0x80;}
/* Flip sign */
#define decimal32FlipSign(d) {(d)->bytes[0]^=0x80;}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
@ -93,12 +99,14 @@ typedef struct
/* ------------------------------------------------------------------ */
#ifdef IN_LIBGCC2
#ifndef decimal32FromString
#define decimal32FromString __decimal32FromString
#define decimal32ToString __decimal32ToString
#define decimal32ToEngString __decimal32ToEngString
#define decimal32FromNumber __decimal32FromNumber
#define decimal32ToNumber __decimal32ToNumber
#endif
#endif
/* String conversions. */
decimal32 *decimal32FromString (decimal32 *, const char *, decContext *);

View File

@ -85,6 +85,12 @@ typedef struct
#define decimal64SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Clear sign */
#define decimal64ClearSign(d) {(d)->bytes[0]&=~0x80;}
/* Flip sign */
#define decimal64FlipSign(d) {(d)->bytes[0]^=0x80;}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; type */
/* of exponent must be unsigned */
@ -97,11 +103,13 @@ typedef struct
/* ------------------------------------------------------------------ */
#ifdef IN_LIBGCC2
#ifndef decimal64FromString
#define decimal64FromString __decimal64FromString
#define decimal64ToString __decimal64ToString
#define decimal64ToEngString __decimal64ToEngString
#define decimal64FromNumber __decimal64FromNumber
#define decimal64ToNumber __decimal64ToNumber
#endif
#endif
/* String conversions */

View File

@ -1,3 +1,18 @@
2007-03-23 Michael Meissner <michael.meissner@amd.com>
H.J. Lu <hongjiu.lu@intel.com>
* Makefile.in (enable_decimal_float): New.
(DECNUMINC): Add
-I$(srcdir)/../libdecnumber/$(enable_decimal_float).
(dec-objects): Move decimal32, decimal64 and decimal128 to ...
(decbits-filenames): This.
(decbits-objects): New.
(libgcc-objects): Add $(decbits-objects).
* configure.ac: Support * --enable-decimal-float={no,yes,bid,dpd}.
Substitute enable_decimal_float.
* configure: Regenerated.
2007-03-19 Hans-Peter Nilsson <hp@axis.com>
* config.host (cris-*-elf | cris-*-none): Set extra_parts.

View File

@ -37,6 +37,7 @@ SHELL = @SHELL@
enable_shared = @enable_shared@
decimal_float = @decimal_float@
enable_decimal_float = @enable_decimal_float@
host_noncanonical = @host_noncanonical@
@ -183,7 +184,13 @@ export slibdir
version := $(shell $(CC) -dumpversion)
DECNUMINC = -I$(srcdir)/../libdecnumber -I$(MULTIBUILDTOP)../../libdecnumber
ifeq ($(decimal_float),yes)
DECNUMINC = -I$(srcdir)/../libdecnumber/$(enable_decimal_float) \
-I$(srcdir)/../libdecnumber \
-I$(MULTIBUILDTOP)../../libdecnumber
else
DECNUMINC =
endif
# Specify the directories to be searched for header files.
# Both . and srcdir are used, in that order,
@ -467,23 +474,33 @@ ifneq ($(D32PBIT)$(D64PBIT)$(D128PBIT),)
dec-filenames += decContext decNumber decExcept decRound decLibrary decUtility
endif
ifneq ($(D32PBIT),)
dec-filenames += decimal32
endif
ifneq ($(D64PBIT),)
dec-filenames += decimal64
endif
ifneq ($(D128PBIT),)
dec-filenames += decimal128
endif
dec-objects = $(patsubst %,%$(objext),$(dec-filenames))
$(dec-objects): %$(objext): $(srcdir)/../libdecnumber/%.c
$(gcc_compile) -c $<
libgcc-objects += $(dec-objects)
decbits-filenames =
ifneq ($(D32PBIT),)
decbits-filenames += decimal32
endif
ifneq ($(D64PBIT),)
decbits-filenames += decimal64
endif
ifneq ($(D128PBIT),)
decbits-filenames += decimal128
endif
ifeq ($(enable_decimal_float),bid)
decbits-filenames += bid2dpd_dpd2bid
endif
decbits-objects = $(patsubst %,%$(objext),$(decbits-filenames))
$(decbits-objects): %$(objext): $(srcdir)/../libdecnumber/$(enable_decimal_float)/%.c
$(gcc_compile) -c $<
libgcc-objects += $(decbits-objects)
# Next build individual support functions.
ifneq ($(D32PBIT),)
d32pbit-o = $(patsubst %,%$(objext),$(D32PBIT_FUNCS))

46
libgcc/configure vendored
View File

@ -272,7 +272,7 @@ PACKAGE_STRING='GNU C Runtime Library 1.0'
PACKAGE_BUGREPORT=''
ac_unique_file="static-object.mk"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float vis_hide tmake_file extra_parts asm_hidden_op LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libgcc_topdir enable_shared slibdir INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK build build_cpu build_vendor build_os host host_cpu host_vendor host_os host_noncanonical build_libsubdir build_subdir host_subdir target_subdir AR ac_ct_AR LIPO ac_ct_LIPO NM ac_ct_NM RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP decimal_float enable_decimal_float vis_hide tmake_file extra_parts asm_hidden_op LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@ -811,6 +811,10 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-shared don't provide a shared libgcc
--enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory
--enable-decimal-float={no,yes,bid,dpd}
enable decimal float extension to C. Selecting 'bid'
or 'dpd' choses which decimal floating point format
to use
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@ -3286,6 +3290,45 @@ echo "${ECHO_T}$libgcc_cv_dfp" >&6
decimal_float=$libgcc_cv_dfp
# Check whether --enable-decimal-float or --disable-decimal-float was given.
if test "${enable_decimal_float+set}" = set; then
enableval="$enable_decimal_float"
case $enable_decimal_float in
yes | no | bid | dpd) ;;
*) { { echo "$as_me:$LINENO: error: '$enable_decimal_float' is an invalid value for --enable-decimal-float.
Valid choices are 'yes', 'bid', 'dpd', and 'no'." >&5
echo "$as_me: error: '$enable_decimal_float' is an invalid value for --enable-decimal-float.
Valid choices are 'yes', 'bid', 'dpd', and 'no'." >&2;}
{ (exit 1); exit 1; }; } ;;
esac
else
case $target in
powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=yes
;;
*)
enable_decimal_float=no
;;
esac
fi;
# x86's use BID format instead of DPD
if test x$enable_decimal_float = xyes; then
case $target in
i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=bid
;;
*)
enable_decimal_float=dpd
;;
esac
fi
# Collect host-machine-specific information.
. ${srcdir}/config.host
@ -4039,6 +4082,7 @@ s,@EXEEXT@,$EXEEXT,;t t
s,@OBJEXT@,$OBJEXT,;t t
s,@CPP@,$CPP,;t t
s,@decimal_float@,$decimal_float,;t t
s,@enable_decimal_float@,$enable_decimal_float,;t t
s,@vis_hide@,$vis_hide,;t t
s,@tmake_file@,$tmake_file,;t t
s,@extra_parts@,$extra_parts,;t t

View File

@ -107,6 +107,42 @@ AC_CACHE_CHECK([whether decimal floating point is supported], [libgcc_cv_dfp],
decimal_float=$libgcc_cv_dfp
AC_SUBST(decimal_float)
AC_ARG_ENABLE(decimal-float,
[ --enable-decimal-float={no,yes,bid,dpd}
enable decimal float extension to C. Selecting 'bid'
or 'dpd' choses which decimal floating point format
to use],
[
case $enable_decimal_float in
yes | no | bid | dpd) ;;
*) AC_MSG_ERROR(['$enable_decimal_float' is an invalid value for --enable-decimal-float.
Valid choices are 'yes', 'bid', 'dpd', and 'no'.]) ;;
esac
],
[
case $target in
powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=yes
;;
*)
enable_decimal_float=no
;;
esac
])
# x86's use BID format instead of DPD
if test x$enable_decimal_float = xyes; then
case $target in
i?86*-*-linux* | x86_64*-*-linux*)
enable_decimal_float=bid
;;
*)
enable_decimal_float=dpd
;;
esac
fi
AC_SUBST(enable_decimal_float)
# Collect host-machine-specific information.
. ${srcdir}/config.host