===========================================================================

				  Libdfp
	    The "Decimal Floating Point C Library" User's Guide
		   for the GNU/Linux OS and GLIBC 2.10+
		      Contributed by IBM Corporation
		Copyright (C) 2010 Free Software Foundation

===========================================================================
NOTE:Eight space tabs are the optimum editor setting for reading this file.
===========================================================================

		Author(s) : Ryan S. Arnold <rsa@us.ibm.com>
		      Date Created: January 27, 2010
		      Last Changed: August 12, 2010

---------------------------------------------------------------------------
Table of Contents:

	1.  Introduction
	  1.1.  ISO/IEC TR 24732
	  1.2.  IEEE 754-2008 (DPD & BID Encodings)
	  1.3.  Backends (libdecnumber & libbid)
	2.  Availability
	3.  Compliance With ISO/IEC TR 24732
	  3.1  __STDC_WANT_DEC_FP__
	  3.2  GNU99 Compatibility
	  3.3  scanf Support
	  3.4  printf Support
	4.  Dependencies
	  4.1  GNU/Linux OS
	  4.2  GLIBC Minimum Version
	  4.3  GCC With --enable-decimal-float Support
	5.  _Decimal* Data Types
	6.  DFP Headers
	7.  Compile and Link
	8.  Unsupported/Non-Standard Additions
	9.  Known Limitations

---------------------------------------------------------------------------
1.  Introduction

The "Decimal Floating Point C Library" is an implementation of ISO/IEC
Technical report  "ISO/IEC TR 24732" which describes the C-Language library
routines necessary to provide the C library runtime support for decimal
floating point data types introduced in IEEE 754-2008, namely _Decimal32,
_Decimal64, and _Decimal128.

---------------------------------------------------------------------------
1.1. ISO/IEC TR 24732

The latest description of ISO/IEC TR 24732 at the time of this writing can
be found here:

	http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1312.pdf

A rationale can be found here:

	http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1242.pdf

---------------------------------------------------------------------------
1.2. IEEE754-2008 (DPD & BID Encodings)

IEEE 754-2008 defines two different encodings for the decimal floating
point data types.  These are DPD and BID.

	DPD (Densely Packed Decimal) - IBM sponsored encoding (implemented
				       in hardware).

	BID (Binary Integer Decimal) - Intel sponsored encoding.

Both encodings can be investigated in the draft IEEE754r:

	http://754r.ucbtest.org/drafts/archive/2006-10-04.pdf

---------------------------------------------------------------------------
1.3. Backends (libdecnumber & libbid)

Libdfp can make use of two backend libraries for software emulation.  These
are "libdecnumber" and "libbid".

For the most part, a user of libdfp should not have to be concerned with
the libdfp backends.

The user's interface is that defined by ISO/IEC TR 24732, i.e. the Decimal
Floating Point addition to the C Language specification.

Currently Libdfp only supports the libdecnumber backend.

---------------------------------------------------------------------------
2. Availability

Libdfp attempts to provide an encoding agnostic API to users based upon the
_Decimal32, _Decimal64, and _Decimal128 data-types and the proposed C-Language
extension for Decimal Floating Point Types.

---------------------------------------------------------------------------
3. Compliance With ISO/IEC TR 24732

This section covers issues related to compliance with ISO/IEC TR 24732.

---------------------------------------------------------------------------
3.1 __STDC_WANT_DEC_FP__

The standard ISO/IEC TR 24732 indicates that programs that wish to use
Decimal Floating Point should define the following macro:

	__STDC_WANT_DEC_FP__

There is no set value for this macro.

Simply passing -D__STDC_WANT_DEC_FP__ on compilation, or defining it in your
program should suffice:

#define __STDC_WANT_DEC_FP__

This macro is REQUIRED when including dfp/math.h dfp/fenv.h, etc to pick
up the DFP function prototypes and data types defined in these headers.

---------------------------------------------------------------------------
3.2 GNU99 Compatibility

GNU99 compatibility is required to pick up some DFP prototypes that are
similar to the binary floating point prototypes guarded in <math.h> by
__USE_ISOC99 and others.  It will define __USE_ISOC99.

Use the following compilation flag: -std=gnu99

NOTE: -std=gnu99 IS NOT THE SAME AS __USE_ISOC99 though -std=gnu99 DOES
DEFINE __USE_ISOC99!  Additionally, simply using -std=c99 isn't enough!

NOTE: If you forget to use -std=gnu99 you may notice that you will get very
screwy results when you call dfp math functions.  If the compiler can't find
the prototypes (due to missing defines) it will attempt to create a default
prototype which will have an incorrect return type.

Compile with -Wall to pick up undefined prototype warnings.

---------------------------------------------------------------------------
3.3 scanf Support

Libdfp does not, and will not comply with the TR 24732 requirement for the
addition of scanf in support of decimal floating point data types.  The
strtod[32|64|128] functions can be used for the same purpose without the
implications of scanf.

---------------------------------------------------------------------------
3.4 printf Support

Libdfp supports the addition of the printf format codes indicated by TR
24732.  GLIBC proper owns the printf implementation.  Libdfp utilizes the
printf-hooks mechanism provided by GLIBC to register support of the DFP
format codes.

The fully functional printf-hooks mechanism was debuted in GLIBC 2.10.

Libdfp has a library constructor which registers the Libdfp printf handlers
with the libc.  If the version of GLIBC that is loaded when your application
is executed is too old (pre-2.10) and doesn't have the printf-hooks interface
you will get an undefined reference error against GLIBC.

When libdfp is loaded printf will recognize the following length modifiers:

	%H - for _Decimal32
	%D - for _Decimal64
	%DD - for _Decimal128

It will recognize the following spec characters:

	%e
	%f
	%g
	%a  (as debuted in TR 24732)

Therefore, any combination of DFP length modifiers and spec characters is
supported.

---------------------------------------------------------------------------
4. Dependencies

---------------------------------------------------------------------------
4.1 GNU/Linux OS

Libdfp is only enabled to work on the GNU/Linux OS.

---------------------------------------------------------------------------
4.2 GLIBC Minimum Version

Libdfp version 1.0.0 relies upon a minimum GLIBC 2.10 for printf-hooks
support.  The libdfp configure stage will check the libc that it is linked
against for the printf-hook support and will warn if it is not found.

---------------------------------------------------------------------------
4.3 GCC With --enable-decimal-float Support

There's a dependency on a version of GCC which supports Decimal Floating
Point.  Use the following to determine if your compiler supports it:

	gcc -v 2>&1 | grep "\-\-enable\-decimal\-float"

If decimal floating point support is not available in your compiler the
libdfp configure stage will fail with a warning.

---------------------------------------------------------------------------
5.  _Decimal* Data Types

The Decimal Floating Point data types are as follows:

	_Decimal32
	_Decimal64
	_Decimal128

The floating point suffix for DFP constants follows:

	'DF' for _Decimal32, e.g. _Decimal32 d32 = 1.045DF;
	'DD' for _Decimal64, e.g. _Decimal64 d64 = 1.4738273DD;
	'DL' for _Decimal128, e.g. _Decimal128 d128 = 1.0823382394823945DL;

NOTE: Assigning a naked constant to a DFP variable will actually be
performing a binary to decimal conversion and, depending on the precision,
can assign an incorrect number.  Always use the decimal floating point
suffix, e.g.,

	_Decimal64 d64 = 1.0DD;

The following will result in a binary-float to decimal-float conversion:

	_Decimal64 d64 = 1.0;

---------------------------------------------------------------------------
6.  DFP Headers

The following Libdfp headers extend the existing system headers.  If the path
to the Libdfp headers is included in the search path then these will be picked
up prior to the system headers.

	dfp/fenv.h
	dfp/math.h
	dfp/stdlib.h
	dfp/wchar.h

Each of these headers uses the GCC construct include_next in order to pick up
the system header as well, e.g.,

	dfp/math.h will include_next <math.h>

This mechanism allows Libdfp to add the Decimal interfaces required by the
specification to the aforementioned headers.

In order to pick up the Libdfp prototypes and classification macro
overrides compile with the following:

-I/pathto/include/dfp/ -D__STDC_WANT_DEC_FP__

And then in the application source simply using the following include will
pick up both /pathto/include/dfp/<foo>.h and /usr/include/<foo>.h:

#include <math.h>
#include <fenv.h>
#include <stdlib.h>
#include <wchar.h>

---------------------------------------------------------------------------
7.  Compile and Link

A compilation and link for a DFP program will look like the following:

	$(CC) -Wall test_dfp.c -o test_dfp -D__STDC_WANT_DEC_FP__ \
	-std=gnu99 -ldfp

---------------------------------------------------------------------------
8.  Unsupported/Non-Standard Additions

Libdfp provides a non-standard method for output of the decoded Densely
Packed Decimal representation using the decoded[32|64|128]() functions.  The
output format is:

	[sign][MSD],[decoded-declet-1],
	...,[decoded-declet-n][E][+|-][decoded exponent]

Examples:

  +0,000,000E+0 = decoded32(0DF)
  +0,000,000,000,001,000E-1 = decoded64(100.0DD)
  -0,000,000,000,000,000,000,000,000,039,654,003E-3 = decoded128(-39654.003DL)
  +9,876,543E+22 = decoded32(9.876543E+28DF)

WARNING:  Do NOT rely on these methods for user space code.  They're only
provided for toolchain development debug support.

A header file providing the prototype for these functions is not provided by
the Advance Toolchain to discourage you from using them.  If you MUST use them
define the following prototypes in your program:

	/* char * should ref a 14 byte char array,
	 * +0,000,000E+0\0  */
	extern char * decoded32 (_Decimal32, char*);

	/* char * should ref a 26 byte char array,
	 * +0,000,000,000,000,000E+0\0  */
	extern char * decoded64 (_Decimal64, char*);

	/* char * should ref a 50 byte char array,
	 * +0,000,000,000,000,000,000,000,000,000,000,000E+0\0  */
	extern char * decoded128 (_Decimal128, char*);

---------------------------------------------------------------------------
9. Known Limitations

IEEE754r currently has an addendum awaiting vote whereby the default quantum
for conversions involving zero will go to a zero exponent (e.g.  0 equals
0.0).  The current IEEE754r specification dictates that the quantum shall go
to the largest supported by the data type, e.g.  _Decimal32 0.0E191;
_Decimal64 0.0E767, _Decimal128 0.0E12287.

Observation of the advance toolchain results will show that we don't follow
any particular convention.  This may change in the future.

For the following examples notice the DPD encoding on both power6[x] and
non-power6:

	_Decimal32 d32 = 0.0DF;
	_Decimal64 d64 = 0.0DD;
	_Decimal128 d128 = 0.0DL;
	
	(_Decimal128)0.0DF: [+0,000,000E+0]
	(_Decimal128)0.0DD: [+0,000,000,000,000,000E+0]
	(_Decimal128)0.0DL: [+0,000,000,000,000,000,000,000,000,000,000,000E+0]

On power6[x] notice the representation of zero after an [int|long|long long]
conversion to _Decimal[32|64|128] respectively:

	(_Decimal32)0DF = (int)0: [+0,000,000E+0]
	(_Decimal32)0.0DF = (float)0.000000: [+0,000,000E+0]
	(_Decimal64)0DD = (long)0: [+0,000,000,000,000,000E+0]
	(_Decimal64)0.0DD = (double)0.000000: [+0,000,000,000,000,000E+0]
	(_Decimal128)0DL = (long long)0:
	  [+0,000,000,000,000,000,000,000,000,000,000,000E+0]
	(_Decimal128)0.0DL = (long double)0.000000:
	  [+0,000,000,000,000,000,000,000,000,000,000,000E+0]

Notice the difference with soft-dfp:

	(_Decimal32)0.0DF = (int)0: [+0,000,000E-1]
	(_Decimal32)0.0DF = (float)0.000000: [+0,000,000E+0]
	(_Decimal64)0.0DD = (long)0: [+0,000,000,000,000,000E-1]
	(_Decimal64)0.0DD = (double)0.000000: [+0,000,000,000,000,000E+0]
	(_Decimal128)0.0DL = (long long)0:
	  [+0,000,000,000,000,000,000,000,000,000,000,000E-1]
	(_Decimal128)0.0DL = (long double)0.000000:
	  [+0,000,000,000,000,000,000,000,000,000,000,000E+0]

Namely the negative sign of the exponent with soft-dfp for int to _Decimal
conversions.



