* src-release (GDB_SUPPORT_DIRS): Add libdecnumber.

* libdecnumber: New directory, imported from GCC.
This commit is contained in:
Daniel Jacobowitz 2007-10-11 18:15:02 +00:00
parent 607ae575a7
commit f5bc1778c3
62 changed files with 42043 additions and 1 deletions

View File

@ -1,3 +1,8 @@
2007-10-11 Daniel Jacobowitz <dan@codesourcery.com>
* src-release (GDB_SUPPORT_DIRS): Add libdecnumber.
* libdecnumber: New directory, imported from GCC.
2007-10-08 Mike Frysinger <vapier@gentoo.org>
* configure.ac (CFLAGS_FOR_BUILD, CXXFLAGS_FOR_BUILD,

View File

@ -57,6 +57,10 @@ intl/; config.rhost; libiberty/; libiberty's part of include/
merge. Otherwise, changes are automatically merged, usually
within a day.
libdecnumber/
See libiberty. The master copy of this directory is in the GCC
repository.
ltconfig; ltmain.sh; ltcf-*.sh
libtool: http://www.gnu.org/software/libtool/
Changes need to be done in tandem with the official LIBTOOL

315
libdecnumber/ChangeLog Normal file
View File

@ -0,0 +1,315 @@
2007-09-10 Janis Johnson <janis187@us.ibm.com>
Ben Elliston <bje@au.ibm.com>
* Makefile.in (libdecnumber_a_OBJS): Remove decUtility.o
(dependencies): Add Symbols headers.
* decContext.c: Upgrade to decNumber 3.53.
* decContext.h: Ditto.
* decDPD.h: Ditto.
* decNumber.c: Ditto.
* decNumber.h: Ditto.
* decNumberLocal.h: Ditto.
* decBasic.c: New file from decNumber 3.53.
* decCommon.c: Ditto.
* decDouble.c: Ditto.
* decDouble.h: Ditto.
* decQuad.c: Ditto.
* decQuad.h: Ditto.
* decSingle.c: Ditto.
* decSingle.h: Ditto.
* decPacked.c: Ditto.
* decPacked.h: Ditto.
* dpd/decimal128.c: Upgrade to decNumber 3.53.
* dpd/decimal128.h: Ditto.
* dpd/decimal32.c: Ditto.
* dpd/decimal32.h: Ditto.
* dpd/decimal64.c: Ditto.
* dpd/decimal64.h: Ditto.
* decLibrary.c (__dec_byte_swap): Remove.
* decContextSymbols.h: New file.
* decDoubleSymbols.h: New file.
* decNumberSymbols.h: New file.
* decPackedSymbols.h: New file.
* decQuadSymbols.h: New file.
* decSingleSymbols.h: New file.
* decUtility.c: Delete file.
* decUtility.h: Delete file.
* bid/decimal128Symbols.h: New file.
* bid/decimal128Local.h: New file.
* bid/decimal32Symbols.h: New file.
* bid/decimal64Symbols.h: New file.
* bid/host-ieee128.c (__swap128): Remove.
(__host_to_ieee_128, __ieee_to_host_128): Don't handle endianness.
* bid/host-ieee32.c (__dec_type_swap): Remove.
(__host_to_ieee_32, __ieee_to_host_32): Don't handle endianness.
* bid/host-ieee64.c (__swap64): Remove.
(__host_to_ieee_64, __ieee_to_host_64): Don't handle endianness.
* dpd/decimal32Symbols.h: New file.
* dpd/decimal64Symbols.h: New file.
* dpd/decimal128Symbols.h: New file.
* dpd/decimal128Local.h: New file.
2007-06-18 Martin Michlmayr <tbm@cyrius.com>
H.J. Lu <hongjiu.lu@intel.com>
* configure.ac: Add AC_CANONICAL_TARGET.
* configure: Regenerated.
2007-04-16 H.J. Lu <hongjiu.lu@intel.com>
* Makefile.in (aclocal.m4): Depend on stdint.m4 instead of
acx.m4.
* aclocal.m4: Regenerated by aclocal 1.9.6.
2007-04-11 Kai Tietz <kai.tietz@onevision.com>
* configure: Regenerate.
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,
decimal128.h, decimal32.c, decimal32.h, decimal64.c, decimal64.h,
decLibrary.c, decNumber.c, decNumber.h, decNumberLocal.h,
decRound.c, decRound.h, decUtility.c, decUtility.h: Add
libgcc-style license exception clause.
2007-03-01 Brooks Moses <brooks.moses@codesourcery.com>
* Makefile.in: Add dummy install-pdf target.
2007-01-29 Janis Johnson <janis187@us.ibm.com>
* decExcept.c: New.
* decExcept.h: New.
2006-11-29 Janis Johnson <janis187@us.ibm.com>
* decRound.c: Move declarations to new file, update comments.
* decRound.h: New file.
2006-11-21 Janis Johnson <janis187@us.ibm.com>
* decLibrary.c (__dec_type_swap): Add prototype.
(__dfp_enable_traps, dfp_raise): Delete.
* Makefile.in: Don't include decRound in library used by compiler.
2006-10-10 Brooks Moses <bmoses@stanford.edu>
* Makefile.in: Added empty "pdf" target.
2006-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* decNumber.c (decNumberPower): Constify.
* decNumber.h (decNumberPower): Likewise.
2006-09-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* configure.ac (ACX_PROG_CC_WARNING_OPTS): Add -Wcast-qual.
* configure, config.in: Regenerate.
* decContext.c (decContextStatusToString): Constify.
* decContext.h (decContextStatusToString): Likewise.
* decNumber.c (decNumberToString, decNumberToEngString,
decNumberAbs, decNumberAdd, decNumberCompare, decNumberDivide,
decNumberDivideInteger, decNumberMax, decNumberMin,
decNumberMinus, decNumberPlus, decNumberMultiply,
decNumberNormalize, decNumberQuantize, decNumberRescale,
decNumberRemainder, decNumberRemainderNear,
decNumberSameQuantum, decNumberSquareRoot, decNumberSubtract,
decNumberToIntegralValue, decNumberCopy, decToString, decAddOp,
decDivideOp, decMultiplyOp, decQuantizeOp, decCompareOp,
decCompare, decUnitCompare, decUnitAddSub, decRoundOperand,
decCopyFit, decSetCoeff, decGetInt, decNaNs, decGetDigits,
decNumberShow, decDumpAr, decCheckOperands, decCheckNumber):
Likewise.
* decNumber.h (decNumberToString, decNumberToEngString,
decNumberAbs, decNumberAdd, decNumberCompare, decNumberDivide,
decNumberDivideInteger, decNumberMax, decNumberMin,
decNumberMinus, decNumberMultiply, decNumberNormalize,
decNumberPlus, decNumberQuantize, decNumberRemainder,
decNumberRemainderNear, decNumberRescale,
decNumberSameQuantum, decNumberSquareRoot, decNumberSubtract,
decNumberToIntegralValue, decNumberCopy): Likewise.
* decUtility.c (decDensePackCoeff, decDenseUnpackCoeff):
Likewise.
* decUtility.h (decDensePackCoeff, decDenseUnpackCoeff):
Likewise.
* decimal128.c (decimal128FromNumber, decimal128ToNumber,
decimal128ToString, decimal128ToEngString, decimal128Show):
Likewise.
* decimal128.h (decimal128ToString, decimal128ToEngString,
decimal128FromNumber, decimal128ToNumber): Likewise.
* decimal32.c (decimal32FromNumber, decimal32ToNumber,
decimal32ToString, decimal32ToEngString, decimal32Show):
Likewise.
* decimal32.h (decimal32ToString, decimal32ToEngString,
decimal32FromNumber, decimal32ToNumber): Likewise.
* decimal64.c (decimal64FromNumber, decimal64ToNumber,
decimal64ToString, decimal64ToEngString, decimal64Show):
Likewise.
* decimal64.h (decimal64ToString, decimal64ToEngString,
decimal64FromNumber, decimal64ToNumber): Likewise.
2006-08-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* decContext.c (decContextSetStatusFromString): Constify.
* decContext.h (decContextSetStatusFromString): Likewise.
* decNumber.c (decNumberFromString): Likewise.
* decNumber.h (decNumberFromString): Likewise.
* decimal128.c (decimal128FromString): Likewise.
* decimal128.h (decimal128FromString): Likewise.
* decimal32.c (decimal32FromString): Likewise.
* decimal32.h (decimal32FromString): Likewise.
* decimal64.c (decimal64FromString): Likewise.
* decimal64.h (decimal64FromString): Likewise.
2006-07-25 Paolo Bonzini <bonzini@gnu.org>
PR build/26188
* configure: Regenerate.
2006-06-23 Ben Elliston <bje@au.ibm.com>
* decNumber.h (decNumberNegate): Remove.
2006-05-23 Carlos O'Donell <carlos@codesourcery.com>
* Makefile.in: Add install-html target. Add install-html to .PHONY
2006-02-06 Ben Elliston <bje@au.ibm.com>
* decLibrary.c (__dec_byte_swap): Use uint32_t for argument and
return types.
2006-01-03 Roger Sayle <roger@eyesopen.com>
Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* decNumber.c (__NO_STRING_INLINES): Define to prevent glibc macro
definition of strcpy from generating compilation warnings.
2006-01-02 Paolo Bonzini <bonzini@gnu.org>
PR target/25259
* configure.ac: Use GCC_HEADER_STDINT.
* decContext.h: Include gstdint.h.
* aclocal.m4: Regenerate.
* configure: Regenerate.
2005-12-20 Roger Sayle <roger@eyesopen.com>
* decNumber.c (decStrEq): Cast string contents to unsigned char
instead of int before calling tolower.
2005-12-20 Roger Sayle <roger@eyesopen.com>
* decNumber.c (decStrEq): Cast operands to int before calling
tolower to avoid compilation warnings on Tru64.
2005-12-05 Ben Elliston <bje@au.ibm.com>
* Makefile.in (clean): Remove stray reference to libcpp.a.
* decimal128.h, decContext.c, decRound.c, decimal32.c,
decNumber.c, decContext.h, decimal64.c, decimal32.h, decNumber.h,
decimal64.h, decUtility.c, decLibrary.c, configure.ac,
decNumberLocal.h, decUtility.h, decDPD.h, decimal128.c: Update FSF
office address.
2005-12-01 Ben Elliston <bje@au.ibm.com>
* Makefile.in (libdecnumber_a_SOURCES): Drop decLibrary.c.
* decUtility.c (__dec_byte_swap): Move from here ..
* decLibrary.c: .. to here.
2005-11-23 Gerald Pfeifer <gerald@pfeifer.com>
* decContext.h: Properly guard inclusion of stdint.h
* decContext.c: Include config.h
* decLibrary.c: Ditto.
* decNumber.c: Ditto.
* decRound.c: Ditto.
* decUtility.c: Ditto.
* decimal32.c: Ditto.
* decimal64.c: Ditto.
* decimal128.c: Ditto.
2005-11-29 Ben Elliston <bje@au.ibm.com>
* decUtility.c: Remove redundant #includes.
* decUtility.h (__dec_byte_swap): Remove prototype.
2005-11-29 Ben Elliston <bje@au.ibm.com>
* configure.ac: New file.
* aclocal.m4: Likewise.
* Makefile.in: Likewise.
* configure: Generate.
* config.in: Likewise.
2005-11-29 Ben Elliston <bje@au.ibm.com>
* decimal32.h, decimal64.h, decimal128.h: New.
* decimal32.c, decimal64.c, decimal128.c: Likewise.
* decContext.c, decContext.h: Likewise.
* decUtility.c, decUtility.h: Likewise.
* decNumber.c, decNumber.h, decNumberLocal.h: Likewise.
* decDPD.h: Likewise.
* decLibrary.c, decRound.c: Likewise.

186
libdecnumber/Makefile.in Normal file
View File

@ -0,0 +1,186 @@
# @configure_input@
# Makefile for libdecnumber. Run 'configure' to generate Makefile from Makefile.in
# Copyright (C) 2005, 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.
@SET_MAKE@
srcdir = @srcdir@
top_builddir = .
VPATH = @srcdir@
INSTALL = @INSTALL@
AR = ar
ARFLAGS = cru
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
CC = @CC@
CFLAGS = @CFLAGS@
WARN_CFLAGS = @WARN_CFLAGS@ @WARN_PEDANTIC@ @WERROR@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBICONV = @LIBICONV@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
SHELL = @SHELL@
datadir = @datadir@
exec_prefix = @prefix@
libdir = @libdir@
localedir = $(datadir)/locale
prefix = @prefix@
enable_decimal_float= @enable_decimal_float@
INCLUDES = -I$(srcdir) -I.
ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS)
libdecnumber_a_OBJS = decNumber.o decContext.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 \
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
.SUFFIXES:
.SUFFIXES: .c .o .obj
libdecnumber.a: $(libdecnumber_a_OBJS)
-rm -f $@
$(AR) $(ARFLAGS) $@ $(libdecnumber_a_OBJS)
$(RANLIB) $@
# Rules to rebuild the configuration
Makefile: $(srcdir)/Makefile.in config.status
$(SHELL) ./config.status Makefile
config.status: $(srcdir)/configure
$(SHELL) ./config.status --recheck
$(srcdir)/configure: @MAINT@ $(srcdir)/aclocal.m4
cd $(srcdir) && $(AUTOCONF)
$(srcdir)/aclocal.m4: @MAINT@ $(srcdir)/../config/stdint.m4 \
$(srcdir)/../config/warnings.m4 \
$(srcdir)/configure.ac
cd $(srcdir) && $(ACLOCAL) -I ../config
config.h: stamp-h1
test -f config.h || (rm -f stamp-h1 && $(MAKE) stamp-h1)
stamp-h1: $(srcdir)/config.in config.status
-rm -f stamp-h1
$(SHELL) ./config.status config.h
$(srcdir)/config.in: @MAINT@ $(srcdir)/configure
cd $(srcdir) && $(AUTOHEADER)
-rm -f stamp-h1
# Dependencies.
decContext.o: decContext.c decContext.h decNumberLocal.h \
decContextSymbols.h
decNumber.o: decNumber.c decNumber.h decContext.h decNumberLocal.h \
decNumberSymbols.h
decimal32.o: $(enable_decimal_float)/decimal32.c \
$(enable_decimal_float)/decimal32.h \
$(enable_decimal_float)/decimal32Symbols.h \
decNumber.h decContext.h decNumberLocal.h
$(COMPILE) $<
decimal64.o: $(enable_decimal_float)/decimal64.c \
$(enable_decimal_float)/decimal64.h \
$(enable_decimal_float)/decimal64Symbols.h \
decNumber.h decContext.h decNumberLocal.h
$(COMPILE) $<
decimal128.o: $(enable_decimal_float)/decimal128.c \
$(enable_decimal_float)/decimal128.h \
$(enable_decimal_float)/decimal128Symbols.h\
$(enable_decimal_float)/decimal128Local.h\
decNumber.h decContext.h decNumberLocal.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:
-rm -f *.o
clean: mostlyclean
-rm -rf makedepend$(EXEEXT) libdecnumber.a $(srcdir)/autom4te.cache
distclean: clean
-rm -f config.h stamp-h1 config.status config.cache config.log \
configure.lineno configure.status.lineno Makefile localedir.h \
localedir.hs
maintainer-clean: distclean
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-rm -f $(srcdir)/configure $(srcdir)/aclocal.m4
check:
installcheck:
dvi:
pdf:
html:
info:
install-info:
install-pdf:
install-man:
install-html:
install:
.PHONY: installdirs install install-strip mostlyclean clean distclean \
maintainer-clean check installcheck dvi pdf html info install-info \
install-pdf install-man update-po install-html
COMPILE = source='$<' object='$@' libtool=no $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(ALL_CFLAGS) -c
# Implicit rules
.c.o:
$(COMPILE) $<
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

15
libdecnumber/aclocal.m4 vendored Normal file
View File

@ -0,0 +1,15 @@
# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_include([../config/stdint.m4])
m4_include([../config/warnings.m4])

View File

@ -0,0 +1,43 @@
/* Copyright (C) 2007
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
typedef unsigned int UINT32;
typedef unsigned long long UINT64;
typedef struct { UINT64 w[2]; } UINT128;
#ifndef IN_LIBGCC2
#define _Decimal32 UINT32
#define _Decimal64 UINT64
#define _Decimal128 UINT128
#endif
void _bid_to_dpd32 (_Decimal32 *, _Decimal32 *);
void _dpd_to_bid32 (_Decimal32 *, _Decimal32 *);
void _bid_to_dpd64 (_Decimal64 *, _Decimal64 *);
void _dpd_to_bid64 (_Decimal64 *, _Decimal64 *);
void _bid_to_dpd128 (_Decimal128 *, _Decimal128 *);
void _dpd_to_bid128 (_Decimal128 *, _Decimal128 *);

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,48 @@
/* 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 <string.h>
#include "bid-dpd.h"
#include "decimal128.h"
void __host_to_ieee_128 (_Decimal128 in, decimal128 *out);
void __ieee_to_host_128 (decimal128 in, _Decimal128 *out);
void
__host_to_ieee_128 (_Decimal128 in, decimal128 *out)
{
memcpy ((char *) out, (char *) &in, 16);
}
void
__ieee_to_host_128 (decimal128 in, _Decimal128 *out)
{
memcpy ((char *) out, (char *) &in, 16);
}

View File

@ -0,0 +1,57 @@
/* 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 <string.h>
#include "bid-dpd.h"
#include "decimal32.h"
void __host_to_ieee_32 (_Decimal32 in, decimal32 *out);
void __ieee_to_host_32 (decimal32 in, _Decimal32 *out);
void
__host_to_ieee_32 (_Decimal32 in, decimal32 *out)
{
memcpy ((char *) out, (char *) &in, 4);
}
void
__ieee_to_host_32 (decimal32 in, _Decimal32 *out)
{
memcpy ((char *) out, (char *) &in, 4);
}

View File

@ -0,0 +1,57 @@
/* 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 <string.h>
#include "bid-dpd.h"
#include "decimal64.h"
void __host_to_ieee_64 (_Decimal64 in, decimal64 *out);
void __ieee_to_host_64 (decimal64 in, _Decimal64 *out);
void
__host_to_ieee_64 (_Decimal64 in, decimal64 *out)
{
memcpy ((char *) out, (char *) &in, 8);
}
void
__ieee_to_host_64 (decimal64 in, _Decimal64 *out)
{
memcpy ((char *) out, (char *) &in, 8);
}

80
libdecnumber/config.in Normal file
View File

@ -0,0 +1,80 @@
/* config.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of a `char', as computed by sizeof. */
#undef SIZEOF_CHAR
/* The size of a `int', as computed by sizeof. */
#undef SIZEOF_INT
/* The size of a `long', as computed by sizeof. */
#undef SIZEOF_LONG
/* The size of a `short', as computed by sizeof. */
#undef SIZEOF_SHORT
/* The size of a `void *', as computed by sizeof. */
#undef SIZEOF_VOID_P
/* 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
/* Define to `long' if <sys/types.h> does not define. */
#undef off_t

9329
libdecnumber/configure vendored Executable file

File diff suppressed because it is too large Load Diff

125
libdecnumber/configure.ac Normal file
View File

@ -0,0 +1,125 @@
# configure.ac for libdecnumber -*- Autoconf -*-
# Process this file with autoconf to generate a configuration script.
# Copyright 2005, 2006 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.
AC_PREREQ(2.59)
AC_INIT(libdecnumber, [ ], gcc-bugs@gcc.gnu.org, libdecnumber)
AC_CONFIG_SRCDIR(decNumber.h)
AC_CONFIG_MACRO_DIR(../config)
# Checks for programs.
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_RANLIB
MISSING=`cd $ac_aux_dir && ${PWDCMD-pwd}`/missing
AC_CHECK_PROGS([ACLOCAL], [aclocal], [$MISSING aclocal])
AC_CHECK_PROGS([AUTOCONF], [autoconf], [$MISSING autoconf])
AC_CHECK_PROGS([AUTOHEADER], [autoheader], [$MISSING autoheader])
# Figure out what compiler warnings we can enable.
# See config/warnings.m4 for details.
ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wstrict-prototypes \
-Wmissing-prototypes -Wold-style-definition \
-Wmissing-format-attribute -Wcast-qual])
ACX_PROG_CC_WARNING_ALMOST_PEDANTIC([-Wno-long-long])
# Only enable with --enable-werror-always until existing warnings are
# corrected.
ACX_PROG_CC_WARNINGS_ARE_ERRORS([manual])
# Checks for header files.
AC_CHECK_HEADERS(ctype.h stddef.h string.h stdio.h)
GCC_HEADER_STDINT(gstdint.h)
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_OFF_T
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
# Checks for library functions.
AC_HEADER_STDC
AC_ARG_ENABLE(maintainer-mode,
[ --enable-maintainer-mode enable rules only needed by maintainers],,
enable_maintainer_mode=no)
if test "x$enable_maintainer_mode" = xno; then
MAINT='#'
else
MAINT=
fi
AC_SUBST(MAINT)
AC_CANONICAL_TARGET
# 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])
AC_CONFIG_FILES(Makefile)
AC_OUTPUT

3769
libdecnumber/decBasic.c Normal file

File diff suppressed because it is too large Load Diff

1771
libdecnumber/decCommon.c Normal file

File diff suppressed because it is too large Load Diff

432
libdecnumber/decContext.c Normal file
View File

@ -0,0 +1,432 @@
/* Decimal context module for the decNumber C Library.
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Decimal Context module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for handling arithmetic */
/* context structures. */
/* ------------------------------------------------------------------ */
#include <string.h> /* for strcmp */
#include <stdio.h> /* for printf if DECCHECK */
#include "config.h" /* for GCC definitions */
#include "decContext.h" /* context and base types */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#if DECCHECK
/* compile-time endian tester [assumes sizeof(Int)>1] */
static const Int mfcone=1; /* constant 1 */
static const Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
#define LITEND *mfctop /* named flag; 1=little-endian */
#endif
/* ------------------------------------------------------------------ */
/* round-for-reround digits */
/* ------------------------------------------------------------------ */
const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
/* ------------------------------------------------------------------ */
/* Powers of ten (powers[n]==10**n, 0<=n<=9) */
/* ------------------------------------------------------------------ */
const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
10000000, 100000000, 1000000000};
/* ------------------------------------------------------------------ */
/* decContextClearStatus -- clear bits in current status */
/* */
/* context is the context structure to be queried */
/* mask indicates the bits to be cleared (the status bit that */
/* corresponds to each 1 bit in the mask is cleared) */
/* returns context */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decContext *decContextClearStatus(decContext *context, uInt mask) {
context->status&=~mask;
return context;
} /* decContextClearStatus */
/* ------------------------------------------------------------------ */
/* decContextDefault -- initialize a context structure */
/* */
/* context is the structure to be initialized */
/* kind selects the required set of default values, one of: */
/* DEC_INIT_BASE -- select ANSI X3-274 defaults */
/* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */
/* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */
/* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */
/* For any other value a valid context is returned, but with */
/* Invalid_operation set in the status field. */
/* returns a context structure with the appropriate initial values. */
/* ------------------------------------------------------------------ */
decContext * decContextDefault(decContext *context, Int kind) {
/* set defaults... */
context->digits=9; /* 9 digits */
context->emax=DEC_MAX_EMAX; /* 9-digit exponents */
context->emin=DEC_MIN_EMIN; /* .. balanced */
context->round=DEC_ROUND_HALF_UP; /* 0.5 rises */
context->traps=DEC_Errors; /* all but informational */
context->status=0; /* cleared */
context->clamp=0; /* no clamping */
#if DECSUBSET
context->extended=0; /* cleared */
#endif
switch (kind) {
case DEC_INIT_BASE:
/* [use defaults] */
break;
case DEC_INIT_DECIMAL32:
context->digits=7; /* digits */
context->emax=96; /* Emax */
context->emin=-95; /* Emin */
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps=0; /* no traps set */
context->clamp=1; /* clamp exponents */
#if DECSUBSET
context->extended=1; /* set */
#endif
break;
case DEC_INIT_DECIMAL64:
context->digits=16; /* digits */
context->emax=384; /* Emax */
context->emin=-383; /* Emin */
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps=0; /* no traps set */
context->clamp=1; /* clamp exponents */
#if DECSUBSET
context->extended=1; /* set */
#endif
break;
case DEC_INIT_DECIMAL128:
context->digits=34; /* digits */
context->emax=6144; /* Emax */
context->emin=-6143; /* Emin */
context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
context->traps=0; /* no traps set */
context->clamp=1; /* clamp exponents */
#if DECSUBSET
context->extended=1; /* set */
#endif
break;
default: /* invalid Kind */
/* use defaults, and .. */
decContextSetStatus(context, DEC_Invalid_operation); /* trap */
}
#if DECCHECK
if (LITEND!=DECLITEND) {
const char *adj;
if (LITEND) adj="little";
else adj="big";
printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
DECLITEND, adj);
}
#endif
return context;} /* decContextDefault */
/* ------------------------------------------------------------------ */
/* decContextGetRounding -- return current rounding mode */
/* */
/* context is the context structure to be queried */
/* returns the rounding mode */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
enum rounding decContextGetRounding(decContext *context) {
return context->round;
} /* decContextGetRounding */
/* ------------------------------------------------------------------ */
/* decContextGetStatus -- return current status */
/* */
/* context is the context structure to be queried */
/* returns status */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decContextGetStatus(decContext *context) {
return context->status;
} /* decContextGetStatus */
/* ------------------------------------------------------------------ */
/* decContextRestoreStatus -- restore bits in current status */
/* */
/* context is the context structure to be updated */
/* newstatus is the source for the bits to be restored */
/* mask indicates the bits to be restored (the status bit that */
/* corresponds to each 1 bit in the mask is set to the value of */
/* the correspnding bit in newstatus) */
/* returns context */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decContext *decContextRestoreStatus(decContext *context,
uInt newstatus, uInt mask) {
context->status&=~mask; /* clear the selected bits */
context->status|=(mask&newstatus); /* or in the new bits */
return context;
} /* decContextRestoreStatus */
/* ------------------------------------------------------------------ */
/* decContextSaveStatus -- save bits in current status */
/* */
/* context is the context structure to be queried */
/* mask indicates the bits to be saved (the status bits that */
/* correspond to each 1 bit in the mask are saved) */
/* returns the AND of the mask and the current status */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decContextSaveStatus(decContext *context, uInt mask) {
return context->status&mask;
} /* decContextSaveStatus */
/* ------------------------------------------------------------------ */
/* decContextSetRounding -- set current rounding mode */
/* */
/* context is the context structure to be updated */
/* newround is the value which will replace the current mode */
/* returns context */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decContext *decContextSetRounding(decContext *context,
enum rounding newround) {
context->round=newround;
return context;
} /* decContextSetRounding */
/* ------------------------------------------------------------------ */
/* decContextSetStatus -- set status and raise trap if appropriate */
/* */
/* context is the context structure to be updated */
/* status is the DEC_ exception code */
/* returns the context structure */
/* */
/* Control may never return from this routine, if there is a signal */
/* handler and it takes a long jump. */
/* ------------------------------------------------------------------ */
decContext * decContextSetStatus(decContext *context, uInt status) {
context->status|=status;
if (status & context->traps) raise(SIGFPE);
return context;} /* decContextSetStatus */
/* ------------------------------------------------------------------ */
/* decContextSetStatusFromString -- set status from a string + trap */
/* */
/* context is the context structure to be updated */
/* string is a string exactly equal to one that might be returned */
/* by decContextStatusToString */
/* */
/* The status bit corresponding to the string is set, and a trap */
/* is raised if appropriate. */
/* */
/* returns the context structure, unless the string is equal to */
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
/* returned. */
/* ------------------------------------------------------------------ */
decContext * decContextSetStatusFromString(decContext *context,
const char *string) {
if (strcmp(string, DEC_Condition_CS)==0)
return decContextSetStatus(context, DEC_Conversion_syntax);
if (strcmp(string, DEC_Condition_DZ)==0)
return decContextSetStatus(context, DEC_Division_by_zero);
if (strcmp(string, DEC_Condition_DI)==0)
return decContextSetStatus(context, DEC_Division_impossible);
if (strcmp(string, DEC_Condition_DU)==0)
return decContextSetStatus(context, DEC_Division_undefined);
if (strcmp(string, DEC_Condition_IE)==0)
return decContextSetStatus(context, DEC_Inexact);
if (strcmp(string, DEC_Condition_IS)==0)
return decContextSetStatus(context, DEC_Insufficient_storage);
if (strcmp(string, DEC_Condition_IC)==0)
return decContextSetStatus(context, DEC_Invalid_context);
if (strcmp(string, DEC_Condition_IO)==0)
return decContextSetStatus(context, DEC_Invalid_operation);
#if DECSUBSET
if (strcmp(string, DEC_Condition_LD)==0)
return decContextSetStatus(context, DEC_Lost_digits);
#endif
if (strcmp(string, DEC_Condition_OV)==0)
return decContextSetStatus(context, DEC_Overflow);
if (strcmp(string, DEC_Condition_PA)==0)
return decContextSetStatus(context, DEC_Clamped);
if (strcmp(string, DEC_Condition_RO)==0)
return decContextSetStatus(context, DEC_Rounded);
if (strcmp(string, DEC_Condition_SU)==0)
return decContextSetStatus(context, DEC_Subnormal);
if (strcmp(string, DEC_Condition_UN)==0)
return decContextSetStatus(context, DEC_Underflow);
if (strcmp(string, DEC_Condition_ZE)==0)
return context;
return NULL; /* Multiple status, or unknown */
} /* decContextSetStatusFromString */
/* ------------------------------------------------------------------ */
/* decContextSetStatusFromStringQuiet -- set status from a string */
/* */
/* context is the context structure to be updated */
/* string is a string exactly equal to one that might be returned */
/* by decContextStatusToString */
/* */
/* The status bit corresponding to the string is set; no trap is */
/* raised. */
/* */
/* returns the context structure, unless the string is equal to */
/* DEC_Condition_MU or is not recognized. In these cases NULL is */
/* returned. */
/* ------------------------------------------------------------------ */
decContext * decContextSetStatusFromStringQuiet(decContext *context,
const char *string) {
if (strcmp(string, DEC_Condition_CS)==0)
return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
if (strcmp(string, DEC_Condition_DZ)==0)
return decContextSetStatusQuiet(context, DEC_Division_by_zero);
if (strcmp(string, DEC_Condition_DI)==0)
return decContextSetStatusQuiet(context, DEC_Division_impossible);
if (strcmp(string, DEC_Condition_DU)==0)
return decContextSetStatusQuiet(context, DEC_Division_undefined);
if (strcmp(string, DEC_Condition_IE)==0)
return decContextSetStatusQuiet(context, DEC_Inexact);
if (strcmp(string, DEC_Condition_IS)==0)
return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
if (strcmp(string, DEC_Condition_IC)==0)
return decContextSetStatusQuiet(context, DEC_Invalid_context);
if (strcmp(string, DEC_Condition_IO)==0)
return decContextSetStatusQuiet(context, DEC_Invalid_operation);
#if DECSUBSET
if (strcmp(string, DEC_Condition_LD)==0)
return decContextSetStatusQuiet(context, DEC_Lost_digits);
#endif
if (strcmp(string, DEC_Condition_OV)==0)
return decContextSetStatusQuiet(context, DEC_Overflow);
if (strcmp(string, DEC_Condition_PA)==0)
return decContextSetStatusQuiet(context, DEC_Clamped);
if (strcmp(string, DEC_Condition_RO)==0)
return decContextSetStatusQuiet(context, DEC_Rounded);
if (strcmp(string, DEC_Condition_SU)==0)
return decContextSetStatusQuiet(context, DEC_Subnormal);
if (strcmp(string, DEC_Condition_UN)==0)
return decContextSetStatusQuiet(context, DEC_Underflow);
if (strcmp(string, DEC_Condition_ZE)==0)
return context;
return NULL; /* Multiple status, or unknown */
} /* decContextSetStatusFromStringQuiet */
/* ------------------------------------------------------------------ */
/* decContextSetStatusQuiet -- set status without trap */
/* */
/* context is the context structure to be updated */
/* status is the DEC_ exception code */
/* returns the context structure */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
context->status|=status;
return context;} /* decContextSetStatusQuiet */
/* ------------------------------------------------------------------ */
/* decContextStatusToString -- convert status flags to a string */
/* */
/* context is a context with valid status field */
/* */
/* returns a constant string describing the condition. If multiple */
/* (or no) flags are set, a generic constant message is returned. */
/* ------------------------------------------------------------------ */
const char *decContextStatusToString(const decContext *context) {
Int status=context->status;
/* test the five IEEE first, as some of the others are ambiguous when */
/* DECEXTFLAG=0 */
if (status==DEC_Invalid_operation ) return DEC_Condition_IO;
if (status==DEC_Division_by_zero ) return DEC_Condition_DZ;
if (status==DEC_Overflow ) return DEC_Condition_OV;
if (status==DEC_Underflow ) return DEC_Condition_UN;
if (status==DEC_Inexact ) return DEC_Condition_IE;
if (status==DEC_Division_impossible ) return DEC_Condition_DI;
if (status==DEC_Division_undefined ) return DEC_Condition_DU;
if (status==DEC_Rounded ) return DEC_Condition_RO;
if (status==DEC_Clamped ) return DEC_Condition_PA;
if (status==DEC_Subnormal ) return DEC_Condition_SU;
if (status==DEC_Conversion_syntax ) return DEC_Condition_CS;
if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
if (status==DEC_Invalid_context ) return DEC_Condition_IC;
#if DECSUBSET
if (status==DEC_Lost_digits ) return DEC_Condition_LD;
#endif
if (status==0 ) return DEC_Condition_ZE;
return DEC_Condition_MU; /* Multiple errors */
} /* decContextStatusToString */
/* ------------------------------------------------------------------ */
/* decContextTestSavedStatus -- test bits in saved status */
/* */
/* oldstatus is the status word to be tested */
/* mask indicates the bits to be tested (the oldstatus bits that */
/* correspond to each 1 bit in the mask are tested) */
/* returns 1 if any of the tested bits are 1, or 0 otherwise */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
return (oldstatus&mask)!=0;
} /* decContextTestSavedStatus */
/* ------------------------------------------------------------------ */
/* decContextTestStatus -- test bits in current status */
/* */
/* context is the context structure to be updated */
/* mask indicates the bits to be tested (the status bits that */
/* correspond to each 1 bit in the mask are tested) */
/* returns 1 if any of the tested bits are 1, or 0 otherwise */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uInt decContextTestStatus(decContext *context, uInt mask) {
return (context->status&mask)!=0;
} /* decContextTestStatus */
/* ------------------------------------------------------------------ */
/* decContextZeroStatus -- clear all status bits */
/* */
/* context is the context structure to be updated */
/* returns context */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decContext *decContextZeroStatus(decContext *context) {
context->status=0;
return context;
} /* decContextZeroStatus */

258
libdecnumber/decContext.h Normal file
View File

@ -0,0 +1,258 @@
/* Decimal context header module for the decNumber C Library.
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Decimal Context module header */
/* ------------------------------------------------------------------ */
/* */
/* Context variables must always have valid values: */
/* */
/* status -- [any bits may be cleared, but not set, by user] */
/* round -- must be one of the enumerated rounding modes */
/* */
/* The following variables are implied for fixed size formats (i.e., */
/* they are ignored) but should still be set correctly in case used */
/* with decNumber functions: */
/* */
/* clamp -- must be either 0 or 1 */
/* digits -- must be in the range 1 through 999999999 */
/* emax -- must be in the range 0 through 999999999 */
/* emin -- must be in the range 0 through -999999999 */
/* extended -- must be either 0 or 1 [present only if DECSUBSET] */
/* traps -- only defined bits may be set */
/* */
/* ------------------------------------------------------------------ */
#if !defined(DECCONTEXT)
#define DECCONTEXT
#define DECCNAME "decContext" /* Short name */
#define DECCFULLNAME "Decimal Context Descriptor" /* Verbose name */
#define DECCAUTHOR "Mike Cowlishaw" /* Who to blame */
#include "gstdint.h" /* C99 standard integers */
#include <stdio.h> /* for printf, etc. */
#include <signal.h> /* for traps */
/* Extended flags setting -- set this to 0 to use only IEEE flags */
#define DECEXTFLAG 1 /* 1=enable extended flags */
/* Conditional code flag -- set this to 0 for best performance */
#define DECSUBSET 0 /* 1=enable subset arithmetic */
/* Context for operations, with associated constants */
enum rounding {
DEC_ROUND_CEILING, /* round towards +infinity */
DEC_ROUND_UP, /* round away from 0 */
DEC_ROUND_HALF_UP, /* 0.5 rounds up */
DEC_ROUND_HALF_EVEN, /* 0.5 rounds to nearest even */
DEC_ROUND_HALF_DOWN, /* 0.5 rounds down */
DEC_ROUND_DOWN, /* round towards 0 (truncate) */
DEC_ROUND_FLOOR, /* round towards -infinity */
DEC_ROUND_05UP, /* round for reround */
DEC_ROUND_MAX /* enum must be less than this */
};
#define DEC_ROUND_DEFAULT DEC_ROUND_HALF_EVEN;
typedef struct {
int32_t digits; /* working precision */
int32_t emax; /* maximum positive exponent */
int32_t emin; /* minimum negative exponent */
enum rounding round; /* rounding mode */
uint32_t traps; /* trap-enabler flags */
uint32_t status; /* status flags */
uint8_t clamp; /* flag: apply IEEE exponent clamp */
#if DECSUBSET
uint8_t extended; /* flag: special-values allowed */
#endif
} decContext;
/* Maxima and Minima for context settings */
#define DEC_MAX_DIGITS 999999999
#define DEC_MIN_DIGITS 1
#define DEC_MAX_EMAX 999999999
#define DEC_MIN_EMAX 0
#define DEC_MAX_EMIN 0
#define DEC_MIN_EMIN -999999999
#define DEC_MAX_MATH 999999 /* max emax, etc., for math funcs. */
/* Classifications for decimal numbers, aligned with 754r (note */
/* that 'normal' and 'subnormal' are meaningful only with a */
/* decContext or a fixed size format). */
enum decClass {
DEC_CLASS_SNAN,
DEC_CLASS_QNAN,
DEC_CLASS_NEG_INF,
DEC_CLASS_NEG_NORMAL,
DEC_CLASS_NEG_SUBNORMAL,
DEC_CLASS_NEG_ZERO,
DEC_CLASS_POS_ZERO,
DEC_CLASS_POS_SUBNORMAL,
DEC_CLASS_POS_NORMAL,
DEC_CLASS_POS_INF
};
/* Strings for the decClasses */
#define DEC_ClassString_SN "sNaN"
#define DEC_ClassString_QN "NaN"
#define DEC_ClassString_NI "-Infinity"
#define DEC_ClassString_NN "-Normal"
#define DEC_ClassString_NS "-Subnormal"
#define DEC_ClassString_NZ "-Zero"
#define DEC_ClassString_PZ "+Zero"
#define DEC_ClassString_PS "+Subnormal"
#define DEC_ClassString_PN "+Normal"
#define DEC_ClassString_PI "+Infinity"
#define DEC_ClassString_UN "Invalid"
/* Trap-enabler and Status flags (exceptional conditions), and */
/* their names. The top byte is reserved for internal use */
#if DECEXTFLAG
/* Extended flags */
#define DEC_Conversion_syntax 0x00000001
#define DEC_Division_by_zero 0x00000002
#define DEC_Division_impossible 0x00000004
#define DEC_Division_undefined 0x00000008
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
#define DEC_Inexact 0x00000020
#define DEC_Invalid_context 0x00000040
#define DEC_Invalid_operation 0x00000080
#if DECSUBSET
#define DEC_Lost_digits 0x00000100
#endif
#define DEC_Overflow 0x00000200
#define DEC_Clamped 0x00000400
#define DEC_Rounded 0x00000800
#define DEC_Subnormal 0x00001000
#define DEC_Underflow 0x00002000
#else
/* IEEE flags only */
#define DEC_Conversion_syntax 0x00000010
#define DEC_Division_by_zero 0x00000002
#define DEC_Division_impossible 0x00000010
#define DEC_Division_undefined 0x00000010
#define DEC_Insufficient_storage 0x00000010 /* [when malloc fails] */
#define DEC_Inexact 0x00000001
#define DEC_Invalid_context 0x00000010
#define DEC_Invalid_operation 0x00000010
#if DECSUBSET
#define DEC_Lost_digits 0x00000000
#endif
#define DEC_Overflow 0x00000008
#define DEC_Clamped 0x00000000
#define DEC_Rounded 0x00000000
#define DEC_Subnormal 0x00000000
#define DEC_Underflow 0x00000004
#endif
/* IEEE 854 groupings for the flags */
/* [DEC_Clamped, DEC_Lost_digits, DEC_Rounded, and DEC_Subnormal */
/* are not in IEEE 854] */
#define DEC_IEEE_854_Division_by_zero (DEC_Division_by_zero)
#if DECSUBSET
#define DEC_IEEE_854_Inexact (DEC_Inexact | DEC_Lost_digits)
#else
#define DEC_IEEE_854_Inexact (DEC_Inexact)
#endif
#define DEC_IEEE_854_Invalid_operation (DEC_Conversion_syntax | \
DEC_Division_impossible | \
DEC_Division_undefined | \
DEC_Insufficient_storage | \
DEC_Invalid_context | \
DEC_Invalid_operation)
#define DEC_IEEE_854_Overflow (DEC_Overflow)
#define DEC_IEEE_854_Underflow (DEC_Underflow)
/* flags which are normally errors (result is qNaN, infinite, or 0) */
#define DEC_Errors (DEC_IEEE_854_Division_by_zero | \
DEC_IEEE_854_Invalid_operation | \
DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow)
/* flags which cause a result to become qNaN */
#define DEC_NaNs DEC_IEEE_854_Invalid_operation
/* flags which are normally for information only (finite results) */
#if DECSUBSET
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact \
| DEC_Lost_digits)
#else
#define DEC_Information (DEC_Clamped | DEC_Rounded | DEC_Inexact)
#endif
/* Name strings for the exceptional conditions */
#define DEC_Condition_CS "Conversion syntax"
#define DEC_Condition_DZ "Division by zero"
#define DEC_Condition_DI "Division impossible"
#define DEC_Condition_DU "Division undefined"
#define DEC_Condition_IE "Inexact"
#define DEC_Condition_IS "Insufficient storage"
#define DEC_Condition_IC "Invalid context"
#define DEC_Condition_IO "Invalid operation"
#if DECSUBSET
#define DEC_Condition_LD "Lost digits"
#endif
#define DEC_Condition_OV "Overflow"
#define DEC_Condition_PA "Clamped"
#define DEC_Condition_RO "Rounded"
#define DEC_Condition_SU "Subnormal"
#define DEC_Condition_UN "Underflow"
#define DEC_Condition_ZE "No status"
#define DEC_Condition_MU "Multiple status"
#define DEC_Condition_Length 21 /* length of the longest string, */
/* including terminator */
/* Initialization descriptors, used by decContextDefault */
#define DEC_INIT_BASE 0
#define DEC_INIT_DECIMAL32 32
#define DEC_INIT_DECIMAL64 64
#define DEC_INIT_DECIMAL128 128
/* Synonyms */
#define DEC_INIT_DECSINGLE DEC_INIT_DECIMAL32
#define DEC_INIT_DECDOUBLE DEC_INIT_DECIMAL64
#define DEC_INIT_DECQUAD DEC_INIT_DECIMAL128
/* decContext routines */
#include "decContextSymbols.h"
extern decContext * decContextClearStatus(decContext *, uint32_t);
extern decContext * decContextDefault(decContext *, int32_t);
extern enum rounding decContextGetRounding(decContext *);
extern uint32_t decContextGetStatus(decContext *);
extern decContext * decContextRestoreStatus(decContext *, uint32_t, uint32_t);
extern uint32_t decContextSaveStatus(decContext *, uint32_t);
extern decContext * decContextSetRounding(decContext *, enum rounding);
extern decContext * decContextSetStatus(decContext *, uint32_t);
extern decContext * decContextSetStatusFromString(decContext *, const char *);
extern decContext * decContextSetStatusFromStringQuiet(decContext *, const char *);
extern decContext * decContextSetStatusQuiet(decContext *, uint32_t);
extern const char * decContextStatusToString(const decContext *);
extern uint32_t decContextTestSavedStatus(uint32_t, uint32_t);
extern uint32_t decContextTestStatus(decContext *, uint32_t);
extern decContext * decContextZeroStatus(decContext *);
#endif

View File

@ -0,0 +1,22 @@
#if !defined(DECCONTEXTSYMBOLS)
#define DECCONTEXTSYMBOLS
#ifdef IN_LIBGCC2
#define decContextClearStatus __decContextClearStatus
#define decContextDefault __decContextDefault
#define decContextGetRounding __decContextGetRounding
#define decContextGetStatus __decContextGetStatus
#define decContextRestoreStatus __decContextRestoreStatus
#define decContextSaveStatus __decContextSaveStatus
#define decContextSetRounding __decContextSetRounding
#define decContextSetStatus __decContextSetStatus
#define decContextSetStatusFromString __decContextSetStatusFromString
#define decContextSetStatusFromStringQuiet __decContextSetStatusFromStringQuiet
#define decContextSetStatusQuiet __decContextSetStatusQuiet
#define decContextStatusToString __decContextStatusToString
#define decContextTestSavedStatus __decContextTestSavedStatus
#define decContextTestStatus __decContextTestStatus
#define decContextZeroStatus __decContextZeroStatus
#endif
#endif

1214
libdecnumber/decDPD.h Normal file

File diff suppressed because it is too large Load Diff

154
libdecnumber/decDouble.c Normal file
View File

@ -0,0 +1,154 @@
/* decDouble module for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* decDouble.c -- decDouble operations module */
/* ------------------------------------------------------------------ */
/* This module comprises decDouble operations (including conversions) */
/* ------------------------------------------------------------------ */
#include "decContext.h" /* public includes */
#include "decDouble.h" /* .. */
/* Constant mappings for shared code */
#define DECPMAX DECDOUBLE_Pmax
#define DECEMIN DECDOUBLE_Emin
#define DECEMAX DECDOUBLE_Emax
#define DECEMAXD DECDOUBLE_EmaxD
#define DECBYTES DECDOUBLE_Bytes
#define DECSTRING DECDOUBLE_String
#define DECECONL DECDOUBLE_EconL
#define DECBIAS DECDOUBLE_Bias
#define DECLETS DECDOUBLE_Declets
#define DECQTINY (-DECDOUBLE_Bias)
/* parameters of next-wider format */
#define DECWBYTES DECQUAD_Bytes
#define DECWPMAX DECQUAD_Pmax
#define DECWECONL DECQUAD_EconL
#define DECWBIAS DECQUAD_Bias
/* Type and function mappings for shared code */
#define decFloat decDouble /* Type name */
#define decFloatWider decQuad /* Type name */
/* Utilities and conversions (binary results, extractors, etc.) */
#define decFloatFromBCD decDoubleFromBCD
#define decFloatFromInt32 decDoubleFromInt32
#define decFloatFromPacked decDoubleFromPacked
#define decFloatFromString decDoubleFromString
#define decFloatFromUInt32 decDoubleFromUInt32
#define decFloatFromWider decDoubleFromWider
#define decFloatGetCoefficient decDoubleGetCoefficient
#define decFloatGetExponent decDoubleGetExponent
#define decFloatSetCoefficient decDoubleSetCoefficient
#define decFloatSetExponent decDoubleSetExponent
#define decFloatShow decDoubleShow
#define decFloatToBCD decDoubleToBCD
#define decFloatToEngString decDoubleToEngString
#define decFloatToInt32 decDoubleToInt32
#define decFloatToInt32Exact decDoubleToInt32Exact
#define decFloatToPacked decDoubleToPacked
#define decFloatToString decDoubleToString
#define decFloatToUInt32 decDoubleToUInt32
#define decFloatToUInt32Exact decDoubleToUInt32Exact
#define decFloatToWider decDoubleToWider
#define decFloatZero decDoubleZero
/* Computational (result is a decFloat) */
#define decFloatAbs decDoubleAbs
#define decFloatAdd decDoubleAdd
#define decFloatAnd decDoubleAnd
#define decFloatDivide decDoubleDivide
#define decFloatDivideInteger decDoubleDivideInteger
#define decFloatFMA decDoubleFMA
#define decFloatInvert decDoubleInvert
#define decFloatLogB decDoubleLogB
#define decFloatMax decDoubleMax
#define decFloatMaxMag decDoubleMaxMag
#define decFloatMin decDoubleMin
#define decFloatMinMag decDoubleMinMag
#define decFloatMinus decDoubleMinus
#define decFloatMultiply decDoubleMultiply
#define decFloatNextMinus decDoubleNextMinus
#define decFloatNextPlus decDoubleNextPlus
#define decFloatNextToward decDoubleNextToward
#define decFloatOr decDoubleOr
#define decFloatPlus decDoublePlus
#define decFloatQuantize decDoubleQuantize
#define decFloatReduce decDoubleReduce
#define decFloatRemainder decDoubleRemainder
#define decFloatRemainderNear decDoubleRemainderNear
#define decFloatRotate decDoubleRotate
#define decFloatScaleB decDoubleScaleB
#define decFloatShift decDoubleShift
#define decFloatSubtract decDoubleSubtract
#define decFloatToIntegralValue decDoubleToIntegralValue
#define decFloatToIntegralExact decDoubleToIntegralExact
#define decFloatXor decDoubleXor
/* Comparisons */
#define decFloatCompare decDoubleCompare
#define decFloatCompareSignal decDoubleCompareSignal
#define decFloatCompareTotal decDoubleCompareTotal
#define decFloatCompareTotalMag decDoubleCompareTotalMag
/* Copies */
#define decFloatCanonical decDoubleCanonical
#define decFloatCopy decDoubleCopy
#define decFloatCopyAbs decDoubleCopyAbs
#define decFloatCopyNegate decDoubleCopyNegate
#define decFloatCopySign decDoubleCopySign
/* Non-computational */
#define decFloatClass decDoubleClass
#define decFloatClassString decDoubleClassString
#define decFloatDigits decDoubleDigits
#define decFloatIsCanonical decDoubleIsCanonical
#define decFloatIsFinite decDoubleIsFinite
#define decFloatIsInfinite decDoubleIsInfinite
#define decFloatIsInteger decDoubleIsInteger
#define decFloatIsNaN decDoubleIsNaN
#define decFloatIsNormal decDoubleIsNormal
#define decFloatIsSignaling decDoubleIsSignaling
#define decFloatIsSignalling decDoubleIsSignalling
#define decFloatIsSigned decDoubleIsSigned
#define decFloatIsSubnormal decDoubleIsSubnormal
#define decFloatIsZero decDoubleIsZero
#define decFloatRadix decDoubleRadix
#define decFloatSameQuantum decDoubleSameQuantum
#define decFloatVersion decDoubleVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-arithmetic decFloat routines */
#include "decBasic.c" /* basic formats routines */
/* Below here will move to shared file as completed */

164
libdecnumber/decDouble.h Normal file
View File

@ -0,0 +1,164 @@
/* decDouble module header for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* decDouble.h -- Decimal 64-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
#if !defined(DECDOUBLE)
#define DECDOUBLE
#define DECDOUBLENAME "decimalDouble" /* Short name */
#define DECDOUBLETITLE "Decimal 64-bit datum" /* Verbose name */
#define DECDOUBLEAUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decDoubles */
#define DECDOUBLE_Bytes 8 /* length */
#define DECDOUBLE_Pmax 16 /* maximum precision (digits) */
#define DECDOUBLE_Emin -383 /* minimum adjusted exponent */
#define DECDOUBLE_Emax 384 /* maximum adjusted exponent */
#define DECDOUBLE_EmaxD 3 /* maximum exponent digits */
#define DECDOUBLE_Bias 398 /* bias for the exponent */
#define DECDOUBLE_String 25 /* maximum string length, +1 */
#define DECDOUBLE_EconL 8 /* exponent continuation length */
#define DECDOUBLE_Declets 5 /* count of declets */
/* highest biased exponent (Elimit-1) */
#define DECDOUBLE_Ehigh (DECDOUBLE_Emax + DECDOUBLE_Bias - (DECDOUBLE_Pmax-1))
/* Required includes */
#include "decContext.h"
#include "decQuad.h"
/* The decDouble decimal 64-bit type, accessible by bytes */
typedef struct {
uint8_t bytes[DECDOUBLE_Bytes]; /* fields: 1, 5, 8, 50 bits */
} decDouble;
/* ---------------------------------------------------------------- */
/* Routines -- implemented as decFloat routines in common files */
/* ---------------------------------------------------------------- */
#include "decDoubleSymbols.h"
/* Utilities and conversions, extractors, etc.) */
extern decDouble * decDoubleFromBCD(decDouble *, int32_t, const uint8_t *, int32_t);
extern decDouble * decDoubleFromInt32(decDouble *, int32_t);
extern decDouble * decDoubleFromPacked(decDouble *, int32_t, const uint8_t *);
extern decDouble * decDoubleFromString(decDouble *, const char *, decContext *);
extern decDouble * decDoubleFromUInt32(decDouble *, uint32_t);
extern decDouble * decDoubleFromWider(decDouble *, const decQuad *, decContext *);
extern int32_t decDoubleGetCoefficient(const decDouble *, uint8_t *);
extern int32_t decDoubleGetExponent(const decDouble *);
extern decDouble * decDoubleSetCoefficient(decDouble *, const uint8_t *, int32_t);
extern decDouble * decDoubleSetExponent(decDouble *, decContext *, int32_t);
extern void decDoubleShow(const decDouble *, const char *);
extern int32_t decDoubleToBCD(const decDouble *, int32_t *, uint8_t *);
extern char * decDoubleToEngString(const decDouble *, char *);
extern int32_t decDoubleToInt32(const decDouble *, decContext *, enum rounding);
extern int32_t decDoubleToInt32Exact(const decDouble *, decContext *, enum rounding);
extern int32_t decDoubleToPacked(const decDouble *, int32_t *, uint8_t *);
extern char * decDoubleToString(const decDouble *, char *);
extern uint32_t decDoubleToUInt32(const decDouble *, decContext *, enum rounding);
extern uint32_t decDoubleToUInt32Exact(const decDouble *, decContext *, enum rounding);
extern decQuad * decDoubleToWider(const decDouble *, decQuad *);
extern decDouble * decDoubleZero(decDouble *);
/* Computational (result is a decDouble) */
extern decDouble * decDoubleAbs(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleAdd(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleAnd(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleDivide(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleDivideInteger(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleFMA(decDouble *, const decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleInvert(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleLogB(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMax(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMaxMag(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMin(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMinMag(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMinus(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleMultiply(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleNextMinus(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleNextPlus(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleNextToward(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleOr(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoublePlus(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleQuantize(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleReduce(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleRemainder(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleRemainderNear(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleRotate(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleScaleB(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleShift(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleSubtract(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleToIntegralValue(decDouble *, const decDouble *, decContext *, enum rounding);
extern decDouble * decDoubleToIntegralExact(decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleXor(decDouble *, const decDouble *, const decDouble *, decContext *);
/* Comparisons */
extern decDouble * decDoubleCompare(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleCompareSignal(decDouble *, const decDouble *, const decDouble *, decContext *);
extern decDouble * decDoubleCompareTotal(decDouble *, const decDouble *, const decDouble *);
extern decDouble * decDoubleCompareTotalMag(decDouble *, const decDouble *, const decDouble *);
/* Copies */
extern decDouble * decDoubleCanonical(decDouble *, const decDouble *);
extern decDouble * decDoubleCopy(decDouble *, const decDouble *);
extern decDouble * decDoubleCopyAbs(decDouble *, const decDouble *);
extern decDouble * decDoubleCopyNegate(decDouble *, const decDouble *);
extern decDouble * decDoubleCopySign(decDouble *, const decDouble *, const decDouble *);
/* Non-computational */
extern enum decClass decDoubleClass(const decDouble *);
extern const char * decDoubleClassString(const decDouble *);
extern uint32_t decDoubleDigits(const decDouble *);
extern uint32_t decDoubleIsCanonical(const decDouble *);
extern uint32_t decDoubleIsFinite(const decDouble *);
extern uint32_t decDoubleIsInfinite(const decDouble *);
extern uint32_t decDoubleIsInteger(const decDouble *);
extern uint32_t decDoubleIsNaN(const decDouble *);
extern uint32_t decDoubleIsNormal(const decDouble *);
extern uint32_t decDoubleIsSignaling(const decDouble *);
extern uint32_t decDoubleIsSignalling(const decDouble *);
extern uint32_t decDoubleIsSigned(const decDouble *);
extern uint32_t decDoubleIsSubnormal(const decDouble *);
extern uint32_t decDoubleIsZero(const decDouble *);
extern uint32_t decDoubleRadix(const decDouble *);
extern uint32_t decDoubleSameQuantum(const decDouble *, const decDouble *);
extern const char * decDoubleVersion(void);
/* decNumber conversions; these are implemented as macros so as not */
/* to force a dependency on decimal64 and decNumber in decDouble. */
#define decDoubleToNumber(dq, dn) decimal64ToNumber((decimal64 *)(dq), dn)
#define decDoubleFromNumber(dq, dn, set) (decDouble *)decimal64FromNumber((decimal64 *)(dq), dn, set)
#endif

View File

@ -0,0 +1,84 @@
#if !defined(DECDOUBLESYMBOLS)
#define DECDOUBLESYMBOLS
#ifdef IN_LIBGCC2
#define decDoubleAbs __decDoubleAbs
#define decDoubleAdd __decDoubleAdd
#define decDoubleAnd __decDoubleAnd
#define decDoubleCanonical __decDoubleCanonical
#define decDoubleClass __decDoubleClass
#define decDoubleClassString __decDoubleClassString
#define decDoubleCompare __decDoubleCompare
#define decDoubleCompareSignal __decDoubleCompareSignal
#define decDoubleCompareTotal __decDoubleCompareTotal
#define decDoubleCompareTotalMag __decDoubleCompareTotalMag
#define decDoubleCopy __decDoubleCopy
#define decDoubleCopyAbs __decDoubleCopyAbs
#define decDoubleCopyNegate __decDoubleCopyNegate
#define decDoubleCopySign __decDoubleCopySign
#define decDoubleDigits __decDoubleDigits
#define decDoubleDivide __decDoubleDivide
#define decDoubleDivideInteger __decDoubleDivideInteger
#define decDoubleFMA __decDoubleFMA
#define decDoubleFromBCD __decDoubleFromBCD
#define decDoubleFromInt32 __decDoubleFromInt32
#define decDoubleFromPacked __decDoubleFromPacked
#define decDoubleFromString __decDoubleFromString
#define decDoubleFromUInt32 __decDoubleFromUInt32
#define decDoubleFromWider __decDoubleFromWider
#define decDoubleGetCoefficient __decDoubleGetCoefficient
#define decDoubleGetExponent __decDoubleGetExponent
#define decDoubleInvert __decDoubleInvert
#define decDoubleIsCanonical __decDoubleIsCanonical
#define decDoubleIsFinite __decDoubleIsFinite
#define decDoubleIsInfinite __decDoubleIsInfinite
#define decDoubleIsInteger __decDoubleIsInteger
#define decDoubleIsNaN __decDoubleIsNaN
#define decDoubleIsNormal __decDoubleIsNormal
#define decDoubleIsSignaling __decDoubleIsSignaling
#define decDoubleIsSignalling __decDoubleIsSignalling
#define decDoubleIsSigned __decDoubleIsSigned
#define decDoubleIsSubnormal __decDoubleIsSubnormal
#define decDoubleIsZero __decDoubleIsZero
#define decDoubleLogB __decDoubleLogB
#define decDoubleMax __decDoubleMax
#define decDoubleMaxMag __decDoubleMaxMag
#define decDoubleMin __decDoubleMin
#define decDoubleMinMag __decDoubleMinMag
#define decDoubleMinus __decDoubleMinus
#define decDoubleMultiply __decDoubleMultiply
#define decDoubleNextMinus __decDoubleNextMinus
#define decDoubleNextPlus __decDoubleNextPlus
#define decDoubleNextToward __decDoubleNextToward
#define decDoubleOr __decDoubleOr
#define decDoublePlus __decDoublePlus
#define decDoubleQuantize __decDoubleQuantize
#define decDoubleRadix __decDoubleRadix
#define decDoubleReduce __decDoubleReduce
#define decDoubleRemainder __decDoubleRemainder
#define decDoubleRemainderNear __decDoubleRemainderNear
#define decDoubleRotate __decDoubleRotate
#define decDoubleSameQuantum __decDoubleSameQuantum
#define decDoubleScaleB __decDoubleScaleB
#define decDoubleSetCoefficient __decDoubleSetCoefficient
#define decDoubleSetExponent __decDoubleSetExponent
#define decDoubleShift __decDoubleShift
#define decDoubleShow __decDoubleShow
#define decDoubleSubtract __decDoubleSubtract
#define decDoubleToBCD __decDoubleToBCD
#define decDoubleToEngString __decDoubleToEngString
#define decDoubleToInt32 __decDoubleToInt32
#define decDoubleToInt32Exact __decDoubleToInt32Exact
#define decDoubleToIntegralExact __decDoubleToIntegralExact
#define decDoubleToIntegralValue __decDoubleToIntegralValue
#define decDoubleToPacked __decDoubleToPacked
#define decDoubleToString __decDoubleToString
#define decDoubleToUInt32 __decDoubleToUInt32
#define decDoubleToUInt32Exact __decDoubleToUInt32Exact
#define decDoubleToWider __decDoubleToWider
#define decDoubleVersion __decDoubleVersion
#define decDoubleXor __decDoubleXor
#define decDoubleZero __decDoubleZero
#endif
#endif

59
libdecnumber/decExcept.c Normal file
View File

@ -0,0 +1,59 @@
/* Temporary library support for decimal floating point.
Copyright (C) 2005, 2006 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 <fenv.h>
#include "config.h"
#include "decContext.h"
#include "decExcept.h"
/* Internal, non-documented functions for testing libgcc functions.
This support is not sufficient for real use. */
static int __dfp_except_flags = 0;
/* Clear the dummy exception flags. */
void
__dfp_clear_except (void)
{
__dfp_except_flags = 0;
}
/* Return the dummy exception flags corresponding to the mask. */
int
__dfp_test_except (int mask)
{
return __dfp_except_flags & mask;
}
/* Set dummy exception flags. */
void
__dfp_raise_except (int flags)
{
__dfp_except_flags |= flags;
}

39
libdecnumber/decExcept.h Normal file
View File

@ -0,0 +1,39 @@
/* Temporary library support for decimal floating point.
Copyright (C) 2006 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 <fenv.h>
#include "config.h"
#include "decContext.h"
#define DFP_EXCEPTIONS_ENABLED 1
#define DFP_HANDLE_EXCEPTIONS(A) __dfp_raise_except(A)
void __dfp_clear_except (void);
int __dfp_test_except (int);
void __dfp_raise_except (int);

76
libdecnumber/decLibrary.c Normal file
View File

@ -0,0 +1,76 @@
/* Temporary library support for decimal floating point.
Copyright (C) 2005, 2006 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 "config.h"
#include "decContext.h"
#include "decimal128.h"
#include "decimal64.h"
#include "decimal32.h"
void __host_to_ieee_32 (_Decimal32, decimal32 *);
void __host_to_ieee_64 (_Decimal64, decimal64 *);
void __host_to_ieee_128 (_Decimal128, decimal128 *);
extern int isinfd32 (_Decimal32);
extern int isinfd64 (_Decimal64);
extern int isinfd128 (_Decimal128);
uint32_t __dec_byte_swap (uint32_t);
int
isinfd32 (_Decimal32 arg)
{
decNumber dn;
decimal32 d32;
__host_to_ieee_32 (arg, &d32);
decimal32ToNumber (&d32, &dn);
return (decNumberIsInfinite (&dn));
}
int
isinfd64 (_Decimal64 arg)
{
decNumber dn;
decimal64 d64;
__host_to_ieee_64 (arg, &d64);
decimal64ToNumber (&d64, &dn);
return (decNumberIsInfinite (&dn));
}
int
isinfd128 (_Decimal128 arg)
{
decNumber dn;
decimal128 d128;
__host_to_ieee_128 (arg, &d128);
decimal128ToNumber (&d128, &dn);
return (decNumberIsInfinite (&dn));
}

8122
libdecnumber/decNumber.c Normal file

File diff suppressed because it is too large Load Diff

200
libdecnumber/decNumber.h Normal file
View File

@ -0,0 +1,200 @@
/* Decimal number arithmetic module header for the decNumber C Library.
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Decimal Number arithmetic module header */
/* ------------------------------------------------------------------ */
#if !defined(DECNUMBER)
#define DECNUMBER
#define DECNAME "decNumber" /* Short name */
#define DECFULLNAME "Decimal Number Module" /* Verbose name */
#define DECAUTHOR "Mike Cowlishaw" /* Who to blame */
#if !defined(DECCONTEXT)
#include "decContext.h"
#endif
/* Bit settings for decNumber.bits */
#define DECNEG 0x80 /* Sign; 1=negative, 0=positive or zero */
#define DECINF 0x40 /* 1=Infinity */
#define DECNAN 0x20 /* 1=NaN */
#define DECSNAN 0x10 /* 1=sNaN */
/* The remaining bits are reserved; they must be 0 */
#define DECSPECIAL (DECINF|DECNAN|DECSNAN) /* any special value */
/* Define the decNumber data structure. The size and shape of the */
/* units array in the structure is determined by the following */
/* constant. This must not be changed without recompiling the */
/* decNumber library modules. */
#define DECDPUN 3 /* DECimal Digits Per UNit [must be >0 */
/* and <10; 3 or powers of 2 are best]. */
/* DECNUMDIGITS is the default number of digits that can be held in */
/* the structure. If undefined, 1 is assumed and it is assumed */
/* that the structure will be immediately followed by extra space, */
/* as required. DECNUMDIGITS is always >0. */
#if !defined(DECNUMDIGITS)
#define DECNUMDIGITS 1
#endif
/* The size (integer data type) of each unit is determined by the */
/* number of digits it will hold. */
#if DECDPUN<=2
#define decNumberUnit uint8_t
#elif DECDPUN<=4
#define decNumberUnit uint16_t
#else
#define decNumberUnit uint32_t
#endif
/* The number of units needed is ceil(DECNUMDIGITS/DECDPUN) */
#define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN)
/* The data structure... */
typedef struct {
int32_t digits; /* Count of digits in the coefficient; >0 */
int32_t exponent; /* Unadjusted exponent, unbiased, in */
/* range: -1999999997 through 999999999 */
uint8_t bits; /* Indicator bits (see above) */
/* Coefficient, from least significant unit */
decNumberUnit lsu[DECNUMUNITS];
} decNumber;
/* Notes: */
/* 1. If digits is > DECDPUN then there will one or more */
/* decNumberUnits immediately following the first element of lsu.*/
/* These contain the remaining (more significant) digits of the */
/* number, and may be in the lsu array, or may be guaranteed by */
/* some other mechanism (such as being contained in another */
/* structure, or being overlaid on dynamically allocated */
/* storage). */
/* */
/* Each integer of the coefficient (except potentially the last) */
/* contains DECDPUN digits (e.g., a value in the range 0 through */
/* 99999999 if DECDPUN is 8, or 0 through 999 if DECDPUN is 3). */
/* */
/* 2. A decNumber converted to a string may need up to digits+14 */
/* characters. The worst cases (non-exponential and exponential */
/* formats) are -0.00000{9...}# and -9.{9...}E+999999999# */
/* (where # is '\0') */
/* ---------------------------------------------------------------- */
/* decNumber public functions and macros */
/* ---------------------------------------------------------------- */
#include "decNumberSymbols.h"
/* Conversions */
decNumber * decNumberFromInt32(decNumber *, int32_t);
decNumber * decNumberFromUInt32(decNumber *, uint32_t);
decNumber * decNumberFromString(decNumber *, const char *, decContext *);
char * decNumberToString(const decNumber *, char *);
char * decNumberToEngString(const decNumber *, char *);
uint32_t decNumberToUInt32(const decNumber *, decContext *);
int32_t decNumberToInt32(const decNumber *, decContext *);
uint8_t * decNumberGetBCD(const decNumber *, uint8_t *);
decNumber * decNumberSetBCD(decNumber *, const uint8_t *, uint32_t);
/* Operators and elementary functions */
decNumber * decNumberAbs(decNumber *, const decNumber *, decContext *);
decNumber * decNumberAdd(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberAnd(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberCompare(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberCompareSignal(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberCompareTotal(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberCompareTotalMag(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberDivide(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberDivideInteger(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberExp(decNumber *, const decNumber *, decContext *);
decNumber * decNumberFMA(decNumber *, const decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberInvert(decNumber *, const decNumber *, decContext *);
decNumber * decNumberLn(decNumber *, const decNumber *, decContext *);
decNumber * decNumberLogB(decNumber *, const decNumber *, decContext *);
decNumber * decNumberLog10(decNumber *, const decNumber *, decContext *);
decNumber * decNumberMax(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberMaxMag(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberMin(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberMinMag(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberMinus(decNumber *, const decNumber *, decContext *);
decNumber * decNumberMultiply(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberNormalize(decNumber *, const decNumber *, decContext *);
decNumber * decNumberOr(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberPlus(decNumber *, const decNumber *, decContext *);
decNumber * decNumberPower(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberQuantize(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberReduce(decNumber *, const decNumber *, decContext *);
decNumber * decNumberRemainder(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberRemainderNear(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberRescale(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberRotate(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberSameQuantum(decNumber *, const decNumber *, const decNumber *);
decNumber * decNumberScaleB(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberShift(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberSquareRoot(decNumber *, const decNumber *, decContext *);
decNumber * decNumberSubtract(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberToIntegralExact(decNumber *, const decNumber *, decContext *);
decNumber * decNumberToIntegralValue(decNumber *, const decNumber *, decContext *);
decNumber * decNumberXor(decNumber *, const decNumber *, const decNumber *, decContext *);
/* Utilities */
enum decClass decNumberClass(const decNumber *, decContext *);
const char * decNumberClassToString(enum decClass);
decNumber * decNumberCopy(decNumber *, const decNumber *);
decNumber * decNumberCopyAbs(decNumber *, const decNumber *);
decNumber * decNumberCopyNegate(decNumber *, const decNumber *);
decNumber * decNumberCopySign(decNumber *, const decNumber *, const decNumber *);
decNumber * decNumberNextMinus(decNumber *, const decNumber *, decContext *);
decNumber * decNumberNextPlus(decNumber *, const decNumber *, decContext *);
decNumber * decNumberNextToward(decNumber *, const decNumber *, const decNumber *, decContext *);
decNumber * decNumberTrim(decNumber *);
const char * decNumberVersion(void);
decNumber * decNumberZero(decNumber *);
/* Functions for testing decNumbers (normality depends on context) */
int32_t decNumberIsNormal(const decNumber *, decContext *);
int32_t decNumberIsSubnormal(const decNumber *, decContext *);
/* Macros for testing decNumber *dn */
#define decNumberIsCanonical(dn) (1) /* All decNumbers are saintly */
#define decNumberIsFinite(dn) (((dn)->bits&DECSPECIAL)==0)
#define decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)
#define decNumberIsNaN(dn) (((dn)->bits&(DECNAN|DECSNAN))!=0)
#define decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)
#define decNumberIsQNaN(dn) (((dn)->bits&(DECNAN))!=0)
#define decNumberIsSNaN(dn) (((dn)->bits&(DECSNAN))!=0)
#define decNumberIsSpecial(dn) (((dn)->bits&DECSPECIAL)!=0)
#define decNumberIsZero(dn) (*(dn)->lsu==0 \
&& (dn)->digits==1 \
&& (((dn)->bits&DECSPECIAL)==0))
#define decNumberRadix(dn) (10)
#endif

View File

@ -0,0 +1,665 @@
/* Local definitions for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* decNumber package local type, tuning, and macro definitions */
/* ------------------------------------------------------------------ */
/* This header file is included by all modules in the decNumber */
/* library, and contains local type definitions, tuning parameters, */
/* etc. It should not need to be used by application programs. */
/* decNumber.h or one of decDouble (etc.) must be included first. */
/* ------------------------------------------------------------------ */
#if !defined(DECNUMBERLOC)
#define DECNUMBERLOC
#define DECVERSION "decNumber 3.53" /* Package Version [16 max.] */
#define DECNLAUTHOR "Mike Cowlishaw" /* Who to blame */
#include <stdlib.h> /* for abs */
#include <string.h> /* for memset, strcpy */
#include "config.h" /* for WORDS_BIGENDIAN */
/* Conditional code flag -- set this to match hardware platform */
/* 1=little-endian, 0=big-endian */
#if WORDS_BIGENDIAN
#define DECLITEND 0
#else
#define DECLITEND 1
#endif
/* Conditional code flag -- set this to 1 for best performance */
#define DECUSE64 1 /* 1=use int64s, 0=int32 & smaller only */
/* Conditional check flags -- set these to 0 for best performance */
#define DECCHECK 0 /* 1 to enable robust checking */
#define DECALLOC 0 /* 1 to enable memory accounting */
#define DECTRACE 0 /* 1 to trace certain internals, etc. */
/* Tuning parameter for decNumber (arbitrary precision) module */
#define DECBUFFER 36 /* Size basis for local buffers. This */
/* should be a common maximum precision */
/* rounded up to a multiple of 4; must */
/* be zero or positive. */
/* ---------------------------------------------------------------- */
/* Definitions for all modules (general-purpose) */
/* ---------------------------------------------------------------- */
/* Local names for common types -- for safety, decNumber modules do */
/* not use int or long directly. */
#define Flag uint8_t
#define Byte int8_t
#define uByte uint8_t
#define Short int16_t
#define uShort uint16_t
#define Int int32_t
#define uInt uint32_t
#define Unit decNumberUnit
#if DECUSE64
#define Long int64_t
#define uLong uint64_t
#endif
/* Development-use definitions */
typedef long int LI; /* for printf arguments only */
#define DECNOINT 0 /* 1 to check no internal use of 'int' */
#if DECNOINT
/* if these interfere with your C includes, do not set DECNOINT */
#define int ? /* enable to ensure that plain C 'int' */
#define long ?? /* .. or 'long' types are not used */
#endif
/* Shared lookup tables */
extern const uByte DECSTICKYTAB[10]; /* re-round digits if sticky */
extern const uInt DECPOWERS[10]; /* powers of ten table */
/* The following are included from decDPD.h */
extern const uShort DPD2BIN[1024]; /* DPD -> 0-999 */
extern const uShort BIN2DPD[1000]; /* 0-999 -> DPD */
extern const uInt DPD2BINK[1024]; /* DPD -> 0-999000 */
extern const uInt DPD2BINM[1024]; /* DPD -> 0-999000000 */
extern const uByte DPD2BCD8[4096]; /* DPD -> ddd + len */
extern const uByte BIN2BCD8[4000]; /* 0-999 -> ddd + len */
extern const uShort BCD2DPD[2458]; /* 0-0x999 -> DPD (0x999=2457)*/
/* LONGMUL32HI -- set w=(u*v)>>32, where w, u, and v are uInts */
/* (that is, sets w to be the high-order word of the 64-bit result; */
/* the low-order word is simply u*v.) */
/* This version is derived from Knuth via Hacker's Delight; */
/* it seems to optimize better than some others tried */
#define LONGMUL32HI(w, u, v) { \
uInt u0, u1, v0, v1, w0, w1, w2, t; \
u0=u & 0xffff; u1=u>>16; \
v0=v & 0xffff; v1=v>>16; \
w0=u0*v0; \
t=u1*v0 + (w0>>16); \
w1=t & 0xffff; w2=t>>16; \
w1=u0*v1 + w1; \
(w)=u1*v1 + w2 + (w1>>16);}
/* ROUNDUP -- round an integer up to a multiple of n */
#define ROUNDUP(i, n) ((((i)+(n)-1)/n)*n)
/* ROUNDDOWN -- round an integer down to a multiple of n */
#define ROUNDDOWN(i, n) (((i)/n)*n)
#define ROUNDDOWN4(i) ((i)&~3) /* special for n=4 */
/* References to multi-byte sequences under different sizes */
/* Refer to a uInt from four bytes starting at a char* or uByte*, */
/* etc. */
#define UINTAT(b) (*((uInt *)(b)))
#define USHORTAT(b) (*((uShort *)(b)))
#define UBYTEAT(b) (*((uByte *)(b)))
/* X10 and X100 -- multiply integer i by 10 or 100 */
/* [shifts are usually faster than multiply; could be conditional] */
#define X10(i) (((i)<<1)+((i)<<3))
#define X100(i) (((i)<<2)+((i)<<5)+((i)<<6))
/* MAXI and MINI -- general max & min (not in ANSI) for integers */
#define MAXI(x,y) ((x)<(y)?(y):(x))
#define MINI(x,y) ((x)>(y)?(y):(x))
/* Useful constants */
#define BILLION 1000000000 /* 10**9 */
/* CHARMASK: 0x30303030 for ASCII/UTF8; 0xF0F0F0F0 for EBCDIC */
#define CHARMASK ((((((((uInt)'0')<<8)+'0')<<8)+'0')<<8)+'0')
/* ---------------------------------------------------------------- */
/* Definitions for arbitary-precision modules (only valid after */
/* decNumber.h has been included) */
/* ---------------------------------------------------------------- */
/* Limits and constants */
#define DECNUMMAXP 999999999 /* maximum precision code can handle */
#define DECNUMMAXE 999999999 /* maximum adjusted exponent ditto */
#define DECNUMMINE -999999999 /* minimum adjusted exponent ditto */
#if (DECNUMMAXP != DEC_MAX_DIGITS)
#error Maximum digits mismatch
#endif
#if (DECNUMMAXE != DEC_MAX_EMAX)
#error Maximum exponent mismatch
#endif
#if (DECNUMMINE != DEC_MIN_EMIN)
#error Minimum exponent mismatch
#endif
/* Set DECDPUNMAX -- the maximum integer that fits in DECDPUN */
/* digits, and D2UTABLE -- the initializer for the D2U table */
#if DECDPUN==1
#define DECDPUNMAX 9
#define D2UTABLE {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17, \
18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, \
33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, \
48,49}
#elif DECDPUN==2
#define DECDPUNMAX 99
#define D2UTABLE {0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10, \
11,11,12,12,13,13,14,14,15,15,16,16,17,17,18, \
18,19,19,20,20,21,21,22,22,23,23,24,24,25}
#elif DECDPUN==3
#define DECDPUNMAX 999
#define D2UTABLE {0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7, \
8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13, \
13,14,14,14,15,15,15,16,16,16,17}
#elif DECDPUN==4
#define DECDPUNMAX 9999
#define D2UTABLE {0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6, \
6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11, \
11,11,11,12,12,12,12,13}
#elif DECDPUN==5
#define DECDPUNMAX 99999
#define D2UTABLE {0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5, \
5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9, \
9,9,10,10,10,10}
#elif DECDPUN==6
#define DECDPUNMAX 999999
#define D2UTABLE {0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4, \
4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8, \
8,8,8,8,8,9}
#elif DECDPUN==7
#define DECDPUNMAX 9999999
#define D2UTABLE {0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3, \
4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7, \
7,7,7,7,7,7}
#elif DECDPUN==8
#define DECDPUNMAX 99999999
#define D2UTABLE {0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3, \
3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6, \
6,6,6,6,6,7}
#elif DECDPUN==9
#define DECDPUNMAX 999999999
#define D2UTABLE {0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3, \
3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5, \
5,5,6,6,6,6}
#elif defined(DECDPUN)
#error DECDPUN must be in the range 1-9
#endif
/* ----- Shared data (in decNumber.c) ----- */
/* Public lookup table used by the D2U macro (see below) */
#define DECMAXD2U 49
extern const uByte d2utable[DECMAXD2U+1];
/* ----- Macros ----- */
/* ISZERO -- return true if decNumber dn is a zero */
/* [performance-critical in some situations] */
#define ISZERO(dn) decNumberIsZero(dn) /* now just a local name */
/* D2U -- return the number of Units needed to hold d digits */
/* (runtime version, with table lookaside for small d) */
#if DECDPUN==8
#define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+7)>>3))
#elif DECDPUN==4
#define D2U(d) ((unsigned)((d)<=DECMAXD2U?d2utable[d]:((d)+3)>>2))
#else
#define D2U(d) ((d)<=DECMAXD2U?d2utable[d]:((d)+DECDPUN-1)/DECDPUN)
#endif
/* SD2U -- static D2U macro (for compile-time calculation) */
#define SD2U(d) (((d)+DECDPUN-1)/DECDPUN)
/* MSUDIGITS -- returns digits in msu, from digits, calculated */
/* using D2U */
#define MSUDIGITS(d) ((d)-(D2U(d)-1)*DECDPUN)
/* D2N -- return the number of decNumber structs that would be */
/* needed to contain that number of digits (and the initial */
/* decNumber struct) safely. Note that one Unit is included in the */
/* initial structure. Used for allocating space that is aligned on */
/* a decNumber struct boundary. */
#define D2N(d) \
((((SD2U(d)-1)*sizeof(Unit))+sizeof(decNumber)*2-1)/sizeof(decNumber))
/* TODIGIT -- macro to remove the leading digit from the unsigned */
/* integer u at column cut (counting from the right, LSD=0) and */
/* place it as an ASCII character into the character pointed to by */
/* c. Note that cut must be <= 9, and the maximum value for u is */
/* 2,000,000,000 (as is needed for negative exponents of */
/* subnormals). The unsigned integer pow is used as a temporary */
/* variable. */
#define TODIGIT(u, cut, c, pow) { \
*(c)='0'; \
pow=DECPOWERS[cut]*2; \
if ((u)>pow) { \
pow*=4; \
if ((u)>=pow) {(u)-=pow; *(c)+=8;} \
pow/=2; \
if ((u)>=pow) {(u)-=pow; *(c)+=4;} \
pow/=2; \
} \
if ((u)>=pow) {(u)-=pow; *(c)+=2;} \
pow/=2; \
if ((u)>=pow) {(u)-=pow; *(c)+=1;} \
}
/* ---------------------------------------------------------------- */
/* Definitions for fixed-precision modules (only valid after */
/* decSingle.h, decDouble.h, or decQuad.h has been included) */
/* ---------------------------------------------------------------- */
/* bcdnum -- a structure describing a format-independent finite */
/* number, whose coefficient is a string of bcd8 uBytes */
typedef struct {
uByte *msd; /* -> most significant digit */
uByte *lsd; /* -> least ditto */
uInt sign; /* 0=positive, DECFLOAT_Sign=negative */
Int exponent; /* Unadjusted signed exponent (q), or */
/* DECFLOAT_NaN etc. for a special */
} bcdnum;
/* Test if exponent or bcdnum exponent must be a special, etc. */
#define EXPISSPECIAL(exp) ((exp)>=DECFLOAT_MinSp)
#define EXPISINF(exp) (exp==DECFLOAT_Inf)
#define EXPISNAN(exp) (exp==DECFLOAT_qNaN || exp==DECFLOAT_sNaN)
#define NUMISSPECIAL(num) (EXPISSPECIAL((num)->exponent))
/* Refer to a 32-bit word or byte in a decFloat (df) by big-endian */
/* (array) notation (the 0 word or byte contains the sign bit), */
/* automatically adjusting for endianness; similarly address a word */
/* in the next-wider format (decFloatWider, or dfw) */
#define DECWORDS (DECBYTES/4)
#define DECWWORDS (DECWBYTES/4)
#if DECLITEND
#define DFWORD(df, off) UINTAT((df)->bytes+(DECWORDS-1-(off))*4)
#define DFBYTE(df, off) UBYTEAT((df)->bytes+(DECBYTES-1-(off)))
#define DFWWORD(dfw, off) UINTAT((dfw)->bytes+(DECWWORDS-1-(off))*4)
#else
#define DFWORD(df, off) UINTAT((df)->bytes+(off)*4)
#define DFBYTE(df, off) UBYTEAT((df)->bytes+(off))
#define DFWWORD(dfw, off) UINTAT((dfw)->bytes+(off)*4)
#endif
/* Tests for sign or specials, directly on DECFLOATs */
#define DFISSIGNED(df) (DFWORD(df, 0)&0x80000000)
#define DFISSPECIAL(df) ((DFWORD(df, 0)&0x78000000)==0x78000000)
#define DFISINF(df) ((DFWORD(df, 0)&0x7c000000)==0x78000000)
#define DFISNAN(df) ((DFWORD(df, 0)&0x7c000000)==0x7c000000)
#define DFISQNAN(df) ((DFWORD(df, 0)&0x7e000000)==0x7c000000)
#define DFISSNAN(df) ((DFWORD(df, 0)&0x7e000000)==0x7e000000)
/* Shared lookup tables */
extern const uInt DECCOMBMSD[64]; /* Combination field -> MSD */
extern const uInt DECCOMBFROM[48]; /* exp+msd -> Combination */
/* Private generic (utility) routine */
#if DECCHECK || DECTRACE
extern void decShowNum(const bcdnum *, const char *);
#endif
/* Format-dependent macros and constants */
#if defined(DECPMAX)
/* Useful constants */
#define DECPMAX9 (ROUNDUP(DECPMAX, 9)/9) /* 'Pmax' in 10**9s */
/* Top words for a zero */
#define SINGLEZERO 0x22500000
#define DOUBLEZERO 0x22380000
#define QUADZERO 0x22080000
/* [ZEROWORD is defined to be one of these in the DFISZERO macro] */
/* Format-dependent common tests: */
/* DFISZERO -- test for (any) zero */
/* DFISCCZERO -- test for coefficient continuation being zero */
/* DFISCC01 -- test for coefficient contains only 0s and 1s */
/* DFISINT -- test for finite and exponent q=0 */
/* DFISUINT01 -- test for sign=0, finite, exponent q=0, and */
/* MSD=0 or 1 */
/* ZEROWORD is also defined here. */
/* In DFISZERO the first test checks the least-significant word */
/* (most likely to be non-zero); the penultimate tests MSD and */
/* DPDs in the signword, and the final test excludes specials and */
/* MSD>7. DFISINT similarly has to allow for the two forms of */
/* MSD codes. DFISUINT01 only has to allow for one form of MSD */
/* code. */
#if DECPMAX==7
#define ZEROWORD SINGLEZERO
/* [test macros not needed except for Zero] */
#define DFISZERO(df) ((DFWORD(df, 0)&0x1c0fffff)==0 \
&& (DFWORD(df, 0)&0x60000000)!=0x60000000)
#elif DECPMAX==16
#define ZEROWORD DOUBLEZERO
#define DFISZERO(df) ((DFWORD(df, 1)==0 \
&& (DFWORD(df, 0)&0x1c03ffff)==0 \
&& (DFWORD(df, 0)&0x60000000)!=0x60000000))
#define DFISINT(df) ((DFWORD(df, 0)&0x63fc0000)==0x22380000 \
||(DFWORD(df, 0)&0x7bfc0000)==0x6a380000)
#define DFISUINT01(df) ((DFWORD(df, 0)&0xfbfc0000)==0x22380000)
#define DFISCCZERO(df) (DFWORD(df, 1)==0 \
&& (DFWORD(df, 0)&0x0003ffff)==0)
#define DFISCC01(df) ((DFWORD(df, 0)&~0xfffc9124)==0 \
&& (DFWORD(df, 1)&~0x49124491)==0)
#elif DECPMAX==34
#define ZEROWORD QUADZERO
#define DFISZERO(df) ((DFWORD(df, 3)==0 \
&& DFWORD(df, 2)==0 \
&& DFWORD(df, 1)==0 \
&& (DFWORD(df, 0)&0x1c003fff)==0 \
&& (DFWORD(df, 0)&0x60000000)!=0x60000000))
#define DFISINT(df) ((DFWORD(df, 0)&0x63ffc000)==0x22080000 \
||(DFWORD(df, 0)&0x7bffc000)==0x6a080000)
#define DFISUINT01(df) ((DFWORD(df, 0)&0xfbffc000)==0x22080000)
#define DFISCCZERO(df) (DFWORD(df, 3)==0 \
&& DFWORD(df, 2)==0 \
&& DFWORD(df, 1)==0 \
&& (DFWORD(df, 0)&0x00003fff)==0)
#define DFISCC01(df) ((DFWORD(df, 0)&~0xffffc912)==0 \
&& (DFWORD(df, 1)&~0x44912449)==0 \
&& (DFWORD(df, 2)&~0x12449124)==0 \
&& (DFWORD(df, 3)&~0x49124491)==0)
#endif
/* Macros to test if a certain 10 bits of a uInt or pair of uInts */
/* are a canonical declet [higher or lower bits are ignored]. */
/* declet is at offset 0 (from the right) in a uInt: */
#define CANONDPD(dpd) (((dpd)&0x300)==0 || ((dpd)&0x6e)!=0x6e)
/* declet is at offset k (a multiple of 2) in a uInt: */
#define CANONDPDOFF(dpd, k) (((dpd)&(0x300<<(k)))==0 \
|| ((dpd)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
/* declet is at offset k (a multiple of 2) in a pair of uInts: */
/* [the top 2 bits will always be in the more-significant uInt] */
#define CANONDPDTWO(hi, lo, k) (((hi)&(0x300>>(32-(k))))==0 \
|| ((hi)&(0x6e>>(32-(k))))!=(0x6e>>(32-(k))) \
|| ((lo)&(((uInt)0x6e)<<(k)))!=(((uInt)0x6e)<<(k)))
/* Macro to test whether a full-length (length DECPMAX) BCD8 */
/* coefficient is zero */
/* test just the LSWord first, then the remainder */
#if DECPMAX==7
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& UINTAT((u)+DECPMAX-7)==0)
#elif DECPMAX==16
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& (UINTAT((u)+DECPMAX-8)+UINTAT((u)+DECPMAX-12) \
+UINTAT((u)+DECPMAX-16))==0)
#elif DECPMAX==34
#define ISCOEFFZERO(u) (UINTAT((u)+DECPMAX-4)==0 \
&& (UINTAT((u)+DECPMAX-8) +UINTAT((u)+DECPMAX-12) \
+UINTAT((u)+DECPMAX-16)+UINTAT((u)+DECPMAX-20) \
+UINTAT((u)+DECPMAX-24)+UINTAT((u)+DECPMAX-28) \
+UINTAT((u)+DECPMAX-32)+USHORTAT((u)+DECPMAX-34))==0)
#endif
/* Macros and masks for the exponent continuation field and MSD */
/* Get the exponent continuation from a decFloat *df as an Int */
#define GETECON(df) ((Int)((DFWORD((df), 0)&0x03ffffff)>>(32-6-DECECONL)))
/* Ditto, from the next-wider format */
#define GETWECON(df) ((Int)((DFWWORD((df), 0)&0x03ffffff)>>(32-6-DECWECONL)))
/* Get the biased exponent similarly */
#define GETEXP(df) ((Int)(DECCOMBEXP[DFWORD((df), 0)>>26]+GETECON(df)))
/* Get the unbiased exponent similarly */
#define GETEXPUN(df) ((Int)GETEXP(df)-DECBIAS)
/* Get the MSD similarly (as uInt) */
#define GETMSD(df) (DECCOMBMSD[DFWORD((df), 0)>>26])
/* Compile-time computes of the exponent continuation field masks */
/* full exponent continuation field: */
#define ECONMASK ((0x03ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
/* same, not including its first digit (the qNaN/sNaN selector): */
#define ECONNANMASK ((0x01ffffff>>(32-6-DECECONL))<<(32-6-DECECONL))
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a BCD string (uByte *bcdin) of length DECPMAX uBytes */
/* In-line sequence to convert 10 bits at right end of uInt dpd */
/* to three BCD8 digits starting at uByte u. Note that an extra */
/* byte is written to the right of the three digits because this */
/* moves four at a time for speed; the alternative macro moves */
/* exactly three bytes */
#define dpd2bcd8(u, dpd) { \
UINTAT(u)=UINTAT(&DPD2BCD8[((dpd)&0x3ff)*4]);}
#define dpd2bcd83(u, dpd) { \
*(u)=DPD2BCD8[((dpd)&0x3ff)*4]; \
*(u+1)=DPD2BCD8[((dpd)&0x3ff)*4+1]; \
*(u+2)=DPD2BCD8[((dpd)&0x3ff)*4+2];}
/* Decode the declets. After extracting each one, it is decoded */
/* to BCD8 using a table lookup (also used for variable-length */
/* decode). Each DPD decode is 3 bytes BCD8 plus a one-byte */
/* length which is not used, here). Fixed-length 4-byte moves */
/* are fast, however, almost everywhere, and so are used except */
/* for the final three bytes (to avoid overrun). The code below */
/* is 36 instructions for Doubles and about 70 for Quads, even */
/* on IA32. */
/* Two macros are defined for each format: */
/* GETCOEFF extracts the coefficient of the current format */
/* GETWCOEFF extracts the coefficient of the next-wider format. */
/* The latter is a copy of the next-wider GETCOEFF using DFWWORD. */
#if DECPMAX==7
#define GETCOEFF(df, bcd) { \
uInt sourhi=DFWORD(df, 0); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>10); \
dpd2bcd83(bcd+4, sourhi);}
#define GETWCOEFF(df, bcd) { \
uInt sourhi=DFWWORD(df, 0); \
uInt sourlo=DFWWORD(df, 1); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>8); \
dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30)); \
dpd2bcd8(bcd+7, sourlo>>20); \
dpd2bcd8(bcd+10, sourlo>>10); \
dpd2bcd83(bcd+13, sourlo);}
#elif DECPMAX==16
#define GETCOEFF(df, bcd) { \
uInt sourhi=DFWORD(df, 0); \
uInt sourlo=DFWORD(df, 1); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>8); \
dpd2bcd8(bcd+4, (sourhi<<2) | (sourlo>>30)); \
dpd2bcd8(bcd+7, sourlo>>20); \
dpd2bcd8(bcd+10, sourlo>>10); \
dpd2bcd83(bcd+13, sourlo);}
#define GETWCOEFF(df, bcd) { \
uInt sourhi=DFWWORD(df, 0); \
uInt sourmh=DFWWORD(df, 1); \
uInt sourml=DFWWORD(df, 2); \
uInt sourlo=DFWWORD(df, 3); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>4); \
dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26)); \
dpd2bcd8(bcd+7, sourmh>>16); \
dpd2bcd8(bcd+10, sourmh>>6); \
dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28)); \
dpd2bcd8(bcd+16, sourml>>18); \
dpd2bcd8(bcd+19, sourml>>8); \
dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30)); \
dpd2bcd8(bcd+25, sourlo>>20); \
dpd2bcd8(bcd+28, sourlo>>10); \
dpd2bcd83(bcd+31, sourlo);}
#elif DECPMAX==34
#define GETCOEFF(df, bcd) { \
uInt sourhi=DFWORD(df, 0); \
uInt sourmh=DFWORD(df, 1); \
uInt sourml=DFWORD(df, 2); \
uInt sourlo=DFWORD(df, 3); \
*(bcd)=(uByte)DECCOMBMSD[sourhi>>26]; \
dpd2bcd8(bcd+1, sourhi>>4); \
dpd2bcd8(bcd+4, ((sourhi)<<6) | (sourmh>>26)); \
dpd2bcd8(bcd+7, sourmh>>16); \
dpd2bcd8(bcd+10, sourmh>>6); \
dpd2bcd8(bcd+13, ((sourmh)<<4) | (sourml>>28)); \
dpd2bcd8(bcd+16, sourml>>18); \
dpd2bcd8(bcd+19, sourml>>8); \
dpd2bcd8(bcd+22, ((sourml)<<2) | (sourlo>>30)); \
dpd2bcd8(bcd+25, sourlo>>20); \
dpd2bcd8(bcd+28, sourlo>>10); \
dpd2bcd83(bcd+31, sourlo);}
#define GETWCOEFF(df, bcd) {??} /* [should never be used] */
#endif
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a base-billion uInt array, with the least-significant */
/* 0-999999999 'digit' at offset 0. */
/* Decode the declets. After extracting each one, it is decoded */
/* to binary using a table lookup. Three tables are used; one */
/* the usual DPD to binary, the other two pre-multiplied by 1000 */
/* and 1000000 to avoid multiplication during decode. These */
/* tables can also be used for multiplying up the MSD as the DPD */
/* code for 0 through 9 is the identity. */
#define DPD2BIN0 DPD2BIN /* for prettier code */
#if DECPMAX==7
#define GETCOEFFBILL(df, buf) { \
uInt sourhi=DFWORD(df, 0); \
(buf)[0]=DPD2BIN0[sourhi&0x3ff] \
+DPD2BINK[(sourhi>>10)&0x3ff] \
+DPD2BINM[DECCOMBMSD[sourhi>>26]];}
#elif DECPMAX==16
#define GETCOEFFBILL(df, buf) { \
uInt sourhi, sourlo; \
sourlo=DFWORD(df, 1); \
(buf)[0]=DPD2BIN0[sourlo&0x3ff] \
+DPD2BINK[(sourlo>>10)&0x3ff] \
+DPD2BINM[(sourlo>>20)&0x3ff]; \
sourhi=DFWORD(df, 0); \
(buf)[1]=DPD2BIN0[((sourhi<<2) | (sourlo>>30))&0x3ff] \
+DPD2BINK[(sourhi>>8)&0x3ff] \
+DPD2BINM[DECCOMBMSD[sourhi>>26]];}
#elif DECPMAX==34
#define GETCOEFFBILL(df, buf) { \
uInt sourhi, sourmh, sourml, sourlo; \
sourlo=DFWORD(df, 3); \
(buf)[0]=DPD2BIN0[sourlo&0x3ff] \
+DPD2BINK[(sourlo>>10)&0x3ff] \
+DPD2BINM[(sourlo>>20)&0x3ff]; \
sourml=DFWORD(df, 2); \
(buf)[1]=DPD2BIN0[((sourml<<2) | (sourlo>>30))&0x3ff] \
+DPD2BINK[(sourml>>8)&0x3ff] \
+DPD2BINM[(sourml>>18)&0x3ff]; \
sourmh=DFWORD(df, 1); \
(buf)[2]=DPD2BIN0[((sourmh<<4) | (sourml>>28))&0x3ff] \
+DPD2BINK[(sourmh>>6)&0x3ff] \
+DPD2BINM[(sourmh>>16)&0x3ff]; \
sourhi=DFWORD(df, 0); \
(buf)[3]=DPD2BIN0[((sourhi<<6) | (sourmh>>26))&0x3ff] \
+DPD2BINK[(sourhi>>4)&0x3ff] \
+DPD2BINM[DECCOMBMSD[sourhi>>26]];}
#endif
/* Macros to decode the coefficient in a finite decFloat *df into */
/* a base-thousand uInt array, with the least-significant 0-999 */
/* 'digit' at offset 0. */
/* Decode the declets. After extracting each one, it is decoded */
/* to binary using a table lookup. */
#if DECPMAX==7
#define GETCOEFFTHOU(df, buf) { \
uInt sourhi=DFWORD(df, 0); \
(buf)[0]=DPD2BIN[sourhi&0x3ff]; \
(buf)[1]=DPD2BIN[(sourhi>>10)&0x3ff]; \
(buf)[2]=DECCOMBMSD[sourhi>>26];}
#elif DECPMAX==16
#define GETCOEFFTHOU(df, buf) { \
uInt sourhi, sourlo; \
sourlo=DFWORD(df, 1); \
(buf)[0]=DPD2BIN[sourlo&0x3ff]; \
(buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff]; \
(buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff]; \
sourhi=DFWORD(df, 0); \
(buf)[3]=DPD2BIN[((sourhi<<2) | (sourlo>>30))&0x3ff]; \
(buf)[4]=DPD2BIN[(sourhi>>8)&0x3ff]; \
(buf)[5]=DECCOMBMSD[sourhi>>26];}
#elif DECPMAX==34
#define GETCOEFFTHOU(df, buf) { \
uInt sourhi, sourmh, sourml, sourlo; \
sourlo=DFWORD(df, 3); \
(buf)[0]=DPD2BIN[sourlo&0x3ff]; \
(buf)[1]=DPD2BIN[(sourlo>>10)&0x3ff]; \
(buf)[2]=DPD2BIN[(sourlo>>20)&0x3ff]; \
sourml=DFWORD(df, 2); \
(buf)[3]=DPD2BIN[((sourml<<2) | (sourlo>>30))&0x3ff]; \
(buf)[4]=DPD2BIN[(sourml>>8)&0x3ff]; \
(buf)[5]=DPD2BIN[(sourml>>18)&0x3ff]; \
sourmh=DFWORD(df, 1); \
(buf)[6]=DPD2BIN[((sourmh<<4) | (sourml>>28))&0x3ff]; \
(buf)[7]=DPD2BIN[(sourmh>>6)&0x3ff]; \
(buf)[8]=DPD2BIN[(sourmh>>16)&0x3ff]; \
sourhi=DFWORD(df, 0); \
(buf)[9]=DPD2BIN[((sourhi<<6) | (sourmh>>26))&0x3ff]; \
(buf)[10]=DPD2BIN[(sourhi>>4)&0x3ff]; \
(buf)[11]=DECCOMBMSD[sourhi>>26];}
#endif
/* Set a decFloat to the maximum positive finite number (Nmax) */
#if DECPMAX==7
#define DFSETNMAX(df) \
{DFWORD(df, 0)=0x77f3fcff;}
#elif DECPMAX==16
#define DFSETNMAX(df) \
{DFWORD(df, 0)=0x77fcff3f; \
DFWORD(df, 1)=0xcff3fcff;}
#elif DECPMAX==34
#define DFSETNMAX(df) \
{DFWORD(df, 0)=0x77ffcff3; \
DFWORD(df, 1)=0xfcff3fcf; \
DFWORD(df, 2)=0xf3fcff3f; \
DFWORD(df, 3)=0xcff3fcff;}
#endif
/* [end of format-dependent macros and constants] */
#endif
#else
#error decNumberLocal included more than once
#endif

View File

@ -0,0 +1,69 @@
#if !defined(DECNUMBERSYMBOLS)
#define DECNUMBERSYMBOLS
#ifdef IN_LIBGCC2
#define decNumberAbs __decNumberAbs
#define decNumberAdd __decNumberAdd
#define decNumberAnd __decNumberAnd
#define decNumberClass __decNumberClass
#define decNumberClassToString __decNumberClassToString
#define decNumberCompare __decNumberCompare
#define decNumberCompareSignal __decNumberCompareSignal
#define decNumberCompareTotal __decNumberCompareTotal
#define decNumberCompareTotalMag __decNumberCompareTotalMag
#define decNumberCopy __decNumberCopy
#define decNumberCopyAbs __decNumberCopyAbs
#define decNumberCopyNegate __decNumberCopyNegate
#define decNumberCopySign __decNumberCopySign
#define decNumberDivide __decNumberDivide
#define decNumberDivideInteger __decNumberDivideInteger
#define decNumberExp __decNumberExp
#define decNumberFMA __decNumberFMA
#define decNumberFromInt32 __decNumberFromInt32
#define decNumberFromString __decNumberFromString
#define decNumberFromUInt32 __decNumberFromUInt32
#define decNumberGetBCD __decNumberGetBCD
#define decNumberInvert __decNumberInvert
#define decNumberIsNormal __decNumberIsNormal
#define decNumberIsSubnormal __decNumberIsSubnormal
#define decNumberLn __decNumberLn
#define decNumberLog10 __decNumberLog10
#define decNumberLogB __decNumberLogB
#define decNumberMax __decNumberMax
#define decNumberMaxMag __decNumberMaxMag
#define decNumberMin __decNumberMin
#define decNumberMinMag __decNumberMinMag
#define decNumberMinus __decNumberMinus
#define decNumberMultiply __decNumberMultiply
#define decNumberNextMinus __decNumberNextMinus
#define decNumberNextPlus __decNumberNextPlus
#define decNumberNextToward __decNumberNextToward
#define decNumberNormalize __decNumberNormalize
#define decNumberOr __decNumberOr
#define decNumberPlus __decNumberPlus
#define decNumberPower __decNumberPower
#define decNumberQuantize __decNumberQuantize
#define decNumberReduce __decNumberReduce
#define decNumberRemainder __decNumberRemainder
#define decNumberRemainderNear __decNumberRemainderNear
#define decNumberRescale __decNumberRescale
#define decNumberRotate __decNumberRotate
#define decNumberSameQuantum __decNumberSameQuantum
#define decNumberScaleB __decNumberScaleB
#define decNumberSetBCD __decNumberSetBCD
#define decNumberShift __decNumberShift
#define decNumberSquareRoot __decNumberSquareRoot
#define decNumberSubtract __decNumberSubtract
#define decNumberToEngString __decNumberToEngString
#define decNumberToInt32 __decNumberToInt32
#define decNumberToIntegralExact __decNumberToIntegralExact
#define decNumberToIntegralValue __decNumberToIntegralValue
#define decNumberToString __decNumberToString
#define decNumberToUInt32 __decNumberToUInt32
#define decNumberTrim __decNumberTrim
#define decNumberVersion __decNumberVersion
#define decNumberXor __decNumberXor
#define decNumberZero __decNumberZero
#endif
#endif

235
libdecnumber/decPacked.c Normal file
View File

@ -0,0 +1,235 @@
/* Packed decimal conversion module for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Packed Decimal conversion module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for Packed Decimal format */
/* numbers. Conversions are supplied to and from decNumber, which in */
/* turn supports: */
/* conversions to and from string */
/* arithmetic routines */
/* utilities. */
/* Conversions from decNumber to and from densely packed decimal */
/* formats are provided by the decimal32 through decimal128 modules. */
/* ------------------------------------------------------------------ */
#include <string.h> /* for NULL */
#include "decNumber.h" /* base number library */
#include "decPacked.h" /* packed decimal */
#include "decNumberLocal.h" /* decNumber local types, etc. */
/* ------------------------------------------------------------------ */
/* decPackedFromNumber -- convert decNumber to BCD Packed Decimal */
/* */
/* bcd is the BCD bytes */
/* length is the length of the BCD array */
/* scale is the scale result */
/* dn is the decNumber */
/* returns bcd, or NULL if error */
/* */
/* The number is converted to a BCD packed decimal byte array, */
/* right aligned in the bcd array, whose length is indicated by the */
/* second parameter. The final 4-bit nibble in the array will be a */
/* sign nibble, C (1100) for + and D (1101) for -. Unused bytes and */
/* nibbles to the left of the number are set to 0. */
/* */
/* scale is set to the scale of the number (this is the exponent, */
/* negated). To force the number to a specified scale, first use the */
/* decNumberRescale routine, which will round and change the exponent */
/* as necessary. */
/* */
/* If there is an error (that is, the decNumber has too many digits */
/* to fit in length bytes, or it is a NaN or Infinity), NULL is */
/* returned and the bcd and scale results are unchanged. Otherwise */
/* bcd is returned. */
/* ------------------------------------------------------------------ */
uByte * decPackedFromNumber(uByte *bcd, Int length, Int *scale,
const decNumber *dn) {
const Unit *up=dn->lsu; /* Unit array pointer */
uByte obyte, *out; /* current output byte, and where it goes */
Int indigs=dn->digits; /* digits processed */
uInt cut=DECDPUN; /* downcounter per Unit */
uInt u=*up; /* work */
uInt nib; /* .. */
#if DECDPUN<=4
uInt temp; /* .. */
#endif
if (dn->digits>length*2-1 /* too long .. */
||(dn->bits & DECSPECIAL)) return NULL; /* .. or special -- hopeless */
if (dn->bits&DECNEG) obyte=DECPMINUS; /* set the sign .. */
else obyte=DECPPLUS;
*scale=-dn->exponent; /* .. and scale */
/* loop from lowest (rightmost) byte */
out=bcd+length-1; /* -> final byte */
for (; out>=bcd; out--) {
if (indigs>0) {
if (cut==0) {
up++;
u=*up;
cut=DECDPUN;
}
#if DECDPUN<=4
temp=(u*6554)>>16; /* fast /10 */
nib=u-X10(temp);
u=temp;
#else
nib=u%10; /* cannot use *6554 trick :-( */
u=u/10;
#endif
obyte|=(nib<<4);
indigs--;
cut--;
}
*out=obyte;
obyte=0; /* assume 0 */
if (indigs>0) {
if (cut==0) {
up++;
u=*up;
cut=DECDPUN;
}
#if DECDPUN<=4
temp=(u*6554)>>16; /* as above */
obyte=(uByte)(u-X10(temp));
u=temp;
#else
obyte=(uByte)(u%10);
u=u/10;
#endif
indigs--;
cut--;
}
} /* loop */
return bcd;
} /* decPackedFromNumber */
/* ------------------------------------------------------------------ */
/* decPackedToNumber -- convert BCD Packed Decimal to a decNumber */
/* */
/* bcd is the BCD bytes */
/* length is the length of the BCD array */
/* scale is the scale associated with the BCD integer */
/* dn is the decNumber [with space for length*2 digits] */
/* returns dn, or NULL if error */
/* */
/* The BCD packed decimal byte array, together with an associated */
/* scale, is converted to a decNumber. The BCD array is assumed full */
/* of digits, and must be ended by a 4-bit sign nibble in the least */
/* significant four bits of the final byte. */
/* */
/* The scale is used (negated) as the exponent of the decNumber. */
/* Note that zeros may have a sign and/or a scale. */
/* */
/* The decNumber structure is assumed to have sufficient space to */
/* hold the converted number (that is, up to length*2-1 digits), so */
/* no error is possible unless the adjusted exponent is out of range, */
/* no sign nibble was found, or a sign nibble was found before the */
/* final nibble. In these error cases, NULL is returned and the */
/* decNumber will be 0. */
/* ------------------------------------------------------------------ */
decNumber * decPackedToNumber(const uByte *bcd, Int length,
const Int *scale, decNumber *dn) {
const uByte *last=bcd+length-1; /* -> last byte */
const uByte *first; /* -> first non-zero byte */
uInt nib; /* work nibble */
Unit *up=dn->lsu; /* output pointer */
Int digits; /* digits count */
Int cut=0; /* phase of output */
decNumberZero(dn); /* default result */
last=&bcd[length-1];
nib=*last & 0x0f; /* get the sign */
if (nib==DECPMINUS || nib==DECPMINUSALT) dn->bits=DECNEG;
else if (nib<=9) return NULL; /* not a sign nibble */
/* skip leading zero bytes [final byte is always non-zero, due to sign] */
for (first=bcd; *first==0;) first++;
digits=(last-first)*2+1; /* calculate digits .. */
if ((*first & 0xf0)==0) digits--; /* adjust for leading zero nibble */
if (digits!=0) dn->digits=digits; /* count of actual digits [if 0, */
/* leave as 1] */
/* check the adjusted exponent; note that scale could be unbounded */
dn->exponent=-*scale; /* set the exponent */
if (*scale>=0) { /* usual case */
if ((dn->digits-*scale-1)<-DECNUMMAXE) { /* underflow */
decNumberZero(dn);
return NULL;}
}
else { /* -ve scale; +ve exponent */
/* need to be careful to avoid wrap, here, also BADINT case */
if ((*scale<-DECNUMMAXE) /* overflow even without digits */
|| ((dn->digits-*scale-1)>DECNUMMAXE)) { /* overflow */
decNumberZero(dn);
return NULL;}
}
if (digits==0) return dn; /* result was zero */
/* copy the digits to the number's units, starting at the lsu */
/* [unrolled] */
for (;;) { /* forever */
/* left nibble first */
nib=(unsigned)(*last & 0xf0)>>4;
/* got a digit, in nib */
if (nib>9) {decNumberZero(dn); return NULL;}
if (cut==0) *up=(Unit)nib;
else *up=(Unit)(*up+nib*DECPOWERS[cut]);
digits--;
if (digits==0) break; /* got them all */
cut++;
if (cut==DECDPUN) {
up++;
cut=0;
}
last--; /* ready for next */
nib=*last & 0x0f; /* get right nibble */
if (nib>9) {decNumberZero(dn); return NULL;}
/* got a digit, in nib */
if (cut==0) *up=(Unit)nib;
else *up=(Unit)(*up+nib*DECPOWERS[cut]);
digits--;
if (digits==0) break; /* got them all */
cut++;
if (cut==DECDPUN) {
up++;
cut=0;
}
} /* forever */
return dn;
} /* decPackedToNumber */

70
libdecnumber/decPacked.h Normal file
View File

@ -0,0 +1,70 @@
/* Packed decimal conversion module header for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Packed Decimal conversion module header */
/* ------------------------------------------------------------------ */
#if !defined(DECPACKED)
#define DECPACKED
#define DECPNAME "decPacked" /* Short name */
#define DECPFULLNAME "Packed Decimal conversions" /* Verbose name */
#define DECPAUTHOR "Mike Cowlishaw" /* Who to blame */
#define DECPACKED_DefP 32 /* default precision */
#ifndef DECNUMDIGITS
#define DECNUMDIGITS DECPACKED_DefP /* size if not already defined*/
#endif
#include "decNumber.h" /* context and number library */
/* Sign nibble constants */
#if !defined(DECPPLUSALT)
#define DECPPLUSALT 0x0A /* alternate plus nibble */
#define DECPMINUSALT 0x0B /* alternate minus nibble */
#define DECPPLUS 0x0C /* preferred plus nibble */
#define DECPMINUS 0x0D /* preferred minus nibble */
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
#endif
/* ---------------------------------------------------------------- */
/* decPacked public routines */
/* ---------------------------------------------------------------- */
#include "decPackedSymbols.h"
/* Conversions */
uint8_t * decPackedFromNumber(uint8_t *, int32_t, int32_t *,
const decNumber *);
decNumber * decPackedToNumber(const uint8_t *, int32_t, const int32_t *,
decNumber *);
#endif

View File

@ -0,0 +1,9 @@
#if !defined(DECPACKEDSYMBOLS)
#define DECPACKEDSYMBOLS
#ifdef IN_LIBGCC2
#define decPackedFromNumber __decPackedFromNumber
#define decPackedToNumber __decPackedToNumber
#endif
#endif

146
libdecnumber/decQuad.c Normal file
View File

@ -0,0 +1,146 @@
/* decQuad module for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* decQuad.c -- decQuad operations module */
/* ------------------------------------------------------------------ */
/* This module comprises decQuad operations (including conversions) */
/* ------------------------------------------------------------------ */
#include "decContext.h" /* public includes */
#include "decQuad.h" /* .. */
/* Constant mappings for shared code */
#define DECPMAX DECQUAD_Pmax
#define DECEMIN DECQUAD_Emin
#define DECEMAX DECQUAD_Emax
#define DECEMAXD DECQUAD_EmaxD
#define DECBYTES DECQUAD_Bytes
#define DECSTRING DECQUAD_String
#define DECECONL DECQUAD_EconL
#define DECBIAS DECQUAD_Bias
#define DECLETS DECQUAD_Declets
#define DECQTINY (-DECQUAD_Bias)
/* Type and function mappings for shared code */
#define decFloat decQuad /* Type name */
/* Utilities and conversions (binary results, extractors, etc.) */
#define decFloatFromBCD decQuadFromBCD
#define decFloatFromInt32 decQuadFromInt32
#define decFloatFromPacked decQuadFromPacked
#define decFloatFromString decQuadFromString
#define decFloatFromUInt32 decQuadFromUInt32
#define decFloatFromWider decQuadFromWider
#define decFloatGetCoefficient decQuadGetCoefficient
#define decFloatGetExponent decQuadGetExponent
#define decFloatSetCoefficient decQuadSetCoefficient
#define decFloatSetExponent decQuadSetExponent
#define decFloatShow decQuadShow
#define decFloatToBCD decQuadToBCD
#define decFloatToEngString decQuadToEngString
#define decFloatToInt32 decQuadToInt32
#define decFloatToInt32Exact decQuadToInt32Exact
#define decFloatToPacked decQuadToPacked
#define decFloatToString decQuadToString
#define decFloatToUInt32 decQuadToUInt32
#define decFloatToUInt32Exact decQuadToUInt32Exact
#define decFloatToWider decQuadToWider
#define decFloatZero decQuadZero
/* Computational (result is a decFloat) */
#define decFloatAbs decQuadAbs
#define decFloatAdd decQuadAdd
#define decFloatAnd decQuadAnd
#define decFloatDivide decQuadDivide
#define decFloatDivideInteger decQuadDivideInteger
#define decFloatFMA decQuadFMA
#define decFloatInvert decQuadInvert
#define decFloatLogB decQuadLogB
#define decFloatMax decQuadMax
#define decFloatMaxMag decQuadMaxMag
#define decFloatMin decQuadMin
#define decFloatMinMag decQuadMinMag
#define decFloatMinus decQuadMinus
#define decFloatMultiply decQuadMultiply
#define decFloatNextMinus decQuadNextMinus
#define decFloatNextPlus decQuadNextPlus
#define decFloatNextToward decQuadNextToward
#define decFloatOr decQuadOr
#define decFloatPlus decQuadPlus
#define decFloatQuantize decQuadQuantize
#define decFloatReduce decQuadReduce
#define decFloatRemainder decQuadRemainder
#define decFloatRemainderNear decQuadRemainderNear
#define decFloatRotate decQuadRotate
#define decFloatScaleB decQuadScaleB
#define decFloatShift decQuadShift
#define decFloatSubtract decQuadSubtract
#define decFloatToIntegralValue decQuadToIntegralValue
#define decFloatToIntegralExact decQuadToIntegralExact
#define decFloatXor decQuadXor
/* Comparisons */
#define decFloatCompare decQuadCompare
#define decFloatCompareSignal decQuadCompareSignal
#define decFloatCompareTotal decQuadCompareTotal
#define decFloatCompareTotalMag decQuadCompareTotalMag
/* Copies */
#define decFloatCanonical decQuadCanonical
#define decFloatCopy decQuadCopy
#define decFloatCopyAbs decQuadCopyAbs
#define decFloatCopyNegate decQuadCopyNegate
#define decFloatCopySign decQuadCopySign
/* Non-computational */
#define decFloatClass decQuadClass
#define decFloatClassString decQuadClassString
#define decFloatDigits decQuadDigits
#define decFloatIsCanonical decQuadIsCanonical
#define decFloatIsFinite decQuadIsFinite
#define decFloatIsInfinite decQuadIsInfinite
#define decFloatIsInteger decQuadIsInteger
#define decFloatIsNaN decQuadIsNaN
#define decFloatIsNormal decQuadIsNormal
#define decFloatIsSignaling decQuadIsSignaling
#define decFloatIsSignalling decQuadIsSignalling
#define decFloatIsSigned decQuadIsSigned
#define decFloatIsSubnormal decQuadIsSubnormal
#define decFloatIsZero decQuadIsZero
#define decFloatRadix decQuadRadix
#define decFloatSameQuantum decQuadSameQuantum
#define decFloatVersion decQuadVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-arithmetic decFloat routines */
#include "decBasic.c" /* basic formats routines */

186
libdecnumber/decQuad.h Normal file
View File

@ -0,0 +1,186 @@
/* decQuad module header for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* decQuad.h -- Decimal 128-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
/* This include file is always included by decSingle and decDouble, */
/* and therefore also holds useful constants used by all three. */
#if !defined(DECQUAD)
#define DECQUAD
#define DECQUADNAME "decimalQuad" /* Short name */
#define DECQUADTITLE "Decimal 128-bit datum" /* Verbose name */
#define DECQUADAUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decQuads */
#define DECQUAD_Bytes 16 /* length */
#define DECQUAD_Pmax 34 /* maximum precision (digits) */
#define DECQUAD_Emin -6143 /* minimum adjusted exponent */
#define DECQUAD_Emax 6144 /* maximum adjusted exponent */
#define DECQUAD_EmaxD 4 /* maximum exponent digits */
#define DECQUAD_Bias 6176 /* bias for the exponent */
#define DECQUAD_String 43 /* maximum string length, +1 */
#define DECQUAD_EconL 12 /* exponent continuation length */
#define DECQUAD_Declets 11 /* count of declets */
/* highest biased exponent (Elimit-1) */
#define DECQUAD_Ehigh (DECQUAD_Emax + DECQUAD_Bias - (DECQUAD_Pmax-1))
/* Required include */
#include "decContext.h"
/* The decQuad decimal 128-bit type, accessible by bytes */
typedef struct {
uint8_t bytes[DECQUAD_Bytes]; /* fields: 1, 5, 12, 110 bits */
} decQuad;
/* ---------------------------------------------------------------- */
/* Shared constants */
/* ---------------------------------------------------------------- */
/* sign and special values [top 32-bits; last two bits are don't-care
for Infinity on input, last bit don't-care for NaNs] */
#define DECFLOAT_Sign 0x80000000 /* 1 00000 00 Sign */
#define DECFLOAT_NaN 0x7c000000 /* 0 11111 00 NaN generic */
#define DECFLOAT_qNaN 0x7c000000 /* 0 11111 00 qNaN */
#define DECFLOAT_sNaN 0x7e000000 /* 0 11111 10 sNaN */
#define DECFLOAT_Inf 0x78000000 /* 0 11110 00 Infinity */
#define DECFLOAT_MinSp 0x78000000 /* minimum special value */
/* [specials are all >=MinSp] */
/* Sign nibble constants */
#if !defined(DECPPLUSALT)
#define DECPPLUSALT 0x0A /* alternate plus nibble */
#define DECPMINUSALT 0x0B /* alternate minus nibble */
#define DECPPLUS 0x0C /* preferred plus nibble */
#define DECPMINUS 0x0D /* preferred minus nibble */
#define DECPPLUSALT2 0x0E /* alternate plus nibble */
#define DECPUNSIGNED 0x0F /* alternate plus nibble (unsigned) */
#endif
/* ---------------------------------------------------------------- */
/* Routines -- implemented as decFloat routines in common files */
/* ---------------------------------------------------------------- */
#include "decQuadSymbols.h"
/* Utilities and conversions, extractors, etc.) */
extern decQuad * decQuadFromBCD(decQuad *, int32_t, const uint8_t *, int32_t);
extern decQuad * decQuadFromInt32(decQuad *, int32_t);
extern decQuad * decQuadFromPacked(decQuad *, int32_t, const uint8_t *);
extern decQuad * decQuadFromString(decQuad *, const char *, decContext *);
extern decQuad * decQuadFromUInt32(decQuad *, uint32_t);
extern int32_t decQuadGetCoefficient(const decQuad *, uint8_t *);
extern int32_t decQuadGetExponent(const decQuad *);
extern decQuad * decQuadSetCoefficient(decQuad *, const uint8_t *, int32_t);
extern decQuad * decQuadSetExponent(decQuad *, decContext *, int32_t);
extern void decQuadShow(const decQuad *, const char *);
extern int32_t decQuadToBCD(const decQuad *, int32_t *, uint8_t *);
extern char * decQuadToEngString(const decQuad *, char *);
extern int32_t decQuadToInt32(const decQuad *, decContext *, enum rounding);
extern int32_t decQuadToInt32Exact(const decQuad *, decContext *, enum rounding);
extern int32_t decQuadToPacked(const decQuad *, int32_t *, uint8_t *);
extern char * decQuadToString(const decQuad *, char *);
extern uint32_t decQuadToUInt32(const decQuad *, decContext *, enum rounding);
extern uint32_t decQuadToUInt32Exact(const decQuad *, decContext *, enum rounding);
extern decQuad * decQuadZero(decQuad *);
/* Computational (result is a decQuad) */
extern decQuad * decQuadAbs(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadAdd(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadAnd(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadDivide(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadDivideInteger(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadFMA(decQuad *, const decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadInvert(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadLogB(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMax(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMaxMag(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMin(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMinMag(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMinus(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadMultiply(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadNextMinus(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadNextPlus(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadNextToward(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadOr(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadPlus(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadQuantize(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadReduce(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadRemainder(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadRemainderNear(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadRotate(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadScaleB(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadShift(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadSubtract(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadToIntegralValue(decQuad *, const decQuad *, decContext *, enum rounding);
extern decQuad * decQuadToIntegralExact(decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadXor(decQuad *, const decQuad *, const decQuad *, decContext *);
/* Comparisons */
extern decQuad * decQuadCompare(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadCompareSignal(decQuad *, const decQuad *, const decQuad *, decContext *);
extern decQuad * decQuadCompareTotal(decQuad *, const decQuad *, const decQuad *);
extern decQuad * decQuadCompareTotalMag(decQuad *, const decQuad *, const decQuad *);
/* Copies */
extern decQuad * decQuadCanonical(decQuad *, const decQuad *);
extern decQuad * decQuadCopy(decQuad *, const decQuad *);
extern decQuad * decQuadCopyAbs(decQuad *, const decQuad *);
extern decQuad * decQuadCopyNegate(decQuad *, const decQuad *);
extern decQuad * decQuadCopySign(decQuad *, const decQuad *, const decQuad *);
/* Non-computational */
extern enum decClass decQuadClass(const decQuad *);
extern const char * decQuadClassString(const decQuad *);
extern uint32_t decQuadDigits(const decQuad *);
extern uint32_t decQuadIsCanonical(const decQuad *);
extern uint32_t decQuadIsFinite(const decQuad *);
extern uint32_t decQuadIsInteger(const decQuad *);
extern uint32_t decQuadIsInfinite(const decQuad *);
extern uint32_t decQuadIsNaN(const decQuad *);
extern uint32_t decQuadIsNormal(const decQuad *);
extern uint32_t decQuadIsSignaling(const decQuad *);
extern uint32_t decQuadIsSignalling(const decQuad *);
extern uint32_t decQuadIsSigned(const decQuad *);
extern uint32_t decQuadIsSubnormal(const decQuad *);
extern uint32_t decQuadIsZero(const decQuad *);
extern uint32_t decQuadRadix(const decQuad *);
extern uint32_t decQuadSameQuantum(const decQuad *, const decQuad *);
extern const char * decQuadVersion(void);
/* decNumber conversions; these are implemented as macros so as not */
/* to force a dependency on decimal128 and decNumber in decQuad. */
#define decQuadToNumber(dq, dn) decimal128ToNumber((decimal128 *)(dq), dn)
#define decQuadFromNumber(dq, dn, set) (decQuad *)decimal128FromNumber((decimal128 *)(dq), dn, set)
#endif

View File

@ -0,0 +1,82 @@
#if !defined(DECQUADSYMBOLS)
#define DECQUADSYMBOLS
#ifdef IN_LIBGCC2
#define decQuadAbs __decQuadAbs
#define decQuadAdd __decQuadAdd
#define decQuadAnd __decQuadAnd
#define decQuadCanonical __decQuadCanonical
#define decQuadClass __decQuadClass
#define decQuadClassString __decQuadClassString
#define decQuadCompare __decQuadCompare
#define decQuadCompareSignal __decQuadCompareSignal
#define decQuadCompareTotal __decQuadCompareTotal
#define decQuadCompareTotalMag __decQuadCompareTotalMag
#define decQuadCopy __decQuadCopy
#define decQuadCopyAbs __decQuadCopyAbs
#define decQuadCopyNegate __decQuadCopyNegate
#define decQuadCopySign __decQuadCopySign
#define decQuadDigits __decQuadDigits
#define decQuadDivide __decQuadDivide
#define decQuadDivideInteger __decQuadDivideInteger
#define decQuadFMA __decQuadFMA
#define decQuadFromBCD __decQuadFromBCD
#define decQuadFromInt32 __decQuadFromInt32
#define decQuadFromPacked __decQuadFromPacked
#define decQuadFromString __decQuadFromString
#define decQuadFromUInt32 __decQuadFromUInt32
#define decQuadGetCoefficient __decQuadGetCoefficient
#define decQuadGetExponent __decQuadGetExponent
#define decQuadInvert __decQuadInvert
#define decQuadIsCanonical __decQuadIsCanonical
#define decQuadIsFinite __decQuadIsFinite
#define decQuadIsInfinite __decQuadIsInfinite
#define decQuadIsInteger __decQuadIsInteger
#define decQuadIsNaN __decQuadIsNaN
#define decQuadIsNormal __decQuadIsNormal
#define decQuadIsSignaling __decQuadIsSignaling
#define decQuadIsSignalling __decQuadIsSignalling
#define decQuadIsSigned __decQuadIsSigned
#define decQuadIsSubnormal __decQuadIsSubnormal
#define decQuadIsZero __decQuadIsZero
#define decQuadLogB __decQuadLogB
#define decQuadMax __decQuadMax
#define decQuadMaxMag __decQuadMaxMag
#define decQuadMin __decQuadMin
#define decQuadMinMag __decQuadMinMag
#define decQuadMinus __decQuadMinus
#define decQuadMultiply __decQuadMultiply
#define decQuadNextMinus __decQuadNextMinus
#define decQuadNextPlus __decQuadNextPlus
#define decQuadNextToward __decQuadNextToward
#define decQuadOr __decQuadOr
#define decQuadPlus __decQuadPlus
#define decQuadQuantize __decQuadQuantize
#define decQuadRadix __decQuadRadix
#define decQuadReduce __decQuadReduce
#define decQuadRemainder __decQuadRemainder
#define decQuadRemainderNear __decQuadRemainderNear
#define decQuadRotate __decQuadRotate
#define decQuadSameQuantum __decQuadSameQuantum
#define decQuadScaleB __decQuadScaleB
#define decQuadSetCoefficient __decQuadSetCoefficient
#define decQuadSetExponent __decQuadSetExponent
#define decQuadShift __decQuadShift
#define decQuadShow __decQuadShow
#define decQuadSubtract __decQuadSubtract
#define decQuadToBCD __decQuadToBCD
#define decQuadToEngString __decQuadToEngString
#define decQuadToInt32 __decQuadToInt32
#define decQuadToInt32Exact __decQuadToInt32Exact
#define decQuadToIntegralExact __decQuadToIntegralExact
#define decQuadToIntegralValue __decQuadToIntegralValue
#define decQuadToPacked __decQuadToPacked
#define decQuadToString __decQuadToString
#define decQuadToUInt32 __decQuadToUInt32
#define decQuadToUInt32Exact __decQuadToUInt32Exact
#define decQuadVersion __decQuadVersion
#define decQuadXor __decQuadXor
#define decQuadZero __decQuadZero
#endif
#endif

102
libdecnumber/decRound.c Normal file
View File

@ -0,0 +1,102 @@
/* Internal testing support for rounding for decimal float.
Copyright (C) 2005, 2006 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 "config.h"
#include "decContext.h"
#include "decRound.h"
/* Internal, non-documented functions for testing libgcc functions.
This support is not sufficient for application use. */
#define FE_DEC_DOWNWARD 0
#define FE_DEC_TONEAREST 1
#define FE_DEC_TONEARESTFROMZERO 2
#define FE_DEC_TOWARDZERO 3
#define FE_DEC_UPWARD 4
#define FE_DEC_MAX 5
static enum rounding __dfp_rounding_mode = DEC_ROUND_HALF_EVEN;
/* Set the decNumber rounding mode from the FE_DEC_* value in MODE. */
void
__dfp_set_round (int mode)
{
switch (mode)
{
case FE_DEC_DOWNWARD:
__dfp_rounding_mode = DEC_ROUND_FLOOR; break;
case FE_DEC_TONEAREST:
__dfp_rounding_mode = DEC_ROUND_HALF_EVEN; break;
case FE_DEC_TONEARESTFROMZERO:
__dfp_rounding_mode = DEC_ROUND_HALF_UP; break;
case FE_DEC_TOWARDZERO:
__dfp_rounding_mode = DEC_ROUND_DOWN; break;
case FE_DEC_UPWARD:
__dfp_rounding_mode = DEC_ROUND_CEILING; break;
default:
/* We can't use assert in libgcc, so just return the default mode. */
__dfp_rounding_mode = DEC_ROUND_HALF_EVEN; break;
}
}
/* Return the decNumber rounding mode as an FE_DEC_* value. */
int
__dfp_get_round (void)
{
int mode;
switch (__dfp_rounding_mode)
{
case DEC_ROUND_FLOOR:
mode = FE_DEC_DOWNWARD; break;
case DEC_ROUND_HALF_EVEN:
mode = FE_DEC_TONEAREST; break;
case DEC_ROUND_HALF_UP:
mode = FE_DEC_TONEARESTFROMZERO; break;
case DEC_ROUND_DOWN:
mode = FE_DEC_TOWARDZERO; break;
case DEC_ROUND_CEILING:
mode = FE_DEC_UPWARD; break;
default:
/* We shouldn't get here, but can't use assert in libgcc. */
mode = -1;
}
return mode;
}
/* Return the decNumber version of the current rounding mode. */
enum rounding
__decGetRound (void)
{
return __dfp_rounding_mode;
}

37
libdecnumber/decRound.h Normal file
View File

@ -0,0 +1,37 @@
/* Internal testing support for rounding for decimal float.
Copyright (C) 2006 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 "decContext.h"
#define DFP_INIT_ROUNDMODE(A) A = __decGetRound()
extern void __dfp_set_round (int);
extern int __dfp_get_round (void);
extern enum rounding __decGetRound (void);

85
libdecnumber/decSingle.c Normal file
View File

@ -0,0 +1,85 @@
/* decSingle module for the decNumber C Library.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* decSingle.c -- decSingle operations module */
/* ------------------------------------------------------------------ */
/* This module comprises decSingle operations (including conversions) */
/* ------------------------------------------------------------------ */
#include "decContext.h" /* public includes */
#include "decSingle.h" /* public includes */
/* Constant mappings for shared code */
#define DECPMAX DECSINGLE_Pmax
#define DECEMIN DECSINGLE_Emin
#define DECEMAX DECSINGLE_Emax
#define DECEMAXD DECSINGLE_EmaxD
#define DECBYTES DECSINGLE_Bytes
#define DECSTRING DECSINGLE_String
#define DECECONL DECSINGLE_EconL
#define DECBIAS DECSINGLE_Bias
#define DECLETS DECSINGLE_Declets
#define DECQTINY (-DECSINGLE_Bias)
/* parameters of next-wider format */
#define DECWBYTES DECDOUBLE_Bytes
#define DECWPMAX DECDOUBLE_Pmax
#define DECWECONL DECDOUBLE_EconL
#define DECWBIAS DECDOUBLE_Bias
/* Type and function mappings for shared code */
#define decFloat decSingle /* Type name */
#define decFloatWider decDouble /* Type name */
/* Utility (binary results, extractors, etc.) */
#define decFloatFromBCD decSingleFromBCD
#define decFloatFromPacked decSingleFromPacked
#define decFloatFromString decSingleFromString
#define decFloatFromWider decSingleFromWider
#define decFloatGetCoefficient decSingleGetCoefficient
#define decFloatGetExponent decSingleGetExponent
#define decFloatSetCoefficient decSingleSetCoefficient
#define decFloatSetExponent decSingleSetExponent
#define decFloatShow decSingleShow
#define decFloatToBCD decSingleToBCD
#define decFloatToEngString decSingleToEngString
#define decFloatToPacked decSingleToPacked
#define decFloatToString decSingleToString
#define decFloatToWider decSingleToWider
#define decFloatZero decSingleZero
/* Non-computational */
#define decFloatRadix decSingleRadix
#define decFloatVersion decSingleVersion
#include "decNumberLocal.h" /* local includes (need DECPMAX) */
#include "decCommon.c" /* non-basic decFloat routines */
/* [Do not include decBasic.c for decimal32] */

101
libdecnumber/decSingle.h Normal file
View File

@ -0,0 +1,101 @@
/* decSingle module header for the decNumber C Library.
Copyright (C) 2005 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* decSingle.h -- Decimal 32-bit format module header */
/* ------------------------------------------------------------------ */
/* Please see decFloats.h for an overview and documentation details. */
/* ------------------------------------------------------------------ */
#if !defined(DECSINGLE)
#define DECSINGLE
#define DECSINGLENAME "decSingle" /* Short name */
#define DECSINGLETITLE "Decimal 32-bit datum" /* Verbose name */
#define DECSINGLEAUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decSingles */
#define DECSINGLE_Bytes 4 /* length */
#define DECSINGLE_Pmax 7 /* maximum precision (digits) */
#define DECSINGLE_Emin -95 /* minimum adjusted exponent */
#define DECSINGLE_Emax 96 /* maximum adjusted exponent */
#define DECSINGLE_EmaxD 3 /* maximum exponent digits */
#define DECSINGLE_Bias 101 /* bias for the exponent */
#define DECSINGLE_String 16 /* maximum string length, +1 */
#define DECSINGLE_EconL 6 /* exponent continuation length */
#define DECSINGLE_Declets 2 /* count of declets */
/* highest biased exponent (Elimit-1) */
#define DECSINGLE_Ehigh (DECSINGLE_Emax + DECSINGLE_Bias - (DECSINGLE_Pmax-1))
/* Required includes */
#include "decContext.h"
#include "decQuad.h"
#include "decDouble.h"
/* The decSingle decimal 32-bit type, accessible by bytes */
typedef struct {
uint8_t bytes[DECSINGLE_Bytes]; /* fields: 1, 5, 6, 20 bits */
} decSingle;
/* ---------------------------------------------------------------- */
/* Routines -- implemented as decFloat routines in common files */
/* ---------------------------------------------------------------- */
#include "decSingleSymbols.h"
/* Utilities (binary argument(s) or result, extractors, etc.) */
extern decSingle * decSingleFromBCD(decSingle *, int32_t, const uint8_t *, int32_t);
extern decSingle * decSingleFromPacked(decSingle *, int32_t, const uint8_t *);
extern decSingle * decSingleFromString(decSingle *, const char *, decContext *);
extern decSingle * decSingleFromWider(decSingle *, const decDouble *, decContext *);
extern int32_t decSingleGetCoefficient(const decSingle *, uint8_t *);
extern int32_t decSingleGetExponent(const decSingle *);
extern decSingle * decSingleSetCoefficient(decSingle *, const uint8_t *, int32_t);
extern decSingle * decSingleSetExponent(decSingle *, decContext *, int32_t);
extern void decSingleShow(const decSingle *, const char *);
extern int32_t decSingleToBCD(const decSingle *, int32_t *, uint8_t *);
extern char * decSingleToEngString(const decSingle *, char *);
extern int32_t decSingleToPacked(const decSingle *, int32_t *, uint8_t *);
extern char * decSingleToString(const decSingle *, char *);
extern decDouble * decSingleToWider(const decSingle *, decDouble *);
extern decSingle * decSingleZero(decSingle *);
/* (No Arithmetic routines for decSingle) */
/* Non-computational */
extern uint32_t decSingleRadix(const decSingle *);
extern const char * decSingleVersion(void);
/* decNumber conversions; these are implemented as macros so as not */
/* to force a dependency on decimal32 and decNumber in decSingle. */
#define decSingleToNumber(dq, dn) decimal32ToNumber((decimal32 *)(dq), dn)
#define decSingleFromNumber(dq, dn, set) (decSingle *)decimal32FromNumber((decimal32 *)(dq), dn, set)
#endif

View File

@ -0,0 +1,24 @@
#if !defined(DECSINGLESYMBOLS)
#define DECSINGLESYMBOLS
#ifdef IN_LIBGCC2
#define decSingleFromBCD __decSingleFromBCD
#define decSingleFromPacked __decSingleFromPacked
#define decSingleFromString __decSingleFromString
#define decSingleFromWider __decSingleFromWider
#define decSingleGetCoefficient __decSingleGetCoefficient
#define decSingleGetExponent __decSingleGetExponent
#define decSingleRadix __decSingleRadix
#define decSingleSetCoefficient __decSingleSetCoefficient
#define decSingleSetExponent __decSingleSetExponent
#define decSingleShow __decSingleShow
#define decSingleToBCD __decSingleToBCD
#define decSingleToEngString __decSingleToEngString
#define decSingleToPacked __decSingleToPacked
#define decSingleToString __decSingleToString
#define decSingleToWider __decSingleToWider
#define decSingleVersion __decSingleVersion
#define decSingleZero __decSingleZero
#endif
#endif

View File

@ -0,0 +1,570 @@
/* Decimal 128-bit format module for the decNumber C Library.
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Decimal 128-bit format module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal128 format numbers. */
/* Conversions are supplied to and from decNumber and String. */
/* */
/* This is used when decNumber provides operations, either for all */
/* operations or as a proxy between decNumber and decSingle. */
/* */
/* Error handling is the same as decNumber (qv.). */
/* ------------------------------------------------------------------ */
#include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */
#include "config.h" /* GCC definitions */
#define DECNUMDIGITS 34 /* make decNumbers with space for 34 */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal128.h" /* our primary include */
/* Utility routines and tables [in decimal64.c] */
/* DPD2BIN and the reverse are renamed to prevent link-time conflict */
/* if decQuad is also built in the same executable */
#define DPD2BIN DPD2BINx
#define BIN2DPD BIN2DPDx
extern const uInt COMBEXP[32], COMBMSD[32];
extern const uShort DPD2BIN[1024];
extern const uShort BIN2DPD[1000]; /* [not used] */
extern const uByte BIN2CHAR[4001];
extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
extern void decDigitsToDPD(const decNumber *, uInt *, Int);
#if DECTRACE || DECCHECK
void decimal128Show(const decimal128 *); /* for debug */
extern void decNumberShow(const decNumber *); /* .. */
#endif
/* Useful macro */
/* Clear a structure (e.g., a decNumber) */
#define DEC_clear(d) memset(d, 0, sizeof(*d))
/* ------------------------------------------------------------------ */
/* decimal128FromNumber -- convert decNumber to decimal128 */
/* */
/* ds is the target decimal128 */
/* dn is the source number (assumed valid) */
/* set is the context, used only for reporting errors */
/* */
/* The set argument is used only for status reporting and for the */
/* rounding mode (used if the coefficient is more than DECIMAL128_Pmax*/
/* digits or an overflow is detected). If the exponent is out of the */
/* valid range then Overflow or Underflow will be raised. */
/* After Underflow a subnormal result is possible. */
/* */
/* DEC_Clamped is set if the number has to be 'folded down' to fit, */
/* by reducing its exponent and multiplying the coefficient by a */
/* power of ten, or if the exponent on a zero had to be clamped. */
/* ------------------------------------------------------------------ */
decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
decContext *set) {
uInt status=0; /* status accumulator */
Int ae; /* adjusted exponent */
decNumber dw; /* work */
decContext dc; /* .. */
uInt *pu; /* .. */
uInt comb, exp; /* .. */
uInt targar[4]={0,0,0,0}; /* target 128-bit */
#define targhi targar[3] /* name the word with the sign */
#define targmh targar[2] /* name the words */
#define targml targar[1] /* .. */
#define targlo targar[0] /* .. */
/* If the number has too many digits, or the exponent could be */
/* out of range then reduce the number under the appropriate */
/* constraints. This could push the number to Infinity or zero, */
/* so this check and rounding must be done before generating the */
/* decimal128] */
ae=dn->exponent+dn->digits-1; /* [0 if special] */
if (dn->digits>DECIMAL128_Pmax /* too many digits */
|| ae>DECIMAL128_Emax /* likely overflow */
|| ae<DECIMAL128_Emin) { /* likely underflow */
decContextDefault(&dc, DEC_INIT_DECIMAL128); /* [no traps] */
dc.round=set->round; /* use supplied rounding */
decNumberPlus(&dw, dn, &dc); /* (round and check) */
/* [this changes -0 to 0, so enforce the sign...] */
dw.bits|=dn->bits&DECNEG;
status=dc.status; /* save status */
dn=&dw; /* use the work number */
} /* maybe out of range */
if (dn->bits&DECSPECIAL) { /* a special value */
if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
else { /* sNaN or qNaN */
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
&& (dn->digits<DECIMAL128_Pmax)) { /* coefficient fits */
decDigitsToDPD(dn, targar, 0);
}
if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
else targhi|=DECIMAL_sNaN<<24;
} /* a NaN */
} /* special */
else { /* is finite */
if (decNumberIsZero(dn)) { /* is a zero */
/* set and clamp exponent */
if (dn->exponent<-DECIMAL128_Bias) {
exp=0; /* low clamp */
status|=DEC_Clamped;
}
else {
exp=dn->exponent+DECIMAL128_Bias; /* bias exponent */
if (exp>DECIMAL128_Ehigh) { /* top clamp */
exp=DECIMAL128_Ehigh;
status|=DEC_Clamped;
}
}
comb=(exp>>9) & 0x18; /* msd=0, exp top 2 bits .. */
}
else { /* non-zero finite number */
uInt msd; /* work */
Int pad=0; /* coefficient pad digits */
/* the dn is known to fit, but it may need to be padded */
exp=(uInt)(dn->exponent+DECIMAL128_Bias); /* bias exponent */
if (exp>DECIMAL128_Ehigh) { /* fold-down case */
pad=exp-DECIMAL128_Ehigh;
exp=DECIMAL128_Ehigh; /* [to maximum] */
status|=DEC_Clamped;
}
/* [fastpath for common case is not a win, here] */
decDigitsToDPD(dn, targar, pad);
/* save and clear the top digit */
msd=targhi>>14;
targhi&=0x00003fff;
/* create the combination field */
if (msd>=8) comb=0x18 | ((exp>>11) & 0x06) | (msd & 0x01);
else comb=((exp>>9) & 0x18) | msd;
}
targhi|=comb<<26; /* add combination field .. */
targhi|=(exp&0xfff)<<14; /* .. and exponent continuation */
} /* finite */
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
/* now write to storage; this is endian */
pu=(uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
pu[0]=targlo; /* directly store the low int */
pu[1]=targml; /* then the mid-low */
pu[2]=targmh; /* then the mid-high */
pu[3]=targhi; /* then the high int */
}
else {
pu[0]=targhi; /* directly store the high int */
pu[1]=targmh; /* then the mid-high */
pu[2]=targml; /* then the mid-low */
pu[3]=targlo; /* then the low int */
}
if (status!=0) decContextSetStatus(set, status); /* pass on status */
/* decimal128Show(d128); */
return d128;
} /* decimal128FromNumber */
/* ------------------------------------------------------------------ */
/* decimal128ToNumber -- convert decimal128 to decNumber */
/* d128 is the source decimal128 */
/* dn is the target number, with appropriate space */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
uInt msd; /* coefficient MSD */
uInt exp; /* exponent top two bits */
uInt comb; /* combination field */
const uInt *pu; /* work */
Int need; /* .. */
uInt sourar[4]; /* source 128-bit */
#define sourhi sourar[3] /* name the word with the sign */
#define sourmh sourar[2] /* and the mid-high word */
#define sourml sourar[1] /* and the mod-low word */
#define sourlo sourar[0] /* and the lowest word */
/* load source from storage; this is endian */
pu=(const uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
sourlo=pu[0]; /* directly load the low int */
sourml=pu[1]; /* then the mid-low */
sourmh=pu[2]; /* then the mid-high */
sourhi=pu[3]; /* then the high int */
}
else {
sourhi=pu[0]; /* directly load the high int */
sourmh=pu[1]; /* then the mid-high */
sourml=pu[2]; /* then the mid-low */
sourlo=pu[3]; /* then the low int */
}
comb=(sourhi>>26)&0x1f; /* combination field */
decNumberZero(dn); /* clean number */
if (sourhi&0x80000000) dn->bits=DECNEG; /* set sign if negative */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) { /* is a special */
if (msd==0) {
dn->bits|=DECINF;
return dn; /* no coefficient needed */
}
else if (sourhi&0x02000000) dn->bits|=DECSNAN;
else dn->bits|=DECNAN;
msd=0; /* no top digit */
}
else { /* is a finite number */
dn->exponent=(exp<<12)+((sourhi>>14)&0xfff)-DECIMAL128_Bias; /* unbiased */
}
/* get the coefficient */
sourhi&=0x00003fff; /* clean coefficient continuation */
if (msd) { /* non-zero msd */
sourhi|=msd<<14; /* prefix to coefficient */
need=12; /* process 12 declets */
}
else { /* msd=0 */
if (sourhi) need=11; /* declets to process */
else if (sourmh) need=10;
else if (sourml) need=7;
else if (sourlo) need=4;
else return dn; /* easy: coefficient is 0 */
} /*msd=0 */
decDigitsFromDPD(dn, sourar, need); /* process declets */
/* decNumberShow(dn); */
return dn;
} /* decimal128ToNumber */
/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */
/* to-engineering-string -- conversion to numeric string */
/* */
/* decimal128ToString(d128, string); */
/* decimal128ToEngString(d128, string); */
/* */
/* d128 is the decimal128 format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least 24 characters */
/* */
/* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */
char * decimal128ToEngString(const decimal128 *d128, char *string){
decNumber dn; /* work */
decimal128ToNumber(d128, &dn);
decNumberToEngString(&dn, string);
return string;
} /* decimal128ToEngString */
char * decimal128ToString(const decimal128 *d128, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
const uInt *pu; /* work */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
const uByte *u; /* .. */
uInt sourar[4]; /* source 128-bit */
#define sourhi sourar[3] /* name the word with the sign */
#define sourmh sourar[2] /* and the mid-high word */
#define sourml sourar[1] /* and the mod-low word */
#define sourlo sourar[0] /* and the lowest word */
/* load source from storage; this is endian */
pu=(const uInt *)d128->bytes; /* overlay */
if (DECLITEND) {
sourlo=pu[0]; /* directly load the low int */
sourml=pu[1]; /* then the mid-low */
sourmh=pu[2]; /* then the mid-high */
sourhi=pu[3]; /* then the high int */
}
else {
sourhi=pu[0]; /* directly load the high int */
sourmh=pu[1]; /* then the mid-high */
sourml=pu[2]; /* then the mid-low */
sourlo=pu[3]; /* then the low int */
}
c=string; /* where result will go */
if (((Int)sourhi)<0) *c++='-'; /* handle sign */
comb=(sourhi>>26)&0x1f; /* combination field */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) {
if (msd==0) { /* infinity */
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
if (sourhi&0x02000000) *c++='s'; /* sNaN */
strcpy(c, "NaN"); /* complete word */
c+=3; /* step past */
if (sourlo==0 && sourml==0 && sourmh==0
&& (sourhi&0x0003ffff)==0) return string; /* zero payload */
/* otherwise drop through to add integer; set correct exp */
exp=0; msd=0; /* setup for following code */
}
else exp=(exp<<12)+((sourhi>>14)&0xfff)-DECIMAL128_Bias; /* unbiased */
/* convert 34 digits of significand to characters */
cstart=c; /* save start of coefficient */
if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */
/* Now decode the declets. After extracting each one, it is */
/* decoded to binary and then to a 4-char sequence by table lookup; */
/* the 4-chars are a 1-char length (significant digits, except 000 */
/* has length 0). This allows us to left-align the first declet */
/* with non-zero content, then remaining ones are full 3-char */
/* length. We use fixed-length memcpys because variable-length */
/* causes a subroutine call in GCC. (These are length 4 for speed */
/* and are safe because the array has an extra terminator byte.) */
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
dpd=(sourhi>>4)&0x3ff; /* declet 1 */
dpd2char;
dpd=((sourhi&0xf)<<6) | (sourmh>>26); /* declet 2 */
dpd2char;
dpd=(sourmh>>16)&0x3ff; /* declet 3 */
dpd2char;
dpd=(sourmh>>6)&0x3ff; /* declet 4 */
dpd2char;
dpd=((sourmh&0x3f)<<4) | (sourml>>28); /* declet 5 */
dpd2char;
dpd=(sourml>>18)&0x3ff; /* declet 6 */
dpd2char;
dpd=(sourml>>8)&0x3ff; /* declet 7 */
dpd2char;
dpd=((sourml&0xff)<<2) | (sourlo>>30); /* declet 8 */
dpd2char;
dpd=(sourlo>>20)&0x3ff; /* declet 9 */
dpd2char;
dpd=(sourlo>>10)&0x3ff; /* declet 10 */
dpd2char;
dpd=(sourlo)&0x3ff; /* declet 11 */
dpd2char;
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
if (exp==0) { /* integer or NaN case -- easy */
*c='\0'; /* terminate */
return string;
}
/* non-0 exponent */
e=0; /* assume no E */
pre=c-cstart+exp;
/* [here, pre-exp is the digits count (==1 for zero)] */
if (exp>0 || pre<-5) { /* need exponential form */
e=pre-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
} /* exponential form */
/* modify the coefficient, adding 0s, '.', and E+nn as needed */
s=c-1; /* source (LSD) */
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
t=c; /* target */
for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */
*t='.'; /* insert the dot */
c++; /* length increased by one */
}
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 4 digits */
if (e!=0) {
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
if (e<0) {
*(c-1)='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
if (e<1000) { /* 3 (or fewer) digits case */
u=&BIN2CHAR[e*4]; /* -> length byte */
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
c+=*u; /* bump pointer appropriately */
}
else { /* 4-digits */
Int thou=((e>>3)*1049)>>17; /* e/1000 */
Int rem=e-(1000*thou); /* e%1000 */
*c++='0'+(char)thou;
u=&BIN2CHAR[rem*4]; /* -> length byte */
memcpy(c, u+1, 4); /* copy fixed 3+1 characters [is safe] */
c+=3; /* bump pointer, always 3 digits */
}
}
*c='\0'; /* add terminator */
/*printf("res %s\n", string); */
return string;
} /* pre>0 */
/* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
t=c+1-pre;
*(t+1)='\0'; /* can add terminator now */
for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */
c=cstart;
*c++='0'; /* always starts with 0. */
*c++='.';
for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */
/*printf("res %s\n", string); */
return string;
} /* decimal128ToString */
/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string */
/* */
/* decimal128FromString(result, string, set); */
/* */
/* result is the decimal128 format number which gets the result of */
/* the conversion */
/* *string is the character string which should contain a valid */
/* number (which may be a special value) */
/* set is the context */
/* */
/* The context is supplied to this routine is used for error handling */
/* (setting of status and traps) and for the rounding mode, only. */
/* If an error occurs, the result will be a valid decimal128 NaN. */
/* ------------------------------------------------------------------ */
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;
} /* decimal128FromString */
/* ------------------------------------------------------------------ */
/* decimal128IsCanonical -- test whether encoding is canonical */
/* d128 is the source decimal128 */
/* returns 1 if the encoding of d128 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uint32_t decimal128IsCanonical(const decimal128 *d128) {
decNumber dn; /* work */
decimal128 canon; /* .. */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL128);
decimal128ToNumber(d128, &dn);
decimal128FromNumber(&canon, &dn, &dc);/* canon will now be canonical */
return memcmp(d128, &canon, DECIMAL128_Bytes)==0;
} /* decimal128IsCanonical */
/* ------------------------------------------------------------------ */
/* decimal128Canonical -- copy an encoding, ensuring it is canonical */
/* d128 is the source decimal128 */
/* result is the target (may be the same decimal128) */
/* returns result */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
decNumber dn; /* work */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL128);
decimal128ToNumber(d128, &dn);
decimal128FromNumber(result, &dn, &dc);/* result will now be canonical */
return result;
} /* decimal128Canonical */
#if DECTRACE || DECCHECK
/* Macros for accessing decimal128 fields. These assume the argument
is a reference (pointer) to the decimal128 structure, and the
decimal128 is in network byte order (big-endian) */
/* Get sign */
#define decimal128Sign(d) ((unsigned)(d)->bytes[0]>>7)
/* Get combination field */
#define decimal128Comb(d) (((d)->bytes[0] & 0x7c)>>2)
/* Get exponent continuation [does not remove bias] */
#define decimal128ExpCon(d) ((((d)->bytes[0] & 0x03)<<10) \
| ((unsigned)(d)->bytes[1]<<2) \
| ((unsigned)(d)->bytes[2]>>6))
/* Set sign [this assumes sign previously 0] */
#define decimal128SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal128SetExpCon(d, e) { \
(d)->bytes[0]|=(uint8_t)((e)>>10); \
(d)->bytes[1] =(uint8_t)(((e)&0x3fc)>>2); \
(d)->bytes[2]|=(uint8_t)(((e)&0x03)<<6);}
/* ------------------------------------------------------------------ */
/* decimal128Show -- display a decimal128 in hexadecimal [debug aid] */
/* d128 -- the number to show */
/* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted */
void decimal128Show(const decimal128 *d128) {
char buf[DECIMAL128_Bytes*2+1];
Int i, j=0;
if (DECLITEND) {
for (i=0; i<DECIMAL128_Bytes; i++, j+=2) {
sprintf(&buf[j], "%02x", d128->bytes[15-i]);
}
printf(" D128> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf,
d128->bytes[15]>>7, (d128->bytes[15]>>2)&0x1f,
((d128->bytes[15]&0x3)<<10)|(d128->bytes[14]<<2)|
(d128->bytes[13]>>6));
}
else {
for (i=0; i<DECIMAL128_Bytes; i++, j+=2) {
sprintf(&buf[j], "%02x", d128->bytes[i]);
}
printf(" D128> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf,
decimal128Sign(d128), decimal128Comb(d128),
decimal128ExpCon(d128));
}
} /* decimal128Show */
#endif

View File

@ -0,0 +1,101 @@
/* Decimal 128-bit format module header for the decNumber C Library.
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Decimal 128-bit format module header */
/* ------------------------------------------------------------------ */
#if !defined(DECIMAL128)
#define DECIMAL128
#define DEC128NAME "decimal128" /* Short name */
#define DEC128FULLNAME "Decimal 128-bit Number" /* Verbose name */
#define DEC128AUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decimal128s */
#define DECIMAL128_Bytes 16 /* length */
#define DECIMAL128_Pmax 34 /* maximum precision (digits) */
#define DECIMAL128_Emax 6144 /* maximum adjusted exponent */
#define DECIMAL128_Emin -6143 /* minimum adjusted exponent */
#define DECIMAL128_Bias 6176 /* bias for the exponent */
#define DECIMAL128_String 43 /* maximum string length, +1 */
#define DECIMAL128_EconL 12 /* exp. continuation length */
/* highest biased exponent (Elimit-1) */
#define DECIMAL128_Ehigh (DECIMAL128_Emax+DECIMAL128_Bias-DECIMAL128_Pmax+1)
/* check enough digits, if pre-defined */
#if defined(DECNUMDIGITS)
#if (DECNUMDIGITS<DECIMAL128_Pmax)
#error decimal128.h needs pre-defined DECNUMDIGITS>=34 for safe use
#endif
#endif
#ifndef DECNUMDIGITS
#define DECNUMDIGITS DECIMAL128_Pmax /* size if not already defined*/
#endif
#ifndef DECNUMBER
#include "decNumber.h" /* context and number library */
#endif
/* Decimal 128-bit type, accessible by bytes */
typedef struct {
uint8_t bytes[DECIMAL128_Bytes]; /* decimal128: 1, 5, 12, 110 bits*/
} decimal128;
/* special values [top byte excluding sign bit; last two bits are */
/* don't-care for Infinity on input, last bit don't-care for NaN] */
#if !defined(DECIMAL_NaN)
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
#endif
#include "decimal128Local.h"
/* ---------------------------------------------------------------- */
/* Routines */
/* ---------------------------------------------------------------- */
#include "decimal128Symbols.h"
/* String conversions */
decimal128 * decimal128FromString(decimal128 *, const char *, decContext *);
char * decimal128ToString(const decimal128 *, char *);
char * decimal128ToEngString(const decimal128 *, char *);
/* decNumber conversions */
decimal128 * decimal128FromNumber(decimal128 *, const decNumber *,
decContext *);
decNumber * decimal128ToNumber(const decimal128 *, decNumber *);
/* Format-dependent utilities */
uint32_t decimal128IsCanonical(const decimal128 *);
decimal128 * decimal128Canonical(decimal128 *, const decimal128 *);
#endif

View File

@ -0,0 +1,47 @@
/* Local definitions for use with the decNumber C 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. */
#if !defined(DECIMAL128LOCAL)
/* The compiler needs sign manipulation functions for decimal128 which
are not part of the decNumber package. */
/* Set sign; this assumes the sign was previously zero. */
#define decimal128SetSign(d,b) \
{ (d)->bytes[FLOAT_WORDS_BIG_ENDIAN ? 0 : 15] |= ((unsigned) (b) << 7); }
/* Clear sign. */
#define decimal128ClearSign(d) \
{ (d)->bytes[FLOAT_WORDS_BIG_ENDIAN ? 0 : 15] &= ~0x80; }
/* Flip sign. */
#define decimal128FlipSign(d) \
{ (d)->bytes[FLOAT_WORDS_BIG_ENDIAN ? 0 : 15] ^= 0x80; }
#endif

View File

@ -0,0 +1,16 @@
#if !defined(DECIMAL128SYMBOLS)
#define DECIMAL128SYMBOLS
#ifdef IN_LIBGCC2
#define decDigitsFromDPD __decDigitsFromDPD
#define decDigitsToDPD __decDigitsToDPD
#define decimal128Canonical __decimal128Canonical
#define decimal128FromNumber __decimal128FromNumber
#define decimal128FromString __decimal128FromString
#define decimal128IsCanonical __decimal128IsCanonical
#define decimal128ToEngString __decimal128ToEngString
#define decimal128ToNumber __decimal128ToNumber
#define decimal128ToString __decimal128ToString
#endif
#endif

View File

@ -0,0 +1,495 @@
/* Decimal 32-bit format module for the decNumber C Library.
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Decimal 32-bit format module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal32 format numbers. */
/* Conversions are supplied to and from decNumber and String. */
/* */
/* This is used when decNumber provides operations, either for all */
/* operations or as a proxy between decNumber and decSingle. */
/* */
/* Error handling is the same as decNumber (qv.). */
/* ------------------------------------------------------------------ */
#include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */
#include "config.h" /* GCC definitions */
#define DECNUMDIGITS 7 /* make decNumbers with space for 7 */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal32.h" /* our primary include */
/* Utility tables and routines [in decimal64.c] */
/* DPD2BIN and the reverse are renamed to prevent link-time conflict */
/* if decQuad is also built in the same executable */
#define DPD2BIN DPD2BINx
#define BIN2DPD BIN2DPDx
extern const uInt COMBEXP[32], COMBMSD[32];
extern const uShort DPD2BIN[1024];
extern const uShort BIN2DPD[1000];
extern const uByte BIN2CHAR[4001];
extern void decDigitsToDPD(const decNumber *, uInt *, Int);
extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
#if DECTRACE || DECCHECK
void decimal32Show(const decimal32 *); /* for debug */
extern void decNumberShow(const decNumber *); /* .. */
#endif
/* Useful macro */
/* Clear a structure (e.g., a decNumber) */
#define DEC_clear(d) memset(d, 0, sizeof(*d))
/* ------------------------------------------------------------------ */
/* decimal32FromNumber -- convert decNumber to decimal32 */
/* */
/* ds is the target decimal32 */
/* dn is the source number (assumed valid) */
/* set is the context, used only for reporting errors */
/* */
/* The set argument is used only for status reporting and for the */
/* rounding mode (used if the coefficient is more than DECIMAL32_Pmax */
/* digits or an overflow is detected). If the exponent is out of the */
/* valid range then Overflow or Underflow will be raised. */
/* After Underflow a subnormal result is possible. */
/* */
/* DEC_Clamped is set if the number has to be 'folded down' to fit, */
/* by reducing its exponent and multiplying the coefficient by a */
/* power of ten, or if the exponent on a zero had to be clamped. */
/* ------------------------------------------------------------------ */
decimal32 * decimal32FromNumber(decimal32 *d32, const decNumber *dn,
decContext *set) {
uInt status=0; /* status accumulator */
Int ae; /* adjusted exponent */
decNumber dw; /* work */
decContext dc; /* .. */
uInt *pu; /* .. */
uInt comb, exp; /* .. */
uInt targ=0; /* target 32-bit */
/* If the number has too many digits, or the exponent could be */
/* out of range then reduce the number under the appropriate */
/* constraints. This could push the number to Infinity or zero, */
/* so this check and rounding must be done before generating the */
/* decimal32] */
ae=dn->exponent+dn->digits-1; /* [0 if special] */
if (dn->digits>DECIMAL32_Pmax /* too many digits */
|| ae>DECIMAL32_Emax /* likely overflow */
|| ae<DECIMAL32_Emin) { /* likely underflow */
decContextDefault(&dc, DEC_INIT_DECIMAL32); /* [no traps] */
dc.round=set->round; /* use supplied rounding */
decNumberPlus(&dw, dn, &dc); /* (round and check) */
/* [this changes -0 to 0, so enforce the sign...] */
dw.bits|=dn->bits&DECNEG;
status=dc.status; /* save status */
dn=&dw; /* use the work number */
} /* maybe out of range */
if (dn->bits&DECSPECIAL) { /* a special value */
if (dn->bits&DECINF) targ=DECIMAL_Inf<<24;
else { /* sNaN or qNaN */
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
&& (dn->digits<DECIMAL32_Pmax)) { /* coefficient fits */
decDigitsToDPD(dn, &targ, 0);
}
if (dn->bits&DECNAN) targ|=DECIMAL_NaN<<24;
else targ|=DECIMAL_sNaN<<24;
} /* a NaN */
} /* special */
else { /* is finite */
if (decNumberIsZero(dn)) { /* is a zero */
/* set and clamp exponent */
if (dn->exponent<-DECIMAL32_Bias) {
exp=0; /* low clamp */
status|=DEC_Clamped;
}
else {
exp=dn->exponent+DECIMAL32_Bias; /* bias exponent */
if (exp>DECIMAL32_Ehigh) { /* top clamp */
exp=DECIMAL32_Ehigh;
status|=DEC_Clamped;
}
}
comb=(exp>>3) & 0x18; /* msd=0, exp top 2 bits .. */
}
else { /* non-zero finite number */
uInt msd; /* work */
Int pad=0; /* coefficient pad digits */
/* the dn is known to fit, but it may need to be padded */
exp=(uInt)(dn->exponent+DECIMAL32_Bias); /* bias exponent */
if (exp>DECIMAL32_Ehigh) { /* fold-down case */
pad=exp-DECIMAL32_Ehigh;
exp=DECIMAL32_Ehigh; /* [to maximum] */
status|=DEC_Clamped;
}
/* fastpath common case */
if (DECDPUN==3 && pad==0) {
targ=BIN2DPD[dn->lsu[0]];
if (dn->digits>3) targ|=(uInt)(BIN2DPD[dn->lsu[1]])<<10;
msd=(dn->digits==7 ? dn->lsu[2] : 0);
}
else { /* general case */
decDigitsToDPD(dn, &targ, pad);
/* save and clear the top digit */
msd=targ>>20;
targ&=0x000fffff;
}
/* create the combination field */
if (msd>=8) comb=0x18 | ((exp>>5) & 0x06) | (msd & 0x01);
else comb=((exp>>3) & 0x18) | msd;
}
targ|=comb<<26; /* add combination field .. */
targ|=(exp&0x3f)<<20; /* .. and exponent continuation */
} /* finite */
if (dn->bits&DECNEG) targ|=0x80000000; /* add sign bit */
/* now write to storage; this is endian */
pu=(uInt *)d32->bytes; /* overlay */
*pu=targ; /* directly store the int */
if (status!=0) decContextSetStatus(set, status); /* pass on status */
/* decimal32Show(d32); */
return d32;
} /* decimal32FromNumber */
/* ------------------------------------------------------------------ */
/* decimal32ToNumber -- convert decimal32 to decNumber */
/* d32 is the source decimal32 */
/* dn is the target number, with appropriate space */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decNumber * decimal32ToNumber(const decimal32 *d32, decNumber *dn) {
uInt msd; /* coefficient MSD */
uInt exp; /* exponent top two bits */
uInt comb; /* combination field */
uInt sour; /* source 32-bit */
const uInt *pu; /* work */
/* load source from storage; this is endian */
pu=(const uInt *)d32->bytes; /* overlay */
sour=*pu; /* directly load the int */
comb=(sour>>26)&0x1f; /* combination field */
decNumberZero(dn); /* clean number */
if (sour&0x80000000) dn->bits=DECNEG; /* set sign if negative */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) { /* is a special */
if (msd==0) {
dn->bits|=DECINF;
return dn; /* no coefficient needed */
}
else if (sour&0x02000000) dn->bits|=DECSNAN;
else dn->bits|=DECNAN;
msd=0; /* no top digit */
}
else { /* is a finite number */
dn->exponent=(exp<<6)+((sour>>20)&0x3f)-DECIMAL32_Bias; /* unbiased */
}
/* get the coefficient */
sour&=0x000fffff; /* clean coefficient continuation */
if (msd) { /* non-zero msd */
sour|=msd<<20; /* prefix to coefficient */
decDigitsFromDPD(dn, &sour, 3); /* process 3 declets */
return dn;
}
/* msd=0 */
if (!sour) return dn; /* easy: coefficient is 0 */
if (sour&0x000ffc00) /* need 2 declets? */
decDigitsFromDPD(dn, &sour, 2); /* process 2 declets */
else
decDigitsFromDPD(dn, &sour, 1); /* process 1 declet */
return dn;
} /* decimal32ToNumber */
/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */
/* to-engineering-string -- conversion to numeric string */
/* */
/* decimal32ToString(d32, string); */
/* decimal32ToEngString(d32, string); */
/* */
/* d32 is the decimal32 format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least 24 characters */
/* */
/* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */
char * decimal32ToEngString(const decimal32 *d32, char *string){
decNumber dn; /* work */
decimal32ToNumber(d32, &dn);
decNumberToEngString(&dn, string);
return string;
} /* decimal32ToEngString */
char * decimal32ToString(const decimal32 *d32, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
const uInt *pu; /* work */
const uByte *u; /* .. */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
uInt sour; /* source 32-bit */
/* load source from storage; this is endian */
pu=(const uInt *)d32->bytes; /* overlay */
sour=*pu; /* directly load the int */
c=string; /* where result will go */
if (((Int)sour)<0) *c++='-'; /* handle sign */
comb=(sour>>26)&0x1f; /* combination field */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) {
if (msd==0) { /* infinity */
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
if (sour&0x02000000) *c++='s'; /* sNaN */
strcpy(c, "NaN"); /* complete word */
c+=3; /* step past */
if ((sour&0x000fffff)==0) return string; /* zero payload */
/* otherwise drop through to add integer; set correct exp */
exp=0; msd=0; /* setup for following code */
}
else exp=(exp<<6)+((sour>>20)&0x3f)-DECIMAL32_Bias; /* unbiased */
/* convert 7 digits of significand to characters */
cstart=c; /* save start of coefficient */
if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */
/* Now decode the declets. After extracting each one, it is */
/* decoded to binary and then to a 4-char sequence by table lookup; */
/* the 4-chars are a 1-char length (significant digits, except 000 */
/* has length 0). This allows us to left-align the first declet */
/* with non-zero content, then remaining ones are full 3-char */
/* length. We use fixed-length memcpys because variable-length */
/* causes a subroutine call in GCC. (These are length 4 for speed */
/* and are safe because the array has an extra terminator byte.) */
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
dpd=(sour>>10)&0x3ff; /* declet 1 */
dpd2char;
dpd=(sour)&0x3ff; /* declet 2 */
dpd2char;
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
if (exp==0) { /* integer or NaN case -- easy */
*c='\0'; /* terminate */
return string;
}
/* non-0 exponent */
e=0; /* assume no E */
pre=c-cstart+exp;
/* [here, pre-exp is the digits count (==1 for zero)] */
if (exp>0 || pre<-5) { /* need exponential form */
e=pre-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
} /* exponential form */
/* modify the coefficient, adding 0s, '.', and E+nn as needed */
s=c-1; /* source (LSD) */
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
t=c; /* target */
for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */
*t='.'; /* insert the dot */
c++; /* length increased by one */
}
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 digits (E-101 case) */
if (e!=0) {
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
if (e<0) {
*(c-1)='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
u=&BIN2CHAR[e*4]; /* -> length byte */
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
c+=*u; /* bump pointer appropriately */
}
*c='\0'; /* add terminator */
/*printf("res %s\n", string); */
return string;
} /* pre>0 */
/* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
t=c+1-pre;
*(t+1)='\0'; /* can add terminator now */
for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */
c=cstart;
*c++='0'; /* always starts with 0. */
*c++='.';
for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */
/*printf("res %s\n", string); */
return string;
} /* decimal32ToString */
/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string */
/* */
/* decimal32FromString(result, string, set); */
/* */
/* result is the decimal32 format number which gets the result of */
/* the conversion */
/* *string is the character string which should contain a valid */
/* number (which may be a special value) */
/* set is the context */
/* */
/* The context is supplied to this routine is used for error handling */
/* (setting of status and traps) and for the rounding mode, only. */
/* If an error occurs, the result will be a valid decimal32 NaN. */
/* ------------------------------------------------------------------ */
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;
} /* decimal32FromString */
/* ------------------------------------------------------------------ */
/* decimal32IsCanonical -- test whether encoding is canonical */
/* d32 is the source decimal32 */
/* returns 1 if the encoding of d32 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uint32_t decimal32IsCanonical(const decimal32 *d32) {
decNumber dn; /* work */
decimal32 canon; /* .. */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL32);
decimal32ToNumber(d32, &dn);
decimal32FromNumber(&canon, &dn, &dc);/* canon will now be canonical */
return memcmp(d32, &canon, DECIMAL32_Bytes)==0;
} /* decimal32IsCanonical */
/* ------------------------------------------------------------------ */
/* decimal32Canonical -- copy an encoding, ensuring it is canonical */
/* d32 is the source decimal32 */
/* result is the target (may be the same decimal32) */
/* returns result */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decimal32 * decimal32Canonical(decimal32 *result, const decimal32 *d32) {
decNumber dn; /* work */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL32);
decimal32ToNumber(d32, &dn);
decimal32FromNumber(result, &dn, &dc);/* result will now be canonical */
return result;
} /* decimal32Canonical */
#if DECTRACE || DECCHECK
/* Macros for accessing decimal32 fields. These assume the argument
is a reference (pointer) to the decimal32 structure, and the
decimal32 is in network byte order (big-endian) */
/* Get sign */
#define decimal32Sign(d) ((unsigned)(d)->bytes[0]>>7)
/* Get combination field */
#define decimal32Comb(d) (((d)->bytes[0] & 0x7c)>>2)
/* Get exponent continuation [does not remove bias] */
#define decimal32ExpCon(d) ((((d)->bytes[0] & 0x03)<<4) \
| ((unsigned)(d)->bytes[1]>>4))
/* Set sign [this assumes sign previously 0] */
#define decimal32SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal32SetExpCon(d, e) { \
(d)->bytes[0]|=(uint8_t)((e)>>4); \
(d)->bytes[1]|=(uint8_t)(((e)&0x0F)<<4);}
/* ------------------------------------------------------------------ */
/* decimal32Show -- display a decimal32 in hexadecimal [debug aid] */
/* d32 -- the number to show */
/* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted - valid bigendian only */
void decimal32Show(const decimal32 *d32) {
char buf[DECIMAL32_Bytes*2+1];
Int i, j=0;
if (DECLITEND) {
for (i=0; i<DECIMAL32_Bytes; i++, j+=2) {
sprintf(&buf[j], "%02x", d32->bytes[3-i]);
}
printf(" D32> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf,
d32->bytes[3]>>7, (d32->bytes[3]>>2)&0x1f,
((d32->bytes[3]&0x3)<<4)| (d32->bytes[2]>>4));
}
else {
for (i=0; i<DECIMAL32_Bytes; i++, j+=2) {
sprintf(&buf[j], "%02x", d32->bytes[i]);
}
printf(" D32> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf,
decimal32Sign(d32), decimal32Comb(d32), decimal32ExpCon(d32));
}
} /* decimal32Show */
#endif

View File

@ -0,0 +1,99 @@
/* Decimal 32-bit format module header for the decNumber C Library.
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Decimal 32-bit format module header */
/* ------------------------------------------------------------------ */
#if !defined(DECIMAL32)
#define DECIMAL32
#define DEC32NAME "decimal32" /* Short name */
#define DEC32FULLNAME "Decimal 32-bit Number" /* Verbose name */
#define DEC32AUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decimal32s */
#define DECIMAL32_Bytes 4 /* length */
#define DECIMAL32_Pmax 7 /* maximum precision (digits) */
#define DECIMAL32_Emax 96 /* maximum adjusted exponent */
#define DECIMAL32_Emin -95 /* minimum adjusted exponent */
#define DECIMAL32_Bias 101 /* bias for the exponent */
#define DECIMAL32_String 15 /* maximum string length, +1 */
#define DECIMAL32_EconL 6 /* exp. continuation length */
/* highest biased exponent (Elimit-1) */
#define DECIMAL32_Ehigh (DECIMAL32_Emax+DECIMAL32_Bias-DECIMAL32_Pmax+1)
/* check enough digits, if pre-defined */
#if defined(DECNUMDIGITS)
#if (DECNUMDIGITS<DECIMAL32_Pmax)
#error decimal32.h needs pre-defined DECNUMDIGITS>=7 for safe use
#endif
#endif
#ifndef DECNUMDIGITS
#define DECNUMDIGITS DECIMAL32_Pmax /* size if not already defined*/
#endif
#ifndef DECNUMBER
#include "decNumber.h" /* context and number library */
#endif
/* Decimal 32-bit type, accessible by bytes */
typedef struct {
uint8_t bytes[DECIMAL32_Bytes]; /* decimal32: 1, 5, 6, 20 bits*/
} decimal32;
/* special values [top byte excluding sign bit; last two bits are */
/* don't-care for Infinity on input, last bit don't-care for NaN] */
#if !defined(DECIMAL_NaN)
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
#endif
/* ---------------------------------------------------------------- */
/* Routines */
/* ---------------------------------------------------------------- */
#include "decimal32Symbols.h"
/* String conversions */
decimal32 * decimal32FromString(decimal32 *, const char *, decContext *);
char * decimal32ToString(const decimal32 *, char *);
char * decimal32ToEngString(const decimal32 *, char *);
/* decNumber conversions */
decimal32 * decimal32FromNumber(decimal32 *, const decNumber *,
decContext *);
decNumber * decimal32ToNumber(const decimal32 *, decNumber *);
/* Format-dependent utilities */
uint32_t decimal32IsCanonical(const decimal32 *);
decimal32 * decimal32Canonical(decimal32 *, const decimal32 *);
#endif

View File

@ -0,0 +1,16 @@
#if !defined(DECIMAL32SYMBOLS)
#define DECIMAL32SYMBOLS
#ifdef IN_LIBGCC2
#define decDigitsFromDPD __decDigitsFromDPD
#define decDigitsToDPD __decDigitsToDPD
#define decimal32Canonical __decimal32Canonical
#define decimal32FromNumber __decimal32FromNumber
#define decimal32FromString __decimal32FromString
#define decimal32IsCanonical __decimal32IsCanonical
#define decimal32ToEngString __decimal32ToEngString
#define decimal32ToNumber __decimal32ToNumber
#define decimal32ToString __decimal32ToString
#endif
#endif

View File

@ -0,0 +1,856 @@
/* Decimal 64-bit format module for the decNumber C Library.
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Decimal 64-bit format module */
/* ------------------------------------------------------------------ */
/* This module comprises the routines for decimal64 format numbers. */
/* Conversions are supplied to and from decNumber and String. */
/* */
/* This is used when decNumber provides operations, either for all */
/* operations or as a proxy between decNumber and decSingle. */
/* */
/* Error handling is the same as decNumber (qv.). */
/* ------------------------------------------------------------------ */
#include <string.h> /* [for memset/memcpy] */
#include <stdio.h> /* [for printf] */
#include "config.h" /* GCC definitions */
#define DECNUMDIGITS 16 /* make decNumbers with space for 16 */
#include "decNumber.h" /* base number library */
#include "decNumberLocal.h" /* decNumber local types, etc. */
#include "decimal64.h" /* our primary include */
/* Utility routines and tables [in decimal64.c]; externs for C++ */
/* DPD2BIN and the reverse are renamed to prevent link-time conflict */
/* if decQuad is also built in the same executable */
#define DPD2BIN DPD2BINx
#define BIN2DPD BIN2DPDx
extern const uInt COMBEXP[32], COMBMSD[32];
extern const uShort DPD2BIN[1024];
extern const uShort BIN2DPD[1000];
extern const uByte BIN2CHAR[4001];
extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
extern void decDigitsToDPD(const decNumber *, uInt *, Int);
#if DECTRACE || DECCHECK
void decimal64Show(const decimal64 *); /* for debug */
extern void decNumberShow(const decNumber *); /* .. */
#endif
/* Useful macro */
/* Clear a structure (e.g., a decNumber) */
#define DEC_clear(d) memset(d, 0, sizeof(*d))
/* define and include the tables to use for conversions */
#define DEC_BIN2CHAR 1
#define DEC_DPD2BIN 1
#define DEC_BIN2DPD 1 /* used for all sizes */
#include "decDPD.h" /* lookup tables */
/* ------------------------------------------------------------------ */
/* decimal64FromNumber -- convert decNumber to decimal64 */
/* */
/* ds is the target decimal64 */
/* dn is the source number (assumed valid) */
/* set is the context, used only for reporting errors */
/* */
/* The set argument is used only for status reporting and for the */
/* rounding mode (used if the coefficient is more than DECIMAL64_Pmax */
/* digits or an overflow is detected). If the exponent is out of the */
/* valid range then Overflow or Underflow will be raised. */
/* After Underflow a subnormal result is possible. */
/* */
/* DEC_Clamped is set if the number has to be 'folded down' to fit, */
/* by reducing its exponent and multiplying the coefficient by a */
/* power of ten, or if the exponent on a zero had to be clamped. */
/* ------------------------------------------------------------------ */
decimal64 * decimal64FromNumber(decimal64 *d64, const decNumber *dn,
decContext *set) {
uInt status=0; /* status accumulator */
Int ae; /* adjusted exponent */
decNumber dw; /* work */
decContext dc; /* .. */
uInt *pu; /* .. */
uInt comb, exp; /* .. */
uInt targar[2]={0, 0}; /* target 64-bit */
#define targhi targar[1] /* name the word with the sign */
#define targlo targar[0] /* and the other */
/* If the number has too many digits, or the exponent could be */
/* out of range then reduce the number under the appropriate */
/* constraints. This could push the number to Infinity or zero, */
/* so this check and rounding must be done before generating the */
/* decimal64] */
ae=dn->exponent+dn->digits-1; /* [0 if special] */
if (dn->digits>DECIMAL64_Pmax /* too many digits */
|| ae>DECIMAL64_Emax /* likely overflow */
|| ae<DECIMAL64_Emin) { /* likely underflow */
decContextDefault(&dc, DEC_INIT_DECIMAL64); /* [no traps] */
dc.round=set->round; /* use supplied rounding */
decNumberPlus(&dw, dn, &dc); /* (round and check) */
/* [this changes -0 to 0, so enforce the sign...] */
dw.bits|=dn->bits&DECNEG;
status=dc.status; /* save status */
dn=&dw; /* use the work number */
} /* maybe out of range */
if (dn->bits&DECSPECIAL) { /* a special value */
if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
else { /* sNaN or qNaN */
if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */
&& (dn->digits<DECIMAL64_Pmax)) { /* coefficient fits */
decDigitsToDPD(dn, targar, 0);
}
if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
else targhi|=DECIMAL_sNaN<<24;
} /* a NaN */
} /* special */
else { /* is finite */
if (decNumberIsZero(dn)) { /* is a zero */
/* set and clamp exponent */
if (dn->exponent<-DECIMAL64_Bias) {
exp=0; /* low clamp */
status|=DEC_Clamped;
}
else {
exp=dn->exponent+DECIMAL64_Bias; /* bias exponent */
if (exp>DECIMAL64_Ehigh) { /* top clamp */
exp=DECIMAL64_Ehigh;
status|=DEC_Clamped;
}
}
comb=(exp>>5) & 0x18; /* msd=0, exp top 2 bits .. */
}
else { /* non-zero finite number */
uInt msd; /* work */
Int pad=0; /* coefficient pad digits */
/* the dn is known to fit, but it may need to be padded */
exp=(uInt)(dn->exponent+DECIMAL64_Bias); /* bias exponent */
if (exp>DECIMAL64_Ehigh) { /* fold-down case */
pad=exp-DECIMAL64_Ehigh;
exp=DECIMAL64_Ehigh; /* [to maximum] */
status|=DEC_Clamped;
}
/* fastpath common case */
if (DECDPUN==3 && pad==0) {
uInt dpd[6]={0,0,0,0,0,0};
uInt i;
Int d=dn->digits;
for (i=0; d>0; i++, d-=3) dpd[i]=BIN2DPD[dn->lsu[i]];
targlo =dpd[0];
targlo|=dpd[1]<<10;
targlo|=dpd[2]<<20;
if (dn->digits>6) {
targlo|=dpd[3]<<30;
targhi =dpd[3]>>2;
targhi|=dpd[4]<<8;
}
msd=dpd[5]; /* [did not really need conversion] */
}
else { /* general case */
decDigitsToDPD(dn, targar, pad);
/* save and clear the top digit */
msd=targhi>>18;
targhi&=0x0003ffff;
}
/* create the combination field */
if (msd>=8) comb=0x18 | ((exp>>7) & 0x06) | (msd & 0x01);
else comb=((exp>>5) & 0x18) | msd;
}
targhi|=comb<<26; /* add combination field .. */
targhi|=(exp&0xff)<<18; /* .. and exponent continuation */
} /* finite */
if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
/* now write to storage; this is now always endian */
pu=(uInt *)d64->bytes; /* overlay */
if (DECLITEND) {
pu[0]=targar[0]; /* directly store the low int */
pu[1]=targar[1]; /* then the high int */
}
else {
pu[0]=targar[1]; /* directly store the high int */
pu[1]=targar[0]; /* then the low int */
}
if (status!=0) decContextSetStatus(set, status); /* pass on status */
/* decimal64Show(d64); */
return d64;
} /* decimal64FromNumber */
/* ------------------------------------------------------------------ */
/* decimal64ToNumber -- convert decimal64 to decNumber */
/* d64 is the source decimal64 */
/* dn is the target number, with appropriate space */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decNumber * decimal64ToNumber(const decimal64 *d64, decNumber *dn) {
uInt msd; /* coefficient MSD */
uInt exp; /* exponent top two bits */
uInt comb; /* combination field */
const uInt *pu; /* work */
Int need; /* .. */
uInt sourar[2]; /* source 64-bit */
#define sourhi sourar[1] /* name the word with the sign */
#define sourlo sourar[0] /* and the lower word */
/* load source from storage; this is endian */
pu=(const uInt *)d64->bytes; /* overlay */
if (DECLITEND) {
sourlo=pu[0]; /* directly load the low int */
sourhi=pu[1]; /* then the high int */
}
else {
sourhi=pu[0]; /* directly load the high int */
sourlo=pu[1]; /* then the low int */
}
comb=(sourhi>>26)&0x1f; /* combination field */
decNumberZero(dn); /* clean number */
if (sourhi&0x80000000) dn->bits=DECNEG; /* set sign if negative */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) { /* is a special */
if (msd==0) {
dn->bits|=DECINF;
return dn; /* no coefficient needed */
}
else if (sourhi&0x02000000) dn->bits|=DECSNAN;
else dn->bits|=DECNAN;
msd=0; /* no top digit */
}
else { /* is a finite number */
dn->exponent=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias; /* unbiased */
}
/* get the coefficient */
sourhi&=0x0003ffff; /* clean coefficient continuation */
if (msd) { /* non-zero msd */
sourhi|=msd<<18; /* prefix to coefficient */
need=6; /* process 6 declets */
}
else { /* msd=0 */
if (!sourhi) { /* top word 0 */
if (!sourlo) return dn; /* easy: coefficient is 0 */
need=3; /* process at least 3 declets */
if (sourlo&0xc0000000) need++; /* process 4 declets */
/* [could reduce some more, here] */
}
else { /* some bits in top word, msd=0 */
need=4; /* process at least 4 declets */
if (sourhi&0x0003ff00) need++; /* top declet!=0, process 5 */
}
} /*msd=0 */
decDigitsFromDPD(dn, sourar, need); /* process declets */
return dn;
} /* decimal64ToNumber */
/* ------------------------------------------------------------------ */
/* to-scientific-string -- conversion to numeric string */
/* to-engineering-string -- conversion to numeric string */
/* */
/* decimal64ToString(d64, string); */
/* decimal64ToEngString(d64, string); */
/* */
/* d64 is the decimal64 format number to convert */
/* string is the string where the result will be laid out */
/* */
/* string must be at least 24 characters */
/* */
/* No error is possible, and no status can be set. */
/* ------------------------------------------------------------------ */
char * decimal64ToEngString(const decimal64 *d64, char *string){
decNumber dn; /* work */
decimal64ToNumber(d64, &dn);
decNumberToEngString(&dn, string);
return string;
} /* decimal64ToEngString */
char * decimal64ToString(const decimal64 *d64, char *string){
uInt msd; /* coefficient MSD */
Int exp; /* exponent top two bits or full */
uInt comb; /* combination field */
char *cstart; /* coefficient start */
char *c; /* output pointer in string */
const uInt *pu; /* work */
char *s, *t; /* .. (source, target) */
Int dpd; /* .. */
Int pre, e; /* .. */
const uByte *u; /* .. */
uInt sourar[2]; /* source 64-bit */
#define sourhi sourar[1] /* name the word with the sign */
#define sourlo sourar[0] /* and the lower word */
/* load source from storage; this is endian */
pu=(const uInt *)d64->bytes; /* overlay */
if (DECLITEND) {
sourlo=pu[0]; /* directly load the low int */
sourhi=pu[1]; /* then the high int */
}
else {
sourhi=pu[0]; /* directly load the high int */
sourlo=pu[1]; /* then the low int */
}
c=string; /* where result will go */
if (((Int)sourhi)<0) *c++='-'; /* handle sign */
comb=(sourhi>>26)&0x1f; /* combination field */
msd=COMBMSD[comb]; /* decode the combination field */
exp=COMBEXP[comb]; /* .. */
if (exp==3) {
if (msd==0) { /* infinity */
strcpy(c, "Inf");
strcpy(c+3, "inity");
return string; /* easy */
}
if (sourhi&0x02000000) *c++='s'; /* sNaN */
strcpy(c, "NaN"); /* complete word */
c+=3; /* step past */
if (sourlo==0 && (sourhi&0x0003ffff)==0) return string; /* zero payload */
/* otherwise drop through to add integer; set correct exp */
exp=0; msd=0; /* setup for following code */
}
else exp=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias;
/* convert 16 digits of significand to characters */
cstart=c; /* save start of coefficient */
if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */
/* Now decode the declets. After extracting each one, it is */
/* decoded to binary and then to a 4-char sequence by table lookup; */
/* the 4-chars are a 1-char length (significant digits, except 000 */
/* has length 0). This allows us to left-align the first declet */
/* with non-zero content, then remaining ones are full 3-char */
/* length. We use fixed-length memcpys because variable-length */
/* causes a subroutine call in GCC. (These are length 4 for speed */
/* and are safe because the array has an extra terminator byte.) */
#define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4]; \
if (c!=cstart) {memcpy(c, u+1, 4); c+=3;} \
else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;}
dpd=(sourhi>>8)&0x3ff; /* declet 1 */
dpd2char;
dpd=((sourhi&0xff)<<2) | (sourlo>>30); /* declet 2 */
dpd2char;
dpd=(sourlo>>20)&0x3ff; /* declet 3 */
dpd2char;
dpd=(sourlo>>10)&0x3ff; /* declet 4 */
dpd2char;
dpd=(sourlo)&0x3ff; /* declet 5 */
dpd2char;
if (c==cstart) *c++='0'; /* all zeros -- make 0 */
if (exp==0) { /* integer or NaN case -- easy */
*c='\0'; /* terminate */
return string;
}
/* non-0 exponent */
e=0; /* assume no E */
pre=c-cstart+exp;
/* [here, pre-exp is the digits count (==1 for zero)] */
if (exp>0 || pre<-5) { /* need exponential form */
e=pre-1; /* calculate E value */
pre=1; /* assume one digit before '.' */
} /* exponential form */
/* modify the coefficient, adding 0s, '.', and E+nn as needed */
s=c-1; /* source (LSD) */
if (pre>0) { /* ddd.ddd (plain), perhaps with E */
char *dotat=cstart+pre;
if (dotat<c) { /* if embedded dot needed... */
t=c; /* target */
for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */
*t='.'; /* insert the dot */
c++; /* length increased by one */
}
/* finally add the E-part, if needed; it will never be 0, and has */
/* a maximum length of 3 digits */
if (e!=0) {
*c++='E'; /* starts with E */
*c++='+'; /* assume positive */
if (e<0) {
*(c-1)='-'; /* oops, need '-' */
e=-e; /* uInt, please */
}
u=&BIN2CHAR[e*4]; /* -> length byte */
memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */
c+=*u; /* bump pointer appropriately */
}
*c='\0'; /* add terminator */
/*printf("res %s\n", string); */
return string;
} /* pre>0 */
/* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
t=c+1-pre;
*(t+1)='\0'; /* can add terminator now */
for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */
c=cstart;
*c++='0'; /* always starts with 0. */
*c++='.';
for (; pre<0; pre++) *c++='0'; /* add any 0's after '.' */
/*printf("res %s\n", string); */
return string;
} /* decimal64ToString */
/* ------------------------------------------------------------------ */
/* to-number -- conversion from numeric string */
/* */
/* decimal64FromString(result, string, set); */
/* */
/* result is the decimal64 format number which gets the result of */
/* the conversion */
/* *string is the character string which should contain a valid */
/* number (which may be a special value) */
/* set is the context */
/* */
/* The context is supplied to this routine is used for error handling */
/* (setting of status and traps) and for the rounding mode, only. */
/* If an error occurs, the result will be a valid decimal64 NaN. */
/* ------------------------------------------------------------------ */
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;
} /* decimal64FromString */
/* ------------------------------------------------------------------ */
/* decimal64IsCanonical -- test whether encoding is canonical */
/* d64 is the source decimal64 */
/* returns 1 if the encoding of d64 is canonical, 0 otherwise */
/* No error is possible. */
/* ------------------------------------------------------------------ */
uint32_t decimal64IsCanonical(const decimal64 *d64) {
decNumber dn; /* work */
decimal64 canon; /* .. */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL64);
decimal64ToNumber(d64, &dn);
decimal64FromNumber(&canon, &dn, &dc);/* canon will now be canonical */
return memcmp(d64, &canon, DECIMAL64_Bytes)==0;
} /* decimal64IsCanonical */
/* ------------------------------------------------------------------ */
/* decimal64Canonical -- copy an encoding, ensuring it is canonical */
/* d64 is the source decimal64 */
/* result is the target (may be the same decimal64) */
/* returns result */
/* No error is possible. */
/* ------------------------------------------------------------------ */
decimal64 * decimal64Canonical(decimal64 *result, const decimal64 *d64) {
decNumber dn; /* work */
decContext dc; /* .. */
decContextDefault(&dc, DEC_INIT_DECIMAL64);
decimal64ToNumber(d64, &dn);
decimal64FromNumber(result, &dn, &dc);/* result will now be canonical */
return result;
} /* decimal64Canonical */
#if DECTRACE || DECCHECK
/* Macros for accessing decimal64 fields. These assume the
argument is a reference (pointer) to the decimal64 structure,
and the decimal64 is in network byte order (big-endian) */
/* Get sign */
#define decimal64Sign(d) ((unsigned)(d)->bytes[0]>>7)
/* Get combination field */
#define decimal64Comb(d) (((d)->bytes[0] & 0x7c)>>2)
/* Get exponent continuation [does not remove bias] */
#define decimal64ExpCon(d) ((((d)->bytes[0] & 0x03)<<6) \
| ((unsigned)(d)->bytes[1]>>2))
/* Set sign [this assumes sign previously 0] */
#define decimal64SetSign(d, b) { \
(d)->bytes[0]|=((unsigned)(b)<<7);}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
/* type of exponent must be unsigned */
#define decimal64SetExpCon(d, e) { \
(d)->bytes[0]|=(uint8_t)((e)>>6); \
(d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);}
/* ------------------------------------------------------------------ */
/* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
/* d64 -- the number to show */
/* ------------------------------------------------------------------ */
/* Also shows sign/cob/expconfields extracted */
void decimal64Show(const decimal64 *d64) {
char buf[DECIMAL64_Bytes*2+1];
Int i, j=0;
if (DECLITEND) {
for (i=0; i<DECIMAL64_Bytes; i++, j+=2) {
sprintf(&buf[j], "%02x", d64->bytes[7-i]);
}
printf(" D64> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf,
d64->bytes[7]>>7, (d64->bytes[7]>>2)&0x1f,
((d64->bytes[7]&0x3)<<6)| (d64->bytes[6]>>2));
}
else { /* big-endian */
for (i=0; i<DECIMAL64_Bytes; i++, j+=2) {
sprintf(&buf[j], "%02x", d64->bytes[i]);
}
printf(" D64> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf,
decimal64Sign(d64), decimal64Comb(d64), decimal64ExpCon(d64));
}
} /* decimal64Show */
#endif
/* ================================================================== */
/* Shared utility routines and tables */
/* ================================================================== */
/* define and include the conversion tables to use for shared code */
#if DECDPUN==3
#define DEC_DPD2BIN 1
#else
#define DEC_DPD2BCD 1
#endif
#include "decDPD.h" /* lookup tables */
/* The maximum number of decNumberUnits needed for a working copy of */
/* the units array is the ceiling of digits/DECDPUN, where digits is */
/* the maximum number of digits in any of the formats for which this */
/* is used. decimal128.h must not be included in this module, so, as */
/* a very special case, that number is defined as a literal here. */
#define DECMAX754 34
#define DECMAXUNITS ((DECMAX754+DECDPUN-1)/DECDPUN)
/* ------------------------------------------------------------------ */
/* Combination field lookup tables (uInts to save measurable work) */
/* */
/* COMBEXP - 2-bit most-significant-bits of exponent */
/* [11 if an Infinity or NaN] */
/* COMBMSD - 4-bit most-significant-digit */
/* [0=Infinity, 1=NaN if COMBEXP=11] */
/* */
/* Both are indexed by the 5-bit combination field (0-31) */
/* ------------------------------------------------------------------ */
const uInt COMBEXP[32]={0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2,
0, 0, 1, 1, 2, 2, 3, 3};
const uInt COMBMSD[32]={0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 8, 9, 8, 9, 0, 1};
/* ------------------------------------------------------------------ */
/* decDigitsToDPD -- pack coefficient into DPD form */
/* */
/* dn is the source number (assumed valid, max DECMAX754 digits) */
/* targ is 1, 2, or 4-element uInt array, which the caller must */
/* have cleared to zeros */
/* shift is the number of 0 digits to add on the right (normally 0) */
/* */
/* The coefficient must be known small enough to fit. The full */
/* coefficient is copied, including the leading 'odd' digit. This */
/* digit is retrieved and packed into the combination field by the */
/* caller. */
/* */
/* The target uInts are altered only as necessary to receive the */
/* digits of the decNumber. When more than one uInt is needed, they */
/* are filled from left to right (that is, the uInt at offset 0 will */
/* end up with the least-significant digits). */
/* */
/* shift is used for 'fold-down' padding. */
/* */
/* No error is possible. */
/* ------------------------------------------------------------------ */
#if DECDPUN<=4
/* Constant multipliers for divide-by-power-of five using reciprocal */
/* multiply, after removing powers of 2 by shifting, and final shift */
/* of 17 [we only need up to **4] */
static const uInt multies[]={131073, 26215, 5243, 1049, 210};
/* QUOT10 -- macro to return the quotient of unit u divided by 10**n */
#define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)
#endif
void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) {
Int cut; /* work */
Int n; /* output bunch counter */
Int digits=dn->digits; /* digit countdown */
uInt dpd; /* densely packed decimal value */
uInt bin; /* binary value 0-999 */
uInt *uout=targ; /* -> current output uInt */
uInt uoff=0; /* -> current output offset [from right] */
const Unit *inu=dn->lsu; /* -> current input unit */
Unit uar[DECMAXUNITS]; /* working copy of units, iff shifted */
#if DECDPUN!=3 /* not fast path */
Unit in; /* current unit */
#endif
if (shift!=0) { /* shift towards most significant required */
/* shift the units array to the left by pad digits and copy */
/* [this code is a special case of decShiftToMost, which could */
/* be used instead if exposed and the array were copied first] */
const Unit *source; /* .. */
Unit *target, *first; /* .. */
uInt next=0; /* work */
source=dn->lsu+D2U(digits)-1; /* where msu comes from */
target=uar+D2U(digits)-1+D2U(shift);/* where upper part of first cut goes */
cut=DECDPUN-MSUDIGITS(shift); /* where to slice */
if (cut==0) { /* unit-boundary case */
for (; source>=dn->lsu; source--, target--) *target=*source;
}
else {
first=uar+D2U(digits+shift)-1; /* where msu will end up */
for (; source>=dn->lsu; source--, target--) {
/* split the source Unit and accumulate remainder for next */
#if DECDPUN<=4
uInt quot=QUOT10(*source, cut);
uInt rem=*source-quot*DECPOWERS[cut];
next+=quot;
#else
uInt rem=*source%DECPOWERS[cut];
next+=*source/DECPOWERS[cut];
#endif
if (target<=first) *target=(Unit)next; /* write to target iff valid */
next=rem*DECPOWERS[DECDPUN-cut]; /* save remainder for next Unit */
}
} /* shift-move */
/* propagate remainder to one below and clear the rest */
for (; target>=uar; target--) {
*target=(Unit)next;
next=0;
}
digits+=shift; /* add count (shift) of zeros added */
inu=uar; /* use units in working array */
}
/* now densely pack the coefficient into DPD declets */
#if DECDPUN!=3 /* not fast path */
in=*inu; /* current unit */
cut=0; /* at lowest digit */
bin=0; /* [keep compiler quiet] */
#endif
for(n=0; digits>0; n++) { /* each output bunch */
#if DECDPUN==3 /* fast path, 3-at-a-time */
bin=*inu; /* 3 digits ready for convert */
digits-=3; /* [may go negative] */
inu++; /* may need another */
#else /* must collect digit-by-digit */
Unit dig; /* current digit */
Int j; /* digit-in-declet count */
for (j=0; j<3; j++) {
#if DECDPUN<=4
Unit temp=(Unit)((uInt)(in*6554)>>16);
dig=(Unit)(in-X10(temp));
in=temp;
#else
dig=in%10;
in=in/10;
#endif
if (j==0) bin=dig;
else if (j==1) bin+=X10(dig);
else /* j==2 */ bin+=X100(dig);
digits--;
if (digits==0) break; /* [also protects *inu below] */
cut++;
if (cut==DECDPUN) {inu++; in=*inu; cut=0;}
}
#endif
/* here there are 3 digits in bin, or have used all input digits */
dpd=BIN2DPD[bin];
/* write declet to uInt array */
*uout|=dpd<<uoff;
uoff+=10;
if (uoff<32) continue; /* no uInt boundary cross */
uout++;
uoff-=32;
*uout|=dpd>>(10-uoff); /* collect top bits */
} /* n declets */
return;
} /* decDigitsToDPD */
/* ------------------------------------------------------------------ */
/* decDigitsFromDPD -- unpack a format's coefficient */
/* */
/* dn is the target number, with 7, 16, or 34-digit space. */
/* sour is a 1, 2, or 4-element uInt array containing only declets */
/* declets is the number of (right-aligned) declets in sour to */
/* be processed. This may be 1 more than the obvious number in */
/* a format, as any top digit is prefixed to the coefficient */
/* continuation field. It also may be as small as 1, as the */
/* caller may pre-process leading zero declets. */
/* */
/* When doing the 'extra declet' case care is taken to avoid writing */
/* extra digits when there are leading zeros, as these could overflow */
/* the units array when DECDPUN is not 3. */
/* */
/* The target uInts are used only as necessary to process declets */
/* declets into the decNumber. When more than one uInt is needed, */
/* they are used from left to right (that is, the uInt at offset 0 */
/* provides the least-significant digits). */
/* */
/* dn->digits is set, but not the sign or exponent. */
/* No error is possible [the redundant 888 codes are allowed]. */
/* ------------------------------------------------------------------ */
void decDigitsFromDPD(decNumber *dn, const uInt *sour, Int declets) {
uInt dpd; /* collector for 10 bits */
Int n; /* counter */
Unit *uout=dn->lsu; /* -> current output unit */
Unit *last=uout; /* will be unit containing msd */
const uInt *uin=sour; /* -> current input uInt */
uInt uoff=0; /* -> current input offset [from right] */
#if DECDPUN!=3
uInt bcd; /* BCD result */
uInt nibble; /* work */
Unit out=0; /* accumulator */
Int cut=0; /* power of ten in current unit */
#endif
#if DECDPUN>4
uInt const *pow; /* work */
#endif
/* Expand the densely-packed integer, right to left */
for (n=declets-1; n>=0; n--) { /* count down declets of 10 bits */
dpd=*uin>>uoff;
uoff+=10;
if (uoff>32) { /* crossed uInt boundary */
uin++;
uoff-=32;
dpd|=*uin<<(10-uoff); /* get waiting bits */
}
dpd&=0x3ff; /* clear uninteresting bits */
#if DECDPUN==3
if (dpd==0) *uout=0;
else {
*uout=DPD2BIN[dpd]; /* convert 10 bits to binary 0-999 */
last=uout; /* record most significant unit */
}
uout++;
} /* n */
#else /* DECDPUN!=3 */
if (dpd==0) { /* fastpath [e.g., leading zeros] */
/* write out three 0 digits (nibbles); out may have digit(s) */
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
if (n==0) break; /* [as below, works even if MSD=0] */
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
continue;
}
bcd=DPD2BCD[dpd]; /* convert 10 bits to 12 bits BCD */
/* now accumulate the 3 BCD nibbles into units */
nibble=bcd & 0x00f;
if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]);
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
bcd>>=4;
/* if this is the last declet and the remaining nibbles in bcd */
/* are 00 then process no more nibbles, because this could be */
/* the 'odd' MSD declet and writing any more Units would then */
/* overflow the unit array */
if (n==0 && !bcd) break;
nibble=bcd & 0x00f;
if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]);
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
bcd>>=4;
nibble=bcd & 0x00f;
if (nibble) out=(Unit)(out+nibble*DECPOWERS[cut]);
cut++;
if (cut==DECDPUN) {*uout=out; if (out) {last=uout; out=0;} uout++; cut=0;}
} /* n */
if (cut!=0) { /* some more left over */
*uout=out; /* write out final unit */
if (out) last=uout; /* and note if non-zero */
}
#endif
/* here, last points to the most significant unit with digits; */
/* inspect it to get the final digits count -- this is essentially */
/* the same code as decGetDigits in decNumber.c */
dn->digits=(last-dn->lsu)*DECDPUN+1; /* floor of digits, plus */
/* must be at least 1 digit */
#if DECDPUN>1
if (*last<10) return; /* common odd digit or 0 */
dn->digits++; /* must be 2 at least */
#if DECDPUN>2
if (*last<100) return; /* 10-99 */
dn->digits++; /* must be 3 at least */
#if DECDPUN>3
if (*last<1000) return; /* 100-999 */
dn->digits++; /* must be 4 at least */
#if DECDPUN>4
for (pow=&DECPOWERS[4]; *last>=*pow; pow++) dn->digits++;
#endif
#endif
#endif
#endif
return;
} /*decDigitsFromDPD */

View File

@ -0,0 +1,101 @@
/* Decimal 64-bit format module header for the decNumber C Library.
Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by IBM Corporation. Author Mike Cowlishaw.
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. */
/* ------------------------------------------------------------------ */
/* Decimal 64-bit format module header */
/* ------------------------------------------------------------------ */
#if !defined(DECIMAL64)
#define DECIMAL64
#define DEC64NAME "decimal64" /* Short name */
#define DEC64FULLNAME "Decimal 64-bit Number" /* Verbose name */
#define DEC64AUTHOR "Mike Cowlishaw" /* Who to blame */
/* parameters for decimal64s */
#define DECIMAL64_Bytes 8 /* length */
#define DECIMAL64_Pmax 16 /* maximum precision (digits) */
#define DECIMAL64_Emax 384 /* maximum adjusted exponent */
#define DECIMAL64_Emin -383 /* minimum adjusted exponent */
#define DECIMAL64_Bias 398 /* bias for the exponent */
#define DECIMAL64_String 24 /* maximum string length, +1 */
#define DECIMAL64_EconL 8 /* exp. continuation length */
/* highest biased exponent (Elimit-1) */
#define DECIMAL64_Ehigh (DECIMAL64_Emax+DECIMAL64_Bias-DECIMAL64_Pmax+1)
/* check enough digits, if pre-defined */
#if defined(DECNUMDIGITS)
#if (DECNUMDIGITS<DECIMAL64_Pmax)
#error decimal64.h needs pre-defined DECNUMDIGITS>=16 for safe use
#endif
#endif
#ifndef DECNUMDIGITS
#define DECNUMDIGITS DECIMAL64_Pmax /* size if not already defined*/
#endif
#ifndef DECNUMBER
#include "decNumber.h" /* context and number library */
#endif
/* Decimal 64-bit type, accessible by bytes */
typedef struct {
uint8_t bytes[DECIMAL64_Bytes]; /* decimal64: 1, 5, 8, 50 bits*/
} decimal64;
/* special values [top byte excluding sign bit; last two bits are */
/* don't-care for Infinity on input, last bit don't-care for NaN] */
#if !defined(DECIMAL_NaN)
#define DECIMAL_NaN 0x7c /* 0 11111 00 NaN */
#define DECIMAL_sNaN 0x7e /* 0 11111 10 sNaN */
#define DECIMAL_Inf 0x78 /* 0 11110 00 Infinity */
#endif
/* ---------------------------------------------------------------- */
/* Routines */
/* ---------------------------------------------------------------- */
#include "decimal64Symbols.h"
/* String conversions */
decimal64 * decimal64FromString(decimal64 *, const char *, decContext *);
char * decimal64ToString(const decimal64 *, char *);
char * decimal64ToEngString(const decimal64 *, char *);
/* decNumber conversions */
decimal64 * decimal64FromNumber(decimal64 *, const decNumber *,
decContext *);
decNumber * decimal64ToNumber(const decimal64 *, decNumber *);
/* Format-dependent utilities */
uint32_t decimal64IsCanonical(const decimal64 *);
decimal64 * decimal64Canonical(decimal64 *, const decimal64 *);
#endif

View File

@ -0,0 +1,16 @@
#if !defined(DECIMAL64SYMBOLS)
#define DECIMAL64SYMBOLS
#ifdef IN_LIBGCC2
#define decDigitsFromDPD __decDigitsFromDPD
#define decDigitsToDPD __decDigitsToDPD
#define decimal64Canonical __decimal64Canonical
#define decimal64FromNumber __decimal64FromNumber
#define decimal64FromString __decimal64FromString
#define decimal64IsCanonical __decimal64IsCanonical
#define decimal64ToEngString __decimal64ToEngString
#define decimal64ToNumber __decimal64ToNumber
#define decimal64ToString __decimal64ToString
#endif
#endif

View File

@ -271,7 +271,7 @@ gnats.tar.bz2: $(DIST_SUPPORT) $(GNATS_SUPPORT_DIRS) gnats
SUPPORT_FILES="$(GNATS_SUPPORT_DIRS)"
.PHONY: gdb.tar.bz2
GDB_SUPPORT_DIRS= bfd include libiberty opcodes readline sim intl
GDB_SUPPORT_DIRS= bfd include libiberty opcodes readline sim intl libdecnumber
gdb.tar.bz2: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
$(MAKE) -f $(SELF) gdb-taz TOOL=gdb \
MD5PROG="$(MD5PROG)" \