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:
parent
cca643862d
commit
79b87c74d7
42 changed files with 12547 additions and 160 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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
59
gcc/configure
vendored
|
@ -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]*)
|
||||
|
|
|
@ -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
|
||||
|
|
16
gcc/dfp.c
16
gcc/dfp.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
83
gcc/optabs.c
83
gcc/optabs.c
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
43
libdecnumber/bid/bid-dpd.h
Normal file
43
libdecnumber/bid/bid-dpd.h
Normal 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 *);
|
428
libdecnumber/bid/bid2dpd_dpd2bid.c
Normal file
428
libdecnumber/bid/bid2dpd_dpd2bid.c
Normal 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;
|
||||
}
|
10407
libdecnumber/bid/bid2dpd_dpd2bid.h
Normal file
10407
libdecnumber/bid/bid2dpd_dpd2bid.h
Normal file
File diff suppressed because it is too large
Load diff
148
libdecnumber/bid/decimal128.c
Normal file
148
libdecnumber/bid/decimal128.c
Normal 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;
|
||||
}
|
1
libdecnumber/bid/decimal128.h
Normal file
1
libdecnumber/bid/decimal128.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include "dpd/decimal128.h"
|
148
libdecnumber/bid/decimal32.c
Normal file
148
libdecnumber/bid/decimal32.c
Normal 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;
|
||||
}
|
1
libdecnumber/bid/decimal32.h
Normal file
1
libdecnumber/bid/decimal32.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include "dpd/decimal32.h"
|
148
libdecnumber/bid/decimal64.c
Normal file
148
libdecnumber/bid/decimal64.c
Normal 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;
|
||||
}
|
1
libdecnumber/bid/decimal64.h
Normal file
1
libdecnumber/bid/decimal64.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include "dpd/decimal64.h"
|
82
libdecnumber/bid/host-ieee128.c
Normal file
82
libdecnumber/bid/host-ieee128.c
Normal 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);
|
||||
}
|
105
libdecnumber/bid/host-ieee32.c
Normal file
105
libdecnumber/bid/host-ieee32.c
Normal 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);
|
||||
}
|
86
libdecnumber/bid/host-ieee64.c
Normal file
86
libdecnumber/bid/host-ieee64.c
Normal 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);
|
||||
}
|
|
@ -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
291
libdecnumber/configure
vendored
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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 */
|
|
@ -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 *);
|
|
@ -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 */
|
|
@ -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.
|
||||
|
|
|
@ -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
46
libgcc/configure
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue