summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreberlein <eberlein@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2007-10-19 00:23:12 +0000
committereberlein <eberlein@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2007-10-19 00:23:12 +0000
commit64f9ec8f74944612448c7f774ccd0e5753071dd8 (patch)
tree9d9ab69b51e5f471193ffdc749e7a45658cb72b5
parent0887701eb1953f963e2815943e6bac8b8dc6145a (diff)
* First commit of libc/dfp addon. Logs from historical development
follow. ======================================== BEGIN HISTORY FOR LIBDFP ======================================== ------------------------------------------------------------------------ r363 | ryanarn | 2007-09-06 11:54:21 -0500 (Thu, 06 Sep 2007) | 9 lines 2007-09-06 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsdddi.S: Fixed usage of 64 bit constant to 128 bit constant. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatditd.S: Fixed erroneous asm opcode 'r0' usage for long parameter to proper 'r3'. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdisd.S: Fixed erroneous asm opcode 'r0' usage for long parameter to proper 'r3'. ------------------------------------------------------------------------ r362 | ryanarn | 2007-09-04 17:06:33 -0500 (Tue, 04 Sep 2007) | 59 lines 2007-09-04 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssisd.S: Corrected conversion bug. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctdsd2.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdisd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssddi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsddi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsdddi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsidd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixdddi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstddi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsitd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdidd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtddi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssidd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssdsi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsdsi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatditd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssitd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdidd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsddsi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsisd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixddsi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsditd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstdsi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdisd.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtdsi.S: same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctddd2.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssisd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctdsd2.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdisd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssddi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsddi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsdddi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsidd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixdddi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstddi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsitd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdidd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtddi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssidd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssdsi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsdsi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatditd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssitd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdidd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsddsi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsisd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixddsi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsditd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstdsi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdisd.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtdsi.S: same as above. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctddd2.S: same as above. * dfp/sysdeps/powerpc/dfpu/fe_decround.c: (__fe_dec_getround) Fixed to * fetch the decimal rounding mode from the high order 32-bits of the 64-bit FPSCR (Thanks Eberlein). ------------------------------------------------------------------------ r361 | eberlein | 2007-07-23 15:16:32 -0500 (Mon, 23 Jul 2007) | 3 lines * dfp/sysdeps/powerpc/dfpu/fe_decround.c: Fixed bit locations for rounding mode in fe_getround. ------------------------------------------------------------------------ r360 | eberlein | 2007-07-11 19:54:36 -0500 (Wed, 11 Jul 2007) | 4 lines * dfp/sysdeps/soft-dfp/convert.h: changed Decimal source to use __signbitd{32|64|128} instead of __builtin_signbitd{32|64|128} ------------------------------------------------------------------------ r359 | eberlein | 2007-06-29 23:44:08 -0500 (Fri, 29 Jun 2007) | 3 lines * dfp/test/test_zero: New file. ------------------------------------------------------------------------ r358 | eberlein | 2007-06-29 23:39:44 -0500 (Fri, 29 Jun 2007) | 4 lines * dfp/sysdeps/soft-dfp/convert.c: Reverted changes to handle negative zero, now that fpclassify works for negative zero. ------------------------------------------------------------------------ r357 | ryanarn | 2007-06-29 17:32:37 -0500 (Fri, 29 Jun 2007) | 5 lines 2007-06-27 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c: Check for -0.0 and mask the sign bit when extracting the combination field. ------------------------------------------------------------------------ r356 | eberlein | 2007-06-29 14:36:22 -0500 (Fri, 29 Jun 2007) | 4 lines * dfp/sysdeps/soft-dfp/convert.h: Added prototype for __builtin_signbit. * dfp/sysdeps/ieee754r/d32/tgamma32.c: Added prototype for __builtin_signbit. ------------------------------------------------------------------------ r355 | eberlein | 2007-06-29 13:17:11 -0500 (Fri, 29 Jun 2007) | 3 lines * dfp/sysdeps/ieee754r/d32/tgamma32.c: Added missing prototype. ------------------------------------------------------------------------ r354 | eberlein | 2007-06-28 14:56:13 -0500 (Thu, 28 Jun 2007) | 5 lines * dfp/sysdeps/soft-dfp/convert.c: Converting DFP->DFP will use user-specified rounding mode. Conversions of -0 will preserve sign bit. ------------------------------------------------------------------------ r353 | ryanarn | 2007-06-27 19:47:56 -0500 (Wed, 27 Jun 2007) | 5 lines 2007-06-27 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/soft-dfp/Versions: Fixed reference of GLIBC_2.6 back to GLIBC_2.5. ------------------------------------------------------------------------ r352 | eberlein | 2007-06-27 16:52:33 -0500 (Wed, 27 Jun 2007) | 7 lines * dfp/Versions: Reverted to GLIBC version 2.5 * dfp/Versions.def: ditto * dfp/sysdeps/dfp/Versions: ditto * dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions: ditto * dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions: ditto ------------------------------------------------------------------------ r351 | ryanarn | 2007-06-27 15:31:10 -0500 (Wed, 27 Jun 2007) | 5 lines 2007-06-27 Ryan S. Arnold <rsa@us.ibm.com> * dfp/fmt_dfp.c: Removed because it has been deprecated by fmt_d[32|64|128].c. ------------------------------------------------------------------------ r350 | ryanarn | 2007-06-27 15:28:24 -0500 (Wed, 27 Jun 2007) | 30 lines 2007-06-27 Ryan S. Arnold <rsa@us.ibm.com> * dfp/fmt_d32.c: Add macroized __fmt_d[32|64|128] function implementation which now supports printf width and precision format flags. * dfp/fmt_d64.c: Set _DECIMAL_SIZE = 64 and #include fmt_d32.c. * dfp/fmt_d128.c: Set _DECIMAL_SIZE = 128 and #include fmt_d32.c. * dfp/fmt_dfp.c: Minor modification in preparation for removal. * dfp/fmt_dfp.h: Remove __fmt_dfp symbol and add _fmt_d[32|64|128]. * dfp/Makefile: Add fmt_d[32|64|128] and removed fmt_dfp. * dfp/test/test_printf.c: Test new printf width and precision format flags. * dfp/test/test_fpclassify.c: Expand the denormal case. * dfp/test/test_isnormal.c: Expand the isnormal testcase. * dfp/test/test_printf2.c: Expand. * dfp/sysdeps/dfp/printf_dfp.c: Modified to invoke __fmt_d[32|64|128] rather than __fmt_dfp(). * dfp/sysdeps/ieee754r/dfpmacro.h: Additions in support of the new __fmt_d[32|64|128] functions. Namely the addition of the IEEE_DECIMAL_TO_STRING and IEEE_DECIMAL_TO_ENG_STRING macros. * dfp/Versions: Removed fmt_dfp symbol and replaced with fmt_d[32|64|128] sybmols. * dfp/test/test_decref.c: New test to check _Decimal32 GCC issue. * dfp/test/test_decode2.c: Added test case to show how extra digits of precision or packed. * dfp/test/test_frexpd.c: Exploratory test used to determine what frexpd is actually returning. ------------------------------------------------------------------------ r349 | eberlein | 2007-06-26 13:13:25 -0500 (Tue, 26 Jun 2007) | 8 lines * Versions: updated requirements to GLIBC 2.6 * sysdeps/dfp/Versions: ditto * sysdeps/soft-dfp/Versions: ditto * sysdeps/powerpc/powerpc32/power6/fpu/Versions: ditto * sysdeps/powerpc/powerpc64/power6/fpu/Versions: ditto * Versions.def: ditto ------------------------------------------------------------------------ r348 | eberlein | 2007-06-21 17:39:23 -0500 (Thu, 21 Jun 2007) | 4 lines * dfp/sysdeps/ieee754r/d32/log1pd32.c: When input is -1.0, return -Infinity, not Infinity. ------------------------------------------------------------------------ r347 | eberlein | 2007-06-21 16:46:46 -0500 (Thu, 21 Jun 2007) | 4 lines * dfp/test/test_set2.c: tgamma(-DEC_INFINITY) should return -DEC_INFINITY, not NaN. ------------------------------------------------------------------------ r346 | eberlein | 2007-06-21 16:44:56 -0500 (Thu, 21 Jun 2007) | 4 lines * dfp/sysdeps/ieee754r/d32/tgammad32.c: Fixed sign of result for non-integer negative inputs. Integer negative inputs return NaN. ------------------------------------------------------------------------ r345 | eberlein | 2007-06-19 14:38:49 -0500 (Tue, 19 Jun 2007) | 4 lines * dfp/sysdeps/ieee754r/d32/tgammad32.c: When input is zero, preserve sign on infinity result. ------------------------------------------------------------------------ r344 | eberlein | 2007-06-11 18:55:18 -0500 (Mon, 11 Jun 2007) | 3 lines * dfp/test/test_except.c: fixed test for FE_INEXACT ------------------------------------------------------------------------ r343 | ryanarn | 2007-06-06 16:41:56 -0500 (Wed, 06 Jun 2007) | 5 lines 2007-06-06 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_conversion.c: Additions for _Decimal64. * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c: Added #include <float.h> ------------------------------------------------------------------------ r342 | ryanarn | 2007-06-05 23:18:36 -0500 (Tue, 05 Jun 2007) | 4 lines 2007-06-05 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/powerpc/decode-decimal.c: Missing NULL terminator. ------------------------------------------------------------------------ r341 | ryanarn | 2007-06-05 17:53:25 -0500 (Tue, 05 Jun 2007) | 9 lines 2007-06-05 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_conversion.c: Fix compilation error and add a long double to _Decimal64 test. * dfp/sysdeps/soft-dfp/convert.c: Fix bug in double to _Decimal32 conversion (truncdfsd) where a rounding error caused a bug in the conversion. Got around this by making the mantissa long long conversion store into a _Decimal128 rather than DEST_TYPE. ------------------------------------------------------------------------ r340 | ryanarn | 2007-06-05 16:51:52 -0500 (Tue, 05 Jun 2007) | 8 lines 2007-06-05 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/powerpc/decode-decimal.c: Fix extraneous exponent sign in the output introduced when sjmunroe's version of itoa was used. * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c: Fixed the denormal detection to account for the oddly encoded, but still normal case of 10E-96 (which is the same as 1E-95). ------------------------------------------------------------------------ r339 | eberlein | 2007-06-04 19:37:35 -0500 (Mon, 04 Jun 2007) | 3 lines * dfp/test/test_except.c: Expanded test to include more exceptions. ------------------------------------------------------------------------ r338 | ryanarn | 2007-06-04 14:19:14 -0500 (Mon, 04 Jun 2007) | 14 lines 2007-06-04 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_printf.c: New. * dfp/test/test_conversion.c: Updated. * dfp/test/test_convert.h: New. * dfp/test/test_double_to_decimal.c: New. * dfp/test/test_printf2.c: New. * dfp/sysdeps/powerpc/decode-decimal.c: Fixed include. * dfp/fmt_dfp.c: Fixed local .h include to global .h include. * dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/Implies: Added to do the same as power6 and pick up FPSCR rounding mode set/get. * dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies: Added to do the same as power6 and pick up FPSCR rounding mode set/get. ------------------------------------------------------------------------ r337 | eberlein | 2007-05-29 16:05:46 -0500 (Tue, 29 May 2007) | 3 lines * dfp/test/test_except.c: New file. ------------------------------------------------------------------------ r336 | ryanarn | 2007-05-29 12:30:23 -0500 (Tue, 29 May 2007) | 7 lines 2007-05-29 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/powerpc/fmt_dfp.c: Removed. It was checked in too early. * dfp/sysdeps/powerpc/dpd-private.h: Fixed cpydeclet to __dfp_cpydeclet. ------------------------------------------------------------------------ r335 | ryanarn | 2007-05-29 12:21:03 -0500 (Tue, 29 May 2007) | 6 lines 2007-05-29 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/unix/sysv/linux/powerpc/Implies: Removed because it pushed the powerpc targets too early in the configure stage. It is unnecessary. ------------------------------------------------------------------------ r334 | ryanarn | 2007-05-23 15:35:33 -0500 (Wed, 23 May 2007) | 7 lines 2007-05-23 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/powerpc/fmt_dfp.c: Moved from disp-decimal.c. The PowerPC based override will directly decode the DPD encoded _Decimal[32|64|128] value. * dfp/sysdeps/powerpc/disp-decimal.c: Moved to fmt_dfp.c. ------------------------------------------------------------------------ r333 | ryanarn | 2007-05-23 15:30:57 -0500 (Wed, 23 May 2007) | 12 lines 2007-05-23 Ryan S. Arnold <rsa@us.ibm.com> * dfp/decode-decimal.c: Moved from disp-decimal.c * dfp/decode-decimal.h: Moved from disp-decimal.h * dfp/disp-decimal.c: Moved to decode-decimal.c. * dfp/Makefile: disp-decimal -> decode_decimal. * dfp/disp-decimal.h: Moved to decode-decimal.h. * dfp/sysdeps/powerpc/decode-decimal.c: Moved from disp-decimal.h. * dfp/sysdeps/powerpc/dpd-private.h: Moved DPD conversion tables from disp-decimal.c. Added static inline helper functions. * dfp/sysdeps/powerpc/disp-decimal.c: Removed conversion tables. ------------------------------------------------------------------------ r332 | eberlein | 2007-05-22 18:46:39 -0500 (Tue, 22 May 2007) | 6 lines * dfp/sysdeps/soft-dfp/classify.c: New file. * dfp/sysdeps/soft-dfp/Makefile: Added classify to libdfp-routines. * dfp/sysdeps/soft-dfp/convert.c: Changed calls to frexp to builtins or dfp versions. * dfp/sysdeps/soft-dfp/convert.h: Added defines for FREXP and CLASSIFY. ------------------------------------------------------------------------ r331 | ryanarn | 2007-05-22 16:11:18 -0500 (Tue, 22 May 2007) | 4 lines 2007-05-22 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/janis.c: Removed, unnecessary. ------------------------------------------------------------------------ r330 | ryanarn | 2007-05-22 15:37:34 -0500 (Tue, 22 May 2007) | 5 lines 2007-05-22 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/README: Fixed test_decimal.c -> test-decimal.c. * dfp/test/CLEANME: Fixed test_decimal.c -> test-decimal.c. ------------------------------------------------------------------------ r329 | ryanarn | 2007-05-22 15:29:58 -0500 (Tue, 22 May 2007) | 34 lines 2006-05-22 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_conversion.c: Updated to point out high precision binary float conversion to lower precision _Decimal problem. * dfp/test/README: Exclude test_decimal.c from build. * dfp/test/CLEANME: New script to remove executables. * dfp/sysdeps/powerpc/truncxfdd.c: Removed, redundant to what's dfp/sysdeps/soft-dfp. * dfp/sysdeps/powerpc/extendsdsf.c: Same. * dfp/sysdeps/powerpc/extendsfsd.c: Same. * dfp/sysdeps/powerpc/extendsftd.c: Same. * dfp/sysdeps/powerpc/extenddfdd.c: Same. * dfp/sysdeps/powerpc/trunctdsf.c: Same. * dfp/sysdeps/powerpc/extendsdxf.c: Same. * dfp/sysdeps/powerpc/truncdddf.c: Same. * dfp/sysdeps/powerpc/extendxftd.c: Same. * dfp/sysdeps/powerpc/truncxfsd.c: Same. * dfp/sysdeps/powerpc/trunctdxf.c: Same. * dfp/sysdeps/powerpc/extendsfdd.c: Same. * dfp/sysdeps/powerpc/extendsddf.c: Same. * dfp/sysdeps/powerpc/extenddftd.c: Same. * dfp/sysdeps/powerpc/truncddsf.c: Same. * dfp/sysdeps/powerpc/truncdfsd.c: Same. * dfp/sysdeps/powerpc/extendddxf.c: Same. * dfp/sysdeps/powerpc/trunctddf.c: Same. * dfp/sysdeps/powerpc/decpowof2.c: Moved to dfp/sysdeps/soft-dfp. * dfp/sysdeps/powerpc/binpowof10.c: Moved to dfp/sysdpes/soft-dfp. * dfp/sysdeps/soft-dfp/decpowof2.c: Moved from dfp/sysdeps/powerpc. * dfp/sysdeps/soft-dfp/binpowof10.c: Moved from dfp/sysdeps/powerpc. * dfp/sysdeps/unix/sysv/linux/powerpc/Implies: Added 'powerpc' referring to dfp/sysdeps/powerpc. This is so that on PowerPC overrides in this directory get picked up before those in dfp/sysdeps/soft-dfp. ------------------------------------------------------------------------ r328 | ryanarn | 2007-05-18 16:36:53 -0500 (Fri, 18 May 2007) | 99 lines 2007-05-18 Ryan S. Arnold <rsa@us.ibm.com> * dfp/libdfp-test.inc: Macroized rounding mode 'get' function name. * dfp/Makefile: Added decroundtls to libc and mapround to libdfp, and moved fe_decround to libdfp. * dfp/test/test_conversion.c: New test to test float to _Decimal32 conversion. * dfp/test/test_round.c: Extended the rounding mode tests. * dfp/sysdeps/powerpc/fpu/bits/fenvinline.h: Updated with a comment for the binary rounding mode. * dfp/sysdeps/powerpc/dfpu/decroundtls.c: Empty stub for power6 so that the dfp/Makefile is satisfied by the target. Power6 doesn't use TLS for the dec rounding mode. It uses the FPSCR. * dfp/sysdeps/powerpc/dfpu/decroundtls.h: Empty except for an empty __decrm_round symbol to satisfy the linker. Power6 doesn't use TLS the dec rounding mode. It uses the FPSRC. * dfp/sysdeps/powerpc/dfpu/fe_decround.c: Updated to use three parameter version of mtfsfi for setting decimal rounding mode. Also updated to accept rounding modes 5/6/7 [hardware supported but no C-spec supported]. * dfp/sysdeps/dfp/decroundtls.c Added to provide TLS and accessor for libc dec rounding mode. * dfp/sysdeps/dfp/decroundtls.h Added to provide a prototype for __decrm_round for fetching the decimal rounding mode TLS variable location. * dfp/sysdeps/dfp/fe_decround.c: Removed TLS declaration and move definition into libdfp rather than libc. * dfp/sysdeps/ieee754r/d32/quantized32.c: Fixed reference of fe_dec_getround() to __dn_getround() which maps from the hardware ordered rounding mode enumeration types to the decNumber enumeration types. * dfp/sysdeps/ieee754r/d32/llrintd32.c: Same * dfp/sysdeps/ieee754r/d32/powd32.c: Same * dfp/sysdeps/ieee754r/d32/lrintd32.c: Same * dfp/sysdeps/ieee754r/d32/nearbyintd32.c: Same * dfp/sysdeps/ieee754r/d32/rintd32.c: Same * dfp/README: Explain TLS for dec rounding mode. * dfp/bits/dfpfenv.h: Reordered rounding mode enumeration types to match Power6 hardware due to precedence for binary rounding mode. * dfp/decNumberMath.h: Added __decNumberPow() prototype that was accidentally taken out. * dfp/mapround.c: Added. Provides __dn_getround which maps Power6 enumeration rounding modes to decNumber rounding modes. * dfp/dfpfenv_private.h: Removed libc_hidden_proto macros. * dfp/Versions: Moved fe_dec_round to libdfp. Added __dec_rm_location to libc in order to provide the TLS rounding mode on non-power6. * dfp/mapround.h: Added to provide the __dn_getround prototype. * dfp/test/gcc-tests/func-scalar.c: New tests from Janis. * dfp/test/gcc-tests/signbit-2.c * dfp/test/gcc-tests/usual-arith-conv.c * dfp/test/gcc-tests/operator-logical.c * dfp/test/gcc-tests/dfp-except.h * dfp/test/gcc-tests/compare-eq-d128.c * dfp/test/gcc-tests/func-array.c * dfp/test/gcc-tests/convert-int.c * dfp/test/gcc-tests/compare-special.h * dfp/test/gcc-tests/compare-rel.h * dfp/test/gcc-tests/compare-rel-dfp.c * dfp/test/gcc-tests/func-struct.c * dfp/test/gcc-tests/doit * dfp/test/gcc-tests/func-vararg-alternate-d32.c * dfp/test/gcc-tests/func-vararg-mixed.c * dfp/test/gcc-tests/compare-eq-d32.c * dfp/test/gcc-tests/compare-special-d128.c * dfp/test/gcc-tests/compare-rel-d128.c * dfp/test/gcc-tests/operator-comma.c * dfp/test/gcc-tests/union-init.c * dfp/test/gcc-tests/func-vararg-alternate.h * dfp/test/gcc-tests/struct-layout-1.c * dfp/test/gcc-tests/convert-int-saturate.c * dfp/test/gcc-tests/compare-eq.h * dfp/test/gcc-tests/compare-special-d64.c * dfp/test/gcc-tests/func-mixed.c * dfp/test/gcc-tests/compare-eq-dfp.c * dfp/test/gcc-tests/operator-assignment.c * dfp/test/gcc-tests/compare-rel-d64.c * dfp/test/gcc-tests/func-vararg-size0.c * dfp/test/gcc-tests/dfp-round.h * dfp/test/gcc-tests/func-vararg-alternate-d128.c * dfp/test/gcc-tests/nan-1.c * dfp/test/gcc-tests/nan-2.c * dfp/test/gcc-tests/operator-cond.c * dfp/test/gcc-tests/loop-index.c * dfp/test/gcc-tests/func-vararg-dfp.c * dfp/test/gcc-tests/func-vararg-alternate-d64.c * dfp/test/gcc-tests/compare-eq-d64.c * dfp/test/gcc-tests/convert-complex.c * dfp/test/gcc-tests/convert-bfp.c * dfp/test/gcc-tests/operator-unary.c * dfp/test/gcc-tests/convert-dfp.c * dfp/test/gcc-tests/cast.c * dfp/test/gcc-tests/compare-special-d32.c * dfp/test/gcc-tests/convert-int-max.c * dfp/test/gcc-tests/compare-rel-d32.c * dfp/test/gcc-tests/call-by-value.c * dfp/test/gcc-tests/signbit-1.c ------------------------------------------------------------------------ r327 | eberlein | 2007-05-18 16:16:40 -0500 (Fri, 18 May 2007) | 3 lines * dfp/sysdeps/soft-dfp/convert.c: fix for extendsfsd and extendsftd returning zero ------------------------------------------------------------------------ r326 | ryanarn | 2007-05-18 15:49:56 -0500 (Fri, 18 May 2007) | 4 lines 2007-05-18 Ryan S. Arnold <rsa@us.ibm.com> * Regularly scheduled glibc-trunk cvs sync for Tue Mar 20 00:00:00 CDT 2007 [for real this time]. ------------------------------------------------------------------------ r325 | ryanarn | 2007-05-18 15:11:26 -0500 (Fri, 18 May 2007) | 1 line Regularly scheduled glibc-trunk cvs sync for date Tue Mar 20 00:00:00 CDT 2007 ------------------------------------------------------------------------ r321 | ryanarn | 2007-05-07 15:53:53 -0500 (Mon, 07 May 2007) | 5 lines 2007-05-07 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/convert.c: Remove erroneous copyright. * dfp/sysdeps/soft-dfp/makecfiles.sh: Remove reference to dfp-bit.c ------------------------------------------------------------------------ r320 | eberlein | 2007-04-20 17:38:40 -0500 (Fri, 20 Apr 2007) | 3 lines * dfp/sysdeps/soft-dfp/Makefile: removed path for binpowof10, decpowof2 ------------------------------------------------------------------------ r319 | eberlein | 2007-04-20 14:55:24 -0500 (Fri, 20 Apr 2007) | 4 lines * dfp/sysdeps/soft-dfp/Makefile: added binpowof10, decpowof2 * dfp/sysdeps/soft-dfp/convert.c: fixed uninitialized variable warnings ------------------------------------------------------------------------ r318 | ryanarn | 2007-04-19 21:29:28 -0500 (Thu, 19 Apr 2007) | 4 lines 2007-04-19 Ryan S. Arnold <rsa@us.ibm.com> * test/janis2.c: Removed. Unnecessary. ------------------------------------------------------------------------ r317 | ryanarn | 2007-04-19 15:12:56 -0500 (Thu, 19 Apr 2007) | 13 lines 2007-04-19 Ryan S. Arnold <rsa@us.ibm.com> * dfp/libdfp-test.inc: House keeping. Cleanup edits. * dfp/Makefile: Removed decPacked as a target. * dfp/disp-decimal.h: House keeping. Cleanup edits. * dfp/decPacked.c: Not necessary. * dfp/decPacked.h: Not necessary. * dfp/decimal64.c: House keeping. Cleanup edits. * dfp/sysdeps/powerpc/fpu/bits/fenvinline.h: Removed fe[get|set]round as redundant redefinition. * dfp/gen-libdfp-test.pl: House keeping. Cleanup edits. * dfp/Versions: Removed decPacked symbols. ------------------------------------------------------------------------ r316 | ryanarn | 2007-04-18 16:27:39 -0500 (Wed, 18 Apr 2007) | 6 lines 2007-04-18 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/soft-dfp/convert.c: Fixed bug where ___decimal*FromString() was being passed a pointer to a _Decimal* type. ------------------------------------------------------------------------ r315 | ryanarn | 2007-04-18 12:44:39 -0500 (Wed, 18 Apr 2007) | 18 lines 2007-04-18 Peter Eberlein <eberlein@us.ibm.com> 2007-04-18 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/soft-dfp/extend_d_f.c: New files to complete cleanroom of the conversion functions with some small changes by ryanarn to fix warnings. * dfp/sysdeps/soft-dfp/extendtfdd.c: Same as above. * dfp/sysdeps/soft-dfp/extend2.c: Same as above. * dfp/sysdeps/soft-dfp/trunc.c: Same as above. * dfp/sysdeps/soft-dfp/float.c: Same as above. * dfp/sysdeps/soft-dfp/floatuns.c: Same as above. * dfp/sysdeps/soft-dfp/fixuns.c: Same as above. * dfp/sysdeps/soft-dfp/trunc2.c: Same as above. * dfp/sysdeps/soft-dfp/convert.c: Same as above. * dfp/sysdeps/soft-dfp/convert.h: Same as above. * dfp/sysdeps/soft-dfp/fix.c: Same as above. * dfp/sysdeps/soft-dfp/extend.c: Same as above. ------------------------------------------------------------------------ r314 | ryanarn | 2007-04-17 14:36:09 -0500 (Tue, 17 Apr 2007) | 59 lines 2007-04-17 Peter Eberlein <eberlein@us.ibm.com> * dfp/sysdeps/soft-dfp/fixunstdsi.c: Completed cleanroom implementation of the conversion functions. * dfp/sysdeps/soft-dfp/floatunsditd.c: Same. * dfp/sysdeps/soft-dfp/subsd3.c: Same. * dfp/sysdeps/soft-dfp/mulsd3.c: Same. * dfp/sysdeps/soft-dfp/extendsddd2.c: Same. * dfp/sysdeps/soft-dfp/extendsdtf.c: Same. * dfp/sysdeps/soft-dfp/extendsftd.c: Same. * dfp/sysdeps/soft-dfp/extenddfdd.c: Same. * dfp/sysdeps/soft-dfp/floatdisd.c: Same. * dfp/sysdeps/soft-dfp/fixtdsi.c: Same. * dfp/sysdeps/soft-dfp/truncddsd2.c: Same. * dfp/sysdeps/soft-dfp/trunctdsf.c: Same. * dfp/sysdeps/soft-dfp/trunctfsd.c: Same. * dfp/sysdeps/soft-dfp/trunctddd2.c: Same. * dfp/sysdeps/soft-dfp/floatunssisd.c: Same. * dfp/sysdeps/soft-dfp/extendsdtd2.c: Same. * dfp/sysdeps/soft-dfp/extendddtf.c: Same. * dfp/sysdeps/soft-dfp/extenddftd.c: Same. * dfp/sysdeps/soft-dfp/Makefile: Same. * dfp/sysdeps/soft-dfp/trunctdsd2.c: Same. * dfp/sysdeps/soft-dfp/floatunsdisd.c: Same. * dfp/sysdeps/soft-dfp/addsd3.c: Same. * dfp/sysdeps/soft-dfp/extendsfsd.c: Same. * dfp/sysdeps/soft-dfp/extendtftd.c: Same. * dfp/sysdeps/soft-dfp/fixunssddi.c: Same. * dfp/sysdeps/soft-dfp/fixsddi.c: Same. * dfp/sysdeps/soft-dfp/fixunsdddi.c: Same. * dfp/sysdeps/soft-dfp/extendddtd2.c: Same. * dfp/sysdeps/soft-dfp/floatsidd.c: Same. * dfp/sysdeps/soft-dfp/fixdddi.c: Same. * dfp/sysdeps/soft-dfp/truncdddf.c: Same. * dfp/sysdeps/soft-dfp/fixunstddi.c * dfp/sysdeps/soft-dfp/floatsitd.c: Same. * dfp/sysdeps/soft-dfp/floatdidd.c: Same. * dfp/sysdeps/soft-dfp/makecfiles.sh: Same. * dfp/sysdeps/soft-dfp/fixtddi.c: Same. * dfp/sysdeps/soft-dfp/divsd3.c: Same. * dfp/sysdeps/soft-dfp/trunctfdd.c: Same. * dfp/sysdeps/soft-dfp/trunctddf.c: Same. * dfp/sysdeps/soft-dfp/floatunssidd.c: Same. * dfp/sysdeps/soft-dfp/fixunssdsi.c: Same. * dfp/sysdeps/soft-dfp/fixsdsi.c: Same. * dfp/sysdeps/soft-dfp/floatditd.c: Same. * dfp/sysdeps/soft-dfp/truncsdsf.c: Same. * dfp/sysdeps/soft-dfp/trunctdtf.c: Same. * dfp/sysdeps/soft-dfp/floatunssitd.c: Same. * dfp/sysdeps/soft-dfp/floatunsdidd.c: Same. * dfp/sysdeps/soft-dfp/fixunsddsi.c: Same. * dfp/sysdeps/soft-dfp/Versions: Same. * dfp/sysdeps/soft-dfp/floatsisd.c: Same. * dfp/sysdeps/soft-dfp/extendsfdd.c: Same. * dfp/sysdeps/soft-dfp/extendsddf.c: Same. * dfp/sysdeps/soft-dfp/fixddsi.c: Same. * dfp/sysdeps/soft-dfp/truncddsf.c: Same. * dfp/sysdeps/soft-dfp/truncdfsd.c: Same. ------------------------------------------------------------------------ r313 | ryanarn | 2007-04-17 10:42:57 -0500 (Tue, 17 Apr 2007) | 20 lines 2007-04-17 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/soft-dfp/dfp_frexp_dd.c: Incremental removal. This checkin will leave the branch unstable until the next revision patches the remaining files in this directory. * dfp/sysdeps/soft-dfp/dfp_frexp_td.c: Same as above. * dfp/sysdeps/soft-dfp/dfp_classify_dd.c: Same as above. * dfp/sysdeps/soft-dfp/dfp_classify_df.c: Same as above. * dfp/sysdeps/soft-dfp/config: Same as above. * dfp/sysdeps/soft-dfp/dfp_trunc_dd.c: Same as above. * dfp/sysdeps/soft-dfp/dfp_classify_td.c: Same as above. * dfp/sysdeps/soft-dfp/dfp_classify_tf.c: Same as above. * dfp/sysdeps/soft-dfp/dfp_frexp_sd.c: Same as above. * dfp/sysdeps/soft-dfp/decRound.h: Same as above. * dfp/sysdeps/soft-dfp/decExcept.h: Same as above. * dfp/sysdeps/soft-dfp/dfp_trunc_td.c: Same as above. * dfp/sysdeps/soft-dfp/dfp_classify_sd.c: Same as above. * dfp/sysdeps/soft-dfp/dfp_classify_sf.c: Same as above. * dfp/sysdeps/soft-dfp/dfp_trunc_sd.c: Same as above. ------------------------------------------------------------------------ r312 | ryanarn | 2007-04-13 11:46:56 -0500 (Fri, 13 Apr 2007) | 5 lines 2007-04-13 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/dfp/printf_dfp.c (__printf_dfp): Changed const char *str_ptr = &str; to const char *str_ptr = str; ------------------------------------------------------------------------ r311 | ryanarn | 2007-04-13 11:40:37 -0500 (Fri, 13 Apr 2007) | 5 lines 2007-04-13 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Makefile: Removed -Werror so that it doesn't cause problems from several known bugs. ------------------------------------------------------------------------ r310 | ryanarn | 2007-04-13 11:09:57 -0500 (Fri, 13 Apr 2007) | 22 lines 2007-04-13 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Makefile: Added -Werror to CFLAGS. * dfp/test/test_decode.c: Updated to enumerate the (int)0 -> _Decimal* and (float)0 -> _Decimal* conversion results. * dfp/test/test_math.h (DISP_HEXD*): Added call to decoded*(). * dfp/test/test_acos.c: Added test case. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsdsi.S (__fixsdsi): Changed blt cr7,L(negative) -> blt cr0,L(negative). * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixddsi.S (__fixddsi): Same as above. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtdsi.S (__fixtdsi): Same as above. * dfp/sysdeps/soft-dfp/subsd3.c (ACTUAL_FUNCTION_NAME): Added decNumber dn_result and made sure decNumber functions used that and converted dn_result into DEC_TYPE result. * dfp/sysdeps/soft-dfp/mulsd3.c (ACTUAL_FUNCTION_NAME): Same as above. * dfp/sysdeps/soft-dfp/addsd3.c (ACTUAL_FUNCTION_NAME): Same as above. * dfp/sysdeps/soft-dfp/divsd3.c (ACTUAL_FUNCTION_NAME): Same as above. * dfp/sysdeps/ieee754r/d32/fmodd32.c (IEEE_FUNCTION_NAME): Commented out unnecessary local variables. ------------------------------------------------------------------------ r309 | ryanarn | 2007-04-10 17:07:38 -0500 (Tue, 10 Apr 2007) | 16 lines 2007-04-10 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssdsi.S: "blt cr1,L(negative)" changed to branch off cr0. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsddsi.S: "blt cr1,L(negative)" changed to branch off cr0. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstdsi.S: "blt cr1,L(negative)" changed to branch off cr0. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsdsi.S: "blt cr1,L(negative)" changed to branch off cr7 * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixddsi.S: "blt cr1,L(negative)" changed to branch off cr7 * dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtdsi.S: "blt cr1,L(negative)" changed to branch off cr7 * dfp/sysdeps/powerpc/disp-decimal.c: Fixed a warning. ------------------------------------------------------------------------ r308 | ryanarn | 2007-04-10 01:32:40 -0500 (Tue, 10 Apr 2007) | 6 lines 2007-04-10 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/README: Add -m64. * dfp/sysdeps/dfp/printf_dfp.c: remove spurious '\0' chars. * dfp/fmt_dfp.c: remove spurious '\0' chars. ------------------------------------------------------------------------ r307 | ryanarn | 2007-04-09 21:25:35 -0500 (Mon, 09 Apr 2007) | 5 lines 2007-04-09 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/unix/sysv/linux/Implies: Removed 'powerpc' as Implies dir because it was breaking the power6/power6x 64-bit builds. ------------------------------------------------------------------------ r306 | eberlein | 2007-04-09 12:41:29 -0500 (Mon, 09 Apr 2007) | 13 lines * dfp/sysdeps/soft-dfp/addtd3.c: Corrected decimal size to 128 * dfp/sysdeps/soft-dfp/divtd3.c: " * dfp/sysdeps/soft-dfp/multd3.c: " * dfp/sysdeps/soft-dfp/subtd3.c: " * dfp/sysdeps/soft-dfp/eqtd2.c: " * dfp/sysdeps/soft-dfp/getd2.c: " * dfp/sysdeps/soft-dfp/gttd2.c: " * dfp/sysdeps/soft-dfp/letd2.c: " * dfp/sysdeps/soft-dfp/lttd2.c: " * dfp/sysdeps/soft-dfp/netd2.c: " * dfp/sysdeps/soft-dfp/unordtd2.c: " ------------------------------------------------------------------------ r305 | eberlein | 2007-04-06 16:42:25 -0500 (Fri, 06 Apr 2007) | 8 lines * dfp/sysdeps/soft-dfp/eqsd2.c: Fixed return value logic * dfp/sysdeps/soft-dfp/nesd2.c: " * dfp/sysdeps/soft-dfp/gesd2.c: " * dfp/sysdeps/soft-dfp/ltsd2.c: " * dfp/sysdeps/soft-dfp/lesd2.c: " * dfp/sysdeps/soft-dfp/gtsd2.c: " ------------------------------------------------------------------------ r304 | eberlein | 2007-04-06 13:15:42 -0500 (Fri, 06 Apr 2007) | 4 lines * dfp/sysdeps/soft-dfp/gesd2.c: Corrected bug when arguments were equal. * dfp/sysdeps/soft-dfp/gtsd2.c: Removed unnecessary test for zero result. ------------------------------------------------------------------------ r303 | ryanarn | 2007-04-06 10:48:22 -0500 (Fri, 06 Apr 2007) | 5 lines 2007-04-06 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_decode.c: Test the decoded[32|64|128]() functions. * dfp/test/README: Take the /opt/at**/bin dir as a parameter. ------------------------------------------------------------------------ r302 | ryanarn | 2007-04-05 18:00:28 -0500 (Thu, 05 Apr 2007) | 14 lines 2007-04-04 Ryan S. Arnold <rsa@us.ibm.com> A dfp/disp-decimal.c: Added decoded32/64/128. M dfp/Makefile: Added decoded32/64/128. A dfp/test/test_decode.c: Test decoded32/64/128. M dfp/test/README A dfp/test/test_itoa.c: Test decoded32/64/128. A dfp/disp-decimal.h Added decoded32/64/128. A dfp/sysdeps/powerpc/dpd-private.h: DPD decoder helpers for disp-decimal.c. A dfp/sysdeps/powerpc/disp-decimal.c: No-op version for non-powerpc. M dfp/sysdeps/unix/sysv/linux/Implies: M dfp/Versions: Added decoded32/64/128. ------------------------------------------------------------------------ r301 | eberlein | 2007-04-05 17:22:54 -0500 (Thu, 05 Apr 2007) | 35 lines * dfp/sysdeps/soft-dfp/adddd3.c: Clean room implementation. * dfp/sysdeps/soft-dfp/addsd3.c: " " " * dfp/sysdeps/soft-dfp/addtd3.c: " " " * dfp/sysdeps/soft-dfp/divdd3.c: " " " * dfp/sysdeps/soft-dfp/divsd3.c: " " " * dfp/sysdeps/soft-dfp/divtd3.c: " " " * dfp/sysdeps/soft-dfp/eqdd2.c: " " " * dfp/sysdeps/soft-dfp/eqsd2.c: " " " * dfp/sysdeps/soft-dfp/eqtd2.c: " " " * dfp/sysdeps/soft-dfp/gedd2.c: " " " * dfp/sysdeps/soft-dfp/gesd2.c: " " " * dfp/sysdeps/soft-dfp/getd2.c: " " " * dfp/sysdeps/soft-dfp/gtdd2.c: " " " * dfp/sysdeps/soft-dfp/gtsd2.c: " " " * dfp/sysdeps/soft-dfp/gttd2.c: " " " * dfp/sysdeps/soft-dfp/ledd2.c: " " " * dfp/sysdeps/soft-dfp/lesd2.c: " " " * dfp/sysdeps/soft-dfp/letd2.c: " " " * dfp/sysdeps/soft-dfp/ltdd2.c: " " " * dfp/sysdeps/soft-dfp/ltsd2.c: " " " * dfp/sysdeps/soft-dfp/lttd2.c: " " " * dfp/sysdeps/soft-dfp/muldd3.c: " " " * dfp/sysdeps/soft-dfp/mulsd3.c: " " " * dfp/sysdeps/soft-dfp/multd3.c: " " " * dfp/sysdeps/soft-dfp/nedd2.c: " " " * dfp/sysdeps/soft-dfp/nesd2.c: " " " * dfp/sysdeps/soft-dfp/netd2.c: " " " * dfp/sysdeps/soft-dfp/subdd3.c: " " " * dfp/sysdeps/soft-dfp/subsd3.c: " " " * dfp/sysdeps/soft-dfp/subtd3.c: " " " * dfp/sysdeps/soft-dfp/unorddd2.c: " " " * dfp/sysdeps/soft-dfp/unordsd2.c: " " " * dfp/sysdeps/soft-dfp/unordtd2.c: " " " ------------------------------------------------------------------------ r300 | ryanarn | 2007-04-03 17:03:16 -0500 (Tue, 03 Apr 2007) | 6 lines 2007-04-03 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/dfp/stdlib/dfpstdlib.h: Removed commented out code. * dfp/bits/dfpcalls.h: Added __BEGIN_DECL and __END_DECL. * dfp/fmt_dfp.h: Added __BEGIN_DECL and __END_DECL. ------------------------------------------------------------------------ r299 | ryanarn | 2007-04-03 14:53:36 -0500 (Tue, 03 Apr 2007) | 43 lines 2007-04-03 Ryan S. Arnold <rsa@us.ibm.com> * dfp/legal/libdecnumber.txt: Added for changing libdecnumber licenses. * dfp/legal/newfiles.txt: new file list. * dfp/legal/copyrights/IBM-2006-2007: Added for changing libdecnumber licenses. * dfp/legal/test-d.txt: Added for changing dfp make check test license. * dfp/legal/copyrights/IBM: Added for changing libdecnumber licenses. * dfp/legal/contributors/IBM: Added for changing libdecnumber licenses. * dfp/legal/legal.pl: Updated to be able to modify libdecnumber v3.37. * dfp/decimal128.h: Modify copyright/license to IBM/LGPLv2.1. * dfp/decimal32.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/decNumber.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/decimal32.h: Modify copyright/license to IBM/LGPLv2.1. * dfp/decNumber.h: Modify copyright/license to IBM/LGPLv2.1. * dfp/test-d64.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/decNumberLocal.h: Modify copyright/license to IBM/LGPLv2.1. * dfp/test-d128.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/decContext.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/decPacked.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/test-d32.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/decContext.h: Modify copyright/license to IBM/LGPLv2.1. * dfp/decPacked.h: Modify copyright/license to IBM/LGPLv2.1. * dfp/decimal64.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/decimal64.h: Modify copyright/license to IBM/LGPLv2.1. * dfp/decNumberMath.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/decNumberMath.h: Modify copyright/license to IBM/LGPLv2.1. * dfp/decDPD.h: Modify copyright/license to IBM/LGPLv2.1. * dfp/decimal128.c: Modify copyright/license to IBM/LGPLv2.1. * dfp/fmt_dfp.h: Removed commented out code. * dfp/fmt_dfp.c: Removed commented out code. * dfp/dfptypeconv.c: Removed commented out code. * dfp/dfpfenv_private.h: Removed commented out code. * dfp/dfptypeconv.h : Removed (deprecated). * dfp/decNumberLocal.c: Removed empty file. * dfp/sysdeps/dfp/math/gen-libm-test.pl: Remove (not used). * dfp/sysdeps/dfp/math/NewUlps: Remove (not used). ------------------------------------------------------------------------ r298 | ryanarn | 2007-04-02 20:49:01 -0500 (Mon, 02 Apr 2007) | 6 lines 2007-04-02 Ryan S. Arnold <rsa@us.ibm.com> * Synced existing dfp svn tree (09/20/2006) with GLIBC cvs head as of 03/20/2007. ------------------------------------------------------------------------ r296 | ryanarn | 2007-04-02 08:53:58 -0500 (Mon, 02 Apr 2007) | 30 lines 2007-04-02 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/powerpc/powerpc64/power6/fpu/Makefile: Updates to add new files to the build target list. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltdd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltsd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/lttd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/gedd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/gesd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/getd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/ledd2.S: Copy of ltdd2.S for ledd2.S. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/lesd2.S: Copy of ltsd2.S for ltsd2.S. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/letd2.S: Copy of letd2.S for lttd2.S. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtdd2.S: Copy of gedd2.S for gtdd2.S. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtsd2.S: Copy of gesd2.S for gtsd2.S. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/gttd2.S: Copy of getd2.S for gttd2.S. ------------------------------------------------------------------------ r295 | ryanarn | 2007-03-30 11:21:54 -0500 (Fri, 30 Mar 2007) | 3 lines 2007-04-30 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/soft-dfp/config/dfp-bit.h: Removed extraneous comments. ------------------------------------------------------------------------ r294 | ryanarn | 2007-03-30 10:20:32 -0500 (Fri, 30 Mar 2007) | 7 lines 2007-03-30 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/soft-dfp/config/dfp-bit.h: Fixed include ordering and updated double underscore decNumber function references to triple underscore. * dfp/Versions: Added ___decimal32/64/128FromString symbols. ------------------------------------------------------------------------ r293 | eberlein | 2007-03-28 17:15:47 -0500 (Wed, 28 Mar 2007) | 3 lines * dfp/sysdeps/soft-dfp/Makefile: corrected WORDS_BIG_ENDIAN ------------------------------------------------------------------------ r292 | ryanarn | 2007-03-28 10:43:04 -0500 (Wed, 28 Mar 2007) | 9 lines 2007-03-28 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_scalb.c: Narrowed down failure case. * dfp/test/janis.c: Added new test. * dfp/test/janis2.c: Added new test. * dfp/sysdeps/soft-dfp/config/dfp-bit.c: Fixed reference of decContextDefault() to ___decContextDefault(). * dfp/sysdeps/ieee754r/d32/cbrtd32.c: Removed erroneous iteration. ------------------------------------------------------------------------ r291 | ryanarn | 2007-03-26 16:03:42 -0500 (Mon, 26 Mar 2007) | 76 lines 2007-03-26 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Makefile: moved binpowof10 and decpowof2 targets to dfp/sysdeps/soft-dfp/Makefile. * dfp/sysdeps/soft-dfp/Makefile: moved binpowof10 and decpowof2 targets to dfp/sysdeps/soft-dfp/Makefile. * dfp/test/test_math.h: Added hex debugging for failures. * dfp/sysdeps/soft-dfp/Versions: Fixed mixed up symbol names. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions: Fixed mixed up symbol names. * dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions: Fixed mixed up symbol names. * dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/Implies: Removed preceding path dfp/sysdeps. * dfp/sysdeps/unix/sysv/linux/powerpc/nofpu/Implies Removed preceding path dfp/sysdeps. * dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies Removed preceding path dfp/sysdeps. * dfp/sysdeps/unix/sysv/linux/powerpc/fpu/Implies Removed preceding path dfp/sysdeps. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssisd.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltdd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/Makefile: Added new targets. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltsd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/lttd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsidd.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsitd.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssidd.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssitd.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/gedd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsisd.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/gesd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/getd2.S: Removed strong_alias. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdisd.S: Added to avoid two symbols in one .c file. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/ledd2.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/lesd2.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/letd2.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdidd.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtdd2.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatditd.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdidd.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtsd2.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/gttd2.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsditd.S: Same. * dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdisd.S: Same. * dfp/sysdeps/soft-dfp/floatsddi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatdddi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatunssddi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floattddi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatunsdddi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatsdsi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatunstddi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatddsi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatunssdsi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floattdsi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatunsddsi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatunstdsi.c: Removed for rename. * dfp/sysdeps/soft-dfp/floatunsditd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatdisd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatunssisd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatunsdisd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatsidd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatsitd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatdidd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatunssidd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatditd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatunssitd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatunsdidd.c: Added for rename. * dfp/sysdeps/soft-dfp/floatsisd.c: Added for rename. ------------------------------------------------------------------------ r290 | ryanarn | 2007-03-22 15:52:08 -0500 (Thu, 22 Mar 2007) | 10 lines 2007-03-22 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Makefile: Added decpowof2 and binpowof10 to target list. * dfp/sysdeps/powerpc/binpowof10.c: Added weak_alias to __dfp_binpowof10. * dfp/sysdeps/powerpc/decpowof2.c: Added weak_alias to __dfp_decpowof2. * dfp/sysdeps/soft-dfp/config/dfp-bit.c: Corrected libdecnumber symbol reference to include 'triple-underscore' prefixes. ------------------------------------------------------------------------ r289 | eberlein | 2007-03-22 14:04:05 -0500 (Thu, 22 Mar 2007) | 17 lines * soft-dfp/Makefile: new files added. * soft-dfp/makecfiles.sh: new files added. * soft-dfp/Versions: new functions added. * soft-dfp/dfp_frexp_dd.c: new file. * soft-dfp/dfp_frexp_td.c: new file. * soft-dfp/dfp_classify_dd.c: new file. * soft-dfp/dfp_classify_df.c: new file. * soft-dfp/dfp_trunc_dd.c: new file. * soft-dfp/dfp_classify_td.c: new file. * soft-dfp/dfp_classify_tf.c: new file. * soft-dfp/dfp_frexp_sd.c: new file. * soft-dfp/dfp_trunc_td.c: new file. * soft-dfp/dfp_classify_sd.c: new file. * soft-dfp/dfp_classify_sf.c: new file. * soft-dfp/dfp_trunc_sd.c: new file. ------------------------------------------------------------------------ r288 | eberlein | 2007-03-21 14:16:49 -0500 (Wed, 21 Mar 2007) | 4 lines * dfp/sysdeps/soft-dfp/config/dfp-bit.c: updated to GCC latest * dfp/sysdeps/soft-dfp/config/dfp-bit.h: updated to GCC latest ------------------------------------------------------------------------ r287 | eberlein | 2007-03-21 04:50:26 -0500 (Wed, 21 Mar 2007) | 5 lines * dfp/sysdeps/soft-dfp/decExcept.h: added copyright. removed decNumber.h include * dfp/sysdeps/soft-dfp/decRound.h: added copyright. ------------------------------------------------------------------------ r286 | ryanarn | 2007-03-21 00:21:43 -0500 (Wed, 21 Mar 2007) | 7 lines 2007-03-21 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_scalb.c: New test. * dfp/test/test_cbrt.c: New test. * dfp/test/test_ilogb.c: New test. * dfp/test/convert.c: New test. ------------------------------------------------------------------------ r285 | ryanarn | 2007-03-21 00:19:51 -0500 (Wed, 21 Mar 2007) | 23 lines 2007-03-21 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_set1a.c: Fixed test expectations or added tests. * dfp/test/test_errno.c: Fixed test expectations or added tests. * dfp/test/test_math.h: Fixed macro to print actual expected value. * dfp/test/test_pow.c: Fixed test expectations or added tests. * dfp/test/test_iscomparison.c: Fixed test expectations or added tests. * dfp/test/README: Fixed to add -ldecnumber * dfp/test/test_set2a.c: Fixed test expectations or added tests. * dfp/test/test_fabsd.c: Fixed test expectations or added tests. * dfp/test/test_exceptions.c: Fixed includes. * dfp/sysdeps/ieee754r/dfpmacro.h: Fixed includes. * dfp/sysdeps/ieee754r/d32/fmodd32.c: Fixed accuracy issues. * dfp/sysdeps/ieee754r/d32/ilogbd32.c: Fixed accuracy issues. * dfp/sysdeps/ieee754r/d32/scalbnd32.c: Fixed accuracy issues. * dfp/sysdeps/ieee754r/d32/scalblnd32.c: Fixed accuracy issues. * dfp/sysdeps/ieee754r/d32/cbrtd32.c: Fixed accuracy issues. * dfp/sysdeps/ieee754r/d32/ldexpd32.c: Fixed accuracy issues. * dfp/sysdeps/ieee754r/d32/islessgreaterd32.c: Fixed accuracy issues. * dfp/sysdeps/ieee754r/d32/logbd32.c: Fixed accuracy issues. * dfp/sysdeps/ieee754r/d64/ilogbd64.c: Fixed accuracy issues. * dfp/sysdeps/ieee754r/d128/ilogbd128.c: Fixed accuracy issues. ------------------------------------------------------------------------ r284 | ryanarn | 2007-03-15 14:04:53 -0500 (Thu, 15 Mar 2007) | 20 lines 2007-03-15 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_isfinite.c: Expand the testcases. * dfp/test/test_set1a.c: Expand the testcases. * dfp/test/test_isinf.c: Fix the nextafter testcases to use -DEC_MAXDF rather than DEC_MINDF, which would go to denormal rather then -DEC_INFINITY. * dfp/sysdeps/dfp/stdlib/stdlib.h: Fix __STDC_WANT_DEC_FP__ guard to be #ifdef rather than #if. * dfp/sysdeps/dfp/math/math.h: Fix __STDC_WANT_DEC_FP__ guard to be #ifdef rather than #if. Fixed erroneous reference to __isfinited32/64/128 and replaced with the proper __finited32/64/128. * dfp/sysdeps/dfp/math/bits/mathcalls.h: Fix __STDC_WANT_DEC_FP__ guard to be #ifdef rather than #if. * dfp/sysdeps/dfp/math/fenv.h: Fix __STDC_WANT_DEC_FP__ guard to be #ifdef rather than #if. * dfp/sysdeps/dfp/wcsmbs/wchar.h: Fix __STDC_WANT_DEC_FP__ guard to be #ifdef rather than #if. * dfp/bits/dfpcalls.h: Added samequantumd prototype. ------------------------------------------------------------------------ r283 | eberlein | 2007-03-15 13:04:39 -0500 (Thu, 15 Mar 2007) | 3 lines * dfp/sysdeps/unix/sysv/linux/Implies: added soft-dfp ------------------------------------------------------------------------ r282 | ryanarn | 2007-03-14 16:55:56 -0500 (Wed, 14 Mar 2007) | 30 lines 2007-03-14 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_nearbyintd.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_quantize.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_isnan.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_isfinite.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_set1a.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_fdim.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_modf.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_errno.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_fmin.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_fmax.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_math.h: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_pow.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_iscomparison.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_isinf.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/README: Added -ldecnumber. * dfp/test/test_set2.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_isunordered.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_isnormal.c: Guard __STDC_WANT_DEC_FP__. * dfp/test/test_arctrig.c: Guard __STDC_WANT_DEC_FP__. * dfp/decContext.c: Changed the default rounding mode back to DEC_ROUND_HALF_EVEN because it got reverted to the libdecnumber version when the new libdecnumber was imported. * dfp/sysdeps/ieee754r/d32/nexttowardd32.c: Fixed erroneous comparison causing improper rounding. * dfp/sysdeps/ieee754r/d32/nextafterd32.c: Fixed erroneous comparison causing improper rounding. * dfp/bits/dfpcalls.h: Updated to add samequantum prototype. ------------------------------------------------------------------------ r281 | ryanarn | 2007-03-14 13:42:25 -0500 (Wed, 14 Mar 2007) | 6 lines 2007-03-14 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/dfp/math/math.h: Updated to use __dfp_compatible() for the polymorphic classification functions. Removed __bfp_compatible() which didn't work properly. ------------------------------------------------------------------------ r280 | ryanarn | 2007-03-13 14:38:48 -0500 (Tue, 13 Mar 2007) | 9 lines 2007-03-13 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/soft-dfp/decExcept.h: Removed #include <decNumberArith.h> as it is no longer necessary * dfp/sysdeps/dfp/math/math.h: Replaced usage of __builtin_types_compatible_p with __dfp_compatible macro which should work for both GCC and XL compilers for distinguishing between bfp and dfp types for usage in polymorphic functions, e.g. isnan. ------------------------------------------------------------------------ r279 | ryanarn | 2007-03-12 14:57:33 -0500 (Mon, 12 Mar 2007) | 89 lines 03/12/2006 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Makefile: Changes to build libdecnumber.so * dfp/decNumber.c: Recommit version libdecnumber 3.37 * dfp/decNumber.h: Recommit version libdecnumber 3.37 * dfp/decNumberLocal.c: Recommit version libdecnumber 3.37 * dfp/dfptypeconv128.h: Necessary to prevent decimal64.h and decimal32.h from being pulled in. * dfp/dfptypeconv64.h: Necessary to prevent decimal128.h and decimal32.h from being pulled in. * dfp/dfptypeconv32.h: Necessary to prevent decimal64.h and decimal128.h from being pulled in. * dfp/dfptypeconv.h: Now unused. * dfp/dfptypeconv.c: Added libc_hidden_defs. * dfp/decNumberLocal.h: Recommit version libdecnumber 3.37 * dfp/decContext.c: Recommit version libdecnumber 3.37 * dfp/decPacked.c: Recommit version libdecnumber 3.37 * dfp/decContext.h: Recommit version libdecnumber 3.37 * dfp/decPacked.h: Recommit version libdecnumber 3.37 * dfp/decimal128.h: Recommit version libdecnumber 3.37 * dfp/decimal128.c: Recommit version libdecnumber 3.37 * dfp/decimal32.c: Recommit version libdecnumber 3.37 * dfp/decimal32.h: Recommit version libdecnumber 3.37 * dfp/decimal64.c: Recommit version libdecnumber 3.37 * dfp/decimal64.h: Recommit version libdecnumber 3.37 * dfp/fmt_dfp.c: #include new dfptypeconv*.h headers. * dfp/fmt_dfp.h: Added libc_hidden_proto(). * dfp/decNumberMath.c: Updated to remove functions newly provided in decNumber.c function. * dfp/decNumberMath.h: Updated to remove functions newly provided in decNumber.c function. * dfp/Versions.def: Added libdecnumber section. * dfp/Versions: Added libdecnumber section. * dfp/decDPD.h:: Recommit version libdecnumber 3.37 * dfp/sysdeps/ieee754r/dfpmacro.h: Updated to account for new guards around DECNUMDIGITS in decimal32/64/128.h * dfp/sysdeps/ieee754r/d32/fmodd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/roundd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/fmaxd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/ilogbd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/quantized32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/samequantumd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/scalbnd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/fmad32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/fabsd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/scalblnd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/logd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/sind32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/islessequald32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/expm1d32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/truncd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/hypotd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/powd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/nand32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/ldexpd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/islessgreaterd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/fdimd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/floord32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/log10d32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/cosd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/isnormald32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/modfd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/fmind32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/tanhd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/atanhd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/copysignd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/nearbyintd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/coshd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/acoshd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/lgammad32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/sinhd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/asinhd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/log2d32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/atan2d32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/tgammad32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/llroundd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/atand32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/isgreaterd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/sqrtd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/expd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/nexttowardd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/signbitd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/nextafterd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/islessd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/remainderd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/ceild32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/isgreaterequald32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/exp2d32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/log1pd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/tand32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/logbd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d32/frexpd32.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d64/nexttowardd64.c: Removed usage of libdecnumber internal functions. * dfp/sysdeps/ieee754r/d128/nexttowardd128.c: Removed usage of libdecnumber internal functions. ------------------------------------------------------------------------ r278 | ryanarn | 2007-03-12 13:34:58 -0500 (Mon, 12 Mar 2007) | 24 lines 03/12/2007 Ryan S. Arnold <rsa@us.ibm.com> * dfp/decimal128.h: Temporarily removed to import new version. * dfp/decimal32.c: Temporarily removed to import new version. * dfp/decNumberUtilities.h: Temporarily removed to import new version. * dfp/decimal32.h: Temporarily removed to import new version. * dfp/deccommon.h: Temporarily removed to import new version. * dfp/decNumber.h: Temporarily removed to import new version. * dfp/decUtility.c: Temporarily removed to import new version. * dfp/decquantize.h: Temporarily removed to import new version. * dfp/decstring.c: Temporarily removed to import new version. * dfp/decnumber: Temporarily removed to import new version. * dfp/decNumberLocal.h: Temporarily removed to import new version. * dfp/decUtility.h: Temporarily removed to import new version. * dfp/decsharedcommon.c: Temporarily removed to import new version. * dfp/decNumberArith.h: Temporarily removed to import new version. * dfp/decContext.h: Temporarily removed to import new version. * dfp/decimal64.c: Temporarily removed to import new version. * dfp/decimal64.h: Temporarily removed to import new version. * dfp/decNumberMath.h: Temporarily removed to import new version. * dfp/decDPD.h: Temporarily removed to import new version. * dfp/decimal128.c: Temporarily removed to import new version. ------------------------------------------------------------------------ r277 | eberlein | 2007-03-09 12:48:41 -0600 (Fri, 09 Mar 2007) | 6 lines 2007-09-03 Pete Eberlein <eberlein@us.ibm.com> * dfp/sysdeps/soft-dfp/config/dfp-bit.c: New file. * dfp/sysdeps/soft-dfp/config/dfp-bit.h: New file. ------------------------------------------------------------------------ r276 | eberlein | 2007-03-09 12:46:07 -0600 (Fri, 09 Mar 2007) | 1 line ------------------------------------------------------------------------ r275 | eberlein | 2007-03-09 12:40:17 -0600 (Fri, 09 Mar 2007) | 93 lines 2007-09-03 Pete Eberlein <eberlein@us.ibm.com> * dfp/sysdeps/soft-dfp/eqdd2.c: New file. * dfp/sysdeps/soft-dfp/fixunstdsi.c: New file. * dfp/sysdeps/soft-dfp/subsd3.c: New file. * dfp/sysdeps/soft-dfp/gesd2.c: New file. * dfp/sysdeps/soft-dfp/subtd3.c: New file. * dfp/sysdeps/soft-dfp/getd2.c: New file. * dfp/sysdeps/soft-dfp/mulsd3.c: New file. * dfp/sysdeps/soft-dfp/multd3.c: New file. * dfp/sysdeps/soft-dfp/extendsddd2.c: New file. * dfp/sysdeps/soft-dfp/extendsdtf.c: New file. * dfp/sysdeps/soft-dfp/extendsftd.c: New file. * dfp/sysdeps/soft-dfp/extenddfdd.c: New file. * dfp/sysdeps/soft-dfp/floatsddi.c: New file. * dfp/sysdeps/soft-dfp/fixtdsi.c: New file. * dfp/sysdeps/soft-dfp/trunctfsd.c: New file. * dfp/sysdeps/soft-dfp/trunctdsf.c: New file. * dfp/sysdeps/soft-dfp/truncddsd2.c: New file. * dfp/sysdeps/soft-dfp/trunctddd2.c: New file. * dfp/sysdeps/soft-dfp/eqsd2.c: New file. * dfp/sysdeps/soft-dfp/eqtd2.c: New file. * dfp/sysdeps/soft-dfp/adddd3.c: New file. * dfp/sysdeps/soft-dfp/extendsdtd2.c: New file. * dfp/sysdeps/soft-dfp/extenddtf.c: New file. * dfp/sysdeps/soft-dfp/extenddftd.c: New file. * dfp/sysdeps/soft-dfp/floatdddi.c: New file. * dfp/sysdeps/soft-dfp/Makefile: New file. * dfp/sysdeps/soft-dfp/trunctdsd2.c: New file. * dfp/sysdeps/soft-dfp/floatunssddi.c: New file. * dfp/sysdeps/soft-dfp/addsd3.c: New file. * dfp/sysdeps/soft-dfp/addtd3.c: New file. * dfp/sysdeps/soft-dfp/extendsfsd.c: New file. * dfp/sysdeps/soft-dfp/extendtftd.c: New file. * dfp/sysdeps/soft-dfp/ltdd2.c: New file. * dfp/sysdeps/soft-dfp/floattddi.c: New file. * dfp/sysdeps/soft-dfp/floatunsdddi.c: New file. * dfp/sysdeps/soft-dfp/fixunssddi.c: New file. * dfp/sysdeps/soft-dfp/unorddd2.c: New file. * dfp/sysdeps/soft-dfp/config: New file. * dfp/sysdeps/soft-dfp/config/dfp-bit.c: New file. * dfp/sysdeps/soft-dfp/config/dfp-bit.h: New file. * dfp/sysdeps/soft-dfp/ltsd2.c: New file. * dfp/sysdeps/soft-dfp/floatsdsi.c: New file. * dfp/sysdeps/soft-dfp/lttd2.c: New file. * dfp/sysdeps/soft-dfp/ledd2.c: New file. * dfp/sysdeps/soft-dfp/fixsddi.c: New file. * dfp/sysdeps/soft-dfp/nedd2.c: New file. * dfp/sysdeps/soft-dfp/floatunstddi.c: New file. * dfp/sysdeps/soft-dfp/unordsd2.c: New file. * dfp/sysdeps/soft-dfp/unordtd2.c: New file. * dfp/sysdeps/soft-dfp/fixunsdddi.c: New file. * dfp/sysdeps/soft-dfp/decRound.h: New file. * dfp/sysdeps/soft-dfp/floatddsi.c: New file. * dfp/sysdeps/soft-dfp/lesd2.c: New file. * dfp/sysdeps/soft-dfp/extendddtd2.c: New file. * dfp/sysdeps/soft-dfp/decExcept.h: New file. * dfp/sysdeps/soft-dfp/letd2.c: New file. * dfp/sysdeps/soft-dfp/fixdddi.c: New file. * dfp/sysdeps/soft-dfp/nesd2.c: New file. * dfp/sysdeps/soft-dfp/netd2.c: New file. * dfp/sysdeps/soft-dfp/truncdddf.c: New file. * dfp/sysdeps/soft-dfp/divdd3.c: New file. * dfp/sysdeps/soft-dfp/floatunssdsi.c: New file. * dfp/sysdeps/soft-dfp/fixunstddi.c: New file. * dfp/sysdeps/soft-dfp/floattdsi.c: New file. * dfp/sysdeps/soft-dfp/makecfiles.sh: New file. * dfp/sysdeps/soft-dfp/fixtddi.c: New file. * dfp/sysdeps/soft-dfp/divsd3.c: New file. * dfp/sysdeps/soft-dfp/trunctddf.c: New file. * dfp/sysdeps/soft-dfp/trunctfdd.c: New file. * dfp/sysdeps/soft-dfp/divtd3.c: New file. * dfp/sysdeps/soft-dfp/floatunsddsi.c: New file. * dfp/sysdeps/soft-dfp/fixunssdsi.c: New file. * dfp/sysdeps/soft-dfp/gtdd2.c: New file. * dfp/sysdeps/soft-dfp/fixsdsi.c: New file. * dfp/sysdeps/soft-dfp/truncsdsf.c: New file. * dfp/sysdeps/soft-dfp/trunctdtf.c: New file. * dfp/sysdeps/soft-dfp/floatunstdsi.c: New file. * dfp/sysdeps/soft-dfp/fixunsddsi.c: New file. * dfp/sysdeps/soft-dfp/gtsd2.c: New file. * dfp/sysdeps/soft-dfp/gttd2.c: New file. * dfp/sysdeps/soft-dfp/subdd3.c: New file. * dfp/sysdeps/soft-dfp/gedd2.c: New file. * dfp/sysdeps/soft-dfp/Versions: New file. * dfp/sysdeps/soft-dfp/extendsddf.c: New file. * dfp/sysdeps/soft-dfp/extendsfdd.c: New file. * dfp/sysdeps/soft-dfp/muldd3.c: New file. * dfp/sysdeps/soft-dfp/fixddsi.c: New file. * dfp/sysdeps/soft-dfp/truncddsf.c: New file. * dfp/sysdeps/soft-dfp/truncdfsd.c: New file. ------------------------------------------------------------------------ r274 | eberlein | 2007-03-06 17:51:14 -0600 (Tue, 06 Mar 2007) | 4 lines * powerpc32/power6/fpu/Versions: fixed __trunctddd2 * powerpc64/power6/fpu/Versions: fixed __trunctddd2 ------------------------------------------------------------------------ r273 | eberlein | 2007-02-26 19:57:19 -0600 (Mon, 26 Feb 2007) | 3 lines * fe_decround.c: Fixed unterminated comment ------------------------------------------------------------------------ r272 | eberlein | 2007-02-15 17:18:39 -0600 (Thu, 15 Feb 2007) | 5 lines 2007-02-15 Pete Eberlein <eberlein@us.ibm.com> * sysdeps/dfp/fe_decround: File moved. ------------------------------------------------------------------------ r271 | eberlein | 2007-02-13 13:25:48 -0600 (Tue, 13 Feb 2007) | 6 lines 2007-02-13 Pete Eberlein <eberlein@us.ibm.com> * fpu/Implies: New file. * nofpu/Implies: New file. ------------------------------------------------------------------------ r270 | eberlein | 2007-02-13 13:24:21 -0600 (Tue, 13 Feb 2007) | 5 lines 2007-02-13 Pete Eberlein <eberlein@us.ibm.com> * 440/nofpu: New directory. ------------------------------------------------------------------------ r269 | eberlein | 2007-02-13 13:23:26 -0600 (Tue, 13 Feb 2007) | 5 lines 2007-02-13 Pete Eberlein <eberlein@us.ibm.com> * 440/nofpu: New directory. ------------------------------------------------------------------------ r268 | eberlein | 2007-02-13 13:21:49 -0600 (Tue, 13 Feb 2007) | 5 lines 2007-02-13 Pete Eberlein <eberlein@us.ibm.com> * nofpu/bits/fenvinline.h: New file. ------------------------------------------------------------------------ r267 | eberlein | 2007-02-13 13:21:13 -0600 (Tue, 13 Feb 2007) | 5 lines 2007-02-13 Pete Eberlein <eberlein@us.ibm.com> * fpu/bits/fenvinline.h: New file. ------------------------------------------------------------------------ r266 | eberlein | 2007-02-13 13:11:10 -0600 (Tue, 13 Feb 2007) | 6 lines 2006-02-13 Pete Eberlein <eberlein@us.ibm.com> * powerpc32/440/nofpu: New directory * powerpc64/440/nofpu: New directory ------------------------------------------------------------------------ r265 | eberlein | 2007-02-13 13:08:27 -0600 (Tue, 13 Feb 2007) | 6 lines 2007-02-13 Pete Eberlein <eberlein@us.ibm.com> * powerpc32/power6/Implies: New file * powerpc64/power6/Implies: New file ------------------------------------------------------------------------ r264 | eberlein | 2007-02-13 13:05:17 -0600 (Tue, 13 Feb 2007) | 5 lines 2007-02-13 Pete Eberlein <eberlein@us.ibm.com> * fe_decround.c: Moved from dfp/. ------------------------------------------------------------------------ r263 | eberlein | 2007-02-13 13:00:31 -0600 (Tue, 13 Feb 2007) | 6 lines 2007-02-13 Pete Eberlein <eberlein@us.ibm.com> * fe_decround.c: New file. Power6 omptimized functions for fe_dec_setround and fe_dec_getround. ------------------------------------------------------------------------ r261 | ryanarn | 2007-02-05 09:20:19 -0600 (Mon, 05 Feb 2007) | 16 lines 2007-02-05 Ryan S. Arnold <rsa@us.ibm.com> * dfp/libdfp-test.inc: Removed decfloat.h or changed to float.h to coincide with GCC revision 121355 which moved the contents of decfloat.h into float.h per the Draft DFP Technical Report. * dfp/test/test_const.c: Same as above. * dfp/test/test_math.h: Same as above. * dfp/test/test_exceptions.c: Same as above. * dfp/test/test_isnormal.c: Same as above. * dfp/sysdeps/dfp/stdlib/strtod32.c: Same as above. * dfp/sysdeps/dfp/math/libm-test.inc: Same as above. * dfp/sysdeps/ieee754r/d32/isnormald32.c: Same as above. * dfp/sysdeps/ieee754r/d32/lgammad32.c: Same as above. * dfp/sysdeps/ieee754r/d32/nexttowardd32.c: Same as above. * dfp/sysdeps/ieee754r/d32/nextafterd32.c: Same as above. ------------------------------------------------------------------------ r260 | ryanarn | 2007-01-23 08:56:01 -0600 (Tue, 23 Jan 2007) | 7 lines 2007-01-19 Ryan S. Arnold <rsa@us.ibm.com> * dfp/libdfp-test.inc: guard frexp, ldexp, and ilogb with #ifndef __STDC_WANT_DEC_FP__. * dfp/Makefile: Fixed misspelling of $(objfpx) -> $(objpfx). Move #include ../Rules so that the 'tests' variable was picked up. ------------------------------------------------------------------------ r259 | ryanarn | 2007-01-09 10:13:18 -0600 (Tue, 09 Jan 2007) | 7 lines 2007-01-09 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/ieee754r/d32/modfd32.c (modfd*): Fixed missing comma. * dfp/sysdeps/ieee754r/d32/atanhd32.c (atanhd*): Fixed improper pointer dereference. ------------------------------------------------------------------------ r258 | jkerian | 2006-12-22 13:11:27 -0600 (Fri, 22 Dec 2006) | 13 lines 2006-12-22 Joseph Kerian joseph_kerian@und.edu * dfp/test/test_set2a.c: Updated for a few changes * dfp/test/test_assign.c: Changing to test 0s * dfp/sysdeps/dfp/stdio-common/vfprintf.c: Specifying FIXME * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c: Adding an Endian check * dfp/sysdeps/ieee754r/d32/expm1d32.c: Fixing in accordance to test suite * dfp/sysdeps/ieee754r/d32/modfd32.c: Fixing in accordance to test suite * dfp/sysdeps/ieee754r/d32/atanhd32.c: Fixing in accordance to test suite * dfp/sysdeps/ieee754r/d32/exp2d32.c: Fixing in accordance to test suite * dfp/sysdeps/ieee754r/d32/tand32.c: Fixing in accordance to test suite * dfp/sysdeps/ieee754r/d32/logbd32.c: Fixing in accordance to test suite ------------------------------------------------------------------------ r257 | jkerian | 2006-12-21 18:22:53 -0600 (Thu, 21 Dec 2006) | 13 lines 2006-12-21 Joseph Kerian jkerian@us.ibm.com * sysdeps/ieee754r/d32/fpclassifyd32.c: Rewrote to not use decNumber * sysdeps/ieee754r/d32/isinfd32.c: Rewrote to not use decNumber * sysdeps/ieee754r/d32/isnand32.c: Rewrote to not use decNumber * sysdeps/ieee754r/d32/isunorderedd32.c: Rewrote to not use decNumber * sysdeps/ieee754r/d32/isnormald32.c: Fixed so that 0.0 is not subnormal * sysdeps/ieee754r/d32/atan2d32.c: Added authorship note * test/test_isnan.c: Added a test and cleaned up #def's * test/test_fpclassify.c: Added a test and cleaned up #def's * sysdeps/ieee754r/dfpmacro.h: Removed unused macro ------------------------------------------------------------------------ r256 | jkerian | 2006-12-21 13:58:35 -0600 (Thu, 21 Dec 2006) | 7 lines 2006-12-21 Joseph Kerian <jkerian@us.ibm.com> * dfptypeconv.h: Removed some macros that belonged in dfpmacro.h * sysdeps/ieee754r/dfpmacro.h: Added macros, removed dead code * sysdeps/ieee754r/d32/nexttowardd32.c: Modified according to a renamed macro ------------------------------------------------------------------------ r255 | ryanarn | 2006-12-21 12:51:11 -0600 (Thu, 21 Dec 2006) | 127 lines 2006-12-14 Steven Munroe <sjmunroe@us.ibm.com> * sysdeps/powerpc/powerpc32/power6/fpu/Makefile: New file. * sysdeps/powerpc/powerpc32/power6/fpu/Versions: New file. * sysdeps/powerpc/powerpc32/power6/fpu/adddd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/addsd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/addtd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/divdd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/divsd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/divtd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/eqdd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/eqsd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/eqtd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/extendddtd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/extendsddd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/extendsdtd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixdddi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixddsi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixsddi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixsdsi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixtddi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixtdsi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixunsdddi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixunsddsi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixunssddi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixunssdsi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixunstddi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/fixunstdsi.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/floatsidd.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/floatsisd.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/floatsitd.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/floatunssidd.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/floatunssisd.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/floatunssitd.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/gedd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/gesd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/getd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/ltdd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/ltsd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/lttd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/muldd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/mulsd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/multd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/nedd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/nesd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/netd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/subdd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/subsd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/subtd3.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/truncddsd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/trunctddd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/trunctdsd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/unorddd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/unordsd2.S: New file. * sysdeps/powerpc/powerpc32/power6/fpu/unordtd2.S: New file. * sysdeps/powerpc/powerpc32/power6x/fpu/Implies: New file. * sysdeps/powerpc/powerpc64/power6/fpu/Makefile: New file. * sysdeps/powerpc/powerpc64/power6/fpu/Versions: New file. * sysdeps/powerpc/powerpc64/power6/fpu/adddd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/addsd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/addtd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/divdd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/divsd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/divtd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/eqdd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/eqsd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/eqtd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/extendddtd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/extendsddd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/extendsdtd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixdddi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixddsi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixsddi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixsdsi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixtddi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixtdsi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixunsdddi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixunsddsi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixunssddi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixunssdsi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixunstddi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/fixunstdsi.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatdidd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatdisd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatditd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatsidd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatsisd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatsitd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatunsdidd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatunsdisd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatunsditd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatunssidd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatunssisd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/floatunssitd.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/gedd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/gesd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/getd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/ltdd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/ltsd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/lttd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/muldd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/mulsd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/multd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/nedd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/nesd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/netd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/subdd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/subsd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/subtd3.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/truncddsd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/trunctddd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/trunctdsd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/unorddd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/unordsd2.S: New file. * sysdeps/powerpc/powerpc64/power6/fpu/unordtd2.S: New file. * sysdeps/powerpc/powerpc64/power6x/fpu/Implies: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/fpu/Implies: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/fpu/Implies: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/fpu/Implies: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/fpu/Implies: New file. 2006-12-21 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/dfp/stdio-common/vfprintf.c: added comments to indicate that var_arg promotion should not be used for _Decimal values. ------------------------------------------------------------------------ r254 | jkerian | 2006-12-20 15:57:20 -0600 (Wed, 20 Dec 2006) | 14 lines 2006-12-20 Joseph Kerian jkerian@us.ibm.com * ieee754r/d32/ldexpd32.c: Changing ldexp implementation to match frexp * ieee754r/d32/atan2d32.c: Fixed numerous test case failures * ieee754r/dfpmacro.h: Cleaning up, commenting, adding DFP_ESPILON and DFP_MIN * ieee754r/d32/isnormald32.c: Using new DFP_MIN macro * ieee754r/d32/nexttowardd32.c: Using new DFP_EPSILON macro * ieee754r/d32/nextafterd32.c: Using new DFP_EPSILON macro * ieee754r/d32/nearbyintd32.c: Rewrote using dfpmacro.h macros * ieee754r/d64/nearbyintd64.c: Replaced with reference to d32 version * ieee754r/d128/nearbyintd128.c: Replaced with reference to d32 version ------------------------------------------------------------------------ r252 | jkerian | 2006-12-15 15:04:15 -0600 (Fri, 15 Dec 2006) | 5 lines 2006-12-15 Joseph Kerian jkerian@us.ibm.com * dfp/test/test-decimal.c: New file. Test cases for BFP<->DFP conversions ------------------------------------------------------------------------ r251 | jkerian | 2006-12-15 15:03:26 -0600 (Fri, 15 Dec 2006) | 25 lines 2006-12-15 Joseph Kerian jkerian@us.ibm.com * dfp/sysdeps/powerpc: New File. Handles conversions between DFP and BFP data types. * dfp/sysdeps/powerpc/truncxfdd.c: New File. * dfp/sysdeps/powerpc/extendsdsf.c: New File. * dfp/sysdeps/powerpc/extendsfsd.c: New File. * dfp/sysdeps/powerpc/extendsftd.c: New File. * dfp/sysdeps/powerpc/extenddfdd.c: New File. * dfp/sysdeps/powerpc/extendsdxf.c: New File. * dfp/sysdeps/powerpc/trunctdsf.c: New File. * dfp/sysdeps/powerpc/extendxftd.c: New File. * dfp/sysdeps/powerpc/truncdddf.c: New File. * dfp/sysdeps/powerpc/truncxfsd.c: New File. * dfp/sysdeps/powerpc/trunctdxf.c: New File. * dfp/sysdeps/powerpc/binpowof10.c: New File. * dfp/sysdeps/powerpc/decpowof2.c: New File. * dfp/sysdeps/powerpc/extendsfdd.c: New File. * dfp/sysdeps/powerpc/extendsddf.c: New File. * dfp/sysdeps/powerpc/extenddftd.c: New File. * dfp/sysdeps/powerpc/truncddsf.c: New File. * dfp/sysdeps/powerpc/truncdfsd.c: New File. * dfp/sysdeps/powerpc/trunctddf.c: New File. * dfp/sysdeps/powerpc/extendddxf.c: New File. ------------------------------------------------------------------------ r250 | ryanarn | 2006-12-14 18:41:19 -0600 (Thu, 14 Dec 2006) | 17 lines 2006-12-14 Ryan S. Arnold <rsa@us.ibm.com> * dfp/libdfp-test.inc: Updated to #ifndef tests which DFP doesn't support and to also macroize the rounding mode functions. * dfp/test-d32.c: Modified to fix PRINTF_XEXPR to print %e since we don't have hex printing of DFP values yet. * dfp/test-d64.c: _Decimal64 copy of dfp/test-d32.c * dfp/test-d128.c: _Decimal128 copy of dfp/test-d32.c * dfp/Makefile: Modified to build and run the test framework. This is currently commented out. * dfp/sysdeps/ieee754r/d32/lgammad32.c: Fixed a bug with the __lgamma_rd128 prototype in the __lgamma_rd* function. * dfp/libdfp-test-ulps: Added d128, d64, d32 ulps. * dfp/gen-libdfp-test.pl: Major modifications to allow macroization of floating point constants. Fixed a beautify bug as well. ------------------------------------------------------------------------ r248 | jkerian | 2006-12-07 11:23:23 -0600 (Thu, 07 Dec 2006) | 10 lines 2006-12-07 Joseph Kerian jkerian@us.ibm.com dfp/sysdeps/ieee754r/d32/roundd32.c: Code is now generic to round/rint dfp/sysdeps/ieee754r/d32/llroundd32.c: Code is now generic to l[l]round/rint dfp/sysdeps/ieee754r/d32/ilogbd32.c: Fixed errno conditionals, minor fixups dfp/sysdeps/ieee754r/d32/rintd32.c: Replaced with a #include roundd32.c dfp/sysdeps/ieee754r/d32/llrintd32.c: Replaced with a #include llroundd32.c dfp/sysdeps/ieee754r/d32/lrintd32.c: Replaced with a #include llroundd32.c dfp/sysdeps/ieee754r/d32/lroundd32.c: Replaced with a #include llroundd32.c ------------------------------------------------------------------------ r247 | jkerian | 2006-12-07 10:08:07 -0600 (Thu, 07 Dec 2006) | 6 lines 2006-12-07 Joseph Kerian jkerian@us.ibm.com * test/test_errno.c: Adding strerror() to the binary output * test/test_pow.c: Correcting a few test constants for DFP * test/test_set2a.c: Declaring fma external ------------------------------------------------------------------------ r246 | jkerian | 2006-12-06 16:30:13 -0600 (Wed, 06 Dec 2006) | 8 lines 2006-12-06 Joseph Kerian jkerian@us.ibm.com * sysdeps/ieee754r/d32/atanhd32.c: Added a comment explaining deviation from binary float (following C99) * sysdeps/ieee754r/d32/powd32.c: Reworked/Clarified logic, reimplemented errno wrapper. * test/test_pow.c: New File. Test cases for pow special cases ------------------------------------------------------------------------ r239 | jkerian | 2006-12-04 11:41:31 -0600 (Mon, 04 Dec 2006) | 18 lines 2006-12-04 Joseph Kerian jkerian@us.ibm.com * dfp/sysdeps/ieee754r/dfpmacro.h: Fixed error with _IEEE_LIBDFP macro declaration * dfp/sysdeps/ieee754r/d32/asind32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/acosd32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/expm1d32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/cosd32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/lrintd32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/nearbyintd32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/sinhd32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/tgammad32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/llroundd32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/lroundd32.c: Added errno.h include * dfp/sysdeps/ieee754r/d32/atand32.c: Added errno.h include, reformatting, removing unused errno.h include * dfp/sysdeps/ieee754r/d32/log10d32.c: Reformatting ------------------------------------------------------------------------ r238 | jkerian | 2006-12-01 12:43:05 -0600 (Fri, 01 Dec 2006) | 28 lines 2006-12-01 Joseph Kerian jkerian@us.ibm.com * dfp/sysdeps/ieee754r/d32/roundd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/scalbnd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/scalblnd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/logd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/sind32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/llrintd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/powd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/ldexpd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/log10d32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/lrintd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/nearbyintd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/lgammad32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/log2d32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/tgammad32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/rintd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/llroundd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/sqrtd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/nexttowardd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/nextafterd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/lroundd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/remainderd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/tand32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/log1pd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/logbd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/sinhd32.c: Minor re-ordering ------------------------------------------------------------------------ r237 | jkerian | 2006-11-30 17:35:58 -0600 (Thu, 30 Nov 2006) | 51 lines 2006-11-30 Joseph Kerian jkerian@us.ibm.com * dfp/decnumber/decNumberMath.c: Made some internal functions const to fix compile warnings * dfp/decnumber/decaddop.c: Added missing decNumberArith.h header * dfp/Makefile: Renamed isfinitedX->finitedX, removed remquo, comments * dfp/Versions: Removed remquo export * dfp/sysdeps/ieee754r/dfpmacro.h: Removed errno include from here. Added _IEEE_LIBDFP constant to indicate error behavior of math routines * dfp/sysdeps/ieee754r/d32/asinhd32.c: Removed errnos as written * dfp/sysdeps/ieee754r/d32/lrintd32.c: Commented out errno's, to fix soon * dfp/sysdeps/ieee754r/d32/llrintd32.c: Commented out errno's, to fix soon * dfp/sysdeps/ieee754r/d32/lroundd32.c: Commented out errno's, to fix soon * dfp/sysdeps/ieee754r/d32/llroundd32.c: Commented out errno's, to fix soon * dfp/sysdeps/ieee754r/d32/lgammad32.c: Commented out errno's, to fix soon * dfp/sysdeps/ieee754r/d32/log2d32.c: Commented out errno's, to fix soon * dfp/sysdeps/ieee754r/d32/logbd32.c: Commented out errno's, to fix soon * dfp/sysdeps/ieee754r/d32/sind32.c: Commented out errno's, to fix soon * dfp/sysdeps/ieee754r/d32/tgammad32.c: Commented out errno's, to fix soon * dfp/sysdeps/ieee754r/d32/acosd32.c: _IEEE_LIBM -> _IEEE_LIBDFP * dfp/sysdeps/ieee754r/d32/acoshd32.c: _IEEE_LIBM -> _IEEE_LIBDFP * dfp/sysdeps/ieee754r/d32/asind32.c: _IEEE_LIBM -> _IEEE_LIBDFP * dfp/sysdeps/ieee754r/d32/sinhd32.c: _IEEE_LIBM -> _IEEE_LIBDFP * dfp/sysdeps/ieee754r/d32/atan2d32.c: Removed unused errno header * dfp/sysdeps/ieee754r/d32/tand32.c: Removed unused errno header * dfp/sysdeps/ieee754r/d32/remainderd32.c: Removed unused errno header * dfp/sysdeps/ieee754r/d32/atanhd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/cosd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/coshd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/ilogbd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/exp2d32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/expd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/expm1d32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/fmad32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/fmodd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/fdimd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/hypotd32.c: Implemented errno wrapper * dfp/sysdeps/ieee754r/d32/floord32.c: Cleaned comments * dfp/sysdeps/ieee754r/d32/ceild32.c: Cleaned comments * dfp/sysdeps/ieee754r/d32/fabsd32.c: Cleaned formatting * dfp/sysdeps/ieee754r/d32/erfd32.c: Made function call references internal * dfp/sysdeps/ieee754r/d32/isfinited32.c: Renamed to finited32.c * dfp/sysdeps/ieee754r/d64/isfinited64.c: Renamed to finited64.c * dfp/sysdeps/ieee754r/d128/isfinited128.c: Renamed to finited128.c * dfp/sysdeps/ieee754r/d32/finited32.c: Renamed from isfinited32.c * dfp/sysdeps/ieee754r/d64/finited64.c: Renamed from isfinited64.c * dfp/sysdeps/ieee754r/d128/finited128.c: Renamed from isfinited128.c * dfp/sysdeps/ieee754r/d32/remquod32.c: Removed as per spec revision * dfp/sysdeps/ieee754r/d64/remquod64.c: Removed as per spec revision * dfp/sysdeps/ieee754r/d128/remquod128.c: Removed as per spec revision ------------------------------------------------------------------------ r236 | jkerian | 2006-11-30 13:20:48 -0600 (Thu, 30 Nov 2006) | 8 lines 2006-11-30 Joseph Kerian jkerian@us.ibm.com * test/test_isfinite.c: Updated for testing both the __finited64() * Versions: GLIBC2.4 -> GLIBC2.5 * Versions.def: GLIBC2.4 -> GLIBC2.5 * sysdeps/dfp/math/math.h: Updating for isfinite() polymorphic macro resolving to __finited*() when needed, instead of isfinited64 ------------------------------------------------------------------------ r235 | jkerian | 2006-11-30 11:37:19 -0600 (Thu, 30 Nov 2006) | 12 lines 2006-11-30 Joseph Kerian jkerian@us.ibm.com * sysdeps/dfp/math/math.h: Fixed #define HUGE_VAL_D128 * sysdeps/ieee754r/dfpmacro.h: Cleaned up error handling macros * sysdeps/ieee754r/d32/isfinited32.c: isfinite -> __finite * sysdeps/ieee754r/d32/asind32.c: created errno wrapper * sysdeps/ieee754r/d32/acosd32.c: created errno wrapper * sysdeps/ieee754r/d32/cbrtd32.c: created errno wrapper * sysdeps/ieee754r/d32/acoshd32.c: created errno wrapper * sysdeps/ieee754r/d32/sinhd32.c: created errno wrapper * Versions: Corrected for isfinite->__finite change ------------------------------------------------------------------------ r234 | jkerian | 2006-11-28 13:25:47 -0600 (Tue, 28 Nov 2006) | 7 lines 2006-11-28 Joseph Kerian jkerian@us.ibm.com * ieee754r/d32/llrintd32.c: Formatting * ieee754r/d32/lrintd32.c: Formatting * ieee754r/d32/llroundd32.c: Formatting * ieee754r/d32/lroundd32.c: Formatting ------------------------------------------------------------------------ r233 | jkerian | 2006-11-22 14:28:26 -0600 (Wed, 22 Nov 2006) | 6 lines 2006-11-22 Joseph Kerian jkerian@us.ibm.com * test/test_set2a.c: Added another testcase for frexp * sysdeps/ieee754r/d32/frexpd32.c: Much simpler implementation that takes advantage of the decNumber format. ------------------------------------------------------------------------ r231 | jkerian | 2006-11-22 11:40:37 -0600 (Wed, 22 Nov 2006) | 4 lines 2006-11-22 Joseph Kerian jkerian@us.ibm.com * test/test_set2a.c: Updated test cases for frexp, and removing remquo ------------------------------------------------------------------------ r230 | jkerian | 2006-11-22 11:28:13 -0600 (Wed, 22 Nov 2006) | 6 lines 2006-11-22 Joseph Kerian jkerian@us.ibm.com * d32/frexpd32.c (__frexpd32): Correcting my misunderstanding of the latest TR. Previously, x was returned in the range [1.0,10.0), it was supposed to be restricted to [0.1,1.0) (a normalized fraction), and the returned integer is to be a power of 10. ------------------------------------------------------------------------ r228 | jkerian | 2006-11-16 14:34:15 -0600 (Thu, 16 Nov 2006) | 8 lines 2006-11-16 Joseph Kerian jkerian@us.ibm.com * dfp/sysdeps/ieee754r/d32/frexpd32.c: Fixed frexp to align with the newest spec revision (old version was bad anyway) * dfp/test/test_math.h: Added test macro for _Dec func(_Dec, int*) pattern * dfp/test/test_set2a.c: Added frexp test using the above pattern ------------------------------------------------------------------------ r227 | jkerian | 2006-11-10 17:47:14 -0600 (Fri, 10 Nov 2006) | 5 lines 2006-11-10 Joseph Kerian jkerian@us.ibm.com * Implemented Pole and Domain exception detection in most of the ieee754 functions ------------------------------------------------------------------------ r226 | jkerian | 2006-11-03 11:57:03 -0600 (Fri, 03 Nov 2006) | 4 lines 2006-11-03 Joseph Kerian jkerian@us.ibm.com * ieee754r/dfpmacro.h (DFP_EXCEPT macro): Added parens to fix warning ------------------------------------------------------------------------ r225 | jkerian | 2006-11-03 11:39:11 -0600 (Fri, 03 Nov 2006) | 10 lines 2006-11-03 Joseph Kerian jkerian@us.ibm.com * dfp/sysdeps/ieee754r/dfpmacro.h: Added exception display macros * dfp/sysdeps/ieee754r/d32/sind32.c: Added floating point exceptions * dfp/sysdeps/ieee754r/d32/cosd32.c: same * dfp/sysdeps/ieee754r/d32/tand32.c: same * dfp/sysdeps/ieee754r/d32/floord32.c: reformat * dfp/sysdeps/ieee754r/d32/copysignd32.c: reformat * dfp/sysdeps/ieee754r/d32/ceild32.c: reformat ------------------------------------------------------------------------ r222 | ryanarn | 2006-10-26 09:48:44 -0500 (Thu, 26 Oct 2006) | 4 lines 2006-10-26 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_fpclassify.c: Fixed declarations of DEC_NAN and DEC_INFINITY. Compile with -std=gnu99. ------------------------------------------------------------------------ r221 | jkerian | 2006-10-25 11:17:59 -0500 (Wed, 25 Oct 2006) | 26 lines 2006-10-25 Joseph Kerian jkerian@us.ibm.com * dfp/sysdeps/ieee754r/d32/asind32.c: Avoiding an odd logic error in the original glibc code (which may not happen for binary float) * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c: Switching to the FUNC_D macro for calling the external function. * dfp/sysdeps/ieee754r/d32/erfd32.c: Switching to FUNC_D and correcting a pre-initialization usage of a local variable. * dfp/sysdeps/ieee754r/d32/cbrtd32.c: Adding an extern FUNC_D * dfp/sysdeps/ieee754r/d32/lgammad32.c: Adding an extern declaration of lgamma_rd128 for all lgamma calls (before using it). * dfp/sysdeps/ieee754r/d32/roundd32.c: Fixing includes to avoid implicit declaration warnings * dfp/sysdeps/ieee754r/d32/ilogbd32.c: same * dfp/sysdeps/ieee754r/d32/fmad32.c: same * dfp/sysdeps/ieee754r/d32/llrintd32.c: same * dfp/sysdeps/ieee754r/d32/lrintd32.c: same * dfp/sysdeps/ieee754r/d32/nearbyintd32.c: same * dfp/sysdeps/ieee754r/d32/atanhd32.c: same * dfp/sysdeps/ieee754r/d32/atan2d32.c: same * dfp/sysdeps/ieee754r/d32/rintd32.c: same * dfp/sysdeps/ieee754r/d32/llroundd32.c: same * dfp/sysdeps/ieee754r/d32/lroundd32.c: same * dfp/sysdeps/ieee754r/d32/remainderd32.c: same * dfp/sysdeps/ieee754r/d32/logbd32.c: same ------------------------------------------------------------------------ r220 | jkerian | 2006-10-24 11:35:00 -0500 (Tue, 24 Oct 2006) | 14 lines 2006-10-24 Joseph Kerian <jkerian@us.ibm.com> * dfp/Makefile: Added build instructions for fma and cbrt * dfp/Versions: Added exports for fma and cbrt * dfp/test/test_math.h: Added 3 argument version of TEST_all * dfp/test/test_set2a.c: Added tests for cbrt and fma * dfp/sysdeps/ieee754r/d32/fmad32.c: New File, fma implementation * dfp/sysdeps/ieee754r/d32/cbrtd32.c: New File, cbrt implementation * dfp/sysdeps/ieee754r/d64/fmad64.c: New File * dfp/sysdeps/ieee754r/d64/cbrtd64.c: New File * dfp/sysdeps/ieee754r/d128/cbrtd128.c: New File * dfp/sysdeps/ieee754r/d128/fmad128.c: New File * dfp/sysdeps/ieee754r/d32/frexpd32.c: Whitespace correction ------------------------------------------------------------------------ r219 | jkerian | 2006-10-23 17:12:03 -0500 (Mon, 23 Oct 2006) | 16 lines 2006-10-23 Joseph Kerian jkerian@us.ibm.com * dfp/sysdeps/ieee754r/d32/remainderd32.c: Correcting whitespace * dfp/Makefile: Added build instructions for fmod,hypot and remquo * dfp/Versions: Added export instructions for fmod,hypot and remquo * dfp/test/test_set2a.c: Added testcases for fmod,hypot and remquo * dfp/sysdeps/ieee754r/d32/fmodd32.c: New file. fmod implementation * dfp/sysdeps/ieee754r/d32/hypotd32.c: New file. hypot implementation * dfp/sysdeps/ieee754r/d32/remquod32.c: New file. remquo implementation * dfp/sysdeps/ieee754r/d64/remquod64.c: New file. _Decimal64 wrapper * dfp/sysdeps/ieee754r/d64/fmodd64.c: New file. _Decimal64 wrapper * dfp/sysdeps/ieee754r/d64/hypotd64.c: New file. _Decimal64 wrapper * dfp/sysdeps/ieee754r/d128/hypotd128.c: New file. _Decimal128 wrapper * dfp/sysdeps/ieee754r/d128/fmodd128.c: New file. _Decimal128 wrapper * dfp/sysdeps/ieee754r/d128/remquod128.c: New file. _Decimal128 wrapper ------------------------------------------------------------------------ r218 | jkerian | 2006-10-19 13:20:52 -0500 (Thu, 19 Oct 2006) | 23 lines 2006-10-19 Joseph Kerian jkerian@us.ibm.com * dfp/Makefile: Added build instructions for expm1,log2,exp2,log1p * dfp/Versions: Added export instructions for the above * dfp/test/test_math.h: Spelling corrections, typecasting special values * dfp/test/test_set2.c: Added declarations to avoid an odd segfault * dfp/test/test_set2a.c: This is the basic testcase file for set2a. New File. * dfp/test/test_fabsd.c: Simple testcase modification * dfp/sysdeps/ieee754r/dfpmacro.h: Added a macro to help generating constants. * dfp/sysdeps/ieee754r/d32/expm1d32.c: New file. Exponent(x)-1 impl. * dfp/sysdeps/ieee754r/d32/log2d32.c: New file. log-base-2 implementation * dfp/sysdeps/ieee754r/d32/exp2d32.c: New file. 2**x implementation * dfp/sysdeps/ieee754r/d32/log1pd32.c: New file. log of x+1 implementation * dfp/sysdeps/ieee754r/d64/exp2d64.c: New File. 64bit wrapper * dfp/sysdeps/ieee754r/d64/log1pd64.c: New File. 64bit wrapper * dfp/sysdeps/ieee754r/d64/expm1d64.c: New File. 64bit wrapper * dfp/sysdeps/ieee754r/d64/log2d64.c: New File. 64bit wrapper * dfp/sysdeps/ieee754r/d128/log2d128.c: New File. 128bit wrapper * dfp/sysdeps/ieee754r/d128/exp2d128.c: New File. 128bit wrapper * dfp/sysdeps/ieee754r/d128/log1pd128.c: New File. 128bit wrapper * dfp/sysdeps/ieee754r/d128/expm1d128.c: New File. 128bit wrapper ------------------------------------------------------------------------ r217 | ryanarn | 2006-10-16 16:49:02 -0500 (Mon, 16 Oct 2006) | 5 lines 2006-10-16 Ryan S. Arnold <rsa@us.ibm.com> * All IBM contributed .c files.: Changed License Text ------------------------------------------------------------------------ r216 | ryanarn | 2006-10-16 12:41:10 -0500 (Mon, 16 Oct 2006) | 6 lines 2006-10-16 Ryan S. Arnold <rsa@us.ibm.com> * dfp/legal/files.txt: Updated list * dfp/sysdeps/ieee754r/d128/erfd128.c: Fixed errant copyright. ------------------------------------------------------------------------ r215 | ryanarn | 2006-10-16 11:32:19 -0500 (Mon, 16 Oct 2006) | 7 lines 2006-10-16 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test-d32.c: Started working on test framework. * dfp/sysdeps/ieee754r/d32/lgammad32.c: Copyright adjustment. * dfp/sysdeps/ieee754r/d32/erfd32.c: Same as previous ------------------------------------------------------------------------ r214 | jkerian | 2006-10-16 11:16:04 -0500 (Mon, 16 Oct 2006) | 14 lines 2006-10-16 Joseph Kerian jkerian@us.ibm.com * dfp/legal/files.txt: Modified for the following files * dfp/sysdeps/ieee754r/d32/tgammad32.c: Corrected copyright * dfp/sysdeps/ieee754r/d32/remainderd32.c: Corrected copyright * dfp/sysdeps/ieee754r/d64/remainderd64.c: Corrected copyright * dfp/sysdeps/ieee754r/d64/lgammad64.c: Corrected copyright * dfp/sysdeps/ieee754r/d64/tgammad64.c: Corrected copyright * dfp/sysdeps/ieee754r/d64/erfd64.c: Corrected copyright * dfp/sysdeps/ieee754r/d128/tgammad128.c: Corrected copyright * dfp/sysdeps/ieee754r/d128/erfd128.c: Corrected copyright * dfp/sysdeps/ieee754r/d128/remainderd128.c: Corrected copyright * dfp/sysdeps/ieee754r/d128/lgammad128.c: Corrected copyright ------------------------------------------------------------------------ r213 | jkerian | 2006-10-16 10:29:29 -0500 (Mon, 16 Oct 2006) | 36 lines 2006-10-16 Joseph Kerian jkerian@us.ibm.com * dfp/Makefile: Modified to build new functions * dfp/Versions: Modified to export new functions * dfp/test/test_math.h: Corrected some NaN handling in the test macros * dfp/test/test_set2.c: New File. Test functions for set2 * dfp/test/test_arctrig.c: Added test for nan malfunctions * dfp/sysdeps/ieee754r/dfpmacro.h: Simplify macros. Add FUNC_D * dfp/sysdeps/ieee754r/d32/asind32.c: Added comments, removed superfluous casting. * dfp/sysdeps/ieee754r/d32/atanhd32.c: Corrected formatting * dfp/sysdeps/ieee754r/d32/acoshd32.c: Corrected formatting * dfp/sysdeps/ieee754r/d32/asinhd32.c: Corrected formatting * dfp/sysdeps/ieee754r/d32/atan2d32.c: Corrected formatting * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c: Modified to use FUNC_D macro * dfp/sysdeps/ieee754r/d32/acosd32.c: Modified to use FUNC_D macro * dfp/sysdeps/ieee754r/d32/isnormald32.c: Corrected formatting * dfp/sysdeps/ieee754r/d32/tgammad32.c: New File. tgamma implementation * dfp/sysdeps/ieee754r/d32/lgammad32.c: New File. lgamma implementation (copied from glibc binary version for 128 bit) * dfp/sysdeps/ieee754r/d32/erfd32.c: New File. erf and erfc implementation (copied from glibc binary version for 128 bit) * dfp/sysdeps/ieee754r/d32/remainderd32.c: New File. remainder implementation (copied from glibc binary version for 128 bit) * dfp/sysdeps/ieee754r/d64/remainderd64.c: New File. * dfp/sysdeps/ieee754r/d64/lgammad64.c: New File. * dfp/sysdeps/ieee754r/d64/tgammad64.c: New File. * dfp/sysdeps/ieee754r/d64/erfd64.c: New File. * dfp/sysdeps/ieee754r/d128/tgammad128.c: New File. * dfp/sysdeps/ieee754r/d128/erfd128.c: New File. * dfp/sysdeps/ieee754r/d128/remainderd128.c: New File. * dfp/sysdeps/ieee754r/d128/lgammad128.c: New File. ------------------------------------------------------------------------ r212 | eberlein | 2006-10-13 17:55:42 -0500 (Fri, 13 Oct 2006) | 4 lines * Makefile: added targets for atanh and atan2 * Versions: added symbols for atanh and atan2 ------------------------------------------------------------------------ r211 | ryanarn | 2006-10-13 16:51:12 -0500 (Fri, 13 Oct 2006) | 7 lines 2006-10-13 Ryan S. Arnold <rsa@us.ibm.com> * dfp/legal/files.txt: Fixed copyright, license, and authorship of dfptypeconv.c to reflect Eberlein's clean room implementation. * dfp/dfptypeconv.c: Fixed prototypes to add triple underscore. Fixed * #if IS_IN_libc, etc to fix internal prototypes. ------------------------------------------------------------------------ r210 | eberlein | 2006-10-12 17:58:47 -0500 (Thu, 12 Oct 2006) | 4 lines * dfptypeconv.c: Rewritten as a clean-room implementation. * dfptypeconv.h: Removed reference to GCC in comments. ------------------------------------------------------------------------ r208 | ryanarn | 2006-10-12 10:20:12 -0500 (Thu, 12 Oct 2006) | 4 lines 2006-10-12 Ryan S. Arnold <rsa@us.ibm.com> * dfp/COPYING.txt: New file with LGPL v2.1 license message ------------------------------------------------------------------------ r207 | ryanarn | 2006-10-12 10:19:21 -0500 (Thu, 12 Oct 2006) | 230 lines 2006-10-12 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/dfp/dfpfloat.h: Removed this unnecessary file. * dfp/legal/authors/Pete: Added a blank line following author. * dfp/legal/files.txt: Updated list. * dfp/legal/legal.pl: Fixed script issues. * dfp/decimal128.h: Changed license/copyright (same for remaining files). * dfp/decimal32.c * dfp/decNumberUtilities.h * dfp/decimal32.h * dfp/deccommon.h * dfp/decNumber.h * dfp/decUtility.c * dfp/decquantize.h * dfp/decstring.c * dfp/decnumber/decNumberMath.c * dfp/decnumber/decNumberUtilities.c * dfp/decnumber/decContext.c * dfp/decnumber/decintegral.c * dfp/decnumber/decquantize.h * dfp/decnumber/decimal64_local.c * dfp/decnumber/decaddop.c * dfp/decnumber/decimal128_local.c * dfp/decnumber/deccommon.c * dfp/decnumber/decintegral.h * dfp/decnumber/decaddop.h * dfp/decnumber/decNumberArith.c * dfp/decnumber/decquantize.c * dfp/decnumber/decimal32_local.c * dfp/decUtility.h * dfp/decNumberLocal.h * dfp/decsharedcommon.c * dfp/dfptypeconv.c * dfp/decNumberArith.h * dfp/decContext.h * dfp/dfptypeconv.h * dfp/decimal64.c * dfp/sysdeps/dfp/stdlib/wcstod128.c * dfp/sysdeps/dfp/stdlib/dfpstdlib.h * dfp/sysdeps/dfp/stdlib/strtod32.c * dfp/sysdeps/dfp/stdlib/wcstod32.c * dfp/sysdeps/dfp/stdlib/strtod64.c * dfp/sysdeps/dfp/stdlib/strtod128.c * dfp/sysdeps/dfp/stdlib/wcstod64.c * dfp/sysdeps/dfp/printf_dfp.h * dfp/sysdeps/dfp/printf_dfphex.c * dfp/sysdeps/dfp/dfpwchar.h * dfp/sysdeps/dfp/printf_dfp.c * dfp/sysdeps/ieee754r/d32/modfd32.c * dfp/sysdeps/ieee754r/d32/roundd32.c * dfp/sysdeps/ieee754r/d32/lrintd32.c * dfp/sysdeps/ieee754r/d32/fmind32.c * dfp/sysdeps/ieee754r/d32/tanhd32.c * dfp/sysdeps/ieee754r/d32/nearbyintd32.c * dfp/sysdeps/ieee754r/d32/copysignd32.c * dfp/sysdeps/ieee754r/d32/fmaxd32.c * dfp/sysdeps/ieee754r/d32/atanhd32.c * dfp/sysdeps/ieee754r/d32/coshd32.c * dfp/sysdeps/ieee754r/d32/ilogbd32.c * dfp/sysdeps/ieee754r/d32/acoshd32.c * dfp/sysdeps/ieee754r/d32/quantized32.c * dfp/sysdeps/ieee754r/d32/samequantumd32.c * dfp/sysdeps/ieee754r/d32/sinhd32.c * dfp/sysdeps/ieee754r/d32/asinhd32.c * dfp/sysdeps/ieee754r/d32/scalbnd32.c * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c * dfp/sysdeps/ieee754r/d32/atan2d32.c * dfp/sysdeps/ieee754r/d32/isinfd32.c * dfp/sysdeps/ieee754r/d32/isfinited32.c * dfp/sysdeps/ieee754r/d32/fabsd32.c * dfp/sysdeps/ieee754r/d32/rintd32.c * dfp/sysdeps/ieee754r/d32/scalblnd32.c * dfp/sysdeps/ieee754r/d32/llroundd32.c * dfp/sysdeps/ieee754r/d32/logd32.c * dfp/sysdeps/ieee754r/d32/atand32.c * dfp/sysdeps/ieee754r/d32/isgreaterd32.c * dfp/sysdeps/ieee754r/d32/sind32.c * dfp/sysdeps/ieee754r/d32/sqrtd32.c * dfp/sysdeps/ieee754r/d32/islessequald32.c * dfp/sysdeps/ieee754r/d32/truncd32.c * dfp/sysdeps/ieee754r/d32/expd32.c * dfp/sysdeps/ieee754r/d32/nexttowardd32.c * dfp/sysdeps/ieee754r/d32/signbitd32.c * dfp/sysdeps/ieee754r/d32/nextafterd32.c * dfp/sysdeps/ieee754r/d32/islessd32.c * dfp/sysdeps/ieee754r/d32/lroundd32.c * dfp/sysdeps/ieee754r/d32/llrintd32.c * dfp/sysdeps/ieee754r/d32/powd32.c * dfp/sysdeps/ieee754r/d32/isnand32.c * dfp/sysdeps/ieee754r/d32/ceild32.c * dfp/sysdeps/ieee754r/d32/islessgreaterd32.c * dfp/sysdeps/ieee754r/d32/nand32.c * dfp/sysdeps/ieee754r/d32/ldexpd32.c * dfp/sysdeps/ieee754r/d32/isgreaterequald32.c * dfp/sysdeps/ieee754r/d32/fdimd32.c * dfp/sysdeps/ieee754r/d32/floord32.c * dfp/sysdeps/ieee754r/d32/tand32.c * dfp/sysdeps/ieee754r/d32/log10d32.c * dfp/sysdeps/ieee754r/d32/isunorderedd32.c * dfp/sysdeps/ieee754r/d32/logbd32.c * dfp/sysdeps/ieee754r/d32/isnormald32.c * dfp/sysdeps/ieee754r/d32/cosd32.c * dfp/sysdeps/ieee754r/d32/frexpd32.c * dfp/sysdeps/ieee754r/d64/logd64.c * dfp/sysdeps/ieee754r/d64/atand64.c * dfp/sysdeps/ieee754r/d64/isgreaterd64.c * dfp/sysdeps/ieee754r/d64/acosd64.c * dfp/sysdeps/ieee754r/d64/sqrtd64.c * dfp/sysdeps/ieee754r/d64/sind64.c * dfp/sysdeps/ieee754r/d64/islessequald64.c * dfp/sysdeps/ieee754r/d64/truncd64.c * dfp/sysdeps/ieee754r/d64/expd64.c * dfp/sysdeps/ieee754r/d64/signbitd64.c * dfp/sysdeps/ieee754r/d64/nexttowardd64.c * dfp/sysdeps/ieee754r/d64/nextafterd64.c * dfp/sysdeps/ieee754r/d64/islessd64.c * dfp/sysdeps/ieee754r/d64/lroundd64.c * dfp/sysdeps/ieee754r/d64/llrintd64.c * dfp/sysdeps/ieee754r/d64/powd64.c * dfp/sysdeps/ieee754r/d64/isnand64.c * dfp/sysdeps/ieee754r/d64/islessgreaterd64.c * dfp/sysdeps/ieee754r/d64/ceild64.c * dfp/sysdeps/ieee754r/d64/nand64.c * dfp/sysdeps/ieee754r/d64/ldexpd64.c * dfp/sysdeps/ieee754r/d64/isgreaterequald64.c * dfp/sysdeps/ieee754r/d64/fdimd64.c * dfp/sysdeps/ieee754r/d64/floord64.c * dfp/sysdeps/ieee754r/d64/tand64.c * dfp/sysdeps/ieee754r/d64/log10d64.c * dfp/sysdeps/ieee754r/d64/isunorderedd64.c * dfp/sysdeps/ieee754r/d64/logbd64.c * dfp/sysdeps/ieee754r/d64/cosd64.c * dfp/sysdeps/ieee754r/d64/isnormald64.c * dfp/sysdeps/ieee754r/d64/frexpd64.c * dfp/sysdeps/ieee754r/d64/modfd64.c * dfp/sysdeps/ieee754r/d64/roundd64.c * dfp/sysdeps/ieee754r/d64/lrintd64.c * dfp/sysdeps/ieee754r/d64/fmind64.c * dfp/sysdeps/ieee754r/d64/tanhd64.c * dfp/sysdeps/ieee754r/d64/asind64.c * dfp/sysdeps/ieee754r/d64/fmaxd64.c * dfp/sysdeps/ieee754r/d64/copysignd64.c * dfp/sysdeps/ieee754r/d64/nearbyintd64.c * dfp/sysdeps/ieee754r/d64/atanhd64.c * dfp/sysdeps/ieee754r/d64/coshd64.c * dfp/sysdeps/ieee754r/d64/ilogbd64.c * dfp/sysdeps/ieee754r/d64/acoshd64.c * dfp/sysdeps/ieee754r/d64/quantized64.c * dfp/sysdeps/ieee754r/d64/samequantumd64.c * dfp/sysdeps/ieee754r/d64/sinhd64.c * dfp/sysdeps/ieee754r/d64/asinhd64.c * dfp/sysdeps/ieee754r/d64/scalbnd64.c * dfp/sysdeps/ieee754r/d64/fpclassifyd64.c * dfp/sysdeps/ieee754r/d64/atan2d64.c * dfp/sysdeps/ieee754r/d64/isinfd64.c * dfp/sysdeps/ieee754r/d64/isfinited64.c * dfp/sysdeps/ieee754r/d64/fabsd64.c * dfp/sysdeps/ieee754r/d64/rintd64.c * dfp/sysdeps/ieee754r/d64/scalblnd64.c * dfp/sysdeps/ieee754r/d64/llroundd64.c * dfp/sysdeps/ieee754r/d128/signbitd128.c * dfp/sysdeps/ieee754r/d128/nexttowardd128.c * dfp/sysdeps/ieee754r/d128/quantized128.c * dfp/sysdeps/ieee754r/d128/samequantumd128.c * dfp/sysdeps/ieee754r/d128/asinhd128.c * dfp/sysdeps/ieee754r/d128/scalbnd128.c * dfp/sysdeps/ieee754r/d128/lroundd128.c * dfp/sysdeps/ieee754r/d128/powd128.c * dfp/sysdeps/ieee754r/d128/isinfd128.c * dfp/sysdeps/ieee754r/d128/isfinited128.c * dfp/sysdeps/ieee754r/d128/rintd128.c * dfp/sysdeps/ieee754r/d128/isgreaterequald128.c * dfp/sysdeps/ieee754r/d128/scalblnd128.c * dfp/sysdeps/ieee754r/d128/fdimd128.c * dfp/sysdeps/ieee754r/d128/floord128.c * dfp/sysdeps/ieee754r/d128/isunorderedd128.c * dfp/sysdeps/ieee754r/d128/logbd128.c * dfp/sysdeps/ieee754r/d128/modfd128.c * dfp/sysdeps/ieee754r/d128/roundd128.c * dfp/sysdeps/ieee754r/d128/fmind128.c * dfp/sysdeps/ieee754r/d128/islessequald128.c * dfp/sysdeps/ieee754r/d128/atanhd128.c * dfp/sysdeps/ieee754r/d128/nearbyintd128.c * dfp/sysdeps/ieee754r/d128/copysignd128.c * dfp/sysdeps/ieee754r/d128/fmaxd128.c * dfp/sysdeps/ieee754r/d128/expd128.c * dfp/sysdeps/ieee754r/d128/acoshd128.c * dfp/sysdeps/ieee754r/d128/nextafterd128.c * dfp/sysdeps/ieee754r/d128/sinhd128.c * dfp/sysdeps/ieee754r/d128/islessd128.c * dfp/sysdeps/ieee754r/d128/fpclassifyd128.c * dfp/sysdeps/ieee754r/d128/llrintd128.c * dfp/sysdeps/ieee754r/d128/atan2d128.c * dfp/sysdeps/ieee754r/d128/isnand128.c * dfp/sysdeps/ieee754r/d128/fabsd128.c * dfp/sysdeps/ieee754r/d128/islessgreaterd128.c * dfp/sysdeps/ieee754r/d128/ceild128.c * dfp/sysdeps/ieee754r/d128/nand128.c * dfp/sysdeps/ieee754r/d128/ldexpd128.c * dfp/sysdeps/ieee754r/d128/llroundd128.c * dfp/sysdeps/ieee754r/d128/logd128.c * dfp/sysdeps/ieee754r/d128/tand128.c * dfp/sysdeps/ieee754r/d128/log10d128.c * dfp/sysdeps/ieee754r/d128/atand128.c * dfp/sysdeps/ieee754r/d128/cosd128.c * dfp/sysdeps/ieee754r/d128/isnormald128.c * dfp/sysdeps/ieee754r/d128/frexpd128.c * dfp/sysdeps/ieee754r/d128/isgreaterd128.c * dfp/sysdeps/ieee754r/d128/acosd128.c * dfp/sysdeps/ieee754r/d128/lrintd128.c * dfp/sysdeps/ieee754r/d128/sqrtd128.c * dfp/sysdeps/ieee754r/d128/sind128.c * dfp/sysdeps/ieee754r/d128/tanhd128.c * dfp/sysdeps/ieee754r/d128/asind128.c * dfp/sysdeps/ieee754r/d128/truncd128.c * dfp/sysdeps/ieee754r/d128/coshd128.c * dfp/sysdeps/ieee754r/d128/ilogbd128.c * dfp/fe_decround.c * dfp/decimal64.h * dfp/fmt_dfp.c * dfp/bits/dfpcalls.h * dfp/bits/dfpfenv.h * dfp/decNumberMath.h * dfp/fmt_dfp.h * dfp/dfpfenv_private.h * dfp/decDPD.h * dfp/decimal128.c ------------------------------------------------------------------------ r206 | ryanarn | 2006-10-11 17:12:11 -0500 (Wed, 11 Oct 2006) | 2 lines o Updated script ------------------------------------------------------------------------ r205 | ryanarn | 2006-10-11 16:33:42 -0500 (Wed, 11 Oct 2006) | 70 lines 2006-10-11 Ryan S. Arnold <rsa@us.ibm.com> * dfp/legal: script to change license/copyright information * dfp/legal/files.txt * dfp/legal/acton.txt * dfp/legal/licenses * dfp/legal/licenses/LGPLv2-GCC * dfp/legal/licenses/GPL * dfp/legal/licenses/LGPLv2.1-glibc * dfp/legal/licenses/LGPLv2.1 * dfp/legal/licenses/GPLwithEx * dfp/legal/authors * dfp/legal/authors/Mike * dfp/legal/authors/dettinger * dfp/legal/authors/Ryan * dfp/legal/authors/RyanandJoe * dfp/legal/authors/PeteAndJoeAndRyan * dfp/legal/authors/Joe * dfp/legal/authors/Pete * dfp/legal/authors/PeteAndJoe * dfp/legal/test.pl * dfp/legal/copyrights * dfp/legal/copyrights/FSF2006-glibc * dfp/legal/copyrights/FSF1997-1999-2000-2006 * dfp/legal/copyrights/FSF-1997-1998-2002-2004-2006 * dfp/legal/copyrights/FSF2006 * dfp/legal/copyrights/IBM * dfp/legal/copyrights/FSF-gcc * dfp/legal/copyrights/FSF-1991-1993-1995-1999-2001-2002-2004-2006 * dfp/legal/copyrights/FSF1996-2006-glibc * dfp/legal/copyrights/FSF2005-2006 * dfp/legal/copyrights/FSF-1991-2003,2004,2005,2006 * dfp/legal/copyrights/FSF-1996-2002-2003-2006 * dfp/legal/contributors * dfp/legal/contributors/IBM * dfp/legal/contributors/Joe * dfp/legal/legal.pl * dfp/legal/basedons * dfp/legal/basedons/Ulrich-strtod * dfp/legal/basedons/libgcc * dfp/legal/basedons/printf_fp * dfp/legal/basedons/mathcalls * dfp/legal/basedons/gcc-decLibrary * dfp/legal/basedons/Joe * dfp/legal/basedons/fenv * dfp/decstring.c: Modified copyright/license/author info. * dfp/decnumber/decNumberMath.c: Modified copyright/license/author info. * dfp/decnumber/decimal64_local.c: Modified copyright/license/author info. * dfp/decnumber/decimal128_local.c: Modified copyright/license/author info. * dfp/test/README: Fixed script to remove .exe file extension requirement. * dfp/decNumberArith.h: Modified copyright/license/author info. * dfp/sysdeps/dfp/stdlib/dfpstdlib.h: Modified copyright/license/author info. * dfp/sysdeps/dfp/dfpwchar.h: Modified copyright/license/author info. * dfp/sysdeps/dfp/printf_dfp.c: Modified copyright/license/author info. * dfp/sysdeps/ieee754r/dfpmath_private.h: Modified copyright/license/author info. * dfp/fmt_dfp.c: Modified copyright/license/author info. * dfp/bits/dfpcalls.h: Modified copyright/license/author info. * dfp/bits/dfpfenv.h: Modified copyright/license/author info. * dfp/decNumberMath.h: Modified copyright/license/author info. * dfp/fmt_dfp.h: Modified copyright/license/author info. * dfp/dfpfenv_private.h: Modified copyright/license/author info. * dfp/decimal128.c: Modified copyright/license/author info. ------------------------------------------------------------------------ r204 | eberlein | 2006-10-10 14:51:28 -0500 (Tue, 10 Oct 2006) | 2 lines * test/test_errno.c: Added tests for atanh and atan2. ------------------------------------------------------------------------ r203 | eberlein | 2006-10-10 14:50:45 -0500 (Tue, 10 Oct 2006) | 8 lines * sysdeps/ieee754r/d128/atan2d128.c: Created. * sysdeps/ieee754r/d32/atan2d32.c: Created. * sysdeps/ieee754r/d64/atan2d64.c: Created. * sysdeps/ieee754r/d128/atanhd128.c: Created. * sysdeps/ieee754r/d32/atanhd32.c: Created. * sysdeps/ieee754r/d64/atanhd64.c: Created. ------------------------------------------------------------------------ r202 | ryanarn | 2006-10-10 10:04:28 -0500 (Tue, 10 Oct 2006) | 20 lines 2006-10-10 Ryan S. Arnold <rsa@us.ibm.com> * dfp/decnumber/decNumberMath.c: Fixed some header comments. * dfp/decnumber/decintegral.c: same * dfp/decnumber/decimal64_local.c: same * dfp/decnumber/decimal128_local.c: same * dfp/decnumber/decintegral.h: same * dfp/test/README: stripped .c from output file name to remove .exe requirement. * dfp/decContext.h: same * dfp/sysdeps/dfp/stdlib/dfpstdlib.h: same * dfp/sysdeps/dfp/printf_dfp.h: same * dfp/sysdeps/dfp/printf_dfphex.c: same * dfp/sysdeps/dfp/dfpwchar.h: same * dfp/sysdeps/dfp/dfpfloat.h: same * dfp/sysdeps/dfp/math/fenv.h: same * dfp/sysdeps/dfp/printf_dfp.c: same * dfp/fmt_dfp.c: same * dfp/fmt_dfp.h: same ------------------------------------------------------------------------ r198 | jkerian | 2006-10-04 17:24:21 -0500 (Wed, 04 Oct 2006) | 15 lines 2006-10-04 Joseph Kerian jkerian@us.ibm.com * dfp/Makefile: Added build directives for asin and acos * dfp/Versions: Added export directives for asin and acos * dfp/test/test_set1a.c: Modified formatting * dfp/test/test_arctrig.c: New file. Test cases for asin and acos * dfp/sysdeps/ieee754r/d32/asind32.c: New file. Implementation of asin, basic structure is taken from the glibc/sysdeps/ieee754/ldbl-128 implementation. * dfp/sysdeps/ieee754r/d32/acosd32.c: New file. Same as above * dfp/sysdeps/ieee754r/d64/acosd64.c: New file * dfp/sysdeps/ieee754r/d64/asind64.c: New file * dfp/sysdeps/ieee754r/d128/acosd128.c: New file * dfp/sysdeps/ieee754r/d128/asind128.c: New file ------------------------------------------------------------------------ r197 | jkerian | 2006-10-04 12:25:02 -0500 (Wed, 04 Oct 2006) | 15 lines 2006-10-04 Joseph Kerian jkerian@us.ibm.com Merge with trunk as of 2006-09-20, revision 196. The previous base had a bug in malloc. There is a slight modification to the instructions for merging with trunk, due to glibc polluting the source directory during compilation. 1) Clean up everything so that "svn status" comes up blank (in the glibc working directory) 2) Update the glibc trunk cvs tracking branch to the target date 3) svn merge -r <this revision number>:<target revision from step 2> glibc/branches/glibc-trunk (done in the glibc working directory) 4) make a copy (using cp -Rp or some rsync cocktail) of the glibc directory (called glibc2 perhaps?) 5) Compile and test the glibc working directory, remember to check for modifications to files we override (printf and scanf related files) 6) Assuming everything compiles and tests nicely, go to the glibc2 directory and check-in, then remove the glibc2 directory ------------------------------------------------------------------------ r194 | eberlein | 2006-10-04 00:31:00 -0500 (Wed, 04 Oct 2006) | 11 lines * dfp/sysdeps/ieee754r/d128/asinhd128.c: created * dfp/sysdeps/ieee754r/d32/asinhd32.c: created * dfp/sysdeps/ieee754r/d64/asinhd64.c: created * dfp/sysdeps/ieee754r/d128/acoshd128.c: created * dfp/sysdeps/ieee754r/d32/acoshd32.c: created * dfp/sysdeps/ieee754r/d64/acoshd64.c: created * dfp/Makefile: added the above asinh and acosh files * dfp/Versions: added the above asinh and acosh functions * dfp/test/test_errno.c: added tests for asinh and acosh ------------------------------------------------------------------------ r193 | jkerian | 2006-10-03 18:29:28 -0500 (Tue, 03 Oct 2006) | 7 lines 2006-10-03 Joseph Kerian jkerian@us.ibm.com * dfp/sysdeps/dfp/stdio-common/vfprintf.c: Updating these to bring inline with the last trunk sync. Mostly this looks like adding __builtin_expect macros inside many of the if statements * dfp/sysdeps/dfp/stdio-common/vfscanf.c: same as above ------------------------------------------------------------------------ r192 | jkerian | 2006-10-03 16:58:13 -0500 (Tue, 03 Oct 2006) | 14 lines 2006-10-03 Joseph Kerian jkerian@us.ibm.com This is a merge with cvs trunk as of 2006-08-30 , revision 169 of glibc/branches/glibc-trunk. The three compilation patches were also applied. In the future... merging should be possible by just: 1) updating the trunk cvs tracking branch 2) svn merge -r <this revision>:HEAD glibc/branches/glibc-trunk 3) conducting a test build When this is done, remember that we need to test for changes in the stdio components that we override. (printf/scanf/etc) ------------------------------------------------------------------------ r191 | jkerian | 2006-10-03 15:39:42 -0500 (Tue, 03 Oct 2006) | 5 lines 2006-10-03 Joseph Kerian jkerian@us.ibm.com * dfp/test/test_vf.c: Removed. These tests no longer apply to a glibc compiled with a dfp-enabled gcc ------------------------------------------------------------------------ r189 | kjelderg | 2006-10-02 17:16:37 -0500 (Mon, 02 Oct 2006) | 2 lines Updated path for new toolchain and put in a for loop to automate this build a bit...really this should be a makefile soon. ------------------------------------------------------------------------ r187 | jkerian | 2006-10-02 12:36:13 -0500 (Mon, 02 Oct 2006) | 18 lines 2006-10-02 Joseph Kerian jkerian@us.ibm.com * dfp/test/test_set1a.c: Corrected a few testcases, added samequantum testcases * dfp/test/test_math.h: Slightly modified to add some boolean aliases * dfp/sysdeps/ieee754r/d32/scalbnd32.c: Removed unused variables * dfp/sysdeps/ieee754r/d32/scalblnd32.c: Removed unused variables * dfp/sysdeps/ieee754r/d32/ilogbd32.c: Added missing headers * dfp/sysdeps/ieee754r/d32/ldexpd32.c: Added missing headers * dfp/sysdeps/ieee754r/d32/logbd32.c: Added missing headers * dfp/sysdeps/ieee754r/d32/isnormald32.c: Added missing headers * dfp/Makefile: Added samequantum to build list * dfp/Versions: Added samequantum to export list * dfp/sysdeps/ieee754r/d32/samequantumd32.c: New File, implements the samequantum function * dfp/sysdeps/ieee754r/d64/samequantumd64.c: New file * dfp/sysdeps/ieee754r/d128/samequantumd128.c: New file ------------------------------------------------------------------------ r184 | jkerian | 2006-09-29 16:30:38 -0500 (Fri, 29 Sep 2006) | 23 lines 2006-09-29 Joseph Kerian jkerian@us.ibm.com M dfp/Makefile: Updated to build the new functions M dfp/Versions: Updated to export the new functions D dfp/test/test_nexttoward.c: Removing. Accidently added this last commit D dfp/test/test_nextafter.c: Removing. Accidently added this last commit M dfp/test/test_set1a.c: Uncommenting tests for nexttoward A dfp/sysdeps/ieee754r/d32/ilogbd32.c: New File. Function implementation A dfp/sysdeps/ieee754r/d32/scalbnd32.c: New File. Function implementation A dfp/sysdeps/ieee754r/d32/scalblnd32.c: New File. Function implementation A dfp/sysdeps/ieee754r/d32/ldexpd32.c: New File. Function implementation A dfp/sysdeps/ieee754r/d32/logbd32.c: New File. Function implementation A dfp/sysdeps/ieee754r/d64/ldexpd64.c: New File. A dfp/sysdeps/ieee754r/d64/logbd64.c: New File. A dfp/sysdeps/ieee754r/d64/ilogbd64.c: New File. A dfp/sysdeps/ieee754r/d64/scalbnd64.c: New File. A dfp/sysdeps/ieee754r/d64/scalblnd64.c: New File. A dfp/sysdeps/ieee754r/d128/scalbnd128.c: New File. A dfp/sysdeps/ieee754r/d128/scalblnd128.c: New File. A dfp/sysdeps/ieee754r/d128/logbd128.c: New File. A dfp/sysdeps/ieee754r/d128/ldexpd128.c: New File. A dfp/sysdeps/ieee754r/d128/ilogbd128.c: New File. ------------------------------------------------------------------------ r182 | jkerian | 2006-09-29 16:19:18 -0500 (Fri, 29 Sep 2006) | 12 lines 2006-09-29 Joseph Kerian jkerian@us.ibm.com * dfp/test/test_math.h: Heavy modification of the macros... it should fairly useable until we get the libm-test.inc stuff working * dfp/test/test_set1a.c: New files. Tests for priority 1a functions * dfp/test/test_iscomparison.c: New file. Summarizes several earlier tests * dfp/test/test_islessgreater.c: File deleted, moved into test_iscomparison.c * dfp/test/test_isgreaterequal.c: File deleted, moved into test_iscomparison.c * dfp/test/test_isgreater.c: File deleted, moved into test_iscomparison.c * dfp/test/test_isless.c: File deleted, moved into test_iscomparison.c * dfp/test/test_islessequal.c: File deleted, moved into test_iscomparison.c ------------------------------------------------------------------------ r181 | ryanarn | 2006-09-29 10:07:39 -0500 (Fri, 29 Sep 2006) | 7 lines 2006-09-29 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/dfp/math/gen-libm-test.pl: new file * dfp/sysdeps/dfp/math/libm-test.inc: new file * dfp/sysdeps/dfp/math/NewUlps: new file ------------------------------------------------------------------------ r180 | ryanarn | 2006-09-28 18:25:31 -0500 (Thu, 28 Sep 2006) | 5 lines 2006-09-28 Ryan S. Arnold <rsa@us.ibm.com> * dfp/sysdeps/dfp/math/math.h: removed redundant #defines. ------------------------------------------------------------------------ r179 | ryanarn | 2006-09-28 18:17:11 -0500 (Thu, 28 Sep 2006) | 24 lines 2006-09-28 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Makefile: Readded the nexttoward filenames and fixed accidental removal of 'calls' from libdfp-routines. * dfp/test/test_longdouble.c: test varargs for long double. PASSES * dfp/test/test_decimal128.c: test varargs for _Decimal128. FAILS * dfp/sysdeps/unix/sysv/linux/Implies: added dfp/math/bits to search path. * dfp/sysdeps/dfp/math/math.h: Added temporary #define to allow nexttoward with a _Decimal128 second parameter when calling bits/mathcalls.h for _Mdouble_ == _Decimal32/64/128. * dfp/sysdeps/dfp/math/bits: Added directory for mathcalls.h override. * dfp/sysdeps/dfp/math/bits/mathcalls.h: override to allow nexttowardd32/64/128 to use _Decimal128 as a second parameter type and added check for __USE_DEC_FP_NEXTTOWARD__ in order to allow non DFP nexttoward prototypes to use 'long double' as a second parameter. * dfp/sysdeps/ieee754r/d32/nexttowardd32.c: Replaced #include <dfpfloat.h> with #include <decfloat.h> * dfp/sysdeps/ieee754r/d32/nextafterd32.c: same as above. * dfp/sysdeps/ieee754r/d32/isnormald32.c: same as above. * dfp/bits/dfpcalls.h: Correct #if __STDC_WANT_DEC_FP__ 1 to just #if * __STDC_WANT_DEC_FP__. * dfp/Versions: readded nexttowardd32/64/128 symbols. ------------------------------------------------------------------------ r174 | ryanarn | 2006-09-28 11:47:41 -0500 (Thu, 28 Sep 2006) | 17 lines 2006-09-28 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Makefile: Cleaned up -D__STDC_WANT_DEC_FP__=1 CFLAG such that it SHOULDN'T be used as a normal command line CFLAG. The Makefile now sets it where appropriate. * dfp/test/test_varargs.c: Added test to verify dfp passing of _Decimal128 in floating point registers. * dfp/sysdeps/dfp/math/math.h: Re-added usage of __builtin_infd* after gcc provided a fix. * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c: Added extern for __isnormald32/64/128. Added some missing #includes to eliminate undefined reference errors. * dfp/sysdeps/ieee754r/d32/isnormald32.c: Added missing #include to eliminate undefined reference errors. * dfp/Versions: Added the symbols for strtod* and wcstod*. ------------------------------------------------------------------------ r173 | jkerian | 2006-09-27 18:37:22 -0500 (Wed, 27 Sep 2006) | 24 lines 2006-09-27 Joseph Kerian jkerian@us.ibm.com * dfp/deccommon.h: Fixed some leftover static scoped debugging functions * dfp/decsharedcommon.c: Fixed some leftover static scoped debuging functions, added some missing includes * dfp/decnumber/decNumberArith.c(___decCompare): Corrected code formatting * dfp/Makefile: Added build command for nextafter * dfp/Versions: Added references to nextafter * dfp/test/test_nexttoward.c: New File. Test for nexttoward * dfp/test/test_nextafter.c: New File. Test for nextafter * dfp/test/test_math.h: Corrected a silly mistake in the 2 argument macro * dfp/sysdeps/ieee754r/d32/nextafterd32.c: New File. Implements the nextafter function. * dfp/sysdeps/ieee754r/d32/nexttowardd32.c: New File. Implements nexttowards. This should be nearly identical to nextafter. Unfortunately there is a problem with the function declaration, so this is not actually working at the moment * dfp/sysdeps/ieee754r/d64/nexttowardd64.c: New File * dfp/sysdeps/ieee754r/d64/nextafterd64.c: New File * dfp/sysdeps/ieee754r/d128/nexttowardd128.c: New File * dfp/sysdeps/ieee754r/d128/nextafterd128.c: New File ------------------------------------------------------------------------ r161 | jkerian | 2006-09-26 17:40:21 -0500 (Tue, 26 Sep 2006) | 9 lines 2006-09-26 Joseph Kerian <jkerian@gmail.com> * dfp/test/test_math.h: A set of small macros which should simplify making quick testcases during development. * dfp/test/test_signbit.c: Fix an error in this testcase * dfp/test/test_strtod.c: A simple testcase for strtod* functions * dfp/sysdeps/ieee754r/d*: Fixed copyright date and contribution info (one of these days I'll realize it's not 2005 anymore) ------------------------------------------------------------------------ r158 | jkerian | 2006-09-26 11:07:34 -0500 (Tue, 26 Sep 2006) | 8 lines 2006-09-26 Joseph Kerian jkerian@us.ibm.com * dfp/sysdeps/dfp/stdlib/stdlib.h: Corrected #if __STDC_WANT_DEC_FP__ == 1 from the older form * dfp/sysdeps/dfp/stdlib/strtod32.c: Renamed FUNCTION_DEC macros to FUNCTION_INTERNAL. Removed unused variables that were generating warnings. Copied in _NL_CURRENT macro overrides from strtod_l.c. ------------------------------------------------------------------------ r155 | ryanarn | 2006-09-26 09:51:11 -0500 (Tue, 26 Sep 2006) | 4 lines 2006-09-26 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Versions: fixed misspelling of strtod128. ------------------------------------------------------------------------ r150 | ryanarn | 2006-09-25 15:50:59 -0500 (Mon, 25 Sep 2006) | 20 lines 2006-09-25 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Makefile * dfp/test/test_isnan.c * dfp/test/test_scanf.c * dfp/test/test_isinf.c * dfp/test/test_assign.c * dfp/sysdeps/unix/sysv/linux/Implies * dfp/sysdeps/dfp/stdlib/dfpstdlib.h * dfp/sysdeps/dfp/stdlib/strtod32.c * dfp/sysdeps/dfp/stdlib/stdlib.h * dfp/sysdeps/dfp/stdlib/strtod64.c * dfp/sysdeps/dfp/stdlib/strtod128.c * dfp/sysdeps/dfp/dfpwchar.h * dfp/sysdeps/dfp/math/math.h * dfp/sysdeps/dfp/wcsmbs * dfp/sysdeps/dfp/wcsmbs/wchar.h * dfp/Versions ------------------------------------------------------------------------ r148 | eberlein | 2006-09-22 14:28:43 -0500 (Fri, 22 Sep 2006) | 4 lines o Added few more tests for atan. o Decimal type size to test is adjustable using TEST_SIZE define. ------------------------------------------------------------------------ r147 | eberlein | 2006-09-22 14:26:45 -0500 (Fri, 22 Sep 2006) | 3 lines o Made changes to return correct values for +/- Infinity as input. ------------------------------------------------------------------------ r146 | jkerian | 2006-09-22 11:31:20 -0500 (Fri, 22 Sep 2006) | 13 lines 2006-09-22 Joseph Kerian <jkerian@us.ibm.com> * dfp/dfptypeconv.h: Edited conversion macros to avoid syntax confusions during compilation. Surrounded variables with parens. * dfp/decnumber/decNumberUtilities.c: Reformated decQuantizeOp according to glibc conventions. * dfp/decnumber/decquantize.c: Same as above * dfp/sysdeps/dfp/stdlib/strtod32.c: Corrected a few formatting irregularities * dfp/sysdeps/dfp/stdlib/strtod64.c: Corrected copyright * dfp/sysdeps/dfp/stdlib/strtod128.c: Corrected copyright * dfp/deccommon.h: Moved some things for readability ------------------------------------------------------------------------ r145 | ryanarn | 2006-09-21 23:12:12 -0500 (Thu, 21 Sep 2006) | 137 lines 2006-09-21 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_quantize.c: Updated tests with #ifndef __STDC_WANT_DEC_FP__. * dfp/test/test_errno.c: same * dfp/test/test_const.c: same * dfp/test/test_sqrt.c: same * dfp/sysdeps/dfp/math/math.h: the gcc __builtin_nand* and __builtin_infd* functions don't work so I had to add a work around to declare DEC_NAN, DEC_INFINITY, and HUGE_VAL_D*. * dfp/sysdeps/ieee754r/d32/modfd32.c: added #include <decimal*.h> same for all the rest of the files in the list. * dfp/sysdeps/ieee754r/d32/roundd32.c * dfp/sysdeps/ieee754r/d32/lrintd32.c * dfp/sysdeps/ieee754r/d32/fmind32.c * dfp/sysdeps/ieee754r/d32/tanhd32.c * dfp/sysdeps/ieee754r/d32/copysignd32.c * dfp/sysdeps/ieee754r/d32/fmaxd32.c * dfp/sysdeps/ieee754r/d32/coshd32.c * dfp/sysdeps/ieee754r/d32/quantized32.c * dfp/sysdeps/ieee754r/d32/sinhd32.c * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c * dfp/sysdeps/ieee754r/d32/isinfd32.c * dfp/sysdeps/ieee754r/d32/isfinited32.c * dfp/sysdeps/ieee754r/d32/fabsd32.c * dfp/sysdeps/ieee754r/d32/rintd32.c * dfp/sysdeps/ieee754r/d32/llroundd32.c * dfp/sysdeps/ieee754r/d32/logd32.c * dfp/sysdeps/ieee754r/d32/atand32.c * dfp/sysdeps/ieee754r/d32/isgreaterd32.c * dfp/sysdeps/ieee754r/d32/sind32.c * dfp/sysdeps/ieee754r/d32/sqrtd32.c * dfp/sysdeps/ieee754r/d32/islessequald32.c * dfp/sysdeps/ieee754r/d32/truncd32.c * dfp/sysdeps/ieee754r/d32/expd32.c * dfp/sysdeps/ieee754r/d32/signbitd32.c * dfp/sysdeps/ieee754r/d32/islessd32.c * dfp/sysdeps/ieee754r/d32/lroundd32.c * dfp/sysdeps/ieee754r/d32/llrintd32.c * dfp/sysdeps/ieee754r/d32/powd32.c * dfp/sysdeps/ieee754r/d32/isnand32.c * dfp/sysdeps/ieee754r/d32/nand32.c * dfp/sysdeps/ieee754r/d32/islessgreaterd32.c * dfp/sysdeps/ieee754r/d32/ceild32.c * dfp/sysdeps/ieee754r/d32/isgreaterequald32.c * dfp/sysdeps/ieee754r/d32/fdimd32.c * dfp/sysdeps/ieee754r/d32/floord32.c * dfp/sysdeps/ieee754r/d32/log10d32.c * dfp/sysdeps/ieee754r/d32/tand32.c * dfp/sysdeps/ieee754r/d32/isunorderedd32.c * dfp/sysdeps/ieee754r/d32/isnormald32.c * dfp/sysdeps/ieee754r/d32/cosd32.c * dfp/sysdeps/ieee754r/d32/frexpd32.c * dfp/sysdeps/ieee754r/d64/logd64.c * dfp/sysdeps/ieee754r/d64/atand64.c * dfp/sysdeps/ieee754r/d64/isgreaterd64.c * dfp/sysdeps/ieee754r/d64/sind64.c * dfp/sysdeps/ieee754r/d64/sqrtd64.c * dfp/sysdeps/ieee754r/d64/islessequald64.c * dfp/sysdeps/ieee754r/d64/truncd64.c * dfp/sysdeps/ieee754r/d64/expd64.c * dfp/sysdeps/ieee754r/d64/signbitd64.c * dfp/sysdeps/ieee754r/d64/islessd64.c * dfp/sysdeps/ieee754r/d64/lroundd64.c * dfp/sysdeps/ieee754r/d64/llrintd64.c * dfp/sysdeps/ieee754r/d64/isnand64.c * dfp/sysdeps/ieee754r/d64/nand64.c * dfp/sysdeps/ieee754r/d64/ceild64.c * dfp/sysdeps/ieee754r/d64/islessgreaterd64.c * dfp/sysdeps/ieee754r/d64/isgreaterequald64.c * dfp/sysdeps/ieee754r/d64/fdimd64.c * dfp/sysdeps/ieee754r/d64/floord64.c * dfp/sysdeps/ieee754r/d64/tand64.c * dfp/sysdeps/ieee754r/d64/log10d64.c * dfp/sysdeps/ieee754r/d64/isunorderedd64.c * dfp/sysdeps/ieee754r/d64/frexpd64.c * dfp/sysdeps/ieee754r/d64/cosd64.c * dfp/sysdeps/ieee754r/d64/isnormald64.c * dfp/sysdeps/ieee754r/d64/modfd64.c * dfp/sysdeps/ieee754r/d64/roundd64.c * dfp/sysdeps/ieee754r/d64/lrintd64.c * dfp/sysdeps/ieee754r/d64/fmind64.c * dfp/sysdeps/ieee754r/d64/tanhd64.c * dfp/sysdeps/ieee754r/d64/copysignd64.c * dfp/sysdeps/ieee754r/d64/fmaxd64.c * dfp/sysdeps/ieee754r/d64/coshd64.c * dfp/sysdeps/ieee754r/d64/quantized64.c * dfp/sysdeps/ieee754r/d64/sinhd64.c * dfp/sysdeps/ieee754r/d64/fpclassifyd64.c * dfp/sysdeps/ieee754r/d64/isinfd64.c * dfp/sysdeps/ieee754r/d64/isfinited64.c * dfp/sysdeps/ieee754r/d64/fabsd64.c * dfp/sysdeps/ieee754r/d64/rintd64.c * dfp/sysdeps/ieee754r/d64/llroundd64.c * dfp/sysdeps/ieee754r/d128/signbitd128.c * dfp/sysdeps/ieee754r/d128/quantized128.c * dfp/sysdeps/ieee754r/d128/lroundd128.c * dfp/sysdeps/ieee754r/d128/powd128.c * dfp/sysdeps/ieee754r/d128/isinfd128.c * dfp/sysdeps/ieee754r/d128/isfinited128.c * dfp/sysdeps/ieee754r/d128/rintd128.c * dfp/sysdeps/ieee754r/d128/isgreaterequald128.c * dfp/sysdeps/ieee754r/d128/fdimd128.c * dfp/sysdeps/ieee754r/d128/floord128.c * dfp/sysdeps/ieee754r/d128/isunorderedd128.c * dfp/sysdeps/ieee754r/d128/modfd128.c * dfp/sysdeps/ieee754r/d128/roundd128.c * dfp/sysdeps/ieee754r/d128/fmind128.c * dfp/sysdeps/ieee754r/d128/islessequald128.c * dfp/sysdeps/ieee754r/d128/fmaxd128.c * dfp/sysdeps/ieee754r/d128/copysignd128.c * dfp/sysdeps/ieee754r/d128/expd128.c * dfp/sysdeps/ieee754r/d128/sinhd128.c * dfp/sysdeps/ieee754r/d128/islessd128.c * dfp/sysdeps/ieee754r/d128/fpclassifyd128.c * dfp/sysdeps/ieee754r/d128/llrintd128.c * dfp/sysdeps/ieee754r/d128/isnand128.c * dfp/sysdeps/ieee754r/d128/fabsd128.c * dfp/sysdeps/ieee754r/d128/ceild128.c * dfp/sysdeps/ieee754r/d128/islessgreaterd128.c * dfp/sysdeps/ieee754r/d128/nand128.c * dfp/sysdeps/ieee754r/d128/llroundd128.c * dfp/sysdeps/ieee754r/d128/logd128.c * dfp/sysdeps/ieee754r/d128/log10d128.c * dfp/sysdeps/ieee754r/d128/tand128.c * dfp/sysdeps/ieee754r/d128/atand128.c * dfp/sysdeps/ieee754r/d128/isnormald128.c * dfp/sysdeps/ieee754r/d128/cosd128.c * dfp/sysdeps/ieee754r/d128/frexpd128.c * dfp/sysdeps/ieee754r/d128/isgreaterd128.c * dfp/sysdeps/ieee754r/d128/lrintd128.c * dfp/sysdeps/ieee754r/d128/sind128.c * dfp/sysdeps/ieee754r/d128/sqrtd128.c * dfp/sysdeps/ieee754r/d128/tanhd128.c * dfp/sysdeps/ieee754r/d128/truncd128.c * dfp/sysdeps/ieee754r/d128/coshd128.c ------------------------------------------------------------------------ r144 | ryanarn | 2006-09-21 15:34:12 -0500 (Thu, 21 Sep 2006) | 14 lines 2006-09-20 Ryan S. Arnold <rsa@us.ibm.com> * dfp/Makefile: One should no longer specify -D__STDC_WANT_DEC_FP__=1 as a global CFLAG. It is now set at the appropriate time in the Makefile. * dfp/test/test_const.c: New test. * dfp/test/test_isinf.c: Now uses DEC_INFINITY. * dfp/test/test_assign.c: Tests integer and float conversions to _Decimal* types. * dfp/sysdeps/dfp/stdlib/strtod32.c: Now uses <decfloat.h> rather than "dfpfloat.h". * dfp/sysdeps/dfp/math/math.h: Added some constants. ------------------------------------------------------------------------ r134 | eberlein | 2006-09-14 18:30:30 -0500 (Thu, 14 Sep 2006) | 3 lines * Added checking for pow(x,0) to return 1 for any x. ------------------------------------------------------------------------ r133 | eberlein | 2006-09-14 18:29:21 -0500 (Thu, 14 Sep 2006) | 3 lines * Added checking for log(0) to return -inf and log(inf) to return inf ------------------------------------------------------------------------ r132 | eberlein | 2006-09-14 18:28:41 -0500 (Thu, 14 Sep 2006) | 4 lines * Added checking for log10(0) to return -inf, and log10(inf) to return inf ------------------------------------------------------------------------ r131 | eberlein | 2006-09-14 18:27:43 -0500 (Thu, 14 Sep 2006) | 2 lines * Added checking for exp(inf) to return inf and exp(-inf) to return 0 ------------------------------------------------------------------------ r130 | eberlein | 2006-09-14 18:26:47 -0500 (Thu, 14 Sep 2006) | 3 lines * Added checking for sinh(+/-inf) to return +/-inf ------------------------------------------------------------------------ r129 | eberlein | 2006-09-14 18:26:16 -0500 (Thu, 14 Sep 2006) | 3 lines * Added checking for cosh(+/-inf) to return inf ------------------------------------------------------------------------ r127 | eberlein | 2006-09-12 15:39:57 -0500 (Tue, 12 Sep 2006) | 3 lines * Specific DFP functions enabled to set errno. ------------------------------------------------------------------------ r126 | eberlein | 2006-09-12 15:34:10 -0500 (Tue, 12 Sep 2006) | 3 lines Test case for various DFP functions which can set errno. ------------------------------------------------------------------------ r125 | ryanarn | 2006-09-12 09:16:36 -0500 (Tue, 12 Sep 2006) | 15 lines 2006-09-12 Ryan S. Arnold <rsa@us.ibm.com> * dfp/decstring.c (decToString): Add #if NOT_IN_libc around ___decCheckOperands. We don't want that being called from within libc. * dfp/decsharedcommon.c (___decNumberZero): same as above. * dfp/Makefile: include libm in the libdfp link. Removed decContext from the libc build to remove libm dependency related to feraiseexcept(). * dfp/decContext.c: moved into dfp/decnumber/ in order to avoid libm dependency in libc related to feraiseexcept(). * dfp/decContext.h: added NOT_IN_libc guard to ___decContext* prototypes to prevent them from being built for libc. ------------------------------------------------------------------------ r122 | jkerian | 2006-09-11 14:31:32 -0500 (Mon, 11 Sep 2006) | 7 lines * Makefile: Added references to the nan files below * sysdeps/ieee754r/d32/nand32.c: New file. Returns DEC_NAN atm, parser not implemented * sysdeps/ieee754r/d64/nand64.c: New file, uses nand32.c * sysdeps/ieee754r/d128/nand128.c: New file, uses nand32.c ------------------------------------------------------------------------ r115 | jkerian | 2006-09-08 10:36:24 -0500 (Fri, 08 Sep 2006) | 9 lines * sysdeps/dfp/stdlib/strtod32.c: Added group and locale specific internal strtod32 conversions, generalized a few more of the macros. * sysdeps/dfp/stdlib/wcstod32.c: New file, simple USE_WIDE_CHAR inclusion of strtod32.c * sysdeps/dfp/stdlib/wcstod64.c: New file, includes strod64.c * sysdeps/dfp/stdlib/wcstod128.c: New file, includes strtod128.c * Makefile: Adjusted to build the wcstod* files ------------------------------------------------------------------------ r112 | ryanarn | 2006-09-07 11:39:25 -0500 (Thu, 07 Sep 2006) | 34 lines 2006-09-07 Ryan S. Arnold <rsa@us.ibm.com> * dfp/test/test_nearbyintd.c: changed #define to #define __STDC_WANT_DEC_FP__ 1 to comply with C-spec revision. * dfp/test/test_signbit.c: same * dfp/test/test_quantize.c: same * dfp/test/test_isless.c: same * dfp/test/test_fpclassify.c: same * dfp/test/test_isinf.c: same * dfp/test/test_isnan.c: same * dfp/test/test_isfinite.c: same * dfp/test/test_islessgreater.c: same * dfp/test/test_ceil.c: same * dfp/test/test_isgreaterequal.c: same * dfp/test/test_fabsd.c: same * dfp/test/test_fdim.c: same * dfp/test/test_floor.c: same * dfp/test/test_isunordered.c: same * dfp/test/test_isgreater.c: same * dfp/test/test_modf.c: same * dfp/test/test_round.c: same * dfp/test/test_fmin.c: same * dfp/test/test_sqrt.c: same * dfp/test/test_islessequal.c: same * dfp/test/test_fmax.c: same * dfp/test/test_copysign.c: same * dfp/sysdeps/dfp/math/math.h: changed check to #if __STDC_WANT_DEC_FP__ == 1. * dfp/sysdeps/dfp/math/fenv.h: same * dfp/bits/dfpcalls.h: same * dfp/decContext.c (___decContextSetStatus): re-added exception support by converting DEC_* decNumber exceptions to FE_* exceptions and invoking feraiseexcept(). ------------------------------------------------------------------------ r111 | jkerian | 2006-09-07 11:21:53 -0500 (Thu, 07 Sep 2006) | 7 lines * dfp/sysdeps/dfp/stdio-common/vfscanf.c: Added proper handling of negatives to _Decimal types * dfp/sysdeps/dfp/stdlib/strtod32.c: Fixed an error in handling exponenents * dfp/test/test_scanf.c: Test updated to be more useful ------------------------------------------------------------------------ r110 | jkerian | 2006-09-06 16:49:38 -0500 (Wed, 06 Sep 2006) | 32 lines * dfp/Makefile: Modified to build the following new files * dfp/Versions: Modified to export symbols from the following * dfp/sysdeps/ieee754r/d32/frexpd32.c: New file. Implementation of frexp for dfp types. * dfp/sysdeps/ieee754r/d64/frexpd64.c: New file. * dfp/sysdeps/ieee754r/d128/frexpd128.c: New file. * dfp/sysdeps/ieee754r/d32/roundd32.c: New file. * dfp/sysdeps/ieee754r/d32/lroundd32.c: New file. * dfp/sysdeps/ieee754r/d32/llroundd32.c: New file. * dfp/sysdeps/ieee754r/d32/rintd32.c: New file. * dfp/sysdeps/ieee754r/d32/lrintd32.c: New file. * dfp/sysdeps/ieee754r/d32/llrintd32.c: New file. * dfp/sysdeps/ieee754r/d32/truncd32.c: New file. * dfp/sysdeps/ieee754r/d64/lroundd64.c: New file. * dfp/sysdeps/ieee754r/d64/truncd64.c: New file. * dfp/sysdeps/ieee754r/d64/llrintd64.c: New file. * dfp/sysdeps/ieee754r/d64/roundd64.c: New file. * dfp/sysdeps/ieee754r/d64/lrintd64.c: New file. * dfp/sysdeps/ieee754r/d64/rintd64.c: New file. * dfp/sysdeps/ieee754r/d64/llroundd64.c: New file. * dfp/sysdeps/ieee754r/d128/roundd128.c: New file. * dfp/sysdeps/ieee754r/d128/lroundd128.c: New file. * dfp/sysdeps/ieee754r/d128/llroundd128.c: New file. * dfp/sysdeps/ieee754r/d128/rintd128.c: New file. * dfp/sysdeps/ieee754r/d128/lrintd128.c: New file. * dfp/sysdeps/ieee754r/d128/llrintd128.c: New file. * dfp/sysdeps/ieee754r/d128/truncd128.c: New file. ------------------------------------------------------------------------ r107 | jkerian | 2006-09-06 14:35:46 -0500 (Wed, 06 Sep 2006) | 12 lines * dfp/sysdeps/dfp/stdlib/strtodec.c: Moved to strtod32.c * dfp/sysdeps/dfp/stdlib/strtod128.c: Implementation in strtod32.c * dfp/sysdeps/dfp/stdlib/strtod64.c: Implementation in strtod32.c * dfp/sysdeps/dfp/stdlib/strtod32.c: Implementation of the dfp version of strtol.c in stdlib. Uses #define's to be dfp type size generic. Need to investigate the _l.c variants in stdlib to see if they need to be done. * dfp/test/test_scanf.c: Updated to use new DF suffixes for tests * dfp/Makefile: Updated as per file changes * dfp/sysdeps/dfp/Makefile: Unused, removed ------------------------------------------------------------------------ r104 | jkerian | 2006-09-05 14:53:49 -0500 (Tue, 05 Sep 2006) | 5 lines * decDPD.h: Prefix BIN2DPD and DPD2BCD with __ to avoid symbol collisions with libgcc * decUtility.c: Same as above ------------------------------------------------------------------------ r103 | jkerian | 2006-09-05 14:50:19 -0500 (Tue, 05 Sep 2006) | 7 lines * sysdeps/ieee754r/d32/modfd32.c: Included some decNumber headers that were missed before * sysdeps/ieee754r/d32/isnormald32.c: Removed commenting around dfp-glibc dependent statements and corrected a typo. ------------------------------------------------------------------------ r102 | ryanarn | 2006-09-01 13:02:29 -0500 (Fri, 01 Sep 2006) | 6 lines * dfp/Makefile: Added comments to rules * dfp/test/test_isnormal.c: Added #include <decfloat.h> to pick up DEC_DEN for denormal numbers. * dfp/sysdeps/dfp/math/math.h: Added #defines for DEC_NAN and DEC_INFINITY. ------------------------------------------------------------------------ r101 | ryanarn | 2006-09-01 01:40:05 -0500 (Fri, 01 Sep 2006) | 4 lines * dfp/sysdeps/ieee754r/d32/isnand32.c: whoops, missed a __dec to ___dec conversion. ------------------------------------------------------------------------ r100 | ryanarn | 2006-09-01 01:06:16 -0500 (Fri, 01 Sep 2006) | 160 lines * dfp/decimal128.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decimal32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decNumberUtilities.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decimal32.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decNumber.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/deccommon.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decUtility.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decquantize.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decstring.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decNumberMath.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decNumberUtilities.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decintegral.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decquantize.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decimal64_local.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decaddop.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decimal128_local.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/deccommon.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decintegral.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decaddop.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decquantize.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decNumberArith.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decnumber/decimal32_local.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decNumberLocal.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decUtility.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decsharedcommon.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/Makefile * dfp/test/test_signbit.c: new test * dfp/test/test_quantize.c: new test * dfp/test/test_isless.c: new test * dfp/test/test_fpclassify.c: new test * dfp/test/test_isinf.c: new test * dfp/test/test_isnan.c: new test * dfp/test/test_isfinite.c: new test * dfp/test/test_islessgreater.c: new test * dfp/test/test_ceil.c: new test * dfp/test/test_ciel.c: new test * dfp/test/test_isgreaterequal.c: new test * dfp/test/test_fdim.c: new test * dfp/test/test_floor.c: new test * dfp/test/test_isunordered.c: new test * dfp/test/test_isnormal.c: new test * dfp/test/test_modf.c: new test * dfp/test/test_isgreater.c: new test * dfp/test/test_fmin.c: new test * dfp/test/test_sqrt.c: new test * dfp/test/test_islessequal.c: new test * dfp/test/test_fmax.c: new test * dfp/test/test_copysign.c: new test * dfp/decContext.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decNumberArith.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/dfptypeconv.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decContext.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/dfptypeconv.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/decimal64.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/dfp/math/math.h: fixed __isinf128 to __isinfd128 * dfp/sysdeps/ieee754r/dfpmacro.h: fixed comment ciel to ceil * dfp/sysdeps/ieee754r/dfpmath_private.h: emptied the file * dfp/sysdeps/ieee754r/d32/modfd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/fmind32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/tanhd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/nearbyintd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/copysignd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/fmaxd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/coshd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/quantized32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/sinhd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/fpclassifyd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/isinfd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/isfinited32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/fabsd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/logd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/atand32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/isgreaterd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/sind32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/sqrtd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/islessequald32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/expd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/signbitd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/islessd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/powd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/cield32.c: rename ciel to ceil. * dfp/sysdeps/ieee754r/d32/islessgreaterd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/ceild32.c: rename ciel to ceil. * dfp/sysdeps/ieee754r/d32/isgreaterequald32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/fdimd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/floord32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/tand32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/log10d32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/isunorderedd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/isnormald32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d32/cosd32.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d64/cield64.c: rename ciel to ceil. * dfp/sysdeps/ieee754r/d64/ceild64.c: rename ciel to ceil. * dfp/sysdeps/ieee754r/d64/nearbyintd64.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d128/nearbyintd128.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/sysdeps/ieee754r/d128/ceild128.c: rename ciel to ceil. * dfp/sysdeps/ieee754r/d128/cield128.c: rename ciel to ceil. * dfp/decimal64.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/fmt_dfp.c: __dec to ___dec to avoid libgcc symbol collision. * dfp/decNumberMath.h: __dec to ___dec to avoid libgcc symbol collision. * dfp/Versions: classification macros export internal '__' prefixed symbols, not non-'__' prefixed symbols. * dfp/decimal128.c: __dec to ___dec to avoid libgcc symbol collision. ------------------------------------------------------------------------ r99 | ryanarn | 2006-08-31 20:20:43 -0500 (Thu, 31 Aug 2006) | 2 lines o started to rename properly to 'ceil' ------------------------------------------------------------------------ r98 | ryanarn | 2006-08-31 20:17:07 -0500 (Thu, 31 Aug 2006) | 2 lines o dfp enabled libgcc compliant ------------------------------------------------------------------------ r97 | ryanarn | 2006-08-31 00:07:29 -0500 (Thu, 31 Aug 2006) | 5 lines o Fixed fe_dec_set/getround to fix symbols issues. o Moved fe_decround.c out of dfp/sysdeps/ieee754r and into dfp/. o Fixed all decNumber functions to fix symbol issues. ------------------------------------------------------------------------ r96 | ryanarn | 2006-08-30 10:20:41 -0500 (Wed, 30 Aug 2006) | 40 lines 2006-08-30 Ryan S. Arnold <rsa@us.ibm.com> * configure.in: Removed references to decimal float and moved it into an add-on configure fragment. * config.h.in: Removed decimal float value. Compiler must now support decimal float to build this add-on. * configure: Regenerated from configure.in. * dfp/configure: Initial configure fragment added. * dfp/Makefile: Added bits/dfpfenv.h to headers. * dfp/test/test_nearbyintd.c: Removed reference to dfpmath.h and replaced with #include <math.h> * dfp/test/test_round.c: Removed reference to dfpmath.h replaced with #include <math.h>. * dfp/test/test_ciel.c: Removed reference to dfpmath.h replaced with #include <math.h>. * dfp/sysdeps/dfp/stdlib/strtodec.c: Removed reference to dfpmath.h replaced with #include <math.h>. * dfp/sysdeps/dfp/dfptypes.h: Removed, unneeded now that gcc support for decimal float is required to build the add-on. * dfp/sysdeps/dfp/configure.in: Added configure fragment to check compiler for decimal float support --enable-decimal-float. * dfp/sysdeps/dfp/math/fenv.h: overridden to support #include <bits/dfpfenv.h>. * dfp/sysdeps/dfp/dfpmath.h: Removed because it was merged into overridden <math.h>. * dfp/sysdeps/dfp/dfpfenv.h: Moved to dfp/bits/dfpfenv.h so it can be installed in include/bits/. * dfp/sysdeps/ieee754r/dfpmath_private.h: Removed redundant prototypes. * dfp/sysdeps/ieee754r/d32/nearbyintd32.c: Replaced <dfpmath.h> and <dfpfenv.h> with <math.h> and <fenv.h>. * dfp/sysdeps/ieee754r/d64/nearbyintd64.c: Replaced <dfpmath.h> and <dfpfenv.h> with <math.h> and <fenv.h>. * dfp/sysdeps/ieee754r/d128/nearbyintd128.c: Replaced <dfpmath.h> and <dfpfenv.h> with <math.h> and <fenv.h>. * dfp/sysdeps/ieee754r/fe_decround.c: Replaced <dfpfenv.h> with <fenv.h>. * dfp/bits/dfpfenv.h: Moved so it can be installed in include/bits/. ------------------------------------------------------------------------ r95 | jkerian | 2006-08-28 15:10:40 -0500 (Mon, 28 Aug 2006) | 3 lines Added an initial version of __decNumberToInteger in decNumberArith.h/c .... needed for rint/lrint/llrint/lround/llround functions ------------------------------------------------------------------------ r94 | ryanarn | 2006-08-28 14:29:30 -0500 (Mon, 28 Aug 2006) | 4 lines * dfp/test/test_fabsd.c: Removed hex assignment and added #defines * dfp/test/test_nearbyintd.c: Removed hex assignment and added #defines * test/test_round.c: Fixed dfpfenv.h ------------------------------------------------------------------------ r93 | jkerian | 2006-08-28 13:34:17 -0500 (Mon, 28 Aug 2006) | 3 lines This includes most of the functions in the dfp/sysdeps/iee754r/d* directories. Most are either untested or barely tested ------------------------------------------------------------------------ r92 | ryanarn | 2006-08-28 12:55:33 -0500 (Mon, 28 Aug 2006) | 2 lines o Updated classification macros to fix macro expansion errors ------------------------------------------------------------------------ r88 | ryanarn | 2006-08-24 09:30:26 -0500 (Thu, 24 Aug 2006) | 2 lines o Fixed a #define in stdlib/dfpstdlib.h ------------------------------------------------------------------------ r87 | ryanarn | 2006-08-24 09:24:35 -0500 (Thu, 24 Aug 2006) | 2 lines o changes to get the tree to build ------------------------------------------------------------------------ r80 | ryanarn | 2006-08-21 09:24:27 -0500 (Mon, 21 Aug 2006) | 2 lines o Removed all reference to dfptypes.h ------------------------------------------------------------------------ r79 | ryanarn | 2006-08-18 14:12:39 -0500 (Fri, 18 Aug 2006) | 2 lines o Removed reference to dfpmath.h and replaced them with math.h ------------------------------------------------------------------------ r78 | ryanarn | 2006-08-17 17:28:19 -0500 (Thu, 17 Aug 2006) | 3 lines o Added classification overrides for _Decimal* types o Added MATHCALL invocations for all math function for each _Decimal* type ------------------------------------------------------------------------ r77 | jkerian | 2006-08-17 16:49:44 -0500 (Thu, 17 Aug 2006) | 5 lines This adds the new system for dealing with fabs (and similer function). Essentially macro-izing them. strtodec code still requires a DFP enabled gcc OR explicit hex values for _Decimal* constants. A macro for detecting subnormal decNumber types was added to decNumber.h ------------------------------------------------------------------------ r76 | ryanarn | 2006-08-17 10:52:36 -0500 (Thu, 17 Aug 2006) | 4 lines o Fixed header install problem. Headers now installed into include/ rather then include/dfp/. Next commit should remove them and replace them with proper C-spec headers. ------------------------------------------------------------------------ r75 | ryanarn | 2006-08-16 17:19:31 -0500 (Wed, 16 Aug 2006) | 2 lines o added header file search path ------------------------------------------------------------------------ r74 | ryanarn | 2006-08-16 16:49:20 -0500 (Wed, 16 Aug 2006) | 2 lines o Moved these to the correct place ------------------------------------------------------------------------ r73 | ryanarn | 2006-08-16 16:35:07 -0500 (Wed, 16 Aug 2006) | 2 lines o Started to remove #include <dfptypes.h> ------------------------------------------------------------------------ r72 | ryanarn | 2006-08-16 15:53:48 -0500 (Wed, 16 Aug 2006) | 2 lines o File move to conform more closely with C-spec. ------------------------------------------------------------------------ r71 | ryanarn | 2006-08-16 15:18:36 -0500 (Wed, 16 Aug 2006) | 2 lines o Temporary broken moves ------------------------------------------------------------------------ r70 | ryanarn | 2006-08-16 15:11:02 -0500 (Wed, 16 Aug 2006) | 2 lines o These changes get the reorder to work ------------------------------------------------------------------------ r69 | ryanarn | 2006-08-16 14:06:14 -0500 (Wed, 16 Aug 2006) | 2 lines o Removed unnecessary directory ------------------------------------------------------------------------ r68 | ryanarn | 2006-08-16 14:05:30 -0500 (Wed, 16 Aug 2006) | 2 lines o Moved the shared files back into the base directory to simplify includes ------------------------------------------------------------------------ r67 | ryanarn | 2006-08-16 14:03:23 -0500 (Wed, 16 Aug 2006) | 2 lines o incremental moves ------------------------------------------------------------------------ r66 | ryanarn | 2006-08-16 14:01:36 -0500 (Wed, 16 Aug 2006) | 2 lines o Unnecessary ------------------------------------------------------------------------ r65 | ryanarn | 2006-08-16 14:00:48 -0500 (Wed, 16 Aug 2006) | 2 lines o Started some more moved ------------------------------------------------------------------------ r64 | ryanarn | 2006-08-15 13:45:29 -0500 (Tue, 15 Aug 2006) | 2 lines o Moved a bunch of files ------------------------------------------------------------------------ r63 | ryanarn | 2006-08-15 12:53:15 -0500 (Tue, 15 Aug 2006) | 3 lines o Sorry about the major shakeup but stuff needs to be re-ordered. It may take several commits to sort everything out. ------------------------------------------------------------------------ r62 | ryanarn | 2006-08-10 15:51:53 -0500 (Thu, 10 Aug 2006) | 2 lines o Began new directory structure creation ------------------------------------------------------------------------ r61 | ryanarn | 2006-08-09 14:50:46 -0500 (Wed, 09 Aug 2006) | 2 lines o Minor updates ------------------------------------------------------------------------ r60 | ryanarn | 2006-08-03 12:23:07 -0500 (Thu, 03 Aug 2006) | 2 lines o Updated an else if check ------------------------------------------------------------------------ r59 | ryanarn | 2006-08-02 18:15:23 -0500 (Wed, 02 Aug 2006) | 2 lines o accidentally removed this earlier ------------------------------------------------------------------------ r58 | ryanarn | 2006-08-02 18:05:06 -0500 (Wed, 02 Aug 2006) | 2 lines o Added HAVE_CC_WITH_DEC_FP to config.h.in ------------------------------------------------------------------------ r57 | ryanarn | 2006-08-02 17:20:01 -0500 (Wed, 02 Aug 2006) | 2 lines o Added more tracing ------------------------------------------------------------------------ r56 | ryanarn | 2006-08-02 17:14:22 -0500 (Wed, 02 Aug 2006) | 6 lines o Added perror traces around vfscanf invocations to try to catch bugs. o Added pc_decimal32 type and is_short detection to vfprintf to work around libgcc bug where _Decimal32 is packed in a 32 bit int, not a 62 bit value. ------------------------------------------------------------------------ r55 | ryanarn | 2006-07-28 15:42:24 -0500 (Fri, 28 Jul 2006) | 3 lines o Fixed some bugs with scanf. It now detects all decimal float format codes and forwards to the correct function.s ------------------------------------------------------------------------ r54 | ryanarn | 2006-07-28 12:47:06 -0500 (Fri, 28 Jul 2006) | 3 lines o Adding scanf hooks for DFP support. ------------------------------------------------------------------------ r53 | ryanarn | 2006-07-27 16:20:49 -0500 (Thu, 27 Jul 2006) | 4 lines Update: o Provided a full test case for nearbyintd* o Fixed up a bunch of test cases. ------------------------------------------------------------------------ r52 | ryanarn | 2006-07-27 14:49:43 -0500 (Thu, 27 Jul 2006) | 10 lines Updated: o Added changes to configure.in to generate a new configure script which sets a compiler flag if the compiler doesn't support decimal float. o Regenerated configure. o Updated the dfp files to include dfptypes.h only if the compiler doesn't support decimal float. o Tested on a system without a decimal float enabled compiler. ------------------------------------------------------------------------ r51 | ryanarn | 2006-07-27 01:08:35 -0500 (Thu, 27 Jul 2006) | 3 lines Updated: o Fixed a parse error both files ------------------------------------------------------------------------ r50 | ryanarn | 2006-07-27 00:52:29 -0500 (Thu, 27 Jul 2006) | 6 lines Updated: o Added the nearbyintd64() and nearbyintd128() functions. ------------------------------------------------------------------------ r49 | ryanarn | 2006-07-26 20:28:23 -0500 (Wed, 26 Jul 2006) | 9 lines Updated: o Added support for nearbyintd32() to test the rounding mode functionality added in a previous commit. o This addition required pulling more functions from decNumber into libdfp. ------------------------------------------------------------------------ r48 | jkerian | 2006-07-26 17:12:23 -0500 (Wed, 26 Jul 2006) | 2 lines fabsd128, including corrected testcase ------------------------------------------------------------------------ r47 | ryanarn | 2006-07-26 14:29:00 -0500 (Wed, 26 Jul 2006) | 6 lines Updated: o Fixed a Makefile error where fe_decround was being built in libdfp. o Fixed an fabsd64() error where the result wasn't being stored into the return value properly. o Updated testcase to add _Decimal64 fabsd64(). ------------------------------------------------------------------------ r46 | ryanarn | 2006-07-26 13:38:30 -0500 (Wed, 26 Jul 2006) | 15 lines Updated: o Added dfpfenv.h to be placed in include/dfp/ o Added fe_dec_setround() and fe_dec_getround() api to dfpfenv.h o Added previously mentioned function definitions and prototypes. o Updated makefile for fe_decround. o The fe_dec_set/getround methods now live in libc. o Added some test files for dfp in dfp/test/ ------------------------------------------------------------------------ r45 | jkerian | 2006-07-26 11:23:33 -0500 (Wed, 26 Jul 2006) | 2 lines Added fabsd64 function and dependent functions ------------------------------------------------------------------------ r44 | ryanarn | 2006-07-25 15:21:14 -0500 (Tue, 25 Jul 2006) | 4 lines o __ieee_32_to_host was improperly passing the address of a pointer, and not a pointer as a parameter to its internal copy function. This has been remedied. ------------------------------------------------------------------------ r43 | ryanarn | 2006-07-25 13:48:54 -0500 (Tue, 25 Jul 2006) | 12 lines Updated: o fabsd32() is now being exported properly from libdfp.so and is linked against properly. o The library now builds and libdfp can be linked against. o The _Decimal* types were exported to an include file. o The library exported math functions were made available in the include file dfpmath.h. This will eventually be moved to math.h. ------------------------------------------------------------------------ r42 | ryanarn | 2006-07-24 18:49:50 -0500 (Mon, 24 Jul 2006) | 3 lines Updated: o Much hackery has resulted in a library that compiles at least. ------------------------------------------------------------------------ r41 | ryanarn | 2006-07-20 21:20:35 -0500 (Thu, 20 Jul 2006) | 15 lines Updated: o Cheated and added decNumberPlus() as a local function that does nothing inside of decimal32.c. This will work to get the library to build but will break when you actually want to try using fabsd32(). ------------------------------------------------------------------------ r40 | ryanarn | 2006-07-20 20:47:38 -0500 (Thu, 20 Jul 2006) | 17 lines Updated: o Added prototypes for fe_dec_getround and fe_dec_setround. o Added hidden_proto() and hidden_def() wrappers around newly added functions. o Updated Makefile to include new .c targets. o Updated Versions file to include new interfaces (fabsd32, fe_dec_setround, and fe_dec_getround). o Provided ieee_32_to_host conversion in fabsd32.c ------------------------------------------------------------------------ r39 | jkerian | 2006-07-20 16:41:58 -0500 (Thu, 20 Jul 2006) | 8 lines Seperated what were local (and static) functions in decNumber.c into decNumberUtilities.c/h . These should only be #include'd by files that were formerly in decNumber.c, and should contain no exported symbols. In the interest of simplification, I pulled out decunitaddsub.c and dumped that function into decNumberUtilities.c . It may get it's own file at a later date... but the files are looking reasonably manageable right now. ------------------------------------------------------------------------ r38 | jkerian | 2006-07-19 12:55:15 -0500 (Wed, 19 Jul 2006) | 17 lines Fixes: Most of the headers now declare the functions properly decNumberLocal.h was generating a #error if included twice (was this intentional?) no undefined symbols in a compile Files renamed to remove _'s __fabsdn.c (__fabsdn) moved back to deccommon.c as __decNumberAbs Remaining Issues: NULL had to be #define'd in deccommon.c errors are generated in the final linking stage for libc_nonshared (I suspect we still have a Makefile issue or three) ------------------------------------------------------------------------ r37 | ryanarn | 2006-07-19 10:41:47 -0500 (Wed, 19 Jul 2006) | 3 lines Updated: o Moved dec_string.c to decstring.c ------------------------------------------------------------------------ r36 | ryanarn | 2006-07-19 10:38:17 -0500 (Wed, 19 Jul 2006) | 7 lines Updated: o moved dfp_type_conv.* to dfptypeconv.* ------------------------------------------------------------------------ r35 | jkerian | 2006-07-19 09:20:10 -0500 (Wed, 19 Jul 2006) | 3 lines Added function declarations for dec_common.c functions in dec_common.h; corrected one misspelled function. ------------------------------------------------------------------------ r34 | jkerian | 2006-07-18 17:23:24 -0500 (Tue, 18 Jul 2006) | 4 lines Everything needed for fabsdn to work should now be in dec_common.c, decaddop.c and decunitaddsub.c . Headers have not been written yet, nor is there any particular way to get these all linking together. ------------------------------------------------------------------------ r33 | jkerian | 2006-07-18 15:43:53 -0500 (Tue, 18 Jul 2006) | 4 lines Approximately half an update to the fabs function and various routines required by it... this shouldn't interfere with compilation though... so I'm uploading it anyways. ------------------------------------------------------------------------ r32 | ryanarn | 2006-07-18 15:15:00 -0500 (Tue, 18 Jul 2006) | 25 lines Updated: o Fixed printf_dfp() to allow it to printf to the FILE pointer rather than to stdout. This allows it to printf inline with the printf string, e.g. 0x22e00065 = 6.5E+10 0x2234000000001a80 = 650.0 0x2206c000000000000000000006500005 = 650.00005 ------------------------------------------------------------------------ r31 | ryanarn | 2006-07-18 10:29:59 -0500 (Tue, 18 Jul 2006) | 19 lines Updated: o Added _Decimal64 and _Decimal128 types to the printf_arg union. o Updated vfprintf in order to get it to properly set pa_decimal128 and pa_decimal64 in printf_arg union. o Added __attribute__((aligned(*))) to _Decimal* types in order to simulated double-width _Decimal32 like it will be represented when gcc 4.1 support for DFP is available. (REASON: 32-bit decimal float values are passed in 64-bit floating point registers.) o Removed trace printfs from decimal*.c files. o The printf API now actually outputs accurate DFP values. ------------------------------------------------------------------------ r29 | ryanarn | 2006-07-11 17:25:15 -0500 (Tue, 11 Jul 2006) | 3 lines o Removed debuf printf's from fmt_dfp(). ------------------------------------------------------------------------ r28 | ryanarn | 2006-07-11 17:24:36 -0500 (Tue, 11 Jul 2006) | 17 lines o Added the _Decimal64 and _Decimal128 to string conversion routines to the proof-of-concept _Decimal32 routines. o Fixed a newbie bug where I wasn't initializing is_decimal=0 in vfprintf.h and therefore any float value was getting sent through printf_dfp(). ------------------------------------------------------------------------ r18 | ryanarn | 2006-07-06 16:49:58 -0500 (Thu, 06 Jul 2006) | 62 lines This updated added basic DFP printf support and a dfp add-on directory. Rudimentary DFP support can be enabled at configure time with the following option: --enable-add-ons=dfp Updated: o Added dfp add-on directory to provide source for libdfp and additional dfp type printf functionality to libc (we don't want libc to rely on libdfp for printf). o ported Andreas Krebbel's dfp integrated code to a completely non-invasive add-on directory 'dfp'. At this time this only includes the vfprintf additions and some Makefile additions. o Fixed the vfprintf routine to recognize %DD as a long format decimal float type. Andreas had a typo. o Moved minimal libdecnumber routines and files into 'dfp' add-on directory in order to determine what is included in both libc and libdfp. We don't want math library routines in libc but we need conversion and printing functionality in both. o Worked some dfp/sysdeps magic with Subdirs and Implies files in order to override the base vfprintf and specify the dfp directory as a target to be built. o Any DFP related data type passed to printf is now recognized as such by libc and the libdecnumber DFP to string conversion routine is invoked. o Provided an entry point for DFP data type to string conversions to libdfp which also exists in libc. ======================================== END HISTORY FOR LIBDFP ======================================== git-svn-id: svn://svn.eglibc.org/branches/libdfp@3856 7b3dc134-2b1b-0410-93df-9e9f96275f8d
-rw-r--r--libc/dfp/COPYING.txt434
-rw-r--r--libc/dfp/Makefile206
-rw-r--r--libc/dfp/README10
-rw-r--r--libc/dfp/Versions305
-rw-r--r--libc/dfp/Versions.def6
-rw-r--r--libc/dfp/bits/dfpcalls.h47
-rw-r--r--libc/dfp/bits/dfpfenv.h56
-rw-r--r--libc/dfp/configure24
-rw-r--r--libc/dfp/decContext.c203
-rw-r--r--libc/dfp/decContext.h175
-rw-r--r--libc/dfp/decDPD.h889
-rw-r--r--libc/dfp/decNumber.c6807
-rw-r--r--libc/dfp/decNumber.h164
-rw-r--r--libc/dfp/decNumberLocal.h211
-rw-r--r--libc/dfp/decNumberMath.c727
-rw-r--r--libc/dfp/decNumberMath.h41
-rw-r--r--libc/dfp/decimal128.c589
-rw-r--r--libc/dfp/decimal128.h113
-rw-r--r--libc/dfp/decimal32.c505
-rw-r--r--libc/dfp/decimal32.h111
-rw-r--r--libc/dfp/decimal64.c865
-rw-r--r--libc/dfp/decimal64.h113
-rw-r--r--libc/dfp/decode-decimal.c50
-rw-r--r--libc/dfp/decode-decimal.h42
-rw-r--r--libc/dfp/dfpfenv_private.h28
-rw-r--r--libc/dfp/dfptypeconv.c131
-rw-r--r--libc/dfp/dfptypeconv128.h44
-rw-r--r--libc/dfp/dfptypeconv32.h44
-rw-r--r--libc/dfp/dfptypeconv64.h44
-rw-r--r--libc/dfp/fmt_d128.c25
-rw-r--r--libc/dfp/fmt_d32.c181
-rw-r--r--libc/dfp/fmt_d64.c25
-rw-r--r--libc/dfp/fmt_dfp.h51
-rwxr-xr-xlibc/dfp/gen-libdfp-test.pl917
-rw-r--r--libc/dfp/libdfp-test-ulps1541
-rw-r--r--libc/dfp/libdfp-test.inc6150
-rw-r--r--libc/dfp/mapround.c81
-rw-r--r--libc/dfp/mapround.h29
-rw-r--r--libc/dfp/sysdeps/dfp/Subdirs1
-rw-r--r--libc/dfp/sysdeps/dfp/Versions6
-rw-r--r--libc/dfp/sysdeps/dfp/configure.in14
-rw-r--r--libc/dfp/sysdeps/dfp/decroundtls.c32
-rw-r--r--libc/dfp/sysdeps/dfp/decroundtls.h33
-rw-r--r--libc/dfp/sysdeps/dfp/dfpwchar.h35
-rw-r--r--libc/dfp/sysdeps/dfp/fe_decround.c71
-rw-r--r--libc/dfp/sysdeps/dfp/math/bits/mathcalls.h367
-rw-r--r--libc/dfp/sysdeps/dfp/math/fenv.h140
-rw-r--r--libc/dfp/sysdeps/dfp/math/math.h645
-rw-r--r--libc/dfp/sysdeps/dfp/printf_dfp.c120
-rw-r--r--libc/dfp/sysdeps/dfp/printf_dfp.h35
-rw-r--r--libc/dfp/sysdeps/dfp/printf_dfphex.c37
-rw-r--r--libc/dfp/sysdeps/dfp/stdio-common/printf-parse.h109
-rw-r--r--libc/dfp/sysdeps/dfp/stdio-common/printf.h149
-rw-r--r--libc/dfp/sysdeps/dfp/stdio-common/vfprintf.c2307
-rw-r--r--libc/dfp/sysdeps/dfp/stdio-common/vfscanf.c2524
-rw-r--r--libc/dfp/sysdeps/dfp/stdlib/dfpstdlib.h35
-rw-r--r--libc/dfp/sysdeps/dfp/stdlib/stdlib.h1000
-rw-r--r--libc/dfp/sysdeps/dfp/stdlib/strtod128.c31
-rw-r--r--libc/dfp/sysdeps/dfp/stdlib/strtod32.c754
-rw-r--r--libc/dfp/sysdeps/dfp/stdlib/strtod64.c32
-rw-r--r--libc/dfp/sysdeps/dfp/stdlib/wcstod128.c24
-rw-r--r--libc/dfp/sysdeps/dfp/stdlib/wcstod32.c24
-rw-r--r--libc/dfp/sysdeps/dfp/stdlib/wcstod64.c24
-rw-r--r--libc/dfp/sysdeps/dfp/wcsmbs/wchar.h866
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/acosd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/acoshd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/asind128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/asinhd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/atan2d128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/atand128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/atanhd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/cbrtd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/ceild128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/copysignd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/cosd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/coshd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/erfd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/exp2d128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/expd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/expm1d128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/fabsd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/fdimd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/finited128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/floord128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/fmad128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/fmaxd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/fmind128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/fmodd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/fpclassifyd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/frexpd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/hypotd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/ilogbd128.c26
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/isgreaterd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/isgreaterequald128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/isinfd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/islessd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/islessequald128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/islessgreaterd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/isnand128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/isnormald128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/isunorderedd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/ldexpd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/lgammad128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/llrintd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/llroundd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/log10d128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/log1pd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/log2d128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/logbd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/logd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/lrintd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/lroundd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/modfd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/nand128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/nearbyintd128.c26
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/nextafterd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/nexttowardd128.c26
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/powd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/quantized128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/remainderd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/rintd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/roundd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/samequantumd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/scalblnd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/scalbnd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/signbitd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/sind128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/sinhd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/sqrtd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/tand128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/tanhd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/tgammad128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d128/truncd128.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/acosd32.c356
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/acoshd32.c103
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/asind32.c296
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/asinhd32.c68
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/atan2d32.c105
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/atand32.c64
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/atanhd32.c110
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/cbrtd32.c155
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/ceild32.c57
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/copysignd32.c57
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/cosd32.c79
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/coshd32.c79
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/erfd32.c962
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/exp2d32.c81
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/expd32.c81
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/expm1d32.c80
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/fabsd32.c53
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/fdimd32.c85
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/finited32.c48
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/floord32.c57
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/fmad32.c105
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/fmaxd32.c58
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/fmind32.c58
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/fmodd32.c86
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/fpclassifyd32.c139
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/frexpd32.c58
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/hypotd32.c85
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/ilogbd32.c101
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/isgreaterd32.c52
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/isgreaterequald32.c52
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/isinfd32.c54
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/islessd32.c52
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/islessequald32.c52
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/islessgreaterd32.c52
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/isnand32.c54
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/isnormald32.c67
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/isunorderedd32.c39
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/ldexpd32.c81
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/lgammad32.c1080
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/llrintd32.c35
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/llroundd32.c89
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/log10d32.c85
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/log1pd32.c91
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/log2d32.c93
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/logbd32.c88
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/logd32.c85
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/lrintd32.c37
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/lroundd32.c37
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/modfd32.c64
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/nand32.c54
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/nearbyintd32.c75
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/nextafterd32.c96
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/nexttowardd32.c100
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/powd32.c188
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/quantized32.c59
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/remainderd32.c83
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/rintd32.c31
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/roundd32.c68
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/samequantumd32.c56
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/scalblnd32.c83
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/scalbnd32.c84
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/signbitd32.c46
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/sind32.c73
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/sinhd32.c76
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/sqrtd32.c79
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/tand32.c78
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/tanhd32.c60
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/tgammad32.c80
-rw-r--r--libc/dfp/sysdeps/ieee754r/d32/truncd32.c55
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/acosd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/acoshd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/asind64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/asinhd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/atan2d64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/atand64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/atanhd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/cbrtd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/ceild64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/copysignd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/cosd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/coshd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/erfd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/exp2d64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/expd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/expm1d64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/fabsd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/fdimd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/finited64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/floord64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/fmad64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/fmaxd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/fmind64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/fmodd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/fpclassifyd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/frexpd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/hypotd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/ilogbd64.c26
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/isgreaterd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/isgreaterequald64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/isinfd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/islessd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/islessequald64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/islessgreaterd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/isnand64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/isnormald64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/isunorderedd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/ldexpd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/lgammad64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/llrintd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/llroundd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/log10d64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/log1pd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/log2d64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/logbd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/logd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/lrintd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/lroundd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/modfd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/nand64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/nearbyintd64.c26
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/nextafterd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/nexttowardd64.c29
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/powd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/quantized64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/remainderd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/rintd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/roundd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/samequantumd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/scalblnd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/scalbnd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/signbitd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/sind64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/sinhd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/sqrtd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/tand64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/tanhd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/tgammad64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/d64/truncd64.c25
-rw-r--r--libc/dfp/sysdeps/ieee754r/dfpmacro.h149
-rw-r--r--libc/dfp/sysdeps/powerpc/decode-decimal.c215
-rw-r--r--libc/dfp/sysdeps/powerpc/dfpu/decroundtls.c25
-rw-r--r--libc/dfp/sysdeps/powerpc/dfpu/decroundtls.h27
-rw-r--r--libc/dfp/sysdeps/powerpc/dfpu/fe_decround.c124
-rw-r--r--libc/dfp/sysdeps/powerpc/dpd-private.h933
-rw-r--r--libc/dfp/sysdeps/powerpc/fpu/bits/fenvinline.h63
-rw-r--r--libc/dfp/sysdeps/powerpc/nofpu/bits/fenvinline.h39
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Makefile25
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions21
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/adddd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/addsd3.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/addtd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divdd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divsd3.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divtd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqdd2.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqsd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqtd2.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendddtd2.S29
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendsddd2.S29
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendsdtd2.S30
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixdddi.S36
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixddsi.S56
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsddi.S37
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsdsi.S57
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtddi.S36
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtdsi.S56
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsdddi.S89
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsddsi.S51
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssddi.S90
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssdsi.S52
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstddi.S99
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstdsi.S52
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdidd.S42
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdisd.S43
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatditd.S42
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsidd.S42
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsisd.S43
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsitd.S42
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdidd.S38
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdisd.S39
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsditd.S38
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssidd.S38
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssisd.S39
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssitd.S38
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gedd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gesd2.S35
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/getd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtdd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtsd2.S35
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gttd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ledd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/lesd2.S35
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/letd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltdd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltsd2.S35
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/lttd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/muldd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/mulsd3.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/multd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/nedd2.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/nesd2.S34
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/netd2.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subdd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subsd3.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subtd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/truncddsd2.S29
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctddd2.S29
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctdsd2.S30
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unorddd2.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unordsd2.S34
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unordtd2.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc32/power6x/fpu/Implies1
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Makefile25
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions21
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/adddd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/addsd3.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/addtd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divdd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divsd3.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divtd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqdd2.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqsd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqtd2.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendddtd2.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendsddd2.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendsdtd2.S29
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixdddi.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixddsi.S51
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsddi.S34
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsdsi.S51
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtddi.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtdsi.S50
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsdddi.S57
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsddsi.S45
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssddi.S59
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssdsi.S47
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstddi.S60
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstdsi.S46
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdidd.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdisd.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatditd.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsidd.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsisd.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsitd.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdidd.S50
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdisd.S52
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsditd.S51
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssidd.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssisd.S34
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssitd.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gedd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gesd2.S35
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/getd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtdd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtsd2.S35
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gttd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ledd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/lesd2.S35
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/letd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltdd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltsd2.S35
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/lttd2.S33
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/muldd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/mulsd3.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/multd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/nedd2.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/nesd2.S34
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/netd2.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subdd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subsd3.S31
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subtd3.S28
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/truncddsd2.S29
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctddd2.S29
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctdsd2.S30
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unorddd2.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unordsd2.S34
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unordtd2.S32
-rw-r--r--libc/dfp/sysdeps/powerpc/powerpc64/power6x/fpu/Implies1
-rw-r--r--libc/dfp/sysdeps/soft-dfp/Makefile34
-rw-r--r--libc/dfp/sysdeps/soft-dfp/Versions35
-rw-r--r--libc/dfp/sysdeps/soft-dfp/adddd3.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/addsd3.c68
-rw-r--r--libc/dfp/sysdeps/soft-dfp/addtd3.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/binpowof10.c335
-rw-r--r--libc/dfp/sysdeps/soft-dfp/classify.c75
-rw-r--r--libc/dfp/sysdeps/soft-dfp/convert.c444
-rw-r--r--libc/dfp/sysdeps/soft-dfp/convert.h294
-rw-r--r--libc/dfp/sysdeps/soft-dfp/decpowof2.c1107
-rw-r--r--libc/dfp/sysdeps/soft-dfp/divdd3.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/divsd3.c68
-rw-r--r--libc/dfp/sysdeps/soft-dfp/divtd3.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/eqdd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/eqsd2.c51
-rw-r--r--libc/dfp/sysdeps/soft-dfp/eqtd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extend.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extend2.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extend_d_f.c31
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendddtd2.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendddtf.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extenddfdd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extenddftd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendsddd2.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendsddf.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendsdtd2.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendsdtf.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendsfdd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendsfsd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendsftd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendtfdd.c55
-rw-r--r--libc/dfp/sysdeps/soft-dfp/extendtftd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fix.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixdddi.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixddsi.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixsddi.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixsdsi.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixtddi.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixtdsi.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixuns.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixunsdddi.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixunsddsi.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixunssddi.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixunssdsi.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixunstddi.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/fixunstdsi.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/float.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatdidd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatdisd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatditd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatsidd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatsisd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatsitd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatuns.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatunsdidd.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatunsdisd.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatunsditd.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatunssidd.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatunssisd.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/floatunssitd.c29
-rw-r--r--libc/dfp/sysdeps/soft-dfp/gedd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/gesd2.c51
-rw-r--r--libc/dfp/sysdeps/soft-dfp/getd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/gtdd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/gtsd2.c51
-rw-r--r--libc/dfp/sysdeps/soft-dfp/gttd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/ledd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/lesd2.c51
-rw-r--r--libc/dfp/sysdeps/soft-dfp/letd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/ltdd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/ltsd2.c51
-rw-r--r--libc/dfp/sysdeps/soft-dfp/lttd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/makecfiles.sh635
-rw-r--r--libc/dfp/sysdeps/soft-dfp/muldd3.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/mulsd3.c68
-rw-r--r--libc/dfp/sysdeps/soft-dfp/multd3.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/nedd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/nesd2.c51
-rw-r--r--libc/dfp/sysdeps/soft-dfp/netd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/subdd3.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/subsd3.c68
-rw-r--r--libc/dfp/sysdeps/soft-dfp/subtd3.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/trunc.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/trunc2.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/truncdddf.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/truncddsd2.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/truncddsf.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/truncdfsd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/truncsdsf.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/trunctddd2.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/trunctddf.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/trunctdsd2.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/trunctdsf.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/trunctdtf.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/trunctfdd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/trunctfsd.c28
-rw-r--r--libc/dfp/sysdeps/soft-dfp/unorddd2.c27
-rw-r--r--libc/dfp/sysdeps/soft-dfp/unordsd2.c48
-rw-r--r--libc/dfp/sysdeps/soft-dfp/unordtd2.c27
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/Implies11
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/fpu/Implies2
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/nofpu/Implies2
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/Implies1
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/fpu/Implies3
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/Implies1
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/fpu/Implies4
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies1
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/fpu/Implies3
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies1
-rw-r--r--libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/fpu/Implies4
-rw-r--r--libc/dfp/test-d128.c73
-rw-r--r--libc/dfp/test-d32.c73
-rw-r--r--libc/dfp/test-d64.c73
-rw-r--r--libc/dfp/test/CLEANME12
-rw-r--r--libc/dfp/test/README22
-rw-r--r--libc/dfp/test/convert.c40
-rw-r--r--libc/dfp/test/test-decimal.c362
-rw-r--r--libc/dfp/test/test_acos.c12
-rw-r--r--libc/dfp/test/test_arctrig.c48
-rw-r--r--libc/dfp/test/test_assign.c42
-rw-r--r--libc/dfp/test/test_cbrt.c25
-rw-r--r--libc/dfp/test/test_ceil.c48
-rw-r--r--libc/dfp/test/test_const.c45
-rw-r--r--libc/dfp/test/test_conversion.c70
-rw-r--r--libc/dfp/test/test_convert.h284
-rw-r--r--libc/dfp/test/test_copysign.c58
-rw-r--r--libc/dfp/test/test_decimal128.c30
-rw-r--r--libc/dfp/test/test_decode.c75
-rw-r--r--libc/dfp/test/test_decode2.c55
-rw-r--r--libc/dfp/test/test_decref.c23
-rw-r--r--libc/dfp/test/test_double_to_decimal.c400
-rw-r--r--libc/dfp/test/test_errno.c212
-rw-r--r--libc/dfp/test/test_except.c55
-rw-r--r--libc/dfp/test/test_exceptions.c25
-rw-r--r--libc/dfp/test/test_fabsd.c32
-rw-r--r--libc/dfp/test/test_fdim.c73
-rw-r--r--libc/dfp/test/test_floor.c48
-rw-r--r--libc/dfp/test/test_fmax.c58
-rw-r--r--libc/dfp/test/test_fmin.c58
-rw-r--r--libc/dfp/test/test_fpclassify.c56
-rw-r--r--libc/dfp/test/test_frexpd.c39
-rw-r--r--libc/dfp/test/test_ilogb.c18
-rw-r--r--libc/dfp/test/test_iscomparison.c213
-rw-r--r--libc/dfp/test/test_isfinite.c99
-rw-r--r--libc/dfp/test/test_isinf.c75
-rw-r--r--libc/dfp/test/test_isnan.c45
-rw-r--r--libc/dfp/test/test_isnormal.c65
-rw-r--r--libc/dfp/test/test_isunordered.c54
-rw-r--r--libc/dfp/test/test_itoa.c56
-rw-r--r--libc/dfp/test/test_longdouble.c27
-rw-r--r--libc/dfp/test/test_math.h229
-rw-r--r--libc/dfp/test/test_modf.c58
-rw-r--r--libc/dfp/test/test_nearbyintd.c64
-rw-r--r--libc/dfp/test/test_pow.c260
-rw-r--r--libc/dfp/test/test_printf.c259
-rw-r--r--libc/dfp/test/test_printf2.c104
-rw-r--r--libc/dfp/test/test_quantize.c60
-rw-r--r--libc/dfp/test/test_round.c76
-rw-r--r--libc/dfp/test/test_scalb.c25
-rw-r--r--libc/dfp/test/test_scanf.c41
-rw-r--r--libc/dfp/test/test_set1a.c80
-rw-r--r--libc/dfp/test/test_set2.c94
-rw-r--r--libc/dfp/test/test_set2a.c220
-rw-r--r--libc/dfp/test/test_signbit.c36
-rw-r--r--libc/dfp/test/test_sqrt.c36
-rw-r--r--libc/dfp/test/test_strtod.c45
-rw-r--r--libc/dfp/test/test_varargs.c13
-rw-r--r--libc/dfp/test/test_zero.c60
579 files changed, 59510 insertions, 0 deletions
diff --git a/libc/dfp/COPYING.txt b/libc/dfp/COPYING.txt
new file mode 100644
index 000000000..3e7e2a8e9
--- /dev/null
+++ b/libc/dfp/COPYING.txt
@@ -0,0 +1,434 @@
+GNU LESSER GENERAL PUBLIC LICENSE
+
+Version 2.1, February 1999
+
+Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public Licenses are intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.
+
+This license, the Lesser General Public License, applies to some specially
+designated software packages--typically libraries--of the Free Software
+Foundation and other authors who decide to use it. You can use it too, but we
+suggest you first think carefully about whether this license or the ordinary
+General Public License is the better strategy to use in any particular case,
+based on the explanations below.
+
+When we speak of free software, we are referring to freedom of use, not price.
+Our General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for this service if you
+wish); that you receive source code or can get it if you want it; that you can
+change the software and use pieces of it in new free programs; and that you are
+informed that you can do these things.
+
+To protect your rights, we need to make restrictions that forbid distributors
+to deny you these rights or to ask you to surrender these rights. These
+restrictions translate to certain responsibilities for you if you distribute
+copies of the library or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for a
+fee, you must give the recipients all the rights that we gave you. You must
+make sure that they, too, receive or can get the source code. If you link other
+code with the library, you must provide complete object files to the
+recipients, so that they can relink them with the library after making changes
+to the library and recompiling it. And you must show them these terms so they
+know their rights.
+
+We protect your rights with a two-step method: (1) we copyright the library,
+and (2) we offer you this license, which gives you legal permission to copy,
+distribute and/or modify the library.
+
+To protect each distributor, we want to make it very clear that there is no
+warranty for the free library. Also, if the library is modified by someone else
+and passed on, the recipients should know that what they have is not the
+original version, so that the original author's reputation will not be affected
+by problems that might be introduced by others.
+
+Finally, software patents pose a constant threat to the existence of any free
+program. We wish to make sure that a company cannot effectively restrict the
+users of a free program by obtaining a restrictive license from a patent
+holder. Therefore, we insist that any patent license obtained for a version of
+the library must be consistent with the full freedom of use specified in this
+license.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU
+General Public License. This license, the GNU Lesser General Public License,
+applies to certain designated libraries, and is quite different from the
+ordinary General Public License. We use this license for certain libraries in
+order to permit linking those libraries into non-free programs.
+
+When a program is linked with a library, whether statically or using a shared
+library, the combination of the two is legally speaking a combined work, a
+derivative of the original library. The ordinary General Public License
+therefore permits such linking only if the entire combination fits its criteria
+of freedom. The Lesser General Public License permits more lax criteria for
+linking other code with the library.
+
+We call this license the "Lesser" General Public License because it does Less
+to protect the user's freedom than the ordinary General Public License. It also
+provides other free software developers Less of an advantage over competing
+non-free programs. These disadvantages are the reason we use the ordinary
+General Public License for many libraries. However, the Lesser license provides
+advantages in certain special circumstances.
+
+For example, on rare occasions, there may be a special need to encourage the
+widest possible use of a certain library, so that it becomes a de-facto
+standard. To achieve this, non-free programs must be allowed to use the
+library. A more frequent case is that a free library does the same job as
+widely used non-free libraries. In this case, there is little to gain by
+limiting the free library to free software only, so we use the Lesser General
+Public License.
+
+In other cases, permission to use a particular library in non-free programs
+enables a greater number of people to use a large body of free software. For
+example, permission to use the GNU C Library in non-free programs enables many
+more people to use the whole GNU operating system, as well as its variant, the
+GNU/Linux operating system.
+
+Although the Lesser General Public License is Less protective of the users'
+freedom, it does ensure that the user of a program that is linked with the
+Library has the freedom and the wherewithal to run that program using a
+modified version of the Library.
+
+The precise terms and conditions for copying, distribution and modification
+follow. Pay close attention to the difference between a "work based on the
+library" and a "work that uses the library". The former contains code derived
+from the library, whereas the latter must be combined with the library in order
+to run.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library or other program
+which contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Lesser General
+Public License (also called "this License"). Each licensee is addressed as
+"you".
+
+A "library" means a collection of software functions and/or data prepared so as
+to be conveniently linked with application programs (which use some of those
+functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has
+been distributed under these terms. A "work based on the Library" means either
+the Library or any derivative work under copyright law: that is to say, a work
+containing the Library or a portion of it, either verbatim or with
+modifications and/or translated straightforwardly into another language.
+(Hereinafter, translation is included without limitation in the term
+"modification".)
+
+"Source code" for a work means the preferred form of the work for making
+modifications to it. For a library, complete source code means all the source
+code for all modules it contains, plus any associated interface definition
+files, plus the scripts used to control compilation and installation of the
+library.
+
+Activities other than copying, distribution and modification are not covered by
+this License; they are outside its scope. The act of running a program using
+the Library is not restricted, and output from such a program is covered only
+if its contents constitute a work based on the Library (independent of the use
+of the Library in a tool for writing it). Whether that is true depends on what
+the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and distribute a copy of this License along
+with the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you may
+at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it, thus
+forming a work based on the Library, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+ * a) The modified work must itself be a software library.
+
+ * b) You must cause the files modified to carry prominent
+ notices stating that you changed the files and the date of any
+ change.
+
+
+ * c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ * d) If a facility in the modified Library refers to a
+ function or a table of data to be supplied by an application program
+ that uses the facility, other than as an argument passed when the
+ facility is invoked, then you must make a good faith effort to
+ ensure that, in the event an application does not supply such
+ function or table, the facility still operates, and performs
+ whatever part of its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots
+ has a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must be
+ optional: if the application does not supply it, the square root
+ function must still compute square roots.)
+
+ These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.
+
+ Thus, it is not the intent of this section to claim rights or
+ contest your rights to work written entirely by you; rather, the
+ intent is to exercise the right to control the distribution of
+ derivative or collective works based on the Library.
+
+ In addition, mere aggregation of another work not based on the
+ Library with the Library (or with a work based on the Library) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License
+instead of this License to a given copy of the Library. To do this, you must
+alter all the notices that refer to this License, so that they refer to the
+ordinary GNU General Public License, version 2, instead of to this License. (If
+a newer version than version 2 of the ordinary GNU General Public License has
+appeared, then you can specify that version instead if you wish.) Do not make
+any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy, so
+the ordinary GNU General Public License applies to all subsequent copies and
+derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library
+into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of it,
+under Section 2) in object code or executable form under the terms of Sections
+1 and 2 above provided that you accompany it with the complete corresponding
+machine-readable source code, which must be distributed under the terms of
+Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a
+designated place, then offering equivalent access to copy the source code from
+the same place satisfies the requirement to distribute the source code, even
+though third parties are not compelled to copy the source along with the object
+code.
+
+5. A program that contains no derivative of any portion of the Library, but is
+designed to work with the Library by being compiled or linked with it, is
+called a "work that uses the Library". Such a work, in isolation, is not a
+derivative work of the Library, and therefore falls outside the scope of this
+License.
+
+However, linking a "work that uses the Library" with the Library creates an
+executable that is a derivative of the Library (because it contains portions of
+the Library), rather than a "work that uses the library". The executable is
+therefore covered by this License. Section 6 states terms for distribution of
+such executables.
+
+When a "work that uses the Library" uses material from a header file that is
+part of the Library, the object code for the work may be a derivative work of
+the Library even though the source code is not. Whether this is true is
+especially significant if the work can be linked without the Library, or if the
+work is itself a library. The threshold for this to be true is not precisely
+defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts
+and accessors, and small macros and small inline functions (ten lines or less
+in length), then the use of the object file is unrestricted, regardless of
+whether it is legally a derivative work. (Executables containing this object
+code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute the
+object code for the work under the terms of Section 6. Any executables
+containing that work also fall under Section 6, whether or not they are linked
+directly with the Library itself.
+
+6. As an exception to the Sections above, you may also combine or link a "work
+that uses the Library" with the Library to produce a work containing portions
+of the Library, and distribute that work under terms of your choice, provided
+that the terms permit modification of the work for the customer's own use and
+reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library is
+used in it and that the Library and its use are covered by this License. You
+must supply a copy of this License. If the work during execution displays
+copyright notices, you must include the copyright notice for the Library among
+them, as well as a reference directing the user to the copy of this License.
+Also, you must do one of these things:
+
+ * a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that uses
+ the Library", as object code and/or source code, so that the user
+ can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood that
+ the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application to
+ use the modified definitions.)
+
+ * b) Use a suitable shared library mechanism for linking with
+ the Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if the
+ user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ * c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+
+ * d) If distribution of the work is made by offering access to
+ copy from a designated place, offer equivalent access to copy the
+ above specified materials from the same place.
+
+ * e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must
+include any data and utility programs needed for reproducing the executable
+from it. However, as a special exception, the materials to be distributed need
+not include anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the operating
+system on which the executable runs, unless that component itself accompanies
+the executable.
+
+It may happen that this requirement contradicts the license restrictions of
+other proprietary libraries that do not normally accompany the operating
+system. Such a contradiction means you cannot use both them and the Library
+together in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library
+side-by-side in a single library together with other library facilities not
+covered by this License, and distribute such a combined library, provided that
+the separate distribution of the work based on the Library and of the other
+library facilities is otherwise permitted, and provided that you do these two
+things:
+
+ * a) Accompany the combined library with a copy of the same
+ work based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the Sections
+ above.
+
+ * b) Give prominent notice with the combined library of the
+ fact that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the Library
+except as expressly provided under this License. Any attempt otherwise to copy,
+modify, sublicense, link with, or distribute the Library is void, and will
+automatically terminate your rights under this License. However, parties who
+have received copies, or rights, from you under this License will not have
+their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the Library
+or its derivative works. These actions are prohibited by law if you do not
+accept this License. Therefore, by modifying or distributing the Library (or
+any work based on the Library), you indicate your acceptance of this License to
+do so, and all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library),
+the recipient automatically receives a license from the original licensor to
+copy, distribute, link with or modify the Library subject to these terms and
+conditions. You may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible for enforcing
+compliance by third parties with this License.
+
+11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License. If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Library at all.
+For example, if a patent license would not permit royalty-free redistribution
+of the Library by all those who receive copies directly or indirectly through
+you, then the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply, and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system which is implemented by public license practices. Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose that
+choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Library under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded. In such
+case, this License incorporates the limitation as if written in the body of
+this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of the
+Lesser General Public License from time to time. Such new versions will be
+similar in spirit to the present version, but may differ in detail to address
+new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that
+version or of any later version published by the Free Software Foundation. If
+the Library does not specify a license version number, you may choose any
+version ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs
+whose distribution conditions are incompatible with these, write to the author
+to ask for permission. For software which is copyrighted by the Free Software
+Foundation, write to the Free Software Foundation; we sometimes make exceptions
+for this. Our decision will be guided by the two goals of preserving the free
+status of all derivatives of our free software and of promoting the sharing and
+reuse of software generally.
+
+NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU
+ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
+LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER
+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
diff --git a/libc/dfp/Makefile b/libc/dfp/Makefile
new file mode 100644
index 000000000..4c899ece8
--- /dev/null
+++ b/libc/dfp/Makefile
@@ -0,0 +1,206 @@
+subdir := dfp
+
+headers := bits/dfpfenv.h bits/dfpcalls.h
+
+# Build the -ldfp and -libdecnumber libraries.
+
+#extra-libs := libdfp
+extra-libs := libdfp libdecnumber
+extra-libs-others := $(extra-libs)
+# install-lib-ldscripts := libdfp.so
+
+# The libdecnumber code is in the libdecnumber/ directory.
+#vpath %.c libdecnumber
+#vpath %.h libdecnumber
+
+# Some symbols need to be in libdfp.so as well as libc.
+libdfp-shared = fmt_d32 fmt_d64 fmt_d128 dfptypeconv decode-decimal
+
+# The libdecnumber printing functions need to be in libc.so as well as
+# libdecnumber.
+libdecnumber-shared = decNumber decimal32 decimal64 decimal128
+
+include ../Makeconfig
+
+# libDecNumber contains some functionality which isn't needed in libc.
+libdecnumber-routines := $(libdecnumber-shared) decContext \
+ decNumberMath
+
+# These get added to libdfp. Anything in $(libdfp-shared) gets
+# added to libc.so as well because they're the printf helpers.
+libdfp-routines := $(libdfp-shared) \
+ roundd32 roundd64 roundd128 \
+ lroundd32 lroundd64 lroundd128 \
+ llroundd32 llroundd64 llroundd128 \
+ rintd32 rintd64 rintd128 \
+ lrintd32 lrintd64 lrintd128 \
+ llrintd32 llrintd64 llrintd128 \
+ truncd32 truncd64 truncd128 \
+ quantized32 quantized64 quantized128 \
+ signbitd32 signbitd64 signbitd128 \
+ copysignd32 copysignd64 copysignd128 \
+ modfd32 modfd64 modfd128 \
+ frexpd32 frexpd64 frexpd128 \
+ fpclassifyd32 fpclassifyd64 fpclassifyd128 \
+ isnormald32 isnormald64 isnormald128 \
+ isgreaterd32 isgreaterd64 isgreaterd128 \
+ isgreaterequald32 isgreaterequald64 isgreaterequald128 \
+ islessd32 islessd64 islessd128 \
+ islessequald32 islessequald64 islessequald128 \
+ islessgreaterd32 islessgreaterd64 islessgreaterd128 \
+ finited32 finited64 finited128 \
+ isinfd32 isinfd64 isinfd128 \
+ nand32 nand64 nand128 \
+ isnand32 isnand64 isnand128 \
+ isunorderedd32 isunorderedd64 isunorderedd128 \
+ fabsd32 fabsd64 fabsd128 \
+ ceild32 ceild64 ceild128 \
+ floord32 floord64 floord128 \
+ fmaxd32 fmaxd64 fmaxd128 \
+ fmind32 fmind64 fmind128 \
+ fdimd32 fdimd64 fdimd128 \
+ powd32 powd64 powd128 \
+ expd32 expd64 expd128 \
+ log10d32 log10d64 log10d128 \
+ logd32 logd64 logd128 \
+ sqrtd32 sqrtd64 sqrtd128 \
+ cbrtd32 cbrtd64 cbrtd128 \
+ atand32 atand64 atand128 \
+ atan2d32 atan2d64 atan2d128 \
+ acosd32 acosd64 acosd128 \
+ asind32 asind64 asind128 \
+ sind32 sind64 sind128 \
+ cosd32 cosd64 cosd128 \
+ tand32 tand64 tand128 \
+ sinhd32 sinhd64 sinhd128 \
+ coshd32 coshd64 coshd128 \
+ tanhd32 tanhd64 tanhd128 \
+ atanhd32 atanhd64 atanhd128 \
+ nearbyintd32 nearbyintd64 nearbyintd128 \
+ nextafterd32 nextafterd64 nextafterd128 \
+ nexttowardd32 nexttowardd64 nexttowardd128 \
+ logbd32 logbd64 logbd128 \
+ ilogbd32 ilogbd64 ilogbd128 \
+ scalbnd32 scalbnd64 scalbnd128 \
+ scalblnd32 scalblnd64 scalblnd128 \
+ ldexpd32 ldexpd64 ldexpd128 \
+ samequantumd32 samequantumd64 samequantumd128 \
+ acoshd32 acoshd64 acoshd128 \
+ asinhd32 asinhd64 asinhd128 \
+ erfd32 erfd64 erfd128 \
+ tgammad32 tgammad64 tgammad128 \
+ lgammad32 lgammad64 lgammad128 \
+ remainderd32 remainderd64 remainderd128 \
+ expm1d32 expm1d64 expm1d128 \
+ exp2d32 exp2d64 exp2d128 \
+ log1pd32 log1pd64 log1pd128 \
+ log2d32 log2d64 log2d128 \
+ fmodd32 fmodd64 fmodd128 \
+ hypotd32 hypotd64 hypotd128 \
+ fmad32 fmad64 fmad128 \
+ mapround fe_decround
+
+# Some of these functions are picked up out of the dfp/sysdeps/dfp directory
+# due to the sysdeps/unix/sysv/linux/Implies sydeps/dfp/Subdirs chain.
+routines = $(libdecnumber-shared:%=libc_%) $(libdfp-shared:%=libc_%) \
+ decroundtls strtod32 strtod64 strtod128 \
+ wcstod32 wcstod64 wcstod128 printf_dfp printf_dfphex
+
+# Will only apply to those C files being built into libdfp
+ifeq ($(subdir), dfp)
+sysdep-CFLAGS += -D__STDC_WANT_DEC_FP__=1
+endif
+
+ifneq ($(subdir), dfp)
+CFLAGS-decroundtls.c = -D__STDC_WANT_DEC_FP__=1
+CFLAGS-strtod32.c = -D__STDC_WANT_DEC_FP__=1
+CFLAGS-wcstod32.c ?= -D__STDC_WANT_DEC_FP__=1
+CFLAGS-strtod64.c = -D__STDC_WANT_DEC_FP__=1
+CFLAGS-wcstod64.c ?= -D__STDC_WANT_DEC_FP__=1
+CFLAGS-strtod128.c = -D__STDC_WANT_DEC_FP__=1
+CFLAGS-wcstod128.c ?= -D__STDC_WANT_DEC_FP__=1
+CFLAGS-fe_decround.c = -D__STDC_WANT_DEC_FP__=1
+endif
+
+#install: $(inst_libdir)/libdfp.so
+
+################BEGIN TEST SPECIFIC STUFF
+
+ifneq (no,$(PERL))
+libdfp-tests = test-d32 test-d64 test-d128
+libdfp-tests.o = $(addsuffix .o,$(libdfp-tests))
+
+# Directs the test framework to run these tests.
+tests += $(libdfp-tests)
+
+# libdfp-test.c is generated by the perl script and the .inc file
+# These will get whacked during a make clean.
+libdfp-tests-generated = libdfp-test-ulps.h libdfp-test.c
+
+# Files created by the Makefile which will be removed with a make clean
+generated += $(libdfp-tests-generated) libdfp-test.stmp
+
+# This gets used for doing pre-make dependency checks and for allowing a
+# Makefile to do something conditional based on something that can only be
+# figured out from headers. This is necessary in the test framework because
+# these are generated files and if they're changed then the test framework
+# needs to be re-run.
+before-compile += $(objpfx)libdfp-test.c
+
+# Pick the file out of the sysdeps directory?
+#ulps-file = $(firstword $(wildcard $(sysdirs:%=%/libdfp-test-ulps)))
+
+# The generated tests should be dependent on the stmp files and rebuilt when
+# the stmp files change.
+$(addprefix $(objpfx), $(libdfp-tests-generated)): $(objpfx)libdfp-test.stmp
+
+# Generate the stamps files if the include file, ulps file, or perl script
+# which generates the libdfp-test.c file have changed.
+#$(objpfx)libdfp-test.stmp: $(ulps-file) libdfp-test.inc gen-libdfp-test.pl
+$(objpfx)libdfp-test.stmp: libdfp-test-ulps libdfp-test.inc gen-libdfp-test.pl
+ $(make-target-directory)
+ $(PERL) gen-libdfp-test.pl -u $< -o "$(objpfx)"
+ @echo > $@
+
+# These .o files are generated from the libdfp-test.c file and must be rebuilt
+# if the stamp files are updated.
+$(objpfx)test-d32.o: $(objpfx)libdfp-test.stmp
+$(objpfx)test-d64.o: $(objpfx)libdfp-test.stmp
+$(objpfx)test-d128.o: $(objpfx)libdfp-test.stmp
+endif
+
+# Adding -D__STDC_WANT_DEC_FP__=1 is redundant due to earlier override.
+CFLAGS-test-d32.c = -fno-inline -fno-builtin -std=gnu99
+CFLAGS-test-d64.c = -fno-inline -fno-builtin -std=gnu99
+CFLAGS-test-d128.c = -fno-inline -fno-builtin -std=gnu99
+
+distribute += libdfp-test.inc gen-libdfp-test.pl
+
+#############END TEST-SPECIFIC STUFF
+
+# This needs to follow the 'tests' variable for that variable to be seen by
+# make check.
+include ../Rules
+
+# In order to provide actual targets for the files added to routines from
+# $(libdecnumber-shared) and $(libdfp-shared) we have to find the c files
+# associated with them and rebuild them as .o files prefaced with libc_ so
+# that they're not built with NOT_IN_libc. This is so that the hidden_proto
+# checks work properly. This doesn't create a new .c file. It simply builds
+# again and creates libc_<libdecnumber-shared>.o and libc_<libdfp-shared>.o
+# files.
+define o-iterator-doit
+$(objpfx)libc_%$o: %.c $(before-compile); $$(compile-command.c)
+endef
+object-suffixes-left := $(all-object-suffixes)
+include $(o-iterator)
+
+# Required to get libdfp linked against the test cases.
+ifeq ($(build-shared),yes)
+$(addprefix $(objpfx),$(tests)): $(objpfx)libdfp.so$(libdfp.so-version) $(objpfx)libdecnumber.so$(libdecnumber.so-version)
+endif
+
+# libc is required for libdfp in order to query the rounding mode when
+# invoking dfp functions because we need the TLS functions.
+# We current link libm.so because we need _LIB_VERSION.
+$(objpfx)libdfp.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a $(common-objpfx)dfp/libdecnumber.so $(common-objpfx)math/libm.so
diff --git a/libc/dfp/README b/libc/dfp/README
new file mode 100644
index 000000000..88402a15b
--- /dev/null
+++ b/libc/dfp/README
@@ -0,0 +1,10 @@
+The source (.c) files in this directory are modules which are included in both
+libdfp and lib. The header files contain headers which may be contained in
+both libc and libdfp but may also define headers for modules only included in
+libdfp.
+
+For Soft-DFP the decimal rounding mode is stored in libc TLS and accessed via
+a pointer to the TLS using the __decrm_location() function. The
+fe_dec_getround() and fe_dec_setround() functions live in libdfp and utilize
+the libc __decrm_location() function for soft-dfp to set/get the rounding
+mode. On Power6[x] they operate directly against the extended FPCSR.
diff --git a/libc/dfp/Versions b/libc/dfp/Versions
new file mode 100644
index 000000000..c1e754cdd
--- /dev/null
+++ b/libc/dfp/Versions
@@ -0,0 +1,305 @@
+libdfp {
+ GLIBC_2.5 {
+ # functions potentially used in other libraries
+ fe_dec_getround;
+ fe_dec_setround;
+ fmt_d32;
+ fmt_d64;
+ fmt_d128;
+ decoded32;
+ decoded64;
+ decoded128;
+ quantized32;
+ quantized64;
+ quantized128;
+ copysignd32;
+ copysignd64;
+ copysignd128;
+ modfd32;
+ modfd64;
+ modfd128;
+ frexpd32;
+ frexpd64;
+ frexpd128;
+ roundd32;
+ roundd64;
+ roundd128;
+ lroundd32;
+ lroundd64;
+ lroundd128;
+ llroundd32;
+ llroundd64;
+ llroundd128;
+ rintd32;
+ rintd64;
+ rintd128;
+ lrintd32;
+ lrintd64;
+ lrintd128;
+ llrintd32;
+ llrintd64;
+ llrintd128;
+ truncd32;
+ truncd64;
+ truncd128;
+# unnecessary externally re math.h though we maintain internal version for use
+# by fpclassifyd32/64/128.
+# isnormald32;
+# isnormald64;
+# isnormald128;
+ isgreaterd32;
+ isgreaterd64;
+ isgreaterd128;
+ isgreaterequald32;
+ isgreaterequald64;
+ isgreaterequald128;
+ islessd32;
+ islessd64;
+ islessd128;
+ islessequald32;
+ islessequald64;
+ islessequald128;
+ islessgreaterd32;
+ islessgreaterd64;
+ islessgreaterd128;
+ isunorderedd32;
+ isunorderedd64;
+ isunorderedd128;
+ fabsd32;
+ fabsd64;
+ fabsd128;
+ ceild32;
+ ceild64;
+ ceild128;
+ floord32;
+ floord64;
+ floord128;
+ fdimd32;
+ fdimd64;
+ fdimd128;
+ fmaxd32;
+ fmaxd64;
+ fmaxd128;
+ fmind32;
+ fmind64;
+ fmind128;
+ powd32;
+ powd64;
+ powd128;
+ sqrtd32;
+ sqrtd64;
+ sqrtd128;
+ cbrtd32;
+ cbrtd64;
+ cbrtd128;
+ logd32;
+ logd64;
+ logd128;
+ log10d32;
+ log10d64;
+ log10d128;
+ expd32;
+ expd64;
+ expd128;
+ asind32;
+ asind64;
+ asind128;
+ acosd32;
+ acosd64;
+ acosd128;
+ atand32;
+ atand64;
+ atand128;
+ sind32;
+ sind64;
+ sind128;
+ cosd32;
+ cosd64;
+ cosd128;
+ tand32;
+ tand64;
+ tand128;
+ atan2d32;
+ atan2d64;
+ atan2d128;
+ sinhd32;
+ sinhd64;
+ sinhd128;
+ coshd32;
+ coshd64;
+ coshd128;
+ tanhd32;
+ tanhd64;
+ tanhd128;
+ nearbyintd32;
+ nearbyintd64;
+ nearbyintd128;
+ nextafterd32;
+ nextafterd64;
+ nextafterd128;
+ nexttowardd32;
+ nexttowardd64;
+ nexttowardd128;
+ logbd32;
+ logbd64;
+ logbd128;
+ ilogbd32;
+ ilogbd64;
+ ilogbd128;
+ scalbnd32;
+ scalbnd64;
+ scalbnd128;
+ scalblnd32;
+ scalblnd64;
+ scalblnd128;
+ ldexpd32;
+ ldexpd64;
+ ldexpd128;
+ samequantumd32;
+ samequantumd64;
+ samequantumd128;
+ acoshd32;
+ acoshd64;
+ acoshd128;
+ asinhd32;
+ asinhd64;
+ asinhd128;
+ atanhd32;
+ atanhd64;
+ atanhd128;
+ erfd32;
+ erfd64;
+ erfd128;
+ erfcd32;
+ erfcd64;
+ erfcd128;
+ tgammad32;
+ tgammad64;
+ tgammad128;
+ lgammad32;
+ lgammad64;
+ lgammad128;
+ remainderd32;
+ remainderd64;
+ remainderd128;
+ log2d32;
+ log2d64;
+ log2d128;
+ log1pd32;
+ log1pd64;
+ log1pd128;
+ exp2d32;
+ exp2d64;
+ exp2d128;
+ expm1d32;
+ expm1d64;
+ expm1d128;
+ hypotd32;
+ hypotd64;
+ hypotd128;
+ fmodd32;
+ fmodd64;
+ fmodd128;
+ fmad32;
+ fmad64;
+ fmad128;
+ # The classification macros expand into these internal forms, thus
+ # internal function exposure is necessary.
+ __fpclassifyd32;
+ __fpclassifyd64;
+ __fpclassifyd128;
+ __signbitd32;
+ __signbitd64;
+ __signbitd128;
+ __finited32;
+ __finited64;
+ __finited128;
+ __isinfd32;
+ __isinfd64;
+ __isinfd128;
+ __isnand32;
+ __isnand64;
+ __isnand128;
+ };
+}
+libc {
+ GLIBC_2.5 {
+ __decrm_location;
+ strtod32;
+ strtod64;
+ strtod128;
+ wcstod32;
+ wcstod64;
+ wcstod128;
+ };
+}
+libdecnumber {
+ GLIBC_2.5 {
+ ___decNumberFromString;
+ ___decNumberToString;
+ ___decNumberToEngString;
+ ___decNumberAbs;
+ ___decNumberAdd;
+ ___decNumberCompare;
+ ___decNumberCompareTotal;
+ ___decNumberDivide;
+ ___decNumberDivideInteger;
+ ___decNumberExp;
+ ___decNumberLn;
+ ___decNumberLog10;
+ ___decNumberMax;
+ ___decNumberMin;
+ ___decNumberMinus;
+ ___decNumberMultiply;
+ ___decNumberNormalize;
+ ___decNumberPlus;
+ ___decNumberPower;
+ ___decNumberQuantize;
+ ___decNumberRemainder;
+ ___decNumberRemainderNear;
+ ___decNumberRescale;
+ ___decNumberSameQuantum;
+ ___decNumberSquareRoot;
+ ___decNumberSubtract;
+ ___decNumberToIntegralValue;
+ ___decNumberCopy;
+ ___decNumberTrim;
+ ___decNumberVersion;
+ ___decNumberZero;
+ ___decContextDefault;
+ ___decContextSetStatus;
+ ___decContextStatusToString;
+ ___decContextSetStatusFromString;
+ ___decNumberLog10;
+ ___decNumberLn;
+ ___decNumberExp;
+ ___decNumberPow;
+ ___decNumberSquareRoot;
+ ___decNumberSinh;
+ ___decNumberCosh;
+ ___decNumberTanh;
+ ___decNumberSin;
+ ___decNumberCos;
+ ___decNumberTan;
+ ___decNumberAtan;
+ ___decNumberMin;
+ ___decNumberMax;
+ ___decimal128FromString;
+ ___decimal128ToString;
+ ___decimal128ToEngString;
+ ___decimal128FromNumber;
+ ___decimal128ToNumber;
+ ___decimal64FromString;
+ ___decimal64ToString;
+ ___decimal64ToEngString;
+ ___decimal64FromNumber;
+ ___decimal64ToNumber;
+ ___decimal32FromString;
+ ___decimal32ToString;
+ ___decimal32ToEngString;
+ ___decimal32FromNumber;
+ ___decimal32ToNumber;
+ # Questionable export
+ ___decFinalize;
+ };
+}
diff --git a/libc/dfp/Versions.def b/libc/dfp/Versions.def
new file mode 100644
index 000000000..2613299e7
--- /dev/null
+++ b/libc/dfp/Versions.def
@@ -0,0 +1,6 @@
+libdfp {
+ GLIBC_2.5
+}
+libdecnumber {
+ GLIBC_2.5
+}
diff --git a/libc/dfp/bits/dfpcalls.h b/libc/dfp/bits/dfpcalls.h
new file mode 100644
index 000000000..aa39ae93f
--- /dev/null
+++ b/libc/dfp/bits/dfpcalls.h
@@ -0,0 +1,47 @@
+/* Prototype declarations for math functions related only to decimal
+ floating point support; helper file for <math.h>.
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* Per comments in <bits/mathcalls.h> this file shouldn't be protected from
+ multiple inclusion. See <bits/mathcalls.h> for more information on
+ declaring new prototypes. */
+
+#ifndef _MATH_H
+# error "Never include <bits/dfpcalls.h> directly; include <math.h> instead."
+#endif
+
+#include <stdbool.h>
+
+#ifdef __STDC_WANT_DEC_FP__
+/* DFP supported functions only; new in ISO C WG14 N1176. */
+_Mdouble_BEGIN_NAMESPACE
+
+/* Retain the value, but set the exponent of x to the exponent of y. */
+__MATHCALL (quantize,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Is the representation exponents of the x and y parameters the same? */
+/* __MATHDECL_1 (_Bool,samequantum,, (_Mdouble_ __x, _Mdouble_ __y)); */
+__MATHDECL_1 (_Bool,samequantum,, (_Mdouble_ __x, _Mdouble_ __y));
+
+_Mdouble_END_NAMESPACE
+
+#endif /* __STDC_WANT_DEC_FP__ */
diff --git a/libc/dfp/bits/dfpfenv.h b/libc/dfp/bits/dfpfenv.h
new file mode 100644
index 000000000..7874363da
--- /dev/null
+++ b/libc/dfp/bits/dfpfenv.h
@@ -0,0 +1,56 @@
+/* Decimal Floating Point rounding modes. Per the C-spec revision
+ this is included from fenv.h.
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _FENV_H
+# error "Never use <bits/dfpfenv.h> directly; include <fenv.h> instead."
+#endif
+
+#include <features.h>
+
+/* Power6[x] chips support all five of the defined rounding modes [and then
+ * some]. We use the bit pattern in the Power6[x] FPSCR as the values for the
+ * appropriate macros. In order to map these to decNumber rounding modes a
+ * conversion will have to take place. */
+enum
+ { /* Corresponds to DEC_ROUND_* */
+ FE_DEC_TONEAREST, /* DEC_ROUND_HALF_EVEN : 3 */
+#define FE_DEC_TONEAREST FE_DEC_TONEAREST
+ FE_DEC_TOWARDZERO, /* DEC_ROUND_DOWN : 5 */
+#define FE_DEC_TOWARDZERO FE_DEC_TOWARDZERO
+ FE_DEC_UPWARD, /* DEC_ROUND_CEILING : 0 */
+#define FE_DEC_UPWARD FE_DEC_UPWARD
+ FE_DEC_DOWNWARD, /* DEC_ROUND_FLOOR : 6 */
+#define FE_DEC_DOWNWARD FE_DEC_DOWNWARD
+ FE_DEC_TONEARESTFROMZERO, /* DEC_ROUND_HALF_UP : 2 */
+#define FE_DEC_TONEARESTFROMZERO FE_DEC_TONEARESTFROMZERO
+ };
+
+__BEGIN_DECLS
+
+/* Establish the rounding direction for decimal floating point operations */
+extern int fe_dec_setround(int __rounding_direction) __THROW;
+
+/* Get current decimal floating point rounding direction. */
+extern int fe_dec_getround(void) __THROW;
+
+__END_DECLS
diff --git a/libc/dfp/configure b/libc/dfp/configure
new file mode 100644
index 000000000..023156393
--- /dev/null
+++ b/libc/dfp/configure
@@ -0,0 +1,24 @@
+libc_add_on_canonical=dfp
+#does the compiler support decimal float
+#echo "$as_me:$LINENO: checking for decimal-float-support in compiler" >&5
+#echo $ECHO_N "checking for decimal-float-support in compiler... $ECHO_C" >&6
+#if test "${libc_cv_cc_with_decimal_float+set}" = set; then
+# echo $ECHO_N "(cached) $ECHO_C" >&6
+#else
+# if ${CC-cc} -v 2>&1 >/dev/null | grep -q " --enable-decimal-float "; then
+# libc_cv_cc_with_decimal_float=yes
+# else
+# libc_cv_cc_with_decimal_float=no
+# fi
+#fi
+#
+#echo "$as_me:$LINENO: result: $libc_cv_cc_with_decimal_float" >&5
+#echo "${ECHO_T}$libc_cv_cc_with_decimal_float" >&6
+#
+#if test $libc_cv_cc_with_decimal_float = no; then
+# ( exit $ac_status )
+# { { echo "$as_me:$LINENO; error: compiler must support decimal floating point." >&5
+# { (exit 1); exit 1; }; }
+#fi
+
+
diff --git a/libc/dfp/decContext.c b/libc/dfp/decContext.c
new file mode 100644
index 000000000..2a8b5f4bd
--- /dev/null
+++ b/libc/dfp/decContext.c
@@ -0,0 +1,203 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Context module */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* ------------------------------------------------------------------ */
+/* This module comprises the routines for handling arithmetic */
+/* context structures. */
+/* ------------------------------------------------------------------ */
+
+#include <string.h> // for strcmp
+#include "decContext.h" // context and base types
+#include "decNumberLocal.h" // decNumber local types, etc.
+
+#if defined NOT_IN_libc /* We don't want any of this stuff in libc. */
+/* ------------------------------------------------------------------ */
+/* ___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 */
+ /* Per the C-spec the default is DEC_ROUND_HALF_EVEN */
+ context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to the nearest even */
+ 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 set status. */
+ ___decContextSetStatus(context, DEC_Invalid_operation);
+ }
+ return context;
+} /* ___decContextDefault */
+
+/* ------------------------------------------------------------------ */
+/* ___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;
+ if (status==DEC_Conversion_syntax ) return DEC_Condition_CS;
+ if (status==DEC_Division_by_zero ) return DEC_Condition_DZ;
+ if (status==DEC_Division_impossible ) return DEC_Condition_DI;
+ if (status==DEC_Division_undefined ) return DEC_Condition_DU;
+ if (status==DEC_Inexact ) return DEC_Condition_IE;
+ if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
+ if (status==DEC_Invalid_context ) return DEC_Condition_IC;
+ if (status==DEC_Invalid_operation ) return DEC_Condition_IO;
+ #if DECSUBSET
+ if (status==DEC_Lost_digits ) return DEC_Condition_LD;
+ #endif
+ if (status==DEC_Overflow ) return DEC_Condition_OV;
+ if (status==DEC_Clamped ) return DEC_Condition_PA;
+ if (status==DEC_Rounded ) return DEC_Condition_RO;
+ if (status==DEC_Subnormal ) return DEC_Condition_SU;
+ if (status==DEC_Underflow ) return DEC_Condition_UN;
+ if (status==0 ) return DEC_Condition_ZE;
+ return DEC_Condition_MU; /* Multiple errors */
+ } /* ___decContextStatusToString */
+
+/* ------------------------------------------------------------------ */
+/* ___decContextSetStatusFromString -- set status from a string */
+/* */
+/* context is the controlling context */
+/* 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 */
+
+/* ------------------------------------------------------------------ */
+/* ___decContextSetStatus -- set status and raise trap if appropriate */
+/* */
+/* context is the controlling context */
+/* 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;
+ /* libdfp won't allow libdecnumber to raise exceptions. This will be done
+ * in libdfp proper after investigating context->status. */
+ /* if (status & context->traps) raise(SIGFPE); */
+ return context;
+} /* ___decContextSetStatus */
+#endif /* NOT_IN_libc */
diff --git a/libc/dfp/decContext.h b/libc/dfp/decContext.h
new file mode 100644
index 000000000..d342a26f6
--- /dev/null
+++ b/libc/dfp/decContext.h
@@ -0,0 +1,175 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Context module header */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* ------------------------------------------------------------------ */
+/* Context must always be set correctly: */
+/* */
+/* 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 */
+/* round -- must be one of the enumerated rounding modes */
+/* traps -- only defined bits may be set */
+/* status -- [any bits may be cleared, but not set, by user] */
+/* clamp -- must be either 0 or 1 */
+/* extended -- must be either 0 or 1 [present only if DECSUBSET] */
+/* */
+/* ------------------------------------------------------------------ */
+
+#ifndef _DEC_CONTEXT_H
+#define _DEC_CONTEXT_H 1
+
+#include <stdint.h> /* C99 standard integers */
+
+#define DECSUBSET 0
+
+/* Conditional code flag -- set this to 0 for best performance */
+#define DECSUBSET 0 /* 1=enable subset arithmetic */
+
+/* Context for operations, with associated constants.
+ * Do NOT change the order of these enums without changing the values of
+ * the corresponding FE_DEC_* enums in <fenv.h>
+ * Per the C Specification the default rounding mode is FE_DEC_TONEAREST which
+ * maps to DEC_ROUND_HALF_EVEN. The decContext->round default was changed to
+ * reflect this. */
+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_MAX /* enum must be less than this */
+};
+
+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 */
+#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 functions */
+
+/* Trap-enabler and Status flags (exceptional conditions), and their names */
+/* Top byte is reserved for internal use */
+#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 /* [used if 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
+
+/* 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 (results are 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 (have 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
+
+#if defined NOT_IN_libc /* We don't want these available in libc. */
+/* decContext routines */
+decContext * ___decContextDefault(decContext *, int32_t);
+decContext * ___decContextSetStatus(decContext *, uint32_t);
+const char * ___decContextStatusToString(const decContext *);
+decContext * ___decContextSetStatusFromString(decContext *, const char *);
+#endif /* NOT_IN_libc */
+
+#endif /* _DEC_CONTEXT_H */
diff --git a/libc/dfp/decDPD.h b/libc/dfp/decDPD.h
new file mode 100644
index 000000000..d169c5299
--- /dev/null
+++ b/libc/dfp/decDPD.h
@@ -0,0 +1,889 @@
+/* ------------------------------------------------------------------------ */
+/* Binary Coded Decimal <--> Densely Packed Decimal lookup tables */
+/* [Automatically generated -- do not edit. 2006.11.09] */
+/* ------------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* For details, see: http://www2.hursley.ibm.com/decimal/DPDecimal.html */
+/* */
+/* This include file defines conversion tables for DPD, as follows. */
+/* */
+/* uint16_t BCD2DPD[2458]; // BCD -> DPD (0x999 => 2457) */
+/* uint16_t __BIND2DPD[1000]; // BIN -> DPD (999 => 2457) */
+/* uint8_t BIN2CHAR[4001]; // Bin -> CHAR (999 => '\3' '9' '9' '9') */
+/* uint16_t DPD2BCD[1024]; // DPD -> BCD (0x3FF => 0x999) */
+/* uint16_t DPD2BIN[1024]; // DPD -> BIN (0x3FF => 999) */
+/* uint8_t DPD2BCD8[4096]; // DPD -> bytes (x3FF => 9 9 9 3) */
+/* */
+/* In all cases the result (10 bits or 12 bits, or binary) is right-aligned */
+/* in the table entry. BIN2CHAR entries are a single byte length (0 for */
+/* value 0) followed by three digit characters; a trailing terminator is */
+/* included to allow 4-char moves always. DPD2BCD8 entries are similar */
+/* with the three BCD8 digits followed by a one-byte length. */
+/* */
+/* To use a table, its name, prefixed with DEC_, must be defined with a */
+/* value of 1 before this header file is included. For example: */
+/* #define DEC_BCD2DPD 1 */
+/* ------------------------------------------------------------------------ */
+
+#if DEC_BCD2DPD==1 && !defined(DECBCD2DPD)
+#define DECBCD2DPD
+
+const uint16_t BCD2DPD[2458]={ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 0, 0, 0, 0, 0, 0, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 0, 0, 0, 0, 0,
+ 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 0,
+ 0, 0, 0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 0, 0, 0, 0, 0, 0, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, 96, 97, 98,
+ 99, 100, 101, 102, 103, 104, 105, 0, 0, 0, 0, 0, 0,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 0, 0, 0,
+ 0, 0, 0, 10, 11, 42, 43, 74, 75, 106, 107, 78, 79,
+ 0, 0, 0, 0, 0, 0, 26, 27, 58, 59, 90, 91, 122,
+ 123, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 42, 43, 74,
+ 75, 106, 107, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 0, 0,
+ 0, 0, 0, 0, 144, 145, 146, 147, 148, 149, 150, 151, 152,
+ 153, 0, 0, 0, 0, 0, 0, 160, 161, 162, 163, 164, 165,
+ 166, 167, 168, 169, 0, 0, 0, 0, 0, 0, 176, 177, 178,
+ 179, 180, 181, 182, 183, 184, 185, 0, 0, 0, 0, 0, 0,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 0, 0, 0,
+ 0, 0, 0, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
+ 0, 0, 0, 0, 0, 0, 224, 225, 226, 227, 228, 229, 230,
+ 231, 232, 233, 0, 0, 0, 0, 0, 0, 240, 241, 242, 243,
+ 244, 245, 246, 247, 248, 249, 0, 0, 0, 0, 0, 0, 138,
+ 139, 170, 171, 202, 203, 234, 235, 206, 207, 0, 0, 0, 0,
+ 0, 0, 154, 155, 186, 187, 218, 219, 250, 251, 222, 223, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 138, 139, 170, 171, 202, 203, 234, 235, 206,
+ 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 257, 258,
+ 259, 260, 261, 262, 263, 264, 265, 0, 0, 0, 0, 0, 0,
+ 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 0, 0, 0,
+ 0, 0, 0, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297,
+ 0, 0, 0, 0, 0, 0, 304, 305, 306, 307, 308, 309, 310,
+ 311, 312, 313, 0, 0, 0, 0, 0, 0, 320, 321, 322, 323,
+ 324, 325, 326, 327, 328, 329, 0, 0, 0, 0, 0, 0, 336,
+ 337, 338, 339, 340, 341, 342, 343, 344, 345, 0, 0, 0, 0,
+ 0, 0, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 0,
+ 0, 0, 0, 0, 0, 368, 369, 370, 371, 372, 373, 374, 375,
+ 376, 377, 0, 0, 0, 0, 0, 0, 266, 267, 298, 299, 330,
+ 331, 362, 363, 334, 335, 0, 0, 0, 0, 0, 0, 282, 283,
+ 314, 315, 346, 347, 378, 379, 350, 351, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 266, 267, 298, 299, 330, 331, 362, 363, 334, 335, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 384, 385, 386, 387, 388, 389, 390,
+ 391, 392, 393, 0, 0, 0, 0, 0, 0, 400, 401, 402, 403,
+ 404, 405, 406, 407, 408, 409, 0, 0, 0, 0, 0, 0, 416,
+ 417, 418, 419, 420, 421, 422, 423, 424, 425, 0, 0, 0, 0,
+ 0, 0, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 0,
+ 0, 0, 0, 0, 0, 448, 449, 450, 451, 452, 453, 454, 455,
+ 456, 457, 0, 0, 0, 0, 0, 0, 464, 465, 466, 467, 468,
+ 469, 470, 471, 472, 473, 0, 0, 0, 0, 0, 0, 480, 481,
+ 482, 483, 484, 485, 486, 487, 488, 489, 0, 0, 0, 0, 0,
+ 0, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 0, 0,
+ 0, 0, 0, 0, 394, 395, 426, 427, 458, 459, 490, 491, 462,
+ 463, 0, 0, 0, 0, 0, 0, 410, 411, 442, 443, 474, 475,
+ 506, 507, 478, 479, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 394, 395, 426, 427,
+ 458, 459, 490, 491, 462, 463, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 0,
+ 0, 0, 0, 0, 0, 528, 529, 530, 531, 532, 533, 534, 535,
+ 536, 537, 0, 0, 0, 0, 0, 0, 544, 545, 546, 547, 548,
+ 549, 550, 551, 552, 553, 0, 0, 0, 0, 0, 0, 560, 561,
+ 562, 563, 564, 565, 566, 567, 568, 569, 0, 0, 0, 0, 0,
+ 0, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 0, 0,
+ 0, 0, 0, 0, 592, 593, 594, 595, 596, 597, 598, 599, 600,
+ 601, 0, 0, 0, 0, 0, 0, 608, 609, 610, 611, 612, 613,
+ 614, 615, 616, 617, 0, 0, 0, 0, 0, 0, 624, 625, 626,
+ 627, 628, 629, 630, 631, 632, 633, 0, 0, 0, 0, 0, 0,
+ 522, 523, 554, 555, 586, 587, 618, 619, 590, 591, 0, 0, 0,
+ 0, 0, 0, 538, 539, 570, 571, 602, 603, 634, 635, 606, 607,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 522, 523, 554, 555, 586, 587, 618, 619,
+ 590, 591, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 640, 641,
+ 642, 643, 644, 645, 646, 647, 648, 649, 0, 0, 0, 0, 0,
+ 0, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 0, 0,
+ 0, 0, 0, 0, 672, 673, 674, 675, 676, 677, 678, 679, 680,
+ 681, 0, 0, 0, 0, 0, 0, 688, 689, 690, 691, 692, 693,
+ 694, 695, 696, 697, 0, 0, 0, 0, 0, 0, 704, 705, 706,
+ 707, 708, 709, 710, 711, 712, 713, 0, 0, 0, 0, 0, 0,
+ 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 0, 0, 0,
+ 0, 0, 0, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745,
+ 0, 0, 0, 0, 0, 0, 752, 753, 754, 755, 756, 757, 758,
+ 759, 760, 761, 0, 0, 0, 0, 0, 0, 650, 651, 682, 683,
+ 714, 715, 746, 747, 718, 719, 0, 0, 0, 0, 0, 0, 666,
+ 667, 698, 699, 730, 731, 762, 763, 734, 735, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 650, 651, 682, 683, 714, 715, 746, 747, 718, 719, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 768, 769, 770, 771, 772, 773,
+ 774, 775, 776, 777, 0, 0, 0, 0, 0, 0, 784, 785, 786,
+ 787, 788, 789, 790, 791, 792, 793, 0, 0, 0, 0, 0, 0,
+ 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 0, 0, 0,
+ 0, 0, 0, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825,
+ 0, 0, 0, 0, 0, 0, 832, 833, 834, 835, 836, 837, 838,
+ 839, 840, 841, 0, 0, 0, 0, 0, 0, 848, 849, 850, 851,
+ 852, 853, 854, 855, 856, 857, 0, 0, 0, 0, 0, 0, 864,
+ 865, 866, 867, 868, 869, 870, 871, 872, 873, 0, 0, 0, 0,
+ 0, 0, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 0,
+ 0, 0, 0, 0, 0, 778, 779, 810, 811, 842, 843, 874, 875,
+ 846, 847, 0, 0, 0, 0, 0, 0, 794, 795, 826, 827, 858,
+ 859, 890, 891, 862, 863, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 778, 779, 810,
+ 811, 842, 843, 874, 875, 846, 847, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905,
+ 0, 0, 0, 0, 0, 0, 912, 913, 914, 915, 916, 917, 918,
+ 919, 920, 921, 0, 0, 0, 0, 0, 0, 928, 929, 930, 931,
+ 932, 933, 934, 935, 936, 937, 0, 0, 0, 0, 0, 0, 944,
+ 945, 946, 947, 948, 949, 950, 951, 952, 953, 0, 0, 0, 0,
+ 0, 0, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 0,
+ 0, 0, 0, 0, 0, 976, 977, 978, 979, 980, 981, 982, 983,
+ 984, 985, 0, 0, 0, 0, 0, 0, 992, 993, 994, 995, 996,
+ 997, 998, 999, 1000, 1001, 0, 0, 0, 0, 0, 0, 1008, 1009,
+ 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, 0, 0,
+ 0, 906, 907, 938, 939, 970, 971, 1002, 1003, 974, 975, 0, 0,
+ 0, 0, 0, 0, 922, 923, 954, 955, 986, 987, 1018, 1019, 990,
+ 991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 906, 907, 938, 939, 970, 971, 1002,
+ 1003, 974, 975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
+ 13, 268, 269, 524, 525, 780, 781, 46, 47, 0, 0, 0, 0,
+ 0, 0, 28, 29, 284, 285, 540, 541, 796, 797, 62, 63, 0,
+ 0, 0, 0, 0, 0, 44, 45, 300, 301, 556, 557, 812, 813,
+ 302, 303, 0, 0, 0, 0, 0, 0, 60, 61, 316, 317, 572,
+ 573, 828, 829, 318, 319, 0, 0, 0, 0, 0, 0, 76, 77,
+ 332, 333, 588, 589, 844, 845, 558, 559, 0, 0, 0, 0, 0,
+ 0, 92, 93, 348, 349, 604, 605, 860, 861, 574, 575, 0, 0,
+ 0, 0, 0, 0, 108, 109, 364, 365, 620, 621, 876, 877, 814,
+ 815, 0, 0, 0, 0, 0, 0, 124, 125, 380, 381, 636, 637,
+ 892, 893, 830, 831, 0, 0, 0, 0, 0, 0, 14, 15, 270,
+ 271, 526, 527, 782, 783, 110, 111, 0, 0, 0, 0, 0, 0,
+ 30, 31, 286, 287, 542, 543, 798, 799, 126, 127, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 14, 15, 270, 271, 526, 527, 782, 783, 110, 111, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 140, 141, 396, 397, 652,
+ 653, 908, 909, 174, 175, 0, 0, 0, 0, 0, 0, 156, 157,
+ 412, 413, 668, 669, 924, 925, 190, 191, 0, 0, 0, 0, 0,
+ 0, 172, 173, 428, 429, 684, 685, 940, 941, 430, 431, 0, 0,
+ 0, 0, 0, 0, 188, 189, 444, 445, 700, 701, 956, 957, 446,
+ 447, 0, 0, 0, 0, 0, 0, 204, 205, 460, 461, 716, 717,
+ 972, 973, 686, 687, 0, 0, 0, 0, 0, 0, 220, 221, 476,
+ 477, 732, 733, 988, 989, 702, 703, 0, 0, 0, 0, 0, 0,
+ 236, 237, 492, 493, 748, 749, 1004, 1005, 942, 943, 0, 0, 0,
+ 0, 0, 0, 252, 253, 508, 509, 764, 765, 1020, 1021, 958, 959,
+ 0, 0, 0, 0, 0, 0, 142, 143, 398, 399, 654, 655, 910,
+ 911, 238, 239, 0, 0, 0, 0, 0, 0, 158, 159, 414, 415,
+ 670, 671, 926, 927, 254, 255};
+#endif
+
+#if DEC_DPD2BCD==1 && !defined(DECDPD2BCD)
+#define DECDPD2BCD
+
+const uint16_t DPD2BCD[1024]={ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 128, 129, 2048, 2049, 2176, 2177, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 144, 145, 2064, 2065, 2192, 2193, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 130, 131, 2080, 2081, 2056,
+ 2057, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 146, 147,
+ 2096, 2097, 2072, 2073, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 132, 133, 2112, 2113, 136, 137, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 148, 149, 2128, 2129, 152, 153, 96, 97, 98,
+ 99, 100, 101, 102, 103, 104, 105, 134, 135, 2144, 2145, 2184, 2185,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 150, 151, 2160,
+ 2161, 2200, 2201, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
+ 384, 385, 2304, 2305, 2432, 2433, 272, 273, 274, 275, 276, 277, 278,
+ 279, 280, 281, 400, 401, 2320, 2321, 2448, 2449, 288, 289, 290, 291,
+ 292, 293, 294, 295, 296, 297, 386, 387, 2336, 2337, 2312, 2313, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 402, 403, 2352, 2353,
+ 2328, 2329, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 388,
+ 389, 2368, 2369, 392, 393, 336, 337, 338, 339, 340, 341, 342, 343,
+ 344, 345, 404, 405, 2384, 2385, 408, 409, 352, 353, 354, 355, 356,
+ 357, 358, 359, 360, 361, 390, 391, 2400, 2401, 2440, 2441, 368, 369,
+ 370, 371, 372, 373, 374, 375, 376, 377, 406, 407, 2416, 2417, 2456,
+ 2457, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 640, 641,
+ 2050, 2051, 2178, 2179, 528, 529, 530, 531, 532, 533, 534, 535, 536,
+ 537, 656, 657, 2066, 2067, 2194, 2195, 544, 545, 546, 547, 548, 549,
+ 550, 551, 552, 553, 642, 643, 2082, 2083, 2088, 2089, 560, 561, 562,
+ 563, 564, 565, 566, 567, 568, 569, 658, 659, 2098, 2099, 2104, 2105,
+ 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 644, 645, 2114,
+ 2115, 648, 649, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601,
+ 660, 661, 2130, 2131, 664, 665, 608, 609, 610, 611, 612, 613, 614,
+ 615, 616, 617, 646, 647, 2146, 2147, 2184, 2185, 624, 625, 626, 627,
+ 628, 629, 630, 631, 632, 633, 662, 663, 2162, 2163, 2200, 2201, 768,
+ 769, 770, 771, 772, 773, 774, 775, 776, 777, 896, 897, 2306, 2307,
+ 2434, 2435, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 912,
+ 913, 2322, 2323, 2450, 2451, 800, 801, 802, 803, 804, 805, 806, 807,
+ 808, 809, 898, 899, 2338, 2339, 2344, 2345, 816, 817, 818, 819, 820,
+ 821, 822, 823, 824, 825, 914, 915, 2354, 2355, 2360, 2361, 832, 833,
+ 834, 835, 836, 837, 838, 839, 840, 841, 900, 901, 2370, 2371, 904,
+ 905, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 916, 917,
+ 2386, 2387, 920, 921, 864, 865, 866, 867, 868, 869, 870, 871, 872,
+ 873, 902, 903, 2402, 2403, 2440, 2441, 880, 881, 882, 883, 884, 885,
+ 886, 887, 888, 889, 918, 919, 2418, 2419, 2456, 2457, 1024, 1025, 1026,
+ 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1152, 1153, 2052, 2053, 2180, 2181,
+ 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1168, 1169, 2068,
+ 2069, 2196, 2197, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065,
+ 1154, 1155, 2084, 2085, 2120, 2121, 1072, 1073, 1074, 1075, 1076, 1077, 1078,
+ 1079, 1080, 1081, 1170, 1171, 2100, 2101, 2136, 2137, 1088, 1089, 1090, 1091,
+ 1092, 1093, 1094, 1095, 1096, 1097, 1156, 1157, 2116, 2117, 1160, 1161, 1104,
+ 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1172, 1173, 2132, 2133,
+ 1176, 1177, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1158,
+ 1159, 2148, 2149, 2184, 2185, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143,
+ 1144, 1145, 1174, 1175, 2164, 2165, 2200, 2201, 1280, 1281, 1282, 1283, 1284,
+ 1285, 1286, 1287, 1288, 1289, 1408, 1409, 2308, 2309, 2436, 2437, 1296, 1297,
+ 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1424, 1425, 2324, 2325, 2452,
+ 2453, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1410, 1411,
+ 2340, 2341, 2376, 2377, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336,
+ 1337, 1426, 1427, 2356, 2357, 2392, 2393, 1344, 1345, 1346, 1347, 1348, 1349,
+ 1350, 1351, 1352, 1353, 1412, 1413, 2372, 2373, 1416, 1417, 1360, 1361, 1362,
+ 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1428, 1429, 2388, 2389, 1432, 1433,
+ 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1414, 1415, 2404,
+ 2405, 2440, 2441, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401,
+ 1430, 1431, 2420, 2421, 2456, 2457, 1536, 1537, 1538, 1539, 1540, 1541, 1542,
+ 1543, 1544, 1545, 1664, 1665, 2054, 2055, 2182, 2183, 1552, 1553, 1554, 1555,
+ 1556, 1557, 1558, 1559, 1560, 1561, 1680, 1681, 2070, 2071, 2198, 2199, 1568,
+ 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1666, 1667, 2086, 2087,
+ 2152, 2153, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1682,
+ 1683, 2102, 2103, 2168, 2169, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607,
+ 1608, 1609, 1668, 1669, 2118, 2119, 1672, 1673, 1616, 1617, 1618, 1619, 1620,
+ 1621, 1622, 1623, 1624, 1625, 1684, 1685, 2134, 2135, 1688, 1689, 1632, 1633,
+ 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1670, 1671, 2150, 2151, 2184,
+ 2185, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1686, 1687,
+ 2166, 2167, 2200, 2201, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800,
+ 1801, 1920, 1921, 2310, 2311, 2438, 2439, 1808, 1809, 1810, 1811, 1812, 1813,
+ 1814, 1815, 1816, 1817, 1936, 1937, 2326, 2327, 2454, 2455, 1824, 1825, 1826,
+ 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1922, 1923, 2342, 2343, 2408, 2409,
+ 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1938, 1939, 2358,
+ 2359, 2424, 2425, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865,
+ 1924, 1925, 2374, 2375, 1928, 1929, 1872, 1873, 1874, 1875, 1876, 1877, 1878,
+ 1879, 1880, 1881, 1940, 1941, 2390, 2391, 1944, 1945, 1888, 1889, 1890, 1891,
+ 1892, 1893, 1894, 1895, 1896, 1897, 1926, 1927, 2406, 2407, 2440, 2441, 1904,
+ 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1942, 1943, 2422, 2423,
+ 2456, 2457};
+/* libc_hidden_data_def (DPD2BCD) */
+#endif
+
+#if DEC___BIND2DPD==1 && !defined(DEC__BIND2DPD)
+#define DEC__BIND2DPD
+
+const uint16_t __BIND2DPD[1000]={ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 10, 11, 42, 43, 74, 75,
+ 106, 107, 78, 79, 26, 27, 58, 59, 90, 91, 122, 123, 94,
+ 95, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 144, 145,
+ 146, 147, 148, 149, 150, 151, 152, 153, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 169, 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 208,
+ 209, 210, 211, 212, 213, 214, 215, 216, 217, 224, 225, 226, 227,
+ 228, 229, 230, 231, 232, 233, 240, 241, 242, 243, 244, 245, 246,
+ 247, 248, 249, 138, 139, 170, 171, 202, 203, 234, 235, 206, 207,
+ 154, 155, 186, 187, 218, 219, 250, 251, 222, 223, 256, 257, 258,
+ 259, 260, 261, 262, 263, 264, 265, 272, 273, 274, 275, 276, 277,
+ 278, 279, 280, 281, 288, 289, 290, 291, 292, 293, 294, 295, 296,
+ 297, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 320, 321,
+ 322, 323, 324, 325, 326, 327, 328, 329, 336, 337, 338, 339, 340,
+ 341, 342, 343, 344, 345, 352, 353, 354, 355, 356, 357, 358, 359,
+ 360, 361, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 266,
+ 267, 298, 299, 330, 331, 362, 363, 334, 335, 282, 283, 314, 315,
+ 346, 347, 378, 379, 350, 351, 384, 385, 386, 387, 388, 389, 390,
+ 391, 392, 393, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409,
+ 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 432, 433, 434,
+ 435, 436, 437, 438, 439, 440, 441, 448, 449, 450, 451, 452, 453,
+ 454, 455, 456, 457, 464, 465, 466, 467, 468, 469, 470, 471, 472,
+ 473, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 496, 497,
+ 498, 499, 500, 501, 502, 503, 504, 505, 394, 395, 426, 427, 458,
+ 459, 490, 491, 462, 463, 410, 411, 442, 443, 474, 475, 506, 507,
+ 478, 479, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 528,
+ 529, 530, 531, 532, 533, 534, 535, 536, 537, 544, 545, 546, 547,
+ 548, 549, 550, 551, 552, 553, 560, 561, 562, 563, 564, 565, 566,
+ 567, 568, 569, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585,
+ 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 608, 609, 610,
+ 611, 612, 613, 614, 615, 616, 617, 624, 625, 626, 627, 628, 629,
+ 630, 631, 632, 633, 522, 523, 554, 555, 586, 587, 618, 619, 590,
+ 591, 538, 539, 570, 571, 602, 603, 634, 635, 606, 607, 640, 641,
+ 642, 643, 644, 645, 646, 647, 648, 649, 656, 657, 658, 659, 660,
+ 661, 662, 663, 664, 665, 672, 673, 674, 675, 676, 677, 678, 679,
+ 680, 681, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 704,
+ 705, 706, 707, 708, 709, 710, 711, 712, 713, 720, 721, 722, 723,
+ 724, 725, 726, 727, 728, 729, 736, 737, 738, 739, 740, 741, 742,
+ 743, 744, 745, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761,
+ 650, 651, 682, 683, 714, 715, 746, 747, 718, 719, 666, 667, 698,
+ 699, 730, 731, 762, 763, 734, 735, 768, 769, 770, 771, 772, 773,
+ 774, 775, 776, 777, 784, 785, 786, 787, 788, 789, 790, 791, 792,
+ 793, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 816, 817,
+ 818, 819, 820, 821, 822, 823, 824, 825, 832, 833, 834, 835, 836,
+ 837, 838, 839, 840, 841, 848, 849, 850, 851, 852, 853, 854, 855,
+ 856, 857, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 880,
+ 881, 882, 883, 884, 885, 886, 887, 888, 889, 778, 779, 810, 811,
+ 842, 843, 874, 875, 846, 847, 794, 795, 826, 827, 858, 859, 890,
+ 891, 862, 863, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905,
+ 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 928, 929, 930,
+ 931, 932, 933, 934, 935, 936, 937, 944, 945, 946, 947, 948, 949,
+ 950, 951, 952, 953, 960, 961, 962, 963, 964, 965, 966, 967, 968,
+ 969, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 992, 993,
+ 994, 995, 996, 997, 998, 999, 1000, 1001, 1008, 1009, 1010, 1011, 1012,
+ 1013, 1014, 1015, 1016, 1017, 906, 907, 938, 939, 970, 971, 1002, 1003,
+ 974, 975, 922, 923, 954, 955, 986, 987, 1018, 1019, 990, 991, 12,
+ 13, 268, 269, 524, 525, 780, 781, 46, 47, 28, 29, 284, 285,
+ 540, 541, 796, 797, 62, 63, 44, 45, 300, 301, 556, 557, 812,
+ 813, 302, 303, 60, 61, 316, 317, 572, 573, 828, 829, 318, 319,
+ 76, 77, 332, 333, 588, 589, 844, 845, 558, 559, 92, 93, 348,
+ 349, 604, 605, 860, 861, 574, 575, 108, 109, 364, 365, 620, 621,
+ 876, 877, 814, 815, 124, 125, 380, 381, 636, 637, 892, 893, 830,
+ 831, 14, 15, 270, 271, 526, 527, 782, 783, 110, 111, 30, 31,
+ 286, 287, 542, 543, 798, 799, 126, 127, 140, 141, 396, 397, 652,
+ 653, 908, 909, 174, 175, 156, 157, 412, 413, 668, 669, 924, 925,
+ 190, 191, 172, 173, 428, 429, 684, 685, 940, 941, 430, 431, 188,
+ 189, 444, 445, 700, 701, 956, 957, 446, 447, 204, 205, 460, 461,
+ 716, 717, 972, 973, 686, 687, 220, 221, 476, 477, 732, 733, 988,
+ 989, 702, 703, 236, 237, 492, 493, 748, 749, 1004, 1005, 942, 943,
+ 252, 253, 508, 509, 764, 765, 1020, 1021, 958, 959, 142, 143, 398,
+ 399, 654, 655, 910, 911, 238, 239, 158, 159, 414, 415, 670, 671,
+ 926, 927, 254, 255};
+/* libc_hidden_data_def(__BIND2DPD) */
+#endif
+
+#if DEC_DPD2BIN==1 && !defined(DECDPD2BIN)
+#define DECDPD2BIN
+
+const uint16_t DPD2BIN[1024]={ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 80, 81, 800, 801, 880, 881, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 90, 91, 810, 811, 890, 891, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 82, 83, 820, 821, 808,
+ 809, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 92, 93,
+ 830, 831, 818, 819, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 84, 85, 840, 841, 88, 89, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 94, 95, 850, 851, 98, 99, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 86, 87, 860, 861, 888, 889,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 96, 97, 870,
+ 871, 898, 899, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 180, 181, 900, 901, 980, 981, 110, 111, 112, 113, 114, 115, 116,
+ 117, 118, 119, 190, 191, 910, 911, 990, 991, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 182, 183, 920, 921, 908, 909, 130,
+ 131, 132, 133, 134, 135, 136, 137, 138, 139, 192, 193, 930, 931,
+ 918, 919, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 184,
+ 185, 940, 941, 188, 189, 150, 151, 152, 153, 154, 155, 156, 157,
+ 158, 159, 194, 195, 950, 951, 198, 199, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 169, 186, 187, 960, 961, 988, 989, 170, 171,
+ 172, 173, 174, 175, 176, 177, 178, 179, 196, 197, 970, 971, 998,
+ 999, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 280, 281,
+ 802, 803, 882, 883, 210, 211, 212, 213, 214, 215, 216, 217, 218,
+ 219, 290, 291, 812, 813, 892, 893, 220, 221, 222, 223, 224, 225,
+ 226, 227, 228, 229, 282, 283, 822, 823, 828, 829, 230, 231, 232,
+ 233, 234, 235, 236, 237, 238, 239, 292, 293, 832, 833, 838, 839,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 284, 285, 842,
+ 843, 288, 289, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
+ 294, 295, 852, 853, 298, 299, 260, 261, 262, 263, 264, 265, 266,
+ 267, 268, 269, 286, 287, 862, 863, 888, 889, 270, 271, 272, 273,
+ 274, 275, 276, 277, 278, 279, 296, 297, 872, 873, 898, 899, 300,
+ 301, 302, 303, 304, 305, 306, 307, 308, 309, 380, 381, 902, 903,
+ 982, 983, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 390,
+ 391, 912, 913, 992, 993, 320, 321, 322, 323, 324, 325, 326, 327,
+ 328, 329, 382, 383, 922, 923, 928, 929, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 392, 393, 932, 933, 938, 939, 340, 341,
+ 342, 343, 344, 345, 346, 347, 348, 349, 384, 385, 942, 943, 388,
+ 389, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 394, 395,
+ 952, 953, 398, 399, 360, 361, 362, 363, 364, 365, 366, 367, 368,
+ 369, 386, 387, 962, 963, 988, 989, 370, 371, 372, 373, 374, 375,
+ 376, 377, 378, 379, 396, 397, 972, 973, 998, 999, 400, 401, 402,
+ 403, 404, 405, 406, 407, 408, 409, 480, 481, 804, 805, 884, 885,
+ 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 490, 491, 814,
+ 815, 894, 895, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429,
+ 482, 483, 824, 825, 848, 849, 430, 431, 432, 433, 434, 435, 436,
+ 437, 438, 439, 492, 493, 834, 835, 858, 859, 440, 441, 442, 443,
+ 444, 445, 446, 447, 448, 449, 484, 485, 844, 845, 488, 489, 450,
+ 451, 452, 453, 454, 455, 456, 457, 458, 459, 494, 495, 854, 855,
+ 498, 499, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 486,
+ 487, 864, 865, 888, 889, 470, 471, 472, 473, 474, 475, 476, 477,
+ 478, 479, 496, 497, 874, 875, 898, 899, 500, 501, 502, 503, 504,
+ 505, 506, 507, 508, 509, 580, 581, 904, 905, 984, 985, 510, 511,
+ 512, 513, 514, 515, 516, 517, 518, 519, 590, 591, 914, 915, 994,
+ 995, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 582, 583,
+ 924, 925, 948, 949, 530, 531, 532, 533, 534, 535, 536, 537, 538,
+ 539, 592, 593, 934, 935, 958, 959, 540, 541, 542, 543, 544, 545,
+ 546, 547, 548, 549, 584, 585, 944, 945, 588, 589, 550, 551, 552,
+ 553, 554, 555, 556, 557, 558, 559, 594, 595, 954, 955, 598, 599,
+ 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 586, 587, 964,
+ 965, 988, 989, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579,
+ 596, 597, 974, 975, 998, 999, 600, 601, 602, 603, 604, 605, 606,
+ 607, 608, 609, 680, 681, 806, 807, 886, 887, 610, 611, 612, 613,
+ 614, 615, 616, 617, 618, 619, 690, 691, 816, 817, 896, 897, 620,
+ 621, 622, 623, 624, 625, 626, 627, 628, 629, 682, 683, 826, 827,
+ 868, 869, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 692,
+ 693, 836, 837, 878, 879, 640, 641, 642, 643, 644, 645, 646, 647,
+ 648, 649, 684, 685, 846, 847, 688, 689, 650, 651, 652, 653, 654,
+ 655, 656, 657, 658, 659, 694, 695, 856, 857, 698, 699, 660, 661,
+ 662, 663, 664, 665, 666, 667, 668, 669, 686, 687, 866, 867, 888,
+ 889, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 696, 697,
+ 876, 877, 898, 899, 700, 701, 702, 703, 704, 705, 706, 707, 708,
+ 709, 780, 781, 906, 907, 986, 987, 710, 711, 712, 713, 714, 715,
+ 716, 717, 718, 719, 790, 791, 916, 917, 996, 997, 720, 721, 722,
+ 723, 724, 725, 726, 727, 728, 729, 782, 783, 926, 927, 968, 969,
+ 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 792, 793, 936,
+ 937, 978, 979, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749,
+ 784, 785, 946, 947, 788, 789, 750, 751, 752, 753, 754, 755, 756,
+ 757, 758, 759, 794, 795, 956, 957, 798, 799, 760, 761, 762, 763,
+ 764, 765, 766, 767, 768, 769, 786, 787, 966, 967, 988, 989, 770,
+ 771, 772, 773, 774, 775, 776, 777, 778, 779, 796, 797, 976, 977,
+ 998, 999};
+/* libc_hidden_data_def(DPD2BIN) */
+#endif
+
+#if DEC_BIN2CHAR==1 && !defined(DECBIN2CHAR)
+#define DECBIN2CHAR
+
+const uint8_t BIN2CHAR[4001]={
+ '\0','0','0','0', '\1','0','0','1', '\1','0','0','2', '\1','0','0','3',
+ '\1','0','0','4', '\1','0','0','5', '\1','0','0','6', '\1','0','0','7',
+ '\1','0','0','8', '\1','0','0','9', '\2','0','1','0', '\2','0','1','1',
+ '\2','0','1','2', '\2','0','1','3', '\2','0','1','4', '\2','0','1','5',
+ '\2','0','1','6', '\2','0','1','7', '\2','0','1','8', '\2','0','1','9',
+ '\2','0','2','0', '\2','0','2','1', '\2','0','2','2', '\2','0','2','3',
+ '\2','0','2','4', '\2','0','2','5', '\2','0','2','6', '\2','0','2','7',
+ '\2','0','2','8', '\2','0','2','9', '\2','0','3','0', '\2','0','3','1',
+ '\2','0','3','2', '\2','0','3','3', '\2','0','3','4', '\2','0','3','5',
+ '\2','0','3','6', '\2','0','3','7', '\2','0','3','8', '\2','0','3','9',
+ '\2','0','4','0', '\2','0','4','1', '\2','0','4','2', '\2','0','4','3',
+ '\2','0','4','4', '\2','0','4','5', '\2','0','4','6', '\2','0','4','7',
+ '\2','0','4','8', '\2','0','4','9', '\2','0','5','0', '\2','0','5','1',
+ '\2','0','5','2', '\2','0','5','3', '\2','0','5','4', '\2','0','5','5',
+ '\2','0','5','6', '\2','0','5','7', '\2','0','5','8', '\2','0','5','9',
+ '\2','0','6','0', '\2','0','6','1', '\2','0','6','2', '\2','0','6','3',
+ '\2','0','6','4', '\2','0','6','5', '\2','0','6','6', '\2','0','6','7',
+ '\2','0','6','8', '\2','0','6','9', '\2','0','7','0', '\2','0','7','1',
+ '\2','0','7','2', '\2','0','7','3', '\2','0','7','4', '\2','0','7','5',
+ '\2','0','7','6', '\2','0','7','7', '\2','0','7','8', '\2','0','7','9',
+ '\2','0','8','0', '\2','0','8','1', '\2','0','8','2', '\2','0','8','3',
+ '\2','0','8','4', '\2','0','8','5', '\2','0','8','6', '\2','0','8','7',
+ '\2','0','8','8', '\2','0','8','9', '\2','0','9','0', '\2','0','9','1',
+ '\2','0','9','2', '\2','0','9','3', '\2','0','9','4', '\2','0','9','5',
+ '\2','0','9','6', '\2','0','9','7', '\2','0','9','8', '\2','0','9','9',
+ '\3','1','0','0', '\3','1','0','1', '\3','1','0','2', '\3','1','0','3',
+ '\3','1','0','4', '\3','1','0','5', '\3','1','0','6', '\3','1','0','7',
+ '\3','1','0','8', '\3','1','0','9', '\3','1','1','0', '\3','1','1','1',
+ '\3','1','1','2', '\3','1','1','3', '\3','1','1','4', '\3','1','1','5',
+ '\3','1','1','6', '\3','1','1','7', '\3','1','1','8', '\3','1','1','9',
+ '\3','1','2','0', '\3','1','2','1', '\3','1','2','2', '\3','1','2','3',
+ '\3','1','2','4', '\3','1','2','5', '\3','1','2','6', '\3','1','2','7',
+ '\3','1','2','8', '\3','1','2','9', '\3','1','3','0', '\3','1','3','1',
+ '\3','1','3','2', '\3','1','3','3', '\3','1','3','4', '\3','1','3','5',
+ '\3','1','3','6', '\3','1','3','7', '\3','1','3','8', '\3','1','3','9',
+ '\3','1','4','0', '\3','1','4','1', '\3','1','4','2', '\3','1','4','3',
+ '\3','1','4','4', '\3','1','4','5', '\3','1','4','6', '\3','1','4','7',
+ '\3','1','4','8', '\3','1','4','9', '\3','1','5','0', '\3','1','5','1',
+ '\3','1','5','2', '\3','1','5','3', '\3','1','5','4', '\3','1','5','5',
+ '\3','1','5','6', '\3','1','5','7', '\3','1','5','8', '\3','1','5','9',
+ '\3','1','6','0', '\3','1','6','1', '\3','1','6','2', '\3','1','6','3',
+ '\3','1','6','4', '\3','1','6','5', '\3','1','6','6', '\3','1','6','7',
+ '\3','1','6','8', '\3','1','6','9', '\3','1','7','0', '\3','1','7','1',
+ '\3','1','7','2', '\3','1','7','3', '\3','1','7','4', '\3','1','7','5',
+ '\3','1','7','6', '\3','1','7','7', '\3','1','7','8', '\3','1','7','9',
+ '\3','1','8','0', '\3','1','8','1', '\3','1','8','2', '\3','1','8','3',
+ '\3','1','8','4', '\3','1','8','5', '\3','1','8','6', '\3','1','8','7',
+ '\3','1','8','8', '\3','1','8','9', '\3','1','9','0', '\3','1','9','1',
+ '\3','1','9','2', '\3','1','9','3', '\3','1','9','4', '\3','1','9','5',
+ '\3','1','9','6', '\3','1','9','7', '\3','1','9','8', '\3','1','9','9',
+ '\3','2','0','0', '\3','2','0','1', '\3','2','0','2', '\3','2','0','3',
+ '\3','2','0','4', '\3','2','0','5', '\3','2','0','6', '\3','2','0','7',
+ '\3','2','0','8', '\3','2','0','9', '\3','2','1','0', '\3','2','1','1',
+ '\3','2','1','2', '\3','2','1','3', '\3','2','1','4', '\3','2','1','5',
+ '\3','2','1','6', '\3','2','1','7', '\3','2','1','8', '\3','2','1','9',
+ '\3','2','2','0', '\3','2','2','1', '\3','2','2','2', '\3','2','2','3',
+ '\3','2','2','4', '\3','2','2','5', '\3','2','2','6', '\3','2','2','7',
+ '\3','2','2','8', '\3','2','2','9', '\3','2','3','0', '\3','2','3','1',
+ '\3','2','3','2', '\3','2','3','3', '\3','2','3','4', '\3','2','3','5',
+ '\3','2','3','6', '\3','2','3','7', '\3','2','3','8', '\3','2','3','9',
+ '\3','2','4','0', '\3','2','4','1', '\3','2','4','2', '\3','2','4','3',
+ '\3','2','4','4', '\3','2','4','5', '\3','2','4','6', '\3','2','4','7',
+ '\3','2','4','8', '\3','2','4','9', '\3','2','5','0', '\3','2','5','1',
+ '\3','2','5','2', '\3','2','5','3', '\3','2','5','4', '\3','2','5','5',
+ '\3','2','5','6', '\3','2','5','7', '\3','2','5','8', '\3','2','5','9',
+ '\3','2','6','0', '\3','2','6','1', '\3','2','6','2', '\3','2','6','3',
+ '\3','2','6','4', '\3','2','6','5', '\3','2','6','6', '\3','2','6','7',
+ '\3','2','6','8', '\3','2','6','9', '\3','2','7','0', '\3','2','7','1',
+ '\3','2','7','2', '\3','2','7','3', '\3','2','7','4', '\3','2','7','5',
+ '\3','2','7','6', '\3','2','7','7', '\3','2','7','8', '\3','2','7','9',
+ '\3','2','8','0', '\3','2','8','1', '\3','2','8','2', '\3','2','8','3',
+ '\3','2','8','4', '\3','2','8','5', '\3','2','8','6', '\3','2','8','7',
+ '\3','2','8','8', '\3','2','8','9', '\3','2','9','0', '\3','2','9','1',
+ '\3','2','9','2', '\3','2','9','3', '\3','2','9','4', '\3','2','9','5',
+ '\3','2','9','6', '\3','2','9','7', '\3','2','9','8', '\3','2','9','9',
+ '\3','3','0','0', '\3','3','0','1', '\3','3','0','2', '\3','3','0','3',
+ '\3','3','0','4', '\3','3','0','5', '\3','3','0','6', '\3','3','0','7',
+ '\3','3','0','8', '\3','3','0','9', '\3','3','1','0', '\3','3','1','1',
+ '\3','3','1','2', '\3','3','1','3', '\3','3','1','4', '\3','3','1','5',
+ '\3','3','1','6', '\3','3','1','7', '\3','3','1','8', '\3','3','1','9',
+ '\3','3','2','0', '\3','3','2','1', '\3','3','2','2', '\3','3','2','3',
+ '\3','3','2','4', '\3','3','2','5', '\3','3','2','6', '\3','3','2','7',
+ '\3','3','2','8', '\3','3','2','9', '\3','3','3','0', '\3','3','3','1',
+ '\3','3','3','2', '\3','3','3','3', '\3','3','3','4', '\3','3','3','5',
+ '\3','3','3','6', '\3','3','3','7', '\3','3','3','8', '\3','3','3','9',
+ '\3','3','4','0', '\3','3','4','1', '\3','3','4','2', '\3','3','4','3',
+ '\3','3','4','4', '\3','3','4','5', '\3','3','4','6', '\3','3','4','7',
+ '\3','3','4','8', '\3','3','4','9', '\3','3','5','0', '\3','3','5','1',
+ '\3','3','5','2', '\3','3','5','3', '\3','3','5','4', '\3','3','5','5',
+ '\3','3','5','6', '\3','3','5','7', '\3','3','5','8', '\3','3','5','9',
+ '\3','3','6','0', '\3','3','6','1', '\3','3','6','2', '\3','3','6','3',
+ '\3','3','6','4', '\3','3','6','5', '\3','3','6','6', '\3','3','6','7',
+ '\3','3','6','8', '\3','3','6','9', '\3','3','7','0', '\3','3','7','1',
+ '\3','3','7','2', '\3','3','7','3', '\3','3','7','4', '\3','3','7','5',
+ '\3','3','7','6', '\3','3','7','7', '\3','3','7','8', '\3','3','7','9',
+ '\3','3','8','0', '\3','3','8','1', '\3','3','8','2', '\3','3','8','3',
+ '\3','3','8','4', '\3','3','8','5', '\3','3','8','6', '\3','3','8','7',
+ '\3','3','8','8', '\3','3','8','9', '\3','3','9','0', '\3','3','9','1',
+ '\3','3','9','2', '\3','3','9','3', '\3','3','9','4', '\3','3','9','5',
+ '\3','3','9','6', '\3','3','9','7', '\3','3','9','8', '\3','3','9','9',
+ '\3','4','0','0', '\3','4','0','1', '\3','4','0','2', '\3','4','0','3',
+ '\3','4','0','4', '\3','4','0','5', '\3','4','0','6', '\3','4','0','7',
+ '\3','4','0','8', '\3','4','0','9', '\3','4','1','0', '\3','4','1','1',
+ '\3','4','1','2', '\3','4','1','3', '\3','4','1','4', '\3','4','1','5',
+ '\3','4','1','6', '\3','4','1','7', '\3','4','1','8', '\3','4','1','9',
+ '\3','4','2','0', '\3','4','2','1', '\3','4','2','2', '\3','4','2','3',
+ '\3','4','2','4', '\3','4','2','5', '\3','4','2','6', '\3','4','2','7',
+ '\3','4','2','8', '\3','4','2','9', '\3','4','3','0', '\3','4','3','1',
+ '\3','4','3','2', '\3','4','3','3', '\3','4','3','4', '\3','4','3','5',
+ '\3','4','3','6', '\3','4','3','7', '\3','4','3','8', '\3','4','3','9',
+ '\3','4','4','0', '\3','4','4','1', '\3','4','4','2', '\3','4','4','3',
+ '\3','4','4','4', '\3','4','4','5', '\3','4','4','6', '\3','4','4','7',
+ '\3','4','4','8', '\3','4','4','9', '\3','4','5','0', '\3','4','5','1',
+ '\3','4','5','2', '\3','4','5','3', '\3','4','5','4', '\3','4','5','5',
+ '\3','4','5','6', '\3','4','5','7', '\3','4','5','8', '\3','4','5','9',
+ '\3','4','6','0', '\3','4','6','1', '\3','4','6','2', '\3','4','6','3',
+ '\3','4','6','4', '\3','4','6','5', '\3','4','6','6', '\3','4','6','7',
+ '\3','4','6','8', '\3','4','6','9', '\3','4','7','0', '\3','4','7','1',
+ '\3','4','7','2', '\3','4','7','3', '\3','4','7','4', '\3','4','7','5',
+ '\3','4','7','6', '\3','4','7','7', '\3','4','7','8', '\3','4','7','9',
+ '\3','4','8','0', '\3','4','8','1', '\3','4','8','2', '\3','4','8','3',
+ '\3','4','8','4', '\3','4','8','5', '\3','4','8','6', '\3','4','8','7',
+ '\3','4','8','8', '\3','4','8','9', '\3','4','9','0', '\3','4','9','1',
+ '\3','4','9','2', '\3','4','9','3', '\3','4','9','4', '\3','4','9','5',
+ '\3','4','9','6', '\3','4','9','7', '\3','4','9','8', '\3','4','9','9',
+ '\3','5','0','0', '\3','5','0','1', '\3','5','0','2', '\3','5','0','3',
+ '\3','5','0','4', '\3','5','0','5', '\3','5','0','6', '\3','5','0','7',
+ '\3','5','0','8', '\3','5','0','9', '\3','5','1','0', '\3','5','1','1',
+ '\3','5','1','2', '\3','5','1','3', '\3','5','1','4', '\3','5','1','5',
+ '\3','5','1','6', '\3','5','1','7', '\3','5','1','8', '\3','5','1','9',
+ '\3','5','2','0', '\3','5','2','1', '\3','5','2','2', '\3','5','2','3',
+ '\3','5','2','4', '\3','5','2','5', '\3','5','2','6', '\3','5','2','7',
+ '\3','5','2','8', '\3','5','2','9', '\3','5','3','0', '\3','5','3','1',
+ '\3','5','3','2', '\3','5','3','3', '\3','5','3','4', '\3','5','3','5',
+ '\3','5','3','6', '\3','5','3','7', '\3','5','3','8', '\3','5','3','9',
+ '\3','5','4','0', '\3','5','4','1', '\3','5','4','2', '\3','5','4','3',
+ '\3','5','4','4', '\3','5','4','5', '\3','5','4','6', '\3','5','4','7',
+ '\3','5','4','8', '\3','5','4','9', '\3','5','5','0', '\3','5','5','1',
+ '\3','5','5','2', '\3','5','5','3', '\3','5','5','4', '\3','5','5','5',
+ '\3','5','5','6', '\3','5','5','7', '\3','5','5','8', '\3','5','5','9',
+ '\3','5','6','0', '\3','5','6','1', '\3','5','6','2', '\3','5','6','3',
+ '\3','5','6','4', '\3','5','6','5', '\3','5','6','6', '\3','5','6','7',
+ '\3','5','6','8', '\3','5','6','9', '\3','5','7','0', '\3','5','7','1',
+ '\3','5','7','2', '\3','5','7','3', '\3','5','7','4', '\3','5','7','5',
+ '\3','5','7','6', '\3','5','7','7', '\3','5','7','8', '\3','5','7','9',
+ '\3','5','8','0', '\3','5','8','1', '\3','5','8','2', '\3','5','8','3',
+ '\3','5','8','4', '\3','5','8','5', '\3','5','8','6', '\3','5','8','7',
+ '\3','5','8','8', '\3','5','8','9', '\3','5','9','0', '\3','5','9','1',
+ '\3','5','9','2', '\3','5','9','3', '\3','5','9','4', '\3','5','9','5',
+ '\3','5','9','6', '\3','5','9','7', '\3','5','9','8', '\3','5','9','9',
+ '\3','6','0','0', '\3','6','0','1', '\3','6','0','2', '\3','6','0','3',
+ '\3','6','0','4', '\3','6','0','5', '\3','6','0','6', '\3','6','0','7',
+ '\3','6','0','8', '\3','6','0','9', '\3','6','1','0', '\3','6','1','1',
+ '\3','6','1','2', '\3','6','1','3', '\3','6','1','4', '\3','6','1','5',
+ '\3','6','1','6', '\3','6','1','7', '\3','6','1','8', '\3','6','1','9',
+ '\3','6','2','0', '\3','6','2','1', '\3','6','2','2', '\3','6','2','3',
+ '\3','6','2','4', '\3','6','2','5', '\3','6','2','6', '\3','6','2','7',
+ '\3','6','2','8', '\3','6','2','9', '\3','6','3','0', '\3','6','3','1',
+ '\3','6','3','2', '\3','6','3','3', '\3','6','3','4', '\3','6','3','5',
+ '\3','6','3','6', '\3','6','3','7', '\3','6','3','8', '\3','6','3','9',
+ '\3','6','4','0', '\3','6','4','1', '\3','6','4','2', '\3','6','4','3',
+ '\3','6','4','4', '\3','6','4','5', '\3','6','4','6', '\3','6','4','7',
+ '\3','6','4','8', '\3','6','4','9', '\3','6','5','0', '\3','6','5','1',
+ '\3','6','5','2', '\3','6','5','3', '\3','6','5','4', '\3','6','5','5',
+ '\3','6','5','6', '\3','6','5','7', '\3','6','5','8', '\3','6','5','9',
+ '\3','6','6','0', '\3','6','6','1', '\3','6','6','2', '\3','6','6','3',
+ '\3','6','6','4', '\3','6','6','5', '\3','6','6','6', '\3','6','6','7',
+ '\3','6','6','8', '\3','6','6','9', '\3','6','7','0', '\3','6','7','1',
+ '\3','6','7','2', '\3','6','7','3', '\3','6','7','4', '\3','6','7','5',
+ '\3','6','7','6', '\3','6','7','7', '\3','6','7','8', '\3','6','7','9',
+ '\3','6','8','0', '\3','6','8','1', '\3','6','8','2', '\3','6','8','3',
+ '\3','6','8','4', '\3','6','8','5', '\3','6','8','6', '\3','6','8','7',
+ '\3','6','8','8', '\3','6','8','9', '\3','6','9','0', '\3','6','9','1',
+ '\3','6','9','2', '\3','6','9','3', '\3','6','9','4', '\3','6','9','5',
+ '\3','6','9','6', '\3','6','9','7', '\3','6','9','8', '\3','6','9','9',
+ '\3','7','0','0', '\3','7','0','1', '\3','7','0','2', '\3','7','0','3',
+ '\3','7','0','4', '\3','7','0','5', '\3','7','0','6', '\3','7','0','7',
+ '\3','7','0','8', '\3','7','0','9', '\3','7','1','0', '\3','7','1','1',
+ '\3','7','1','2', '\3','7','1','3', '\3','7','1','4', '\3','7','1','5',
+ '\3','7','1','6', '\3','7','1','7', '\3','7','1','8', '\3','7','1','9',
+ '\3','7','2','0', '\3','7','2','1', '\3','7','2','2', '\3','7','2','3',
+ '\3','7','2','4', '\3','7','2','5', '\3','7','2','6', '\3','7','2','7',
+ '\3','7','2','8', '\3','7','2','9', '\3','7','3','0', '\3','7','3','1',
+ '\3','7','3','2', '\3','7','3','3', '\3','7','3','4', '\3','7','3','5',
+ '\3','7','3','6', '\3','7','3','7', '\3','7','3','8', '\3','7','3','9',
+ '\3','7','4','0', '\3','7','4','1', '\3','7','4','2', '\3','7','4','3',
+ '\3','7','4','4', '\3','7','4','5', '\3','7','4','6', '\3','7','4','7',
+ '\3','7','4','8', '\3','7','4','9', '\3','7','5','0', '\3','7','5','1',
+ '\3','7','5','2', '\3','7','5','3', '\3','7','5','4', '\3','7','5','5',
+ '\3','7','5','6', '\3','7','5','7', '\3','7','5','8', '\3','7','5','9',
+ '\3','7','6','0', '\3','7','6','1', '\3','7','6','2', '\3','7','6','3',
+ '\3','7','6','4', '\3','7','6','5', '\3','7','6','6', '\3','7','6','7',
+ '\3','7','6','8', '\3','7','6','9', '\3','7','7','0', '\3','7','7','1',
+ '\3','7','7','2', '\3','7','7','3', '\3','7','7','4', '\3','7','7','5',
+ '\3','7','7','6', '\3','7','7','7', '\3','7','7','8', '\3','7','7','9',
+ '\3','7','8','0', '\3','7','8','1', '\3','7','8','2', '\3','7','8','3',
+ '\3','7','8','4', '\3','7','8','5', '\3','7','8','6', '\3','7','8','7',
+ '\3','7','8','8', '\3','7','8','9', '\3','7','9','0', '\3','7','9','1',
+ '\3','7','9','2', '\3','7','9','3', '\3','7','9','4', '\3','7','9','5',
+ '\3','7','9','6', '\3','7','9','7', '\3','7','9','8', '\3','7','9','9',
+ '\3','8','0','0', '\3','8','0','1', '\3','8','0','2', '\3','8','0','3',
+ '\3','8','0','4', '\3','8','0','5', '\3','8','0','6', '\3','8','0','7',
+ '\3','8','0','8', '\3','8','0','9', '\3','8','1','0', '\3','8','1','1',
+ '\3','8','1','2', '\3','8','1','3', '\3','8','1','4', '\3','8','1','5',
+ '\3','8','1','6', '\3','8','1','7', '\3','8','1','8', '\3','8','1','9',
+ '\3','8','2','0', '\3','8','2','1', '\3','8','2','2', '\3','8','2','3',
+ '\3','8','2','4', '\3','8','2','5', '\3','8','2','6', '\3','8','2','7',
+ '\3','8','2','8', '\3','8','2','9', '\3','8','3','0', '\3','8','3','1',
+ '\3','8','3','2', '\3','8','3','3', '\3','8','3','4', '\3','8','3','5',
+ '\3','8','3','6', '\3','8','3','7', '\3','8','3','8', '\3','8','3','9',
+ '\3','8','4','0', '\3','8','4','1', '\3','8','4','2', '\3','8','4','3',
+ '\3','8','4','4', '\3','8','4','5', '\3','8','4','6', '\3','8','4','7',
+ '\3','8','4','8', '\3','8','4','9', '\3','8','5','0', '\3','8','5','1',
+ '\3','8','5','2', '\3','8','5','3', '\3','8','5','4', '\3','8','5','5',
+ '\3','8','5','6', '\3','8','5','7', '\3','8','5','8', '\3','8','5','9',
+ '\3','8','6','0', '\3','8','6','1', '\3','8','6','2', '\3','8','6','3',
+ '\3','8','6','4', '\3','8','6','5', '\3','8','6','6', '\3','8','6','7',
+ '\3','8','6','8', '\3','8','6','9', '\3','8','7','0', '\3','8','7','1',
+ '\3','8','7','2', '\3','8','7','3', '\3','8','7','4', '\3','8','7','5',
+ '\3','8','7','6', '\3','8','7','7', '\3','8','7','8', '\3','8','7','9',
+ '\3','8','8','0', '\3','8','8','1', '\3','8','8','2', '\3','8','8','3',
+ '\3','8','8','4', '\3','8','8','5', '\3','8','8','6', '\3','8','8','7',
+ '\3','8','8','8', '\3','8','8','9', '\3','8','9','0', '\3','8','9','1',
+ '\3','8','9','2', '\3','8','9','3', '\3','8','9','4', '\3','8','9','5',
+ '\3','8','9','6', '\3','8','9','7', '\3','8','9','8', '\3','8','9','9',
+ '\3','9','0','0', '\3','9','0','1', '\3','9','0','2', '\3','9','0','3',
+ '\3','9','0','4', '\3','9','0','5', '\3','9','0','6', '\3','9','0','7',
+ '\3','9','0','8', '\3','9','0','9', '\3','9','1','0', '\3','9','1','1',
+ '\3','9','1','2', '\3','9','1','3', '\3','9','1','4', '\3','9','1','5',
+ '\3','9','1','6', '\3','9','1','7', '\3','9','1','8', '\3','9','1','9',
+ '\3','9','2','0', '\3','9','2','1', '\3','9','2','2', '\3','9','2','3',
+ '\3','9','2','4', '\3','9','2','5', '\3','9','2','6', '\3','9','2','7',
+ '\3','9','2','8', '\3','9','2','9', '\3','9','3','0', '\3','9','3','1',
+ '\3','9','3','2', '\3','9','3','3', '\3','9','3','4', '\3','9','3','5',
+ '\3','9','3','6', '\3','9','3','7', '\3','9','3','8', '\3','9','3','9',
+ '\3','9','4','0', '\3','9','4','1', '\3','9','4','2', '\3','9','4','3',
+ '\3','9','4','4', '\3','9','4','5', '\3','9','4','6', '\3','9','4','7',
+ '\3','9','4','8', '\3','9','4','9', '\3','9','5','0', '\3','9','5','1',
+ '\3','9','5','2', '\3','9','5','3', '\3','9','5','4', '\3','9','5','5',
+ '\3','9','5','6', '\3','9','5','7', '\3','9','5','8', '\3','9','5','9',
+ '\3','9','6','0', '\3','9','6','1', '\3','9','6','2', '\3','9','6','3',
+ '\3','9','6','4', '\3','9','6','5', '\3','9','6','6', '\3','9','6','7',
+ '\3','9','6','8', '\3','9','6','9', '\3','9','7','0', '\3','9','7','1',
+ '\3','9','7','2', '\3','9','7','3', '\3','9','7','4', '\3','9','7','5',
+ '\3','9','7','6', '\3','9','7','7', '\3','9','7','8', '\3','9','7','9',
+ '\3','9','8','0', '\3','9','8','1', '\3','9','8','2', '\3','9','8','3',
+ '\3','9','8','4', '\3','9','8','5', '\3','9','8','6', '\3','9','8','7',
+ '\3','9','8','8', '\3','9','8','9', '\3','9','9','0', '\3','9','9','1',
+ '\3','9','9','2', '\3','9','9','3', '\3','9','9','4', '\3','9','9','5',
+ '\3','9','9','6', '\3','9','9','7', '\3','9','9','8', '\3','9','9','9',
+ '\0'};
+/* libc_hidden_data_def(BIN2CHAR) */
+#endif
+
+#if DEC_DPD2BCD8==1 && !defined(DECDPD2BCD8)
+#define DECDPD2BCD8
+
+const uint8_t DPD2BCD8[4096]={
+ 0,0,0,0, 0,0,1,1, 0,0,2,1, 0,0,3,1, 0,0,4,1, 0,0,5,1, 0,0,6,1, 0,0,7,1,
+ 0,0,8,1, 0,0,9,1, 0,8,0,2, 0,8,1,2, 8,0,0,3, 8,0,1,3, 8,8,0,3, 8,8,1,3,
+ 0,1,0,2, 0,1,1,2, 0,1,2,2, 0,1,3,2, 0,1,4,2, 0,1,5,2, 0,1,6,2, 0,1,7,2,
+ 0,1,8,2, 0,1,9,2, 0,9,0,2, 0,9,1,2, 8,1,0,3, 8,1,1,3, 8,9,0,3, 8,9,1,3,
+ 0,2,0,2, 0,2,1,2, 0,2,2,2, 0,2,3,2, 0,2,4,2, 0,2,5,2, 0,2,6,2, 0,2,7,2,
+ 0,2,8,2, 0,2,9,2, 0,8,2,2, 0,8,3,2, 8,2,0,3, 8,2,1,3, 8,0,8,3, 8,0,9,3,
+ 0,3,0,2, 0,3,1,2, 0,3,2,2, 0,3,3,2, 0,3,4,2, 0,3,5,2, 0,3,6,2, 0,3,7,2,
+ 0,3,8,2, 0,3,9,2, 0,9,2,2, 0,9,3,2, 8,3,0,3, 8,3,1,3, 8,1,8,3, 8,1,9,3,
+ 0,4,0,2, 0,4,1,2, 0,4,2,2, 0,4,3,2, 0,4,4,2, 0,4,5,2, 0,4,6,2, 0,4,7,2,
+ 0,4,8,2, 0,4,9,2, 0,8,4,2, 0,8,5,2, 8,4,0,3, 8,4,1,3, 0,8,8,2, 0,8,9,2,
+ 0,5,0,2, 0,5,1,2, 0,5,2,2, 0,5,3,2, 0,5,4,2, 0,5,5,2, 0,5,6,2, 0,5,7,2,
+ 0,5,8,2, 0,5,9,2, 0,9,4,2, 0,9,5,2, 8,5,0,3, 8,5,1,3, 0,9,8,2, 0,9,9,2,
+ 0,6,0,2, 0,6,1,2, 0,6,2,2, 0,6,3,2, 0,6,4,2, 0,6,5,2, 0,6,6,2, 0,6,7,2,
+ 0,6,8,2, 0,6,9,2, 0,8,6,2, 0,8,7,2, 8,6,0,3, 8,6,1,3, 8,8,8,3, 8,8,9,3,
+ 0,7,0,2, 0,7,1,2, 0,7,2,2, 0,7,3,2, 0,7,4,2, 0,7,5,2, 0,7,6,2, 0,7,7,2,
+ 0,7,8,2, 0,7,9,2, 0,9,6,2, 0,9,7,2, 8,7,0,3, 8,7,1,3, 8,9,8,3, 8,9,9,3,
+ 1,0,0,3, 1,0,1,3, 1,0,2,3, 1,0,3,3, 1,0,4,3, 1,0,5,3, 1,0,6,3, 1,0,7,3,
+ 1,0,8,3, 1,0,9,3, 1,8,0,3, 1,8,1,3, 9,0,0,3, 9,0,1,3, 9,8,0,3, 9,8,1,3,
+ 1,1,0,3, 1,1,1,3, 1,1,2,3, 1,1,3,3, 1,1,4,3, 1,1,5,3, 1,1,6,3, 1,1,7,3,
+ 1,1,8,3, 1,1,9,3, 1,9,0,3, 1,9,1,3, 9,1,0,3, 9,1,1,3, 9,9,0,3, 9,9,1,3,
+ 1,2,0,3, 1,2,1,3, 1,2,2,3, 1,2,3,3, 1,2,4,3, 1,2,5,3, 1,2,6,3, 1,2,7,3,
+ 1,2,8,3, 1,2,9,3, 1,8,2,3, 1,8,3,3, 9,2,0,3, 9,2,1,3, 9,0,8,3, 9,0,9,3,
+ 1,3,0,3, 1,3,1,3, 1,3,2,3, 1,3,3,3, 1,3,4,3, 1,3,5,3, 1,3,6,3, 1,3,7,3,
+ 1,3,8,3, 1,3,9,3, 1,9,2,3, 1,9,3,3, 9,3,0,3, 9,3,1,3, 9,1,8,3, 9,1,9,3,
+ 1,4,0,3, 1,4,1,3, 1,4,2,3, 1,4,3,3, 1,4,4,3, 1,4,5,3, 1,4,6,3, 1,4,7,3,
+ 1,4,8,3, 1,4,9,3, 1,8,4,3, 1,8,5,3, 9,4,0,3, 9,4,1,3, 1,8,8,3, 1,8,9,3,
+ 1,5,0,3, 1,5,1,3, 1,5,2,3, 1,5,3,3, 1,5,4,3, 1,5,5,3, 1,5,6,3, 1,5,7,3,
+ 1,5,8,3, 1,5,9,3, 1,9,4,3, 1,9,5,3, 9,5,0,3, 9,5,1,3, 1,9,8,3, 1,9,9,3,
+ 1,6,0,3, 1,6,1,3, 1,6,2,3, 1,6,3,3, 1,6,4,3, 1,6,5,3, 1,6,6,3, 1,6,7,3,
+ 1,6,8,3, 1,6,9,3, 1,8,6,3, 1,8,7,3, 9,6,0,3, 9,6,1,3, 9,8,8,3, 9,8,9,3,
+ 1,7,0,3, 1,7,1,3, 1,7,2,3, 1,7,3,3, 1,7,4,3, 1,7,5,3, 1,7,6,3, 1,7,7,3,
+ 1,7,8,3, 1,7,9,3, 1,9,6,3, 1,9,7,3, 9,7,0,3, 9,7,1,3, 9,9,8,3, 9,9,9,3,
+ 2,0,0,3, 2,0,1,3, 2,0,2,3, 2,0,3,3, 2,0,4,3, 2,0,5,3, 2,0,6,3, 2,0,7,3,
+ 2,0,8,3, 2,0,9,3, 2,8,0,3, 2,8,1,3, 8,0,2,3, 8,0,3,3, 8,8,2,3, 8,8,3,3,
+ 2,1,0,3, 2,1,1,3, 2,1,2,3, 2,1,3,3, 2,1,4,3, 2,1,5,3, 2,1,6,3, 2,1,7,3,
+ 2,1,8,3, 2,1,9,3, 2,9,0,3, 2,9,1,3, 8,1,2,3, 8,1,3,3, 8,9,2,3, 8,9,3,3,
+ 2,2,0,3, 2,2,1,3, 2,2,2,3, 2,2,3,3, 2,2,4,3, 2,2,5,3, 2,2,6,3, 2,2,7,3,
+ 2,2,8,3, 2,2,9,3, 2,8,2,3, 2,8,3,3, 8,2,2,3, 8,2,3,3, 8,2,8,3, 8,2,9,3,
+ 2,3,0,3, 2,3,1,3, 2,3,2,3, 2,3,3,3, 2,3,4,3, 2,3,5,3, 2,3,6,3, 2,3,7,3,
+ 2,3,8,3, 2,3,9,3, 2,9,2,3, 2,9,3,3, 8,3,2,3, 8,3,3,3, 8,3,8,3, 8,3,9,3,
+ 2,4,0,3, 2,4,1,3, 2,4,2,3, 2,4,3,3, 2,4,4,3, 2,4,5,3, 2,4,6,3, 2,4,7,3,
+ 2,4,8,3, 2,4,9,3, 2,8,4,3, 2,8,5,3, 8,4,2,3, 8,4,3,3, 2,8,8,3, 2,8,9,3,
+ 2,5,0,3, 2,5,1,3, 2,5,2,3, 2,5,3,3, 2,5,4,3, 2,5,5,3, 2,5,6,3, 2,5,7,3,
+ 2,5,8,3, 2,5,9,3, 2,9,4,3, 2,9,5,3, 8,5,2,3, 8,5,3,3, 2,9,8,3, 2,9,9,3,
+ 2,6,0,3, 2,6,1,3, 2,6,2,3, 2,6,3,3, 2,6,4,3, 2,6,5,3, 2,6,6,3, 2,6,7,3,
+ 2,6,8,3, 2,6,9,3, 2,8,6,3, 2,8,7,3, 8,6,2,3, 8,6,3,3, 8,8,8,3, 8,8,9,3,
+ 2,7,0,3, 2,7,1,3, 2,7,2,3, 2,7,3,3, 2,7,4,3, 2,7,5,3, 2,7,6,3, 2,7,7,3,
+ 2,7,8,3, 2,7,9,3, 2,9,6,3, 2,9,7,3, 8,7,2,3, 8,7,3,3, 8,9,8,3, 8,9,9,3,
+ 3,0,0,3, 3,0,1,3, 3,0,2,3, 3,0,3,3, 3,0,4,3, 3,0,5,3, 3,0,6,3, 3,0,7,3,
+ 3,0,8,3, 3,0,9,3, 3,8,0,3, 3,8,1,3, 9,0,2,3, 9,0,3,3, 9,8,2,3, 9,8,3,3,
+ 3,1,0,3, 3,1,1,3, 3,1,2,3, 3,1,3,3, 3,1,4,3, 3,1,5,3, 3,1,6,3, 3,1,7,3,
+ 3,1,8,3, 3,1,9,3, 3,9,0,3, 3,9,1,3, 9,1,2,3, 9,1,3,3, 9,9,2,3, 9,9,3,3,
+ 3,2,0,3, 3,2,1,3, 3,2,2,3, 3,2,3,3, 3,2,4,3, 3,2,5,3, 3,2,6,3, 3,2,7,3,
+ 3,2,8,3, 3,2,9,3, 3,8,2,3, 3,8,3,3, 9,2,2,3, 9,2,3,3, 9,2,8,3, 9,2,9,3,
+ 3,3,0,3, 3,3,1,3, 3,3,2,3, 3,3,3,3, 3,3,4,3, 3,3,5,3, 3,3,6,3, 3,3,7,3,
+ 3,3,8,3, 3,3,9,3, 3,9,2,3, 3,9,3,3, 9,3,2,3, 9,3,3,3, 9,3,8,3, 9,3,9,3,
+ 3,4,0,3, 3,4,1,3, 3,4,2,3, 3,4,3,3, 3,4,4,3, 3,4,5,3, 3,4,6,3, 3,4,7,3,
+ 3,4,8,3, 3,4,9,3, 3,8,4,3, 3,8,5,3, 9,4,2,3, 9,4,3,3, 3,8,8,3, 3,8,9,3,
+ 3,5,0,3, 3,5,1,3, 3,5,2,3, 3,5,3,3, 3,5,4,3, 3,5,5,3, 3,5,6,3, 3,5,7,3,
+ 3,5,8,3, 3,5,9,3, 3,9,4,3, 3,9,5,3, 9,5,2,3, 9,5,3,3, 3,9,8,3, 3,9,9,3,
+ 3,6,0,3, 3,6,1,3, 3,6,2,3, 3,6,3,3, 3,6,4,3, 3,6,5,3, 3,6,6,3, 3,6,7,3,
+ 3,6,8,3, 3,6,9,3, 3,8,6,3, 3,8,7,3, 9,6,2,3, 9,6,3,3, 9,8,8,3, 9,8,9,3,
+ 3,7,0,3, 3,7,1,3, 3,7,2,3, 3,7,3,3, 3,7,4,3, 3,7,5,3, 3,7,6,3, 3,7,7,3,
+ 3,7,8,3, 3,7,9,3, 3,9,6,3, 3,9,7,3, 9,7,2,3, 9,7,3,3, 9,9,8,3, 9,9,9,3,
+ 4,0,0,3, 4,0,1,3, 4,0,2,3, 4,0,3,3, 4,0,4,3, 4,0,5,3, 4,0,6,3, 4,0,7,3,
+ 4,0,8,3, 4,0,9,3, 4,8,0,3, 4,8,1,3, 8,0,4,3, 8,0,5,3, 8,8,4,3, 8,8,5,3,
+ 4,1,0,3, 4,1,1,3, 4,1,2,3, 4,1,3,3, 4,1,4,3, 4,1,5,3, 4,1,6,3, 4,1,7,3,
+ 4,1,8,3, 4,1,9,3, 4,9,0,3, 4,9,1,3, 8,1,4,3, 8,1,5,3, 8,9,4,3, 8,9,5,3,
+ 4,2,0,3, 4,2,1,3, 4,2,2,3, 4,2,3,3, 4,2,4,3, 4,2,5,3, 4,2,6,3, 4,2,7,3,
+ 4,2,8,3, 4,2,9,3, 4,8,2,3, 4,8,3,3, 8,2,4,3, 8,2,5,3, 8,4,8,3, 8,4,9,3,
+ 4,3,0,3, 4,3,1,3, 4,3,2,3, 4,3,3,3, 4,3,4,3, 4,3,5,3, 4,3,6,3, 4,3,7,3,
+ 4,3,8,3, 4,3,9,3, 4,9,2,3, 4,9,3,3, 8,3,4,3, 8,3,5,3, 8,5,8,3, 8,5,9,3,
+ 4,4,0,3, 4,4,1,3, 4,4,2,3, 4,4,3,3, 4,4,4,3, 4,4,5,3, 4,4,6,3, 4,4,7,3,
+ 4,4,8,3, 4,4,9,3, 4,8,4,3, 4,8,5,3, 8,4,4,3, 8,4,5,3, 4,8,8,3, 4,8,9,3,
+ 4,5,0,3, 4,5,1,3, 4,5,2,3, 4,5,3,3, 4,5,4,3, 4,5,5,3, 4,5,6,3, 4,5,7,3,
+ 4,5,8,3, 4,5,9,3, 4,9,4,3, 4,9,5,3, 8,5,4,3, 8,5,5,3, 4,9,8,3, 4,9,9,3,
+ 4,6,0,3, 4,6,1,3, 4,6,2,3, 4,6,3,3, 4,6,4,3, 4,6,5,3, 4,6,6,3, 4,6,7,3,
+ 4,6,8,3, 4,6,9,3, 4,8,6,3, 4,8,7,3, 8,6,4,3, 8,6,5,3, 8,8,8,3, 8,8,9,3,
+ 4,7,0,3, 4,7,1,3, 4,7,2,3, 4,7,3,3, 4,7,4,3, 4,7,5,3, 4,7,6,3, 4,7,7,3,
+ 4,7,8,3, 4,7,9,3, 4,9,6,3, 4,9,7,3, 8,7,4,3, 8,7,5,3, 8,9,8,3, 8,9,9,3,
+ 5,0,0,3, 5,0,1,3, 5,0,2,3, 5,0,3,3, 5,0,4,3, 5,0,5,3, 5,0,6,3, 5,0,7,3,
+ 5,0,8,3, 5,0,9,3, 5,8,0,3, 5,8,1,3, 9,0,4,3, 9,0,5,3, 9,8,4,3, 9,8,5,3,
+ 5,1,0,3, 5,1,1,3, 5,1,2,3, 5,1,3,3, 5,1,4,3, 5,1,5,3, 5,1,6,3, 5,1,7,3,
+ 5,1,8,3, 5,1,9,3, 5,9,0,3, 5,9,1,3, 9,1,4,3, 9,1,5,3, 9,9,4,3, 9,9,5,3,
+ 5,2,0,3, 5,2,1,3, 5,2,2,3, 5,2,3,3, 5,2,4,3, 5,2,5,3, 5,2,6,3, 5,2,7,3,
+ 5,2,8,3, 5,2,9,3, 5,8,2,3, 5,8,3,3, 9,2,4,3, 9,2,5,3, 9,4,8,3, 9,4,9,3,
+ 5,3,0,3, 5,3,1,3, 5,3,2,3, 5,3,3,3, 5,3,4,3, 5,3,5,3, 5,3,6,3, 5,3,7,3,
+ 5,3,8,3, 5,3,9,3, 5,9,2,3, 5,9,3,3, 9,3,4,3, 9,3,5,3, 9,5,8,3, 9,5,9,3,
+ 5,4,0,3, 5,4,1,3, 5,4,2,3, 5,4,3,3, 5,4,4,3, 5,4,5,3, 5,4,6,3, 5,4,7,3,
+ 5,4,8,3, 5,4,9,3, 5,8,4,3, 5,8,5,3, 9,4,4,3, 9,4,5,3, 5,8,8,3, 5,8,9,3,
+ 5,5,0,3, 5,5,1,3, 5,5,2,3, 5,5,3,3, 5,5,4,3, 5,5,5,3, 5,5,6,3, 5,5,7,3,
+ 5,5,8,3, 5,5,9,3, 5,9,4,3, 5,9,5,3, 9,5,4,3, 9,5,5,3, 5,9,8,3, 5,9,9,3,
+ 5,6,0,3, 5,6,1,3, 5,6,2,3, 5,6,3,3, 5,6,4,3, 5,6,5,3, 5,6,6,3, 5,6,7,3,
+ 5,6,8,3, 5,6,9,3, 5,8,6,3, 5,8,7,3, 9,6,4,3, 9,6,5,3, 9,8,8,3, 9,8,9,3,
+ 5,7,0,3, 5,7,1,3, 5,7,2,3, 5,7,3,3, 5,7,4,3, 5,7,5,3, 5,7,6,3, 5,7,7,3,
+ 5,7,8,3, 5,7,9,3, 5,9,6,3, 5,9,7,3, 9,7,4,3, 9,7,5,3, 9,9,8,3, 9,9,9,3,
+ 6,0,0,3, 6,0,1,3, 6,0,2,3, 6,0,3,3, 6,0,4,3, 6,0,5,3, 6,0,6,3, 6,0,7,3,
+ 6,0,8,3, 6,0,9,3, 6,8,0,3, 6,8,1,3, 8,0,6,3, 8,0,7,3, 8,8,6,3, 8,8,7,3,
+ 6,1,0,3, 6,1,1,3, 6,1,2,3, 6,1,3,3, 6,1,4,3, 6,1,5,3, 6,1,6,3, 6,1,7,3,
+ 6,1,8,3, 6,1,9,3, 6,9,0,3, 6,9,1,3, 8,1,6,3, 8,1,7,3, 8,9,6,3, 8,9,7,3,
+ 6,2,0,3, 6,2,1,3, 6,2,2,3, 6,2,3,3, 6,2,4,3, 6,2,5,3, 6,2,6,3, 6,2,7,3,
+ 6,2,8,3, 6,2,9,3, 6,8,2,3, 6,8,3,3, 8,2,6,3, 8,2,7,3, 8,6,8,3, 8,6,9,3,
+ 6,3,0,3, 6,3,1,3, 6,3,2,3, 6,3,3,3, 6,3,4,3, 6,3,5,3, 6,3,6,3, 6,3,7,3,
+ 6,3,8,3, 6,3,9,3, 6,9,2,3, 6,9,3,3, 8,3,6,3, 8,3,7,3, 8,7,8,3, 8,7,9,3,
+ 6,4,0,3, 6,4,1,3, 6,4,2,3, 6,4,3,3, 6,4,4,3, 6,4,5,3, 6,4,6,3, 6,4,7,3,
+ 6,4,8,3, 6,4,9,3, 6,8,4,3, 6,8,5,3, 8,4,6,3, 8,4,7,3, 6,8,8,3, 6,8,9,3,
+ 6,5,0,3, 6,5,1,3, 6,5,2,3, 6,5,3,3, 6,5,4,3, 6,5,5,3, 6,5,6,3, 6,5,7,3,
+ 6,5,8,3, 6,5,9,3, 6,9,4,3, 6,9,5,3, 8,5,6,3, 8,5,7,3, 6,9,8,3, 6,9,9,3,
+ 6,6,0,3, 6,6,1,3, 6,6,2,3, 6,6,3,3, 6,6,4,3, 6,6,5,3, 6,6,6,3, 6,6,7,3,
+ 6,6,8,3, 6,6,9,3, 6,8,6,3, 6,8,7,3, 8,6,6,3, 8,6,7,3, 8,8,8,3, 8,8,9,3,
+ 6,7,0,3, 6,7,1,3, 6,7,2,3, 6,7,3,3, 6,7,4,3, 6,7,5,3, 6,7,6,3, 6,7,7,3,
+ 6,7,8,3, 6,7,9,3, 6,9,6,3, 6,9,7,3, 8,7,6,3, 8,7,7,3, 8,9,8,3, 8,9,9,3,
+ 7,0,0,3, 7,0,1,3, 7,0,2,3, 7,0,3,3, 7,0,4,3, 7,0,5,3, 7,0,6,3, 7,0,7,3,
+ 7,0,8,3, 7,0,9,3, 7,8,0,3, 7,8,1,3, 9,0,6,3, 9,0,7,3, 9,8,6,3, 9,8,7,3,
+ 7,1,0,3, 7,1,1,3, 7,1,2,3, 7,1,3,3, 7,1,4,3, 7,1,5,3, 7,1,6,3, 7,1,7,3,
+ 7,1,8,3, 7,1,9,3, 7,9,0,3, 7,9,1,3, 9,1,6,3, 9,1,7,3, 9,9,6,3, 9,9,7,3,
+ 7,2,0,3, 7,2,1,3, 7,2,2,3, 7,2,3,3, 7,2,4,3, 7,2,5,3, 7,2,6,3, 7,2,7,3,
+ 7,2,8,3, 7,2,9,3, 7,8,2,3, 7,8,3,3, 9,2,6,3, 9,2,7,3, 9,6,8,3, 9,6,9,3,
+ 7,3,0,3, 7,3,1,3, 7,3,2,3, 7,3,3,3, 7,3,4,3, 7,3,5,3, 7,3,6,3, 7,3,7,3,
+ 7,3,8,3, 7,3,9,3, 7,9,2,3, 7,9,3,3, 9,3,6,3, 9,3,7,3, 9,7,8,3, 9,7,9,3,
+ 7,4,0,3, 7,4,1,3, 7,4,2,3, 7,4,3,3, 7,4,4,3, 7,4,5,3, 7,4,6,3, 7,4,7,3,
+ 7,4,8,3, 7,4,9,3, 7,8,4,3, 7,8,5,3, 9,4,6,3, 9,4,7,3, 7,8,8,3, 7,8,9,3,
+ 7,5,0,3, 7,5,1,3, 7,5,2,3, 7,5,3,3, 7,5,4,3, 7,5,5,3, 7,5,6,3, 7,5,7,3,
+ 7,5,8,3, 7,5,9,3, 7,9,4,3, 7,9,5,3, 9,5,6,3, 9,5,7,3, 7,9,8,3, 7,9,9,3,
+ 7,6,0,3, 7,6,1,3, 7,6,2,3, 7,6,3,3, 7,6,4,3, 7,6,5,3, 7,6,6,3, 7,6,7,3,
+ 7,6,8,3, 7,6,9,3, 7,8,6,3, 7,8,7,3, 9,6,6,3, 9,6,7,3, 9,8,8,3, 9,8,9,3,
+ 7,7,0,3, 7,7,1,3, 7,7,2,3, 7,7,3,3, 7,7,4,3, 7,7,5,3, 7,7,6,3, 7,7,7,3,
+ 7,7,8,3, 7,7,9,3, 7,9,6,3, 7,9,7,3, 9,7,6,3, 9,7,7,3, 9,9,8,3, 9,9,9,3
+};
+#endif
+
diff --git a/libc/dfp/decNumber.c b/libc/dfp/decNumber.c
new file mode 100644
index 000000000..6788bd731
--- /dev/null
+++ b/libc/dfp/decNumber.c
@@ -0,0 +1,6807 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Number arithmetic module */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* ------------------------------------------------------------------ */
+/* This module comprises the routines for General Decimal Arithmetic */
+/* as defined in the specification which may be found on the */
+/* http://www2.hursley.ibm.com/decimal web pages. It implements both */
+/* the full ('extended') arithmetic and the simpler ('subset') */
+/* arithmetic. */
+/* */
+/* Usage notes: */
+/* */
+/* 1. This code is ANSI C89 except: */
+/* */
+/* a) C99 line comments (double forward slash) are used. (Most C */
+/* compilers accept these. If yours does not, a simple script */
+/* can be used to convert them to ANSI C comments.) */
+/* */
+/* b) Types from C99 stdint.h are used. If you do not have this */
+/* header file, see the User's Guide section of the decNumber */
+/* documentation; this lists the necessary definitions. */
+/* */
+/* c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and */
+/* uint64_t types may be used. To avoid these, set DECUSE64=0 */
+/* and DECDPUN<=4 (see documentation). */
+/* */
+/* 2. The decNumber format which this library uses is optimized for */
+/* efficient processing of relatively short numbers; in particular */
+/* it allows the use of fixed sized structures and minimizes copy */
+/* and move operations. It does, however, support arbitrary */
+/* precision (up to 999,999,999 digits) and arbitrary exponent */
+/* range (Emax in the range 0 through 999,999,999 and Emin in the */
+/* range -999,999,999 through 0). Mathematical functions (for */
+/* example decNumberExp) as identified below are restricted more */
+/* tightly: digits, emax, and -emin in the context must be <= */
+/* DEC_MAX_MATH (999999), and their operand(s) must be within */
+/* these bounds. */
+/* */
+/* 3. Operands to operator functions are never modified unless they */
+/* are also specified to be the result number (which is always */
+/* permitted). Other than that case, operands must not overlap. */
+/* */
+/* 4. Error handling: the type of the error is ORed into the status */
+/* flags in the current context (decContext structure). The */
+/* SIGFPE signal is then raised if the corresponding trap-enabler */
+/* flag in the decContext is set (is 1). */
+/* */
+/* It is the responsibility of the caller to clear the status */
+/* flags as required. */
+/* */
+/* The result of any routine which returns a number will always */
+/* be a valid number (which may be a special value, such as an */
+/* Infinity or NaN). */
+/* */
+/* 5. The decNumber format is not an exchangeable concrete */
+/* representation as it comprises fields which may be machine- */
+/* dependent (packed or unpacked, or special length, for example). */
+/* Canonical conversions to and from strings are provided; other */
+/* conversions are available in separate modules. */
+/* */
+/* 6. Normally, input operands are assumed to be valid. Set DECCHECK */
+/* to 1 for extended operand checking (including NULL operands). */
+/* Results are undefined if a badly-formed structure (or a NULL */
+/* pointer to a structure) is provided, though with DECCHECK */
+/* enabled the operator routines are protected against exceptions. */
+/* (Except if the result pointer is NULL, which is unrecoverable.) */
+/* */
+/* However, the routines will never cause exceptions if they are */
+/* given well-formed operands, even if the value of the operands */
+/* is inappropriate for the operation and DECCHECK is not set. */
+/* (Except for SIGFPE, as and where documented.) */
+/* */
+/* 7. Subset arithmetic is available only if DECSUBSET is set to 1. */
+/* ------------------------------------------------------------------ */
+/* Implementation notes for maintenance of this module: */
+/* */
+/* 1. Storage leak protection: Routines which use malloc are not */
+/* permitted to use return for fastpath or error exits (i.e., */
+/* they follow strict structured programming conventions). */
+/* Instead they have a do{}while(0); construct surrounding the */
+/* code which is protected -- break may be used to exit this. */
+/* Other routines can safely use the return statement inline. */
+/* */
+/* Storage leak accounting can be enabled using DECALLOC. */
+/* */
+/* 2. All loops use the for(;;) construct. Any do construct does */
+/* not loop; it is for allocation protection as just described. */
+/* */
+/* 3. Setting status in the context must always be the very last */
+/* action in a routine, as non-0 status may raise a trap and hence */
+/* the call to set status may not return (if the handler uses long */
+/* jump). Therefore all cleanup must be done first. In general, */
+/* to achieve this status is accumulated and is only applied just */
+/* before return by calling decContextSetStatus (via decStatus). */
+/* */
+/* Routines which allocate storage cannot, in general, use the */
+/* 'top level' routines which could cause a non-returning */
+/* transfer of control. The decXxxxOp routines are safe (do not */
+/* call decStatus even if traps are set in the context) and should */
+/* be used instead (they are also a little faster). */
+/* */
+/* 4. Exponent checking is minimized by allowing the exponent to */
+/* grow outside its limits during calculations, provided that */
+/* the decFinalize function is called later. Multiplication and */
+/* division, and intermediate calculations in exponentiation, */
+/* require more careful checks because of the risk of 31-bit */
+/* overflow (the most negative valid exponent is -1999999997, for */
+/* a 999999999-digit number with adjusted exponent of -999999999). */
+/* */
+/* 5. Rounding is deferred until finalization of results, with any */
+/* 'off to the right' data being represented as a single digit */
+/* residue (in the range -1 through 9). This avoids any double- */
+/* rounding when more than one shortening takes place (for */
+/* example, when a result is subnormal). */
+/* */
+/* 6. The digits count is allowed to rise to a multiple of DECDPUN */
+/* during many operations, so whole Units are handled and exact */
+/* accounting of digits is not needed. The correct digits value */
+/* is found by decGetDigits, which accounts for leading zeros. */
+/* This must be called before any rounding if the number of digits */
+/* is not known exactly. */
+/* */
+/* 7. The multiply-by-reciprocal 'trick' is used for partitioning */
+/* numbers up to four digits, using appropriate constants. This */
+/* is not useful for longer numbers because overflow of 32 bits */
+/* would lead to 4 multiplies, which is almost as expensive as */
+/* a divide (unless a floating-point or 64-bit multiply is */
+/* assumed to be available). */
+/* */
+/* 8. Unusual abbreviations that may be used in the commentary: */
+/* lhs -- left hand side (operand, of an operation) */
+/* lsd -- least significant digit (of coefficient) */
+/* lsu -- least significant Unit (of coefficient) */
+/* msd -- most significant digit (of coefficient) */
+/* msi -- most significant item (in an array) */
+/* msu -- most significant Unit (of coefficient) */
+/* rhs -- right hand side (operand, of an operation) */
+/* +ve -- positive */
+/* -ve -- negative */
+/* ** -- raise to the power */
+/* ------------------------------------------------------------------ */
+
+#include <stdlib.h> // for malloc, free, etc.
+#include <stdio.h> // for printf [if needed]
+#include <string.h> // for strcpy
+#include <ctype.h> // for lower
+#include "decNumber.h" // base number library
+#include "decNumberLocal.h" // decNumber local types, etc.
+
+/* Constants */
+// Public constant array: powers of ten (__powers[n]==10**n, 0<=n<=9)
+const uInt __powers[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
+ 10000000, 100000000, 1000000000};
+libc_hidden_data_def (__powers)
+
+// Public lookup table used by the D2U macro
+const uByte d2utable[DECMAXD2U+1]=D2UTABLE;
+libc_hidden_data_def (d2utable) /* Used internally by D2U */
+
+// Local constants
+#define DIVIDE 0x80 // Divide operators
+#define REMAINDER 0x40 // ..
+#define DIVIDEINT 0x20 // ..
+#define REMNEAR 0x10 // ..
+#define COMPARE 0x01 // Compare operators
+#define COMPMAX 0x02 // ..
+#define COMPMIN 0x03 // ..
+#define COMPTOTAL 0x04 // ..
+#define COMPNAN 0x05 // .. [NaN processing]
+
+#define DEC_sNaN 0x40000000 // local status: sNaN signal
+#define BADINT (Int)0x80000000 // most-negative Int; error indicator
+// Next two indicate an integer >= 10**6, and its parity (bottom bit)
+#define BIGEVEN (Int)0x80000002
+#define BIGODD (Int)0x80000003
+
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Unit uarrone[1]={1}; // Unit array of 1, used for incrementing
+#endif /* NOT_IN_libc */
+
+ /* MAX and MIN -- general max & min (not in ANSI) */
+ #ifndef MAX
+ #define MAX(x,y) ((x)<(y)?(y):(x))
+ #endif
+ #ifndef MIN
+ #define MIN(x,y) ((x)>(y)?(y):(x))
+ #endif
+
+/* Granularity-dependent code */
+#if DECDPUN<=4
+ #define eInt Int // extended integer
+ #define ueInt uInt // unsigned extended integer
+
+ #if defined NOT_IN_libc /* Not needed in libc */
+ // 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 /* NOT_IN_libc */
+#else
+ // For DECDPUN>4 non-ANSI-89 64-bit types are needed.
+ #if !DECUSE64
+ #error decNumber.c: DECUSE64 must be 1 when DECDPUN>4
+ #endif
+ #define eInt Long // extended integer
+ #define ueInt uLong // unsigned extended integer
+#endif
+
+/* Local routines */
+#if defined NOT_IN_libc /* These aren't needed in libc. */
+static decNumber * ___decAddOp(decNumber *, const decNumber *, const decNumber *,
+ decContext *, uByte, uInt *);
+static Flag ___decBiStr(const char *, const char *, const char *);
+static uInt ___decCheckMath(const decNumber *, decContext *, uInt *);
+static void ___decApplyRound(decNumber *, decContext *, Int, uInt *);
+/*static Int ___decCompare(const decNumber *lhs, const decNumber *rhs, * Flag); */
+static decNumber * ___decCompareOp(decNumber *, const decNumber *,
+ const decNumber *, decContext *,
+ Flag, uInt *);
+static void ___decCopyFit(decNumber *, const decNumber *, decContext *,
+ Int *, uInt *);
+static decNumber * ___decDivideOp(decNumber *, const decNumber *,
+ const decNumber *, decContext *, Flag, uInt *);
+static decNumber * ___decExpOp(decNumber *, const decNumber *,
+ decContext *, uInt *);
+/*static void ___decFinalize(decNumber *, decContext *, Int *, uInt *); */
+static Int ___decGetDigits(Unit *, Int);
+static Int ___decGetInt(const decNumber *);
+static decNumber * ___decLnOp(decNumber *, const decNumber *,
+ decContext *, uInt *);
+static decNumber * ___decMultiplyOp(decNumber *, const decNumber *,
+ const decNumber *, decContext *,
+ uInt *);
+static decNumber * ___decNaNs(decNumber *, const decNumber *,
+ const decNumber *, uInt *);
+static decNumber * ___decPutInt(decNumber *, Int);
+static decNumber * ___decQuantizeOp(decNumber *, const decNumber *,
+ const decNumber *, decContext *, Flag,
+ uInt *);
+/*static void ___decSetCoeff(decNumber *, decContext *, const Unit *,
+ Int, Int *, uInt *); */
+static void ___decSetOverflow(decNumber *, decContext *, uInt *);
+static void ___decSetSubnormal(decNumber *, decContext *, Int *, uInt *);
+static Int ___decShiftToLeast(Unit *, Int, Int);
+static Int ___decShiftToMost(Unit *, Int, Int);
+/*static void ___decStatus(decNumber *, uInt, decContext *); */
+static decNumber * ___decTrim(decNumber *, Flag, Int *);
+static Int ___decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
+ Unit *, Int);
+static Int ___decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
+#endif /* NOT_IN_libc */
+
+static void ___decToString(const decNumber *, char[], Flag);
+
+#if defined NOT_IN_libc /* Not needed in libc. */
+#if !DECSUBSET
+/* decFinish == decFinalize when no subset arithmetic needed */
+#define ___decFinish(a,b,c,d) ___decFinalize(a,b,c,d)
+#else
+static void ___decFinish(decNumber *, decContext *, Int *, uInt *);
+static decNumber * ___decRoundOperand(const decNumber *, decContext *, uInt *);
+#endif /* !DECSUBSET */
+#endif /* NOT_IN_libc */
+
+/* Local macros */
+// masked special-values bits
+#define SPECIALARG (rhs->bits & DECSPECIAL)
+#define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)
+
+/* Diagnostic macros, etc. */
+#if DECALLOC
+// Handle malloc/free accounting. If enabled, our accountable routines
+// are used; otherwise the code just goes straight to the system malloc
+// and free routines.
+#if defined NOT_IN_libc /* Not needed in libc. */
+#define malloc(a) ___decMalloc(a)
+#define free(a) ___decFree(a)
+#define DECFENCE 0x5a // corruption detector
+// 'Our' malloc and free:
+static void *___decMalloc(size_t);
+static void ___decFree(void *);
+uInt decAllocBytes=0; // count of bytes allocated
+#endif /* NOT_IN_libc */
+// Note that DECALLOC code only checks for storage buffer overflow.
+// To check for memory leaks, the decAllocBytes variable must be
+// checked to be 0 at appropriate times (e.g., after the test
+// harness completes a set of tests). This checking may be unreliable
+// if the testing is done in a multi-thread environment.
+#endif
+
+#if DECCHECK
+// Optional checking routines. Enabling these means that decNumber
+// and decContext operands to operator routines are checked for
+// correctness. This roughly doubles the execution time of the
+// fastest routines (and adds 600+ bytes), so should not normally be
+// used in 'production'.
+// decCheckInexact is used to check that inexact results have a full
+// complement of digits (where appropriate -- this is not the case
+// for Quantize, for example)
+#if defined NOT_IN_libc /* Not needed in libc. */
+#define DECUNUSED (void *)(0xffffffff)
+static Flag ___decCheckOperands(decNumber *, const decNumber *,
+ const decNumber *, decContext *);
+static Flag ___decCheckNumber(const decNumber *, decContext *);
+static void ___decCheckInexact(const decNumber *, decContext *);
+#endif /* NOT_IN_libc */
+#endif /* DECCHECK */
+
+#if DECTRACE || DECCHECK
+#if defined NOT_IN_libc /* Not needed in libc. */
+// Optional trace/debugging routines (may or may not be used)
+void ___decNumberShow(const decNumber *); // displays the components of a number
+static void ___decDumpAr(char, const Unit *, Int);
+#endif /* NOT_IN_libc */
+#endif /* DECTRACE || DECCHECK */
+
+/* ================================================================== */
+/* Conversions */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* to-scientific-string -- conversion to numeric string */
+/* to-engineering-string -- conversion to numeric string */
+/* */
+/* ___decNumberToString(dn, string); */
+/* ___decNumberToEngString(dn, string); */
+/* */
+/* dn is the decNumber to convert */
+/* string is the string where the result will be laid out */
+/* */
+/* string must be at least dn->digits+14 characters long */
+/* */
+/* No error is possible, and no status can be set. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+char * ___decNumberToString(const decNumber *dn, char *string){
+ ___decToString(dn, string, 0);
+ return string;
+} /* __DecNumberToString */
+#endif
+
+char * ___decNumberToEngString(const decNumber *dn, char *string){
+ ___decToString(dn, string, 1);
+ return string;
+} /* ___decNumberToEngString */
+libc_hidden_def (___decNumberToEngString)
+
+/* ------------------------------------------------------------------ */
+/* to-number -- conversion from numeric string */
+/* */
+/* ___decNumberFromString -- convert string to decNumber */
+/* dn -- the number structure to fill */
+/* chars[] -- the string to convert ('\0' terminated) */
+/* set -- the context used for processing any error, */
+/* determining the maximum precision available */
+/* (set.digits), determining the maximum and minimum */
+/* exponent (set.emax and set.emin), determining if */
+/* extended values are allowed, and checking the */
+/* rounding mode if overflow occurs or rounding is */
+/* needed. */
+/* */
+/* The length of the coefficient and the size of the exponent are */
+/* checked by this routine, so the correct error (Underflow or */
+/* Overflow) can be reported or rounding applied, as necessary. */
+/* */
+/* If bad syntax is detected, the result will be a quiet NaN. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberFromString(decNumber *dn, const char chars[],
+ decContext *set) {
+ Int exponent=0; // working exponent [assume 0]
+ uByte bits=0; // working flags [assume +ve]
+ Unit *res; // where result will be built
+ Unit resbuff[SD2U(DECBUFFER+1)];// local buffer in case need temporary
+ Unit *allocres=NULL; // -> allocated result, iff allocated
+ Int d=0; // count of digits found in decimal part
+ const char *dotchar=NULL; // where dot was found
+ const char *cfirst=chars; // -> first character of decimal part
+ const char *last=NULL; // -> last digit of decimal part
+ const char *c; // work
+ Unit *up; // ..
+ #if DECDPUN>1
+ Int cut, out; // ..
+ #endif
+ Int residue; // rounding residue
+ uInt status=0; // error code
+
+ #if DECCHECK
+ if (___decCheckOperands(DECUNUSED, DECUNUSED, DECUNUSED, set))
+ return ___decNumberZero(dn);
+ #endif
+
+ do { // status & malloc protection
+ for (c=chars;; c++) { // -> input character
+ if (*c>='0' && *c<='9') { // test for Arabic digit
+ last=c;
+ d++; // count of real digits
+ continue; // still in decimal part
+ }
+ if (*c=='.' && dotchar==NULL) { // first '.'
+ dotchar=c; // record offset into decimal part
+ if (c==cfirst) cfirst++; // first digit must follow
+ continue;}
+ if (c==chars) { // first in string...
+ if (*c=='-') { // valid - sign
+ cfirst++;
+ bits=DECNEG;
+ continue;}
+ if (*c=='+') { // valid + sign
+ cfirst++;
+ continue;}
+ }
+ // *c is not a digit, or a valid +, -, or '.'
+ break;
+ } // c
+
+ if (last==NULL) { // no digits yet
+ status=DEC_Conversion_syntax;// assume the worst
+ if (*c=='\0') break; // and no more to come...
+ #if DECSUBSET
+ // if subset then infinities and NaNs are not allowed
+ if (!set->extended) break; // hopeless
+ #endif
+ // Infinities and NaNs are possible, here
+ if (dotchar!=NULL) break; // .. unless had a dot
+ ___decNumberZero(dn); // be optimistic
+ if (___decBiStr(c, "infinity", "INFINITY")
+ || ___decBiStr(c, "inf", "INF")) {
+ dn->bits=bits | DECINF;
+ status=0; // is OK
+ break; // all done
+ }
+ // a NaN expected
+ // 2003.09.10 NaNs are now permitted to have a sign
+ dn->bits=bits | DECNAN; // assume simple NaN
+ if (*c=='s' || *c=='S') { // looks like an sNaN
+ c++;
+ dn->bits=bits | DECSNAN;
+ }
+ if (*c!='n' && *c!='N') break; // check caseless "NaN"
+ c++;
+ if (*c!='a' && *c!='A') break; // ..
+ c++;
+ if (*c!='n' && *c!='N') break; // ..
+ c++;
+ // now either nothing, or nnnn payload, expected
+ // -> start of integer and skip leading 0s [including plain 0]
+ for (cfirst=c; *cfirst=='0';) cfirst++;
+ if (*cfirst=='\0') { // "NaN" or "sNaN", maybe with all 0s
+ status=0; // it's good
+ break; // ..
+ }
+ // something other than 0s; setup last and d as usual [no dots]
+ for (c=cfirst;; c++, d++) {
+ if (*c<'0' || *c>'9') break; // test for Arabic digit
+ last=c;
+ }
+ if (*c!='\0') break; // not all digits
+ if (d>set->digits-1) {
+ // [NB: payload in a decNumber can be full length unless
+ // clamped, in which case can only be digits-1]
+ if (set->clamp) break;
+ if (d>set->digits) break;
+ } // too many digits?
+ // good; drop through to convert the integer to coefficient
+ status=0; // syntax is OK
+ bits=dn->bits; // for copy-back
+ } // last==NULL
+
+ else if (*c!='\0') { // more to process...
+ // had some digits; exponent is only valid sequence now
+ Flag nege; // 1=negative exponent
+ const char *firstexp; // -> first significant exponent digit
+ status=DEC_Conversion_syntax;// assume the worst
+ if (*c!='e' && *c!='E') break;
+ /* Found 'e' or 'E' -- now process explicit exponent */
+ // 1998.07.11: sign no longer required
+ nege=0;
+ c++; // to (possible) sign
+ if (*c=='-') {nege=1; c++;}
+ else if (*c=='+') c++;
+ if (*c=='\0') break;
+
+ for (; *c=='0' && *(c+1)!='\0';) c++; // strip insignificant zeros
+ firstexp=c; // save exponent digit place
+ for (; ;c++) {
+ if (*c<'0' || *c>'9') break; // not a digit
+ exponent=X10(exponent)+(Int)*c-(Int)'0';
+ } // c
+ // if not now on a '\0', *c must not be a digit
+ if (*c!='\0') break;
+
+ // (this next test must be after the syntax checks)
+ // if it was too long the exponent may have wrapped, so check
+ // carefully and set it to a certain overflow if wrap possible
+ if (c>=firstexp+9+1) {
+ if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2;
+ // [up to 1999999999 is OK, for example 1E-1000000998]
+ }
+ if (nege) exponent=-exponent; // was negative
+ status=0; // is OK
+ } // stuff after digits
+
+ // Here when whole string has been inspected; syntax is good
+ // cfirst->first digit (never dot), last->last digit (ditto)
+
+ // strip leading zeros/dot [leave final 0 if all 0's]
+ if (*cfirst=='0') { // [cfirst has stepped over .]
+ for (c=cfirst; c<last; c++, cfirst++) {
+ if (*c=='.') continue; // ignore dots
+ if (*c!='0') break; // non-zero found
+ d--; // 0 stripped
+ } // c
+ #if DECSUBSET
+ // make a rapid exit for easy zeros if !extended
+ if (*cfirst=='0' && !set->extended) {
+ ___decNumberZero(dn); // clean result
+ break; // [could be return]
+ }
+ #endif
+ } // at least one leading 0
+
+ // Handle decimal point...
+ if (dotchar!=NULL && dotchar<last) // non-trailing '.' found?
+ exponent-=(last-dotchar); // adjust exponent
+ // [we can now ignore the .]
+
+ // OK, the digits string is good. Assemble in the decNumber, or in
+ // a temporary units array if rounding is needed
+ if (d<=set->digits) res=dn->lsu; // fits into supplied decNumber
+ else { // rounding needed
+ Int needbytes=D2U(d)*sizeof(Unit);// bytes needed
+ res=resbuff; // assume use local buffer
+ if (needbytes>(Int)sizeof(resbuff)) { // too big for local
+ allocres=(Unit *)malloc(needbytes);
+ if (allocres==NULL) {status|=DEC_Insufficient_storage; break;}
+ res=allocres;
+ }
+ }
+ // res now -> number lsu, buffer, or allocated storage for Unit array
+
+ // Place the coefficient into the selected Unit array
+ // [this is often 70% of the cost of this function when DECDPUN>1]
+ #if DECDPUN>1
+ out=0; // accumulator
+ up=res+D2U(d)-1; // -> msu
+ cut=d-(up-res)*DECDPUN; // digits in top unit
+ for (c=cfirst;; c++) { // along the digits
+ if (*c=='.') continue; // ignore '.' [don't decrement cut]
+ out=X10(out)+(Int)*c-(Int)'0';
+ if (c==last) break; // done [never get to trailing '.']
+ cut--;
+ if (cut>0) continue; // more for this unit
+ *up=(Unit)out; // write unit
+ up--; // prepare for unit below..
+ cut=DECDPUN; // ..
+ out=0; // ..
+ } // c
+ *up=(Unit)out; // write lsu
+
+ #else
+ // DECDPUN==1
+ up=res; // -> lsu
+ for (c=last; c>=cfirst; c--) { // over each character, from least
+ if (*c=='.') continue; // ignore . [don't step up]
+ *up=(Unit)((Int)*c-(Int)'0');
+ up++;
+ } // c
+ #endif
+
+ dn->bits=bits;
+ dn->exponent=exponent;
+ dn->digits=d;
+
+ // if not in number (too long) shorten into the number
+ if (d>set->digits) {
+ residue=0;
+ ___decSetCoeff(dn, set, res, d, &residue, &status);
+ // always check for overflow or subnormal and round as needed
+ ___decFinalize(dn, set, &residue, &status);
+ }
+ else { // no rounding, but may still have overflow or subnormal
+ // [these tests are just for performance; finalize repeats them]
+ if ((dn->exponent-1<set->emin-dn->digits)
+ || (dn->exponent-1>set->emax-set->digits)) {
+ residue=0;
+ ___decFinalize(dn, set, &residue, &status);
+ }
+ }
+ // ___decNumberShow(dn);
+ } while(0); // [for break]
+
+ if (allocres!=NULL) free(allocres); // drop any storage used
+ if (status!=0) ___decStatus(dn, status, set);
+ return dn;
+} /* ___decNumberFromString */
+#endif /* NOT_IN_libc */
+
+/* ================================================================== */
+/* Operators */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberAbs -- absolute value operator */
+/* */
+/* This computes C = abs(A) */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+/* This has the same effect as ___decNumberPlus unless A is negative, */
+/* in which case it has the same effect as ___decNumberMinus. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberAbs(decNumber *res, const decNumber *rhs,
+ decContext *set) {
+ decNumber dzero; // for 0
+ uInt status=0; // accumulator
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ ___decNumberZero(&dzero); // set 0
+ dzero.exponent=rhs->exponent; // [no coefficient expansion]
+ ___decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberAbs */
+#endif
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberAdd -- add two Numbers */
+/* */
+/* This computes C = A + B */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X+X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+/* This just calls the routine shared with Subtract */
+#if defined NOT_IN_libc
+decNumber * ___decNumberAdd(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decAddOp(res, lhs, rhs, set, 0, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberAdd */
+#endif
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberCompare -- compare two Numbers */
+/* */
+/* This computes C = A ? B */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for one digit (or NaN). */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberCompare(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decCompareOp(res, lhs, rhs, set, COMPARE, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ return res;
+} /* ___decNumberCompare */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberCompareTotal -- compare two Numbers, using total ordering */
+/* */
+/* This computes C = A ? B, under total ordering */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for one digit; the result will always be one of */
+/* -1, 0, or 1. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberCompareTotal(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ return res;
+} /* ___decNumberCompareTotal */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberDivide -- divide one number by another */
+/* */
+/* This computes C = A / B */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X/X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberDivide(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberDivide */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberDivideInteger -- divide and return integer quotient */
+/* */
+/* This computes C = A # B, where # is the integer divide operator */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X#X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberDivideInteger(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ return res;
+} /* ___decNumberDivideInteger */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberExp -- exponentiation */
+/* */
+/* This computes C = exp(A) */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context; note that rounding mode has no effect */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* Mathematical function restrictions apply (see above); a NaN is */
+/* returned with Invalid_operation if a restriction is violated. */
+/* */
+/* Finite results will always be full precision and Inexact, except */
+/* when A is a zero or -Infinity (giving 1 or 0 respectively). */
+/* */
+/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */
+/* almost always be correctly rounded, but may be up to 1 ulp in */
+/* error in rare cases. */
+/* ------------------------------------------------------------------ */
+/* This is a wrapper for ___decExpOp which can handle the slightly wider */
+/* (double) range needed by Ln (which has to be able to calculate */
+/* exp(-a) where a can be the tiniest number (Ntiny). */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberExp(decNumber *res, const decNumber *rhs,
+ decContext *set) {
+ uInt status=0; // accumulator
+ #if DECSUBSET
+ decNumber *allocrhs=NULL; // non-NULL if rounded rhs allocated
+ #endif
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ // Check restrictions; these restrictions ensure that if h=8 (see
+ // ___decExpOp) then the result will either overflow or underflow to 0.
+ // Other math functions restrict the input range, too, for inverses.
+ // If not violated then carry out the operation.
+ if (!___decCheckMath(rhs, set, &status)) do { // protect allocation
+ #if DECSUBSET
+ if (!set->extended) {
+ // reduce operand and set lostDigits status, as needed
+ if (rhs->digits>set->digits) {
+ allocrhs=___decRoundOperand(rhs, set, &status);
+ if (allocrhs==NULL) break;
+ rhs=allocrhs;
+ }
+ }
+ #endif
+ ___decExpOp(res, rhs, set, &status);
+ } while(0); // end protected
+
+ #if DECSUBSET
+ if (allocrhs !=NULL) free(allocrhs); // drop any storage used
+ #endif
+ // apply significant status
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberExp */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberLn -- natural logarithm */
+/* */
+/* This computes C = ln(A) */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context; note that rounding mode has no effect */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* Notable cases: */
+/* A<0 -> Invalid */
+/* A=0 -> -Infinity (Exact) */
+/* A=+Infinity -> +Infinity (Exact) */
+/* A=1 exactly -> 0 (Exact) */
+/* */
+/* Mathematical function restrictions apply (see above); a NaN is */
+/* returned with Invalid_operation if a restriction is violated. */
+/* */
+/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */
+/* almost always be correctly rounded, but may be up to 1 ulp in */
+/* error in rare cases. */
+/* ------------------------------------------------------------------ */
+/* This is a wrapper for ___decLnOp which can handle the slightly wider */
+/* (+11) range needed by Ln, Log10, etc. (which may have to be able */
+/* to calculate at p+e+2). */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberLn(decNumber *res, const decNumber *rhs,
+ decContext *set) {
+ uInt status=0; // accumulator
+ #if DECSUBSET
+ decNumber *allocrhs=NULL; // non-NULL if rounded rhs allocated
+ #endif
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ // Check restrictions; this is a math function; if not violated
+ // then carry out the operation.
+ if (!___decCheckMath(rhs, set, &status)) do { // protect allocation
+ #if DECSUBSET
+ if (!set->extended) {
+ // reduce operand and set lostDigits status, as needed
+ if (rhs->digits>set->digits) {
+ allocrhs=___decRoundOperand(rhs, set, &status);
+ if (allocrhs==NULL) break;
+ rhs=allocrhs;
+ }
+ // special check in subset for rhs=0
+ if (ISZERO(rhs)) { // +/- zeros -> error
+ status|=DEC_Invalid_operation;
+ break;}
+ } // extended=0
+ #endif
+ ___decLnOp(res, rhs, set, &status);
+ } while(0); // end protected
+
+ #if DECSUBSET
+ if (allocrhs !=NULL) free(allocrhs); // drop any storage used
+ #endif
+ // apply significant status
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberLn */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberLog10 -- logarithm in base 10 */
+/* */
+/* This computes C = log10(A) */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context; note that rounding mode has no effect */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* Notable cases: */
+/* A<0 -> Invalid */
+/* A=0 -> -Infinity (Exact) */
+/* A=+Infinity -> +Infinity (Exact) */
+/* A=10**n (if n is an integer) -> n (Exact) */
+/* */
+/* Mathematical function restrictions apply (see above); a NaN is */
+/* returned with Invalid_operation if a restriction is violated. */
+/* */
+/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */
+/* almost always be correctly rounded, but may be up to 1 ulp in */
+/* error in rare cases. */
+/* ------------------------------------------------------------------ */
+/* This calculates ln(A)/ln(10) using appropriate precision. For */
+/* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the */
+/* requested digits and t is the number of digits in the exponent */
+/* (maximum 6). For ln(10) it is p + 3; this is often handled by the */
+/* fastpath in ___decLnOp. The final division is done to the requested */
+/* precision. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberLog10(decNumber *res, const decNumber *rhs,
+ decContext *set) {
+ uInt status=0, ignore=0; // status accumulators
+ uInt needbytes; // for space calculations
+ Int p; // working precision
+ Int t; // digits in exponent of A
+
+ // buffers for a and b working decimals
+ // (adjustment calculator, same size)
+ decNumber bufa[D2N(DECBUFFER+2)];
+ decNumber *allocbufa=NULL; // -> allocated bufa, iff allocated
+ decNumber *a=bufa; // temporary a
+ decNumber bufb[D2N(DECBUFFER+2)];
+ decNumber *allocbufb=NULL; // -> allocated bufa, iff allocated
+ decNumber *b=bufb; // temporary b
+ decNumber bufw[D2N(10)]; // working 2-10 digit number
+ decNumber *w=bufw; // ..
+ #if DECSUBSET
+ decNumber *allocrhs=NULL; // non-NULL if rounded rhs allocated
+ #endif
+
+ decContext aset; // working context
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ // Check restrictions; this is a math function; if not violated
+ // then carry out the operation.
+ if (!___decCheckMath(rhs, set, &status)) do { // protect malloc
+ #if DECSUBSET
+ if (!set->extended) {
+ // reduce operand and set lostDigits status, as needed
+ if (rhs->digits>set->digits) {
+ allocrhs=___decRoundOperand(rhs, set, &status);
+ if (allocrhs==NULL) break;
+ rhs=allocrhs;
+ }
+ // special check in subset for rhs=0
+ if (ISZERO(rhs)) { // +/- zeros -> error
+ status|=DEC_Invalid_operation;
+ break;}
+ } // extended=0
+ #endif
+
+ ___decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
+
+ // handle exact powers of 10; only check if +ve finite
+ if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) {
+ Int residue=0; // (no residue)
+ uInt copystat=0; // clean status
+
+ // round to a single digit...
+ aset.digits=1;
+ ___decCopyFit(w, rhs, &aset, &residue, &copystat); // copy & shorten
+ // if exact and the digit is 1, rhs is a power of 10
+ if (!(copystat&DEC_Inexact) && w->lsu[0]==1) {
+ // the exponent, conveniently, is the power of 10; making
+ // this the result needs a little care as it might not fit,
+ // so first convert it into the working number, and then move
+ // to res
+ ___decPutInt(w, w->exponent);
+ residue=0;
+ ___decCopyFit(res, w, set, &residue, &status); // copy & round
+ ___decFinish(res, set, &residue, &status); // cleanup/set flags
+ break;
+ } // not a power of 10
+ } // not a candidate for exact
+
+ // simplify the information-content calculation to use 'total
+ // number of digits in a, including exponent' as compared to the
+ // requested digits, as increasing this will only rarely cost an
+ // iteration in ln(a) anyway
+ t=6; // it can never be >6
+
+ // allocate space when needed...
+ p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;
+ needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
+ if (needbytes>sizeof(bufa)) { // need malloc space
+ allocbufa=(decNumber *)malloc(needbytes);
+ if (allocbufa==NULL) { // hopeless -- abandon
+ status|=DEC_Insufficient_storage;
+ break;}
+ a=allocbufa; // use the allocated space
+ }
+ aset.digits=p; // as calculated
+ aset.emax=DEC_MAX_MATH; // usual bounds
+ aset.emin=-DEC_MAX_MATH; // ..
+ aset.clamp=0; // and no concrete format
+ ___decLnOp(a, rhs, &aset, &status); // a=ln(rhs)
+
+ // skip the division if the result so far is infinite, NaN, or
+ // zero, or there was an error; note NaN from sNaN needs copy
+ if (status&DEC_NaNs && !(status&DEC_sNaN)) break;
+ if (a->bits&DECSPECIAL || ISZERO(a)) {
+ ___decNumberCopy(res, a); // [will fit]
+ break;}
+
+ // for ln(10) an extra 3 digits of precision are needed
+ p=set->digits+3;
+ needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
+ if (needbytes>sizeof(bufb)) { // need malloc space
+ allocbufb=(decNumber *)malloc(needbytes);
+ if (allocbufb==NULL) { // hopeless -- abandon
+ status|=DEC_Insufficient_storage;
+ break;}
+ b=allocbufb; // use the allocated space
+ }
+ ___decNumberZero(w); // set up 10...
+ #if DECDPUN==1
+ w->lsu[1]=1; w->lsu[0]=0; // ..
+ #else
+ w->lsu[0]=10; // ..
+ #endif
+ w->digits=2; // ..
+
+ aset.digits=p;
+ ___decLnOp(b, w, &aset, &ignore); // b=ln(10)
+
+ aset.digits=set->digits; // for final divide
+ ___decDivideOp(res, a, b, &aset, DIVIDE, &status); // into result
+ } while(0); // [for break]
+
+ if (allocbufa!=NULL) free(allocbufa); // drop any storage used
+ if (allocbufb!=NULL) free(allocbufb); // ..
+ #if DECSUBSET
+ if (allocrhs !=NULL) free(allocrhs); // ..
+ #endif
+ // apply significant status
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberLog10 */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberMax -- compare two Numbers and return the maximum */
+/* */
+/* This computes C = A ? B, returning the maximum or A if equal */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberMax(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberMax */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberMin -- compare two Numbers and return the minimum */
+/* */
+/* This computes C = A ? B, returning the minimum or A if equal */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberMin(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberMin */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberMinus -- prefix minus operator */
+/* */
+/* This computes C = 0 - A */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+/* Simply use AddOp for the subtract, which will do the necessary. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberMinus(decNumber *res, const decNumber *rhs,
+ decContext *set) {
+ decNumber dzero;
+ uInt status=0; // accumulator
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ ___decNumberZero(&dzero); // make 0
+ dzero.exponent=rhs->exponent; // [no coefficient expansion]
+ ___decAddOp(res, &dzero, rhs, set, DECNEG, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberMinus */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberPlus -- prefix plus operator */
+/* */
+/* This computes C = 0 + A */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+/* This simply uses AddOp; Add will take fast path after preparing A. */
+/* Performance is a concern here, as this routine is often used to */
+/* check operands and apply rounding and overflow/underflow testing. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberPlus(decNumber *res, const decNumber *rhs,
+ decContext *set) {
+ decNumber dzero;
+ uInt status=0; // accumulator
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ ___decNumberZero(&dzero); // make 0
+ dzero.exponent=rhs->exponent; // [no coefficient expansion]
+ ___decAddOp(res, &dzero, rhs, set, 0, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberPlus */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberMultiply -- multiply two Numbers */
+/* */
+/* This computes C = A x B */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X+X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberMultiply(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decMultiplyOp(res, lhs, rhs, set, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberMultiply */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberNormalize -- remove trailing zeros */
+/* */
+/* This computes C = 0 + A, and normalizes the result */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberNormalize(decNumber *res, const decNumber *rhs,
+ decContext *set) {
+ #if DECSUBSET
+ decNumber *allocrhs=NULL; // non-NULL if rounded rhs allocated
+ #endif
+ uInt status=0; // as usual
+ Int residue=0; // as usual
+ Int dropped; // work
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ do { // protect allocated storage
+ #if DECSUBSET
+ if (!set->extended) {
+ // reduce operand and set lostDigits status, as needed
+ if (rhs->digits>set->digits) {
+ allocrhs=___decRoundOperand(rhs, set, &status);
+ if (allocrhs==NULL) break;
+ rhs=allocrhs;
+ }
+ }
+ #endif
+ // [following code does not require input rounding]
+
+ // specials copy through, except NaNs need care
+ if (___decNumberIsNaN(rhs)) {
+ ___decNaNs(res, rhs, NULL, &status);
+ break;
+ }
+
+ // reduce result to the requested length and copy to result
+ ___decCopyFit(res, rhs, set, &residue, &status); // copy & round
+ ___decFinish(res, set, &residue, &status); // cleanup/set flags
+ ___decTrim(res, 1, &dropped); // normalize in place
+ } while(0); // end protected
+
+ #if DECSUBSET
+ if (allocrhs !=NULL) free(allocrhs); // ..
+ #endif
+ if (status!=0) ___decStatus(res, status, set);// then report status
+ return res;
+} /* ___decNumberNormalize */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberPower -- raise a number to a power */
+/* */
+/* This computes C = A ** B */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X**X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* Mathematical function restrictions apply (see above); a NaN is */
+/* returned with Invalid_operation if a restriction is violated. */
+/* */
+/* However, if 1999999997<=B<=999999999 and B is an integer then the */
+/* restrictions on A and the context are relaxed to the usual bounds, */
+/* for compatibility with the earlier (integer power only) version */
+/* of this function. */
+/* */
+/* When B is an integer, the result may be exact, even if rounded. */
+/* */
+/* The final result is rounded according to the context; it will */
+/* almost always be correctly rounded, but may be up to 1 ulp in */
+/* error in rare cases. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberPower(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ #if DECSUBSET
+ decNumber *alloclhs=NULL; // non-NULL if rounded lhs allocated
+ decNumber *allocrhs=NULL; // .., rhs
+ #endif
+ decNumber *allocdac=NULL; // -> allocated acc buffer, iff used
+ decNumber *allocinv=NULL; // -> allocated 1/x buffer, iff used
+ Int reqdigits=set->digits; // requested DIGITS
+ Int n; // rhs in binary
+ Flag rhsint=0; // 1 if rhs is an integer
+ Flag useint=0; // 1 if can use integer calculation
+ Flag isoddint=0; // 1 if rhs is an integer and odd
+ Int i; // work
+ #if DECSUBSET
+ Int dropped; // ..
+ #endif
+ uInt needbytes; // buffer size needed
+ Flag seenbit; // seen a bit while powering
+ Int residue=0; // rounding residue
+ uInt status=0; // accumulators
+ uByte bits=0; // result sign if errors
+ decContext aset; // working context
+ decNumber dnOne; // work value 1...
+ // local accumulator buffer [a decNumber, with digits+elength+1 digits]
+ decNumber dacbuff[D2N(DECBUFFER+9)];
+ decNumber *dac=dacbuff; // -> result accumulator
+ // same again for possible 1/lhs calculation
+ decNumber invbuff[D2N(DECBUFFER+9)];
+
+ #if DECCHECK
+ if (___decCheckOperands(res, lhs, rhs, set)) return res;
+ #endif
+
+ do { // protect allocated storage
+ #if DECSUBSET
+ if (!set->extended) { // reduce operands and set status, as needed
+ if (lhs->digits>reqdigits) {
+ alloclhs=___decRoundOperand(lhs, set, &status);
+ if (alloclhs==NULL) break;
+ lhs=alloclhs;
+ }
+ if (rhs->digits>reqdigits) {
+ allocrhs=___decRoundOperand(rhs, set, &status);
+ if (allocrhs==NULL) break;
+ rhs=allocrhs;
+ }
+ }
+ #endif
+ // [following code does not require input rounding]
+
+ // handle NaNs and rhs Infinity (lhs infinity is harder)
+ if (SPECIALARGS) {
+ if (___decNumberIsNaN(lhs) || ___decNumberIsNaN(rhs)) { // NaNs
+ ___decNaNs(res, lhs, rhs, &status);
+ break;}
+ if (___decNumberIsInfinite(rhs)) { // rhs Infinity
+ Flag rhsneg=rhs->bits&DECNEG; // save rhs sign
+ if (___decNumberIsNegative(lhs) // lhs<0
+ && !___decNumberIsZero(lhs)) // ..
+ status|=DEC_Invalid_operation;
+ else { // lhs >=0
+ ___decNumberZero(&dnOne); // set up 1
+ dnOne.lsu[0]=1;
+ ___decNumberCompare(dac, lhs, &dnOne, set); // lhs ? 1
+ ___decNumberZero(res); // prepare for 0/1/Infinity
+ if (___decNumberIsNegative(dac)) { // lhs<1
+ if (rhsneg) res->bits|=DECINF; // +Infinity [else is +0]
+ }
+ else if (dac->lsu[0]==0) { // lhs=1
+ // 1**Infinity is inexact, so return fully-padded 1.0000
+ Int shift=set->digits-1;
+ *res->lsu=1; // was 0, make int 1
+ res->digits=___decShiftToMost(res->lsu, 1, shift);
+ res->exponent=-shift; // make 1.0000...
+ status|=DEC_Inexact|DEC_Rounded; // deemed inexact
+ }
+ else { // lhs>1
+ if (!rhsneg) res->bits|=DECINF; // +Infinity [else is +0]
+ }
+ } // lhs>=0
+ break;}
+ // [lhs infinity drops through]
+ } // specials
+
+ // Original rhs may be an integer that fits and is in range
+ n=___decGetInt(rhs);
+ if (n!=BADINT) { // it is an integer
+ rhsint=1; // record the fact for 1**n
+ isoddint=(Flag)n&1; // [works even if big]
+ if (n!=BIGEVEN && n!=BIGODD) // can use integer path?
+ useint=1; // looks good
+ }
+
+ if (___decNumberIsNegative(lhs) // -x ..
+ && isoddint) bits=DECNEG; // .. to an odd power
+
+ // handle LHS infinity
+ if (___decNumberIsInfinite(lhs)) { // [NaNs already handled]
+ uByte rbits=rhs->bits; // save
+ ___decNumberZero(res); // prepare
+ if (n==0) *res->lsu=1; // [-]Inf**0 => 1
+ else {
+ // -Inf**nonint -> error
+ if (!rhsint && ___decNumberIsNegative(lhs)) {
+ status|=DEC_Invalid_operation; // -Inf**nonint is error
+ break;}
+ if (!(rbits & DECNEG)) bits|=DECINF; // was not a **-n
+ // [otherwise will be 0 or -0]
+ res->bits=bits;
+ }
+ break;}
+
+ // similarly handle LHS zero
+ if (___decNumberIsZero(lhs)) {
+ if (n==0) { // 0**0 => Error
+ #if DECSUBSET
+ if (!set->extended) { // [unless subset]
+ ___decNumberZero(res);
+ *res->lsu=1; // return 1
+ break;}
+ #endif
+ status|=DEC_Invalid_operation;
+ }
+ else { // 0**x
+ uByte rbits=rhs->bits; // save
+ if (rbits & DECNEG) { // was a 0**(-n)
+ #if DECSUBSET
+ if (!set->extended) { // [bad if subset]
+ status|=DEC_Invalid_operation;
+ break;}
+ #endif
+ bits|=DECINF;
+ }
+ ___decNumberZero(res); // prepare
+ // [otherwise will be 0 or -0]
+ res->bits=bits;
+ }
+ break;}
+
+ // here both lhs and rhs are finite; rhs==0 is handled in the
+ // integer path. Next handle the non-integer cases
+ if (!useint) { // non-integral rhs
+ // any -ve lhs is bad, as is either operand or context out of
+ // bounds
+ if (___decNumberIsNegative(lhs)) {
+ status|=DEC_Invalid_operation;
+ break;}
+ if (___decCheckMath(lhs, set, &status)
+ || ___decCheckMath(rhs, set, &status)) break; // variable status
+
+ ___decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
+ aset.emax=DEC_MAX_MATH; // usual bounds
+ aset.emin=-DEC_MAX_MATH; // ..
+ aset.clamp=0; // and no concrete format
+
+ // calculate the result using exp(ln(lhs)*rhs), which can
+ // all be done into the accumulator, dac. The precision needed
+ // is enough to contain the full information in the lhs (which
+ // is the total digits, including exponent), or the requested
+ // precision, if larger, + 4; 6 is used for the exponent
+ // maximum length, and this is also used when it is shorter
+ // than the requested digits as it greatly reduces the >0.5 ulp
+ // cases at little cost (because Ln doubles digits each
+ // iteration so a few extra digits rarely causes an extra
+ // iteration)
+ aset.digits=MAX(lhs->digits, set->digits)+6+4;
+ } // non-integer rhs
+
+ else { // rhs is in-range integer
+ if (n==0) { // x**0 = 1
+ // (0**0 was handled above)
+ ___decNumberZero(res); // result=1
+ *res->lsu=1; // ..
+ break;}
+ // rhs is a non-zero integer
+ if (n<0) n=-n; // use abs(n)
+
+ aset=*set; // clone the context
+ aset.round=DEC_ROUND_HALF_EVEN; // internally use balanced
+ // calculate the working DIGITS
+ aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;
+ #if DECSUBSET
+ if (!set->extended) aset.digits--; // use classic precision
+ #endif
+ // it's an error if this is more than can be handled
+ if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;}
+ } // integer path
+
+ // aset.digits is the count of digits for the accumulator needed
+ // if accumulator is too long for local storage, then allocate
+ needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit);
+ // [needbytes also used below if 1/lhs needed]
+ if (needbytes>sizeof(dacbuff)) {
+ allocdac=(decNumber *)malloc(needbytes);
+ if (allocdac==NULL) { // hopeless -- abandon
+ status|=DEC_Insufficient_storage;
+ break;}
+ dac=allocdac; // use the allocated space
+ }
+ // here, aset is set up and accumulator is ready for use
+
+ if (!useint) { // non-integral rhs
+ // x ** y; special-case x=1 here as it will otherwise always
+ // reduce to integer 1; decLnOp has a fastpath which detects
+ // the case of x=1
+ ___decLnOp(dac, lhs, &aset, &status); // dac=ln(lhs)
+ // [no error possible, as lhs 0 already handled]
+ if (ISZERO(dac)) { // x==1, 1.0, etc.
+ // need to return fully-padded 1.0000 etc., but rhsint->1
+ *dac->lsu=1; // was 0, make int 1
+ if (!rhsint) { // add padding
+ Int shift=set->digits-1;
+ dac->digits=___decShiftToMost(dac->lsu, 1, shift);
+ dac->exponent=-shift; // make 1.0000...
+ status|=DEC_Inexact|DEC_Rounded; // deemed inexact
+ }
+ }
+ else {
+ ___decMultiplyOp(dac, dac, rhs, &aset, &status); // dac=dac*rhs
+ ___decExpOp(dac, dac, &aset, &status); // dac=exp(dac)
+ }
+ // and drop through for final rounding
+ } // non-integer rhs
+
+ else { // carry on with integer
+ ___decNumberZero(dac); // acc=1
+ *dac->lsu=1; // ..
+
+ // if a negative power the constant 1 is needed, and if not subset
+ // invert the lhs now rather than inverting the result later
+ if (___decNumberIsNegative(rhs)) { // was a **-n [hence digits>0]
+ decNumber *inv=invbuff; // asssume use fixed buffer
+ ___decNumberCopy(&dnOne, dac); // dnOne=1; [needed now or later]
+ #if DECSUBSET
+ if (set->extended) { // need to calculate 1/lhs
+ #endif
+ // divide lhs into 1, putting result in dac [dac=1/dac]
+ ___decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status);
+ // now locate or allocate space for the inverted lhs
+ if (needbytes>sizeof(invbuff)) {
+ allocinv=(decNumber *)malloc(needbytes);
+ if (allocinv==NULL) { // hopeless -- abandon
+ status|=DEC_Insufficient_storage;
+ break;}
+ inv=allocinv; // use the allocated space
+ }
+ // [inv now points to big-enough buffer or allocated storage]
+ ___decNumberCopy(inv, dac); // copy the 1/lhs
+ ___decNumberCopy(dac, &dnOne); // restore acc=1
+ lhs=inv; // .. and go forward with new lhs
+ #if DECSUBSET
+ }
+ #endif
+ }
+
+ // Raise-to-the-power loop...
+ seenbit=0; // set once a 1-bit is encountered
+ for (i=1;;i++){ // for each bit [top bit ignored]
+ // abandon if had overflow or terminal underflow
+ if (status & (DEC_Overflow|DEC_Underflow)) { // interesting?
+ if (status&DEC_Overflow || ISZERO(dac)) break;
+ }
+ // [the following two lines revealed an optimizer bug in a C++
+ // compiler, with symptom: 5**3 -> 25, when n=n+n was used]
+ n=n<<1; // move next bit to testable position
+ if (n<0) { // top bit is set
+ seenbit=1; // OK, significant bit seen
+ ___decMultiplyOp(dac, dac, lhs, &aset, &status); // dac=dac*x
+ }
+ if (i==31) break; // that was the last bit
+ if (!seenbit) continue; // no need to square 1
+ ___decMultiplyOp(dac, dac, dac, &aset, &status); // dac=dac*dac [square]
+ } /*i*/ // 32 bits
+
+ // complete internal overflow or underflow processing
+ if (status & (DEC_Overflow|DEC_Subnormal)) {
+ #if DECSUBSET
+ // If subset, and power was negative, reverse the kind of -erflow
+ // [1/x not yet done]
+ if (!set->extended && ___decNumberIsNegative(rhs)) {
+ if (status & DEC_Overflow)
+ status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal;
+ else { // trickier -- Underflow may or may not be set
+ status&=~(DEC_Underflow | DEC_Subnormal); // [one or both]
+ status|=DEC_Overflow;
+ }
+ }
+ #endif
+ dac->bits=(dac->bits & ~DECNEG) | bits; // force correct sign
+ // round subnormals [to set.digits rather than aset.digits]
+ // or set overflow result similarly as required
+ ___decFinalize(dac, set, &residue, &status);
+ ___decNumberCopy(res, dac); // copy to result (is now OK length)
+ break;
+ }
+
+ #if DECSUBSET
+ if (!set->extended && // subset math
+ ___decNumberIsNegative(rhs)) { // was a **-n [hence digits>0]
+ // so divide result into 1 [dac=1/dac]
+ ___decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status);
+ }
+ #endif
+ } // rhs integer path
+
+ // reduce result to the requested length and copy to result
+ ___decCopyFit(res, dac, set, &residue, &status);
+ ___decFinish(res, set, &residue, &status); // final cleanup
+ #if DECSUBSET
+ if (!set->extended) ___decTrim(res, 0, &dropped); // trailing zeros
+ #endif
+ } while(0); // end protected
+
+ if (allocdac!=NULL) free(allocdac); // drop any storage used
+ if (allocinv!=NULL) free(allocinv); // ..
+ #if DECSUBSET
+ if (alloclhs!=NULL) free(alloclhs); // ..
+ if (allocrhs!=NULL) free(allocrhs); // ..
+ #endif
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberPower */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberQuantize -- force exponent to requested value */
+/* */
+/* This computes C = op(A, B), where op adjusts the coefficient */
+/* of C (by rounding or shifting) such that the exponent (-scale) */
+/* of C has exponent of B. The numerical value of C will equal A, */
+/* except for the effects of any rounding that occurred. */
+/* */
+/* res is C, the result. C may be A or B */
+/* lhs is A, the number to adjust */
+/* rhs is B, the number with exponent to match */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* Unless there is an error or the result is infinite, the exponent */
+/* after the operation is guaranteed to be equal to that of B. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberQuantize(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decQuantizeOp(res, lhs, rhs, set, 1, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ return res;
+} /* ___decNumberQuantize */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberRescale -- force exponent to requested value */
+/* */
+/* This computes C = op(A, B), where op adjusts the coefficient */
+/* of C (by rounding or shifting) such that the exponent (-scale) */
+/* of C has the value B. The numerical value of C will equal A, */
+/* except for the effects of any rounding that occurred. */
+/* */
+/* res is C, the result. C may be A or B */
+/* lhs is A, the number to adjust */
+/* rhs is B, the requested exponent */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* Unless there is an error or the result is infinite, the exponent */
+/* after the operation is guaranteed to be equal to B. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberRescale(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decQuantizeOp(res, lhs, rhs, set, 0, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ return res;
+} /* ___decNumberRescale */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberRemainder -- divide and return remainder */
+/* */
+/* This computes C = A % B */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X%X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberRemainder(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberRemainder */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberRemainderNear -- divide and return remainder from nearest */
+/* */
+/* This computes C = A % B, where % is the IEEE remainder operator */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X%X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberRemainderNear(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+ ___decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberRemainderNear */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberSameQuantum -- test for equal exponents */
+/* */
+/* res is the result number, which will contain either 0 or 1 */
+/* lhs is a number to test */
+/* rhs is the second (usually a pattern) */
+/* */
+/* No errors are possible and no context is needed. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberSameQuantum(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs) {
+ Unit ret=0; // return value
+
+ #if DECCHECK
+ if (___decCheckOperands(res, lhs, rhs, DECUNUSED)) return res;
+ #endif
+
+ if (SPECIALARGS) {
+ if (___decNumberIsNaN(lhs) && ___decNumberIsNaN(rhs)) ret=1;
+ else if (___decNumberIsInfinite(lhs) && ___decNumberIsInfinite(rhs)) ret=1;
+ // [anything else with a special gives 0]
+ }
+ else if (lhs->exponent==rhs->exponent) ret=1;
+
+ ___decNumberZero(res); // OK to overwrite an operand now
+ *res->lsu=ret;
+ return res;
+} /* ___decNumberSameQuantum */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberSquareRoot -- square root operator */
+/* */
+/* This computes C = squareroot(A) */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context; note that rounding mode has no effect */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+/* This uses the following varying-precision algorithm in: */
+/* */
+/* Properly Rounded Variable Precision Square Root, T. E. Hull and */
+/* A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */
+/* pp229-237, ACM, September 1985. */
+/* */
+/* The square-root is calculated using Newton's method, after which */
+/* a check is made to ensure the result is correctly rounded. */
+/* */
+/* % [Reformatted original Numerical Turing source code follows.] */
+/* function sqrt(x : real) : real */
+/* % sqrt(x) returns the properly rounded approximation to the square */
+/* % root of x, in the precision of the calling environment, or it */
+/* % fails if x < 0. */
+/* % t e hull and a abrham, august, 1984 */
+/* if x <= 0 then */
+/* if x < 0 then */
+/* assert false */
+/* else */
+/* result 0 */
+/* end if */
+/* end if */
+/* var f := setexp(x, 0) % fraction part of x [0.1 <= x < 1] */
+/* var e := getexp(x) % exponent part of x */
+/* var approx : real */
+/* if e mod 2 = 0 then */
+/* approx := .259 + .819 * f % approx to root of f */
+/* else */
+/* f := f/l0 % adjustments */
+/* e := e + 1 % for odd */
+/* approx := .0819 + 2.59 * f % exponent */
+/* end if */
+/* */
+/* var p:= 3 */
+/* const maxp := currentprecision + 2 */
+/* loop */
+/* p := min(2*p - 2, maxp) % p = 4,6,10, . . . , maxp */
+/* precision p */
+/* approx := .5 * (approx + f/approx) */
+/* exit when p = maxp */
+/* end loop */
+/* */
+/* % approx is now within 1 ulp of the properly rounded square root */
+/* % of f; to ensure proper rounding, compare squares of (approx - */
+/* % l/2 ulp) and (approx + l/2 ulp) with f. */
+/* p := currentprecision */
+/* begin */
+/* precision p + 2 */
+/* const approxsubhalf := approx - setexp(.5, -p) */
+/* if mulru(approxsubhalf, approxsubhalf) > f then */
+/* approx := approx - setexp(.l, -p + 1) */
+/* else */
+/* const approxaddhalf := approx + setexp(.5, -p) */
+/* if mulrd(approxaddhalf, approxaddhalf) < f then */
+/* approx := approx + setexp(.l, -p + 1) */
+/* end if */
+/* end if */
+/* end */
+/* result setexp(approx, e div 2) % fix exponent */
+/* end sqrt */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberSquareRoot(decNumber *res, const decNumber *rhs,
+ decContext *set) {
+ decContext workset, approxset; // work contexts
+ decNumber dzero; // used for constant zero
+ Int maxp=set->digits+2; // largest working precision
+ Int residue=0; // rounding residue
+ uInt status=0, ignore=0; // status accumulators
+ Int exp; // working exponent
+ Int ideal; // ideal (preferred) exponent
+ Int needbytes; // work
+ Int dropped; // ..
+
+ #if DECSUBSET
+ decNumber *allocrhs=NULL; // non-NULL if rounded rhs allocated
+ #endif
+ // buffer for f [needs +1 in case DECBUFFER 0]
+ decNumber buff[D2N(DECBUFFER+1)];
+ // buffer for a [needs +2 to match maxp]
+ decNumber bufa[D2N(DECBUFFER+2)];
+ // buffer for temporary, b [must be same size as a]
+ decNumber bufb[D2N(DECBUFFER+2)];
+ decNumber *allocbuff=NULL; // -> allocated buff, iff allocated
+ decNumber *allocbufa=NULL; // -> allocated bufa, iff allocated
+ decNumber *allocbufb=NULL; // -> allocated bufb, iff allocated
+ decNumber *f=buff; // reduced fraction
+ decNumber *a=bufa; // approximation to result
+ decNumber *b=bufb; // intermediate result
+ // buffer for temporary variable, up to 3 digits
+ decNumber buft[D2N(3)];
+ decNumber *t=buft; // up-to-3-digit constant or work
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ do { // protect allocated storage
+ #if DECSUBSET
+ if (!set->extended) {
+ // reduce operand and set lostDigits status, as needed
+ if (rhs->digits>set->digits) {
+ allocrhs=___decRoundOperand(rhs, set, &status);
+ if (allocrhs==NULL) break;
+ // [Note: 'f' allocation below could reuse this buffer if
+ // used, but as this is rare they are kept separate for clarity.]
+ rhs=allocrhs;
+ }
+ }
+ #endif
+ // [following code does not require input rounding]
+
+ // handle infinities and NaNs
+ if (SPECIALARG) {
+ if (___decNumberIsInfinite(rhs)) { // an infinity
+ if (___decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;
+ else ___decNumberCopy(res, rhs); // +Infinity
+ }
+ else ___decNaNs(res, rhs, NULL, &status); // a NaN
+ break;
+ }
+
+ // calculate the ideal (preferred) exponent [floor(exp/2)]
+ // [We would like to write: ideal=rhs->exponent>>1, but this
+ // generates a compiler warning. Generated code is the same.]
+ ideal=(rhs->exponent&~1)/2; // target
+
+ // handle zeros
+ if (ISZERO(rhs)) {
+ ___decNumberCopy(res, rhs); // could be 0 or -0
+ res->exponent=ideal; // use the ideal [safe]
+ break;
+ }
+
+ // any other -x is an oops
+ if (___decNumberIsNegative(rhs)) {
+ status|=DEC_Invalid_operation;
+ break;
+ }
+
+ // space is needed for three working variables
+ // f -- the same precision as the RHS, reduced to 0.01->0.99...
+ // a -- Hull's approximation -- precision, when assigned, is
+ // currentprecision (we allow +2 for use as temporary)
+ // b -- intermediate temporary result
+ // if any is too long for local storage, then allocate
+ needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
+ if (needbytes>(Int)sizeof(buff)) {
+ allocbuff=(decNumber *)malloc(needbytes);
+ if (allocbuff==NULL) { // hopeless -- abandon
+ status|=DEC_Insufficient_storage;
+ break;}
+ f=allocbuff; // use the allocated space
+ }
+ // a and b both need to be able to hold a maxp-length number
+ needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);
+ if (needbytes>(Int)sizeof(bufa)) { // [same applies to b]
+ allocbufa=(decNumber *)malloc(needbytes);
+ allocbufb=(decNumber *)malloc(needbytes);
+ if (allocbufa==NULL || allocbufb==NULL) { // hopeless
+ status|=DEC_Insufficient_storage;
+ break;}
+ a=allocbufa; // use the allocated space
+ b=allocbufb; // ..
+ }
+
+ // copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1
+ ___decNumberCopy(f, rhs);
+ exp=f->exponent+f->digits; // adjusted to Hull rules
+ f->exponent=-(f->digits); // to range
+
+ // set up working contexts (the second is used for Numerical
+ // Turing assignment)
+ ___decContextDefault(&workset, DEC_INIT_DECIMAL64);
+ ___decContextDefault(&approxset, DEC_INIT_DECIMAL64);
+ approxset.digits=set->digits; // approx's length
+
+ // [Until further notice, no error is possible and status bits
+ // (Rounded, etc.) should be ignored, not accumulated.]
+
+ // Calculate initial approximation, and allow for odd exponent
+ workset.digits=set->digits; // p for initial calculation
+ t->bits=0; t->digits=3;
+ a->bits=0; a->digits=3;
+ if ((exp & 1)==0) { // even exponent
+ // Set t=0.259, a=0.819
+ t->exponent=-3;
+ a->exponent=-3;
+ #if DECDPUN>=3
+ t->lsu[0]=259;
+ a->lsu[0]=819;
+ #elif DECDPUN==2
+ t->lsu[0]=59; t->lsu[1]=2;
+ a->lsu[0]=19; a->lsu[1]=8;
+ #else
+ t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
+ a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
+ #endif
+ }
+ else { // odd exponent
+ // Set t=0.0819, a=2.59
+ f->exponent--; // f=f/10
+ exp++; // e=e+1
+ t->exponent=-4;
+ a->exponent=-2;
+ #if DECDPUN>=3
+ t->lsu[0]=819;
+ a->lsu[0]=259;
+ #elif DECDPUN==2
+ t->lsu[0]=19; t->lsu[1]=8;
+ a->lsu[0]=59; a->lsu[1]=2;
+ #else
+ t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
+ a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
+ #endif
+ }
+ ___decMultiplyOp(a, a, f, &workset, &ignore); // a=a*f
+ ___decAddOp(a, a, t, &workset, 0, &ignore); // ..+t
+ // [a is now the initial approximation for sqrt(f), calculated with
+ // currentprecision, which is also a's precision.]
+
+ // the main calculation loop
+ ___decNumberZero(&dzero); // make 0
+ ___decNumberZero(t); // set t = 0.5
+ t->lsu[0]=5; // ..
+ t->exponent=-1; // ..
+ workset.digits=3; // initial p
+ for (;;) {
+ // set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp]
+ workset.digits=workset.digits*2-2;
+ if (workset.digits>maxp) workset.digits=maxp;
+ // a = 0.5 * (a + f/a)
+ // [calculated at p then rounded to currentprecision]
+ ___decDivideOp(b, f, a, &workset, DIVIDE, &ignore); // b=f/a
+ ___decAddOp(b, b, a, &workset, 0, &ignore); // b=b+a
+ ___decMultiplyOp(a, b, t, &workset, &ignore); // a=b*0.5
+ // assign to approx [round to length]
+ ___decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+ if (workset.digits==maxp) break; // just did final
+ } // loop
+
+ // a is now at currentprecision and within 1 ulp of the properly
+ // rounded square root of f; to ensure proper rounding, compare
+ // squares of (a - l/2 ulp) and (a + l/2 ulp) with f.
+ // Here workset.digits=maxp and t=0.5
+ workset.digits--; // maxp-1 is OK now
+ t->exponent=-set->digits-1; // make 0.5 ulp
+ ___decNumberCopy(b, a);
+ ___decAddOp(b, b, t, &workset, DECNEG, &ignore); // b = a - 0.5 ulp
+ workset.round=DEC_ROUND_UP;
+ ___decMultiplyOp(b, b, b, &workset, &ignore); // b = mulru(b, b)
+ ___decCompareOp(b, f, b, &workset, COMPARE, &ignore); // b ? f, reversed
+ if (___decNumberIsNegative(b)) { // f < b [i.e., b > f]
+ // this is the more common adjustment, though both are rare
+ t->exponent++; // make 1.0 ulp
+ t->lsu[0]=1; // ..
+ ___decAddOp(a, a, t, &workset, DECNEG, &ignore); // a = a - 1 ulp
+ // assign to approx [round to length]
+ ___decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+ }
+ else {
+ ___decNumberCopy(b, a);
+ ___decAddOp(b, b, t, &workset, 0, &ignore); // b = a + 0.5 ulp
+ workset.round=DEC_ROUND_DOWN;
+ ___decMultiplyOp(b, b, b, &workset, &ignore); // b = mulrd(b, b)
+ ___decCompareOp(b, b, f, &workset, COMPARE, &ignore); // b ? f
+ if (___decNumberIsNegative(b)) { // b < f
+ t->exponent++; // make 1.0 ulp
+ t->lsu[0]=1; // ..
+ ___decAddOp(a, a, t, &workset, 0, &ignore); // a = a + 1 ulp
+ // assign to approx [round to length]
+ ___decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+ }
+ }
+ // [no errors are possible in the above, and rounding/inexact during
+ // estimation are irrelevant, so status was not accumulated]
+
+ // Here, 0.1 <= a < 1 [Hull]
+ a->exponent+=exp/2; // set correct exponent
+
+ // Process Subnormals
+ ___decFinalize(a, set, &residue, &status);
+
+ // count droppable zeros [after any subnormal rounding] by
+ // trimming a copy
+ ___decNumberCopy(b, a);
+ ___decTrim(b, 1, &dropped); // [drops trailing zeros]
+
+ // Finally set Inexact and Rounded. The answer can only be exact if
+ // it is short enough so that squaring it could fit in set->digits,
+ // so this is the only (relatively rare) time a careful check is
+ // needed
+ if (b->digits*2-1 > set->digits) { // cannot fit
+ status|=DEC_Inexact|DEC_Rounded;
+ }
+ else { // could be exact/unrounded
+ uInt mstatus=0; // local status
+ ___decMultiplyOp(b, b, b, &workset, &mstatus); // try the multiply
+ if (mstatus!=0) { // result won't fit
+ status|=DEC_Inexact|DEC_Rounded;
+ }
+ else { // plausible
+ ___decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); // b ? rhs
+ if (!ISZERO(t)) {
+ status|=DEC_Inexact|DEC_Rounded;
+ }
+ else { // is Exact
+ Int todrop; // work
+ // here, dropped is the count of trailing zeros in 'a'
+ // use closest exponent to ideal...
+ todrop=ideal-a->exponent; // most that can be dropped
+ if (todrop<0) { // ideally would add 0s
+ status|=DEC_Rounded;
+ }
+ else { // unrounded
+ if (dropped<todrop) todrop=dropped; // clamp to those available
+ if (todrop>0) { // OK, some to drop
+ ___decShiftToLeast(a->lsu, D2U(a->digits), todrop);
+ a->exponent+=todrop; // maintain numerical value
+ a->digits-=todrop; // new length
+ }
+ }
+ }
+ }
+ }
+
+ // make sure there is a full complement of digits for normal
+ // inexact results
+ if ((status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact) {
+ Int shift=set->digits-a->digits;
+ if (shift>0) {
+ a->digits=___decShiftToMost(a->lsu, a->digits, shift);
+ a->exponent-=shift; // adjust the exponent.
+ }
+ }
+ ___decNumberCopy(res, a); // a is now the result
+ } while(0); // end protected
+
+ if (allocbuff!=NULL) free(allocbuff); // drop any storage used
+ if (allocbufa!=NULL) free(allocbufa); // ..
+ if (allocbufb!=NULL) free(allocbufb); // ..
+ #if DECSUBSET
+ if (allocrhs !=NULL) free(allocrhs); // ..
+ #endif
+ if (status!=0) ___decStatus(res, status, set);// then report status
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberSquareRoot */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberSubtract -- subtract two Numbers */
+/* */
+/* This computes C = A - B */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X-X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberSubtract(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ uInt status=0; // accumulator
+
+ ___decAddOp(res, lhs, rhs, set, DECNEG, &status);
+ if (status!=0) ___decStatus(res, status, set);
+ #if DECCHECK
+ ___decCheckInexact(res, set);
+ #endif
+ return res;
+} /* ___decNumberSubtract */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberToIntegralValue -- round-to-integral-value */
+/* */
+/* res is the result */
+/* rhs is input number */
+/* set is the context */
+/* */
+/* res must have space for any value of rhs. */
+/* */
+/* This implements the IEEE special operator and therefore treats */
+/* special values as valid, and also never sets Inexact. For finite */
+/* numbers it returns rescale(rhs, 0) if rhs->exponent is <0. */
+/* Otherwise the result is rhs (so no error is possible). */
+/* */
+/* The context is used for rounding mode and status after sNaN, but */
+/* the digits setting is ignored. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+decNumber * ___decNumberToIntegralValue(decNumber *res, const decNumber *rhs,
+ decContext *set) {
+ decNumber dn;
+ decContext workset; // working context
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ // handle infinities and NaNs
+ if (SPECIALARG) {
+ uInt status=0;
+ if (___decNumberIsInfinite(rhs)) ___decNumberCopy(res, rhs); // an Infinity
+ else ___decNaNs(res, rhs, NULL, &status); // a NaN
+ if (status!=0) ___decStatus(res, status, set);
+ return res;
+ }
+
+ // have a finite number; no error possible (res must be big enough)
+ if (rhs->exponent>=0) return ___decNumberCopy(res, rhs);
+ // that was easy, but if negative exponent there is work to do...
+ workset=*set; // clone rounding, etc.
+ workset.digits=rhs->digits; // no length rounding
+ workset.traps=0; // no traps
+ ___decNumberZero(&dn); // make a number with exponent 0
+ return ___decNumberQuantize(res, rhs, &dn, &workset);
+} /* ___decNumberToIntegralValue */
+#endif /* NOT_IN_libc */
+
+/* ================================================================== */
+/* Utility routines */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberCopy -- copy a number */
+/* */
+/* dest is the target decNumber */
+/* src is the source decNumber */
+/* returns dest */
+/* */
+/* (dest==src is allowed and is a no-op) */
+/* All fields are updated as required. This is a utility operation, */
+/* so special values are unchanged and no error is possible. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+decNumber * ___decNumberCopy(decNumber *dest, const decNumber *src) {
+
+ #if DECCHECK
+ if (src==NULL) return ___decNumberZero(dest);
+ #endif
+
+ if (dest==src) return dest; // no copy required
+
+ // Use explicit assignments here as structure assignment could copy
+ // more than just the lsu (for small DECDPUN). This would not affect
+ // the value of the results, but could disturb test harness spill
+ // checking.
+ dest->bits=src->bits;
+ dest->exponent=src->exponent;
+ dest->digits=src->digits;
+ dest->lsu[0]=src->lsu[0];
+ if (src->digits>DECDPUN) { // more Units to come
+ const Unit *smsup, *s; // work
+ Unit *d; // ..
+ // memcpy for the remaining Units would be safe as they cannot
+ // overlap. However, this explicit loop is faster in short cases.
+ d=dest->lsu+1; // -> first destination
+ smsup=src->lsu+D2U(src->digits); // -> source msu+1
+ for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
+ }
+ return dest;
+} /* ___decNumberCopy */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberTrim -- remove insignificant zeros */
+/* */
+/* dn is the number to trim */
+/* returns dn */
+/* */
+/* All fields are updated as required. This is a utility operation, */
+/* so special values are unchanged and no error is possible. */
+/* ------------------------------------------------------------------ */
+
+#if defined NOT_IN_libc /* Not needed in libc. */
+decNumber * ___decNumberTrim(decNumber *dn) {
+ Int dropped; // work
+ return ___decTrim(dn, 0, &dropped);
+} /* ___decNumberTrim */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberVersion -- return the name and version of this module */
+/* */
+/* No error is possible. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+const char * ___decNumberVersion(void) {
+ return DECVERSION;
+} /* ___decNumberVersion */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNumberZero -- set a number to 0 */
+/* */
+/* dn is the number to set, with space for one digit */
+/* returns dn */
+/* */
+/* No error is possible. */
+/* ------------------------------------------------------------------ */
+// Memset is not used as it is much slower in some environments.
+decNumber * ___decNumberZero(decNumber *dn) {
+
+ dn->bits=0;
+ dn->exponent=0;
+ dn->digits=1;
+ dn->lsu[0]=0;
+ return dn;
+} /* ___decNumberZero */
+libc_hidden_def(___decNumberZero)
+
+/* ================================================================== */
+/* Local routines */
+/* ================================================================== */
+
+/* ------------------------------------------------------------------ */
+/* ___decToString -- lay out a number into a string */
+/* */
+/* dn is the number to lay out */
+/* string is where to lay out the number */
+/* eng is 1 if Engineering, 0 if Scientific */
+/* */
+/* string must be at least dn->digits+14 characters long */
+/* No error is possible. */
+/* */
+/* Note that this routine can generate a -0 or 0.000. These are */
+/* never generated in subset to-number or arithmetic, but can occur */
+/* in non-subset arithmetic (e.g., -1*0 or 1.234-1.234). */
+/* ------------------------------------------------------------------ */
+// If DECCHECK is enabled the string "?" is returned if a number is
+// invalid.
+static void ___decToString(const decNumber *dn, char *string, Flag eng) {
+ Int exp=dn->exponent; // local copy
+ Int e; // E-part value
+ Int pre; // digits before the '.'
+ Int cut; // for counting digits in a Unit
+ char *c=string; // work [output pointer]
+ const Unit *up=dn->lsu+D2U(dn->digits)-1; // -> msu [input pointer]
+ uInt u, pow; // work
+
+ if (___decNumberIsNegative(dn)) { // Negatives get a minus
+ *c='-';
+ c++;
+ }
+ if (dn->bits&DECSPECIAL) { // Is a special value
+ if (___decNumberIsInfinite(dn)) {
+ strcpy(c, "Infinity");
+ return;}
+ // a NaN
+ if (dn->bits&DECSNAN) { // signalling NaN
+ *c='s';
+ c++;
+ }
+ strcpy(c, "NaN");
+ c+=3; // step past
+ // if not a clean non-zero coefficient, that's all there is in a
+ // NaN string
+ if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return;
+ // [drop through to add integer]
+ }
+
+ // calculate how many digits in msu, and hence first cut
+ cut=MSUDIGITS(dn->digits); // [faster than remainder]
+ cut--; // power of ten for digit
+
+ if (exp==0) { // simple integer [common fastpath]
+ for (;up>=dn->lsu; up--) { // each Unit from msu
+ u=*up; // contains DECDPUN digits to lay out
+ for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow);
+ cut=DECDPUN-1; // next Unit has all digits
+ }
+ *c='\0'; // terminate the string
+ return;}
+
+ /* non-0 exponent -- assume plain form */
+ pre=dn->digits+exp; // digits before '.'
+ e=0; // no E
+ if ((exp>0) || (pre<-5)) { // need exponential form
+ e=exp+dn->digits-1; // calculate E value
+ pre=1; // assume one digit before '.'
+ if (eng && (e!=0)) { // engineering: may need to adjust
+ Int adj; // adjustment
+ // The C remainder operator is undefined for negative numbers, so
+ // a positive remainder calculation must be used here
+ if (e<0) {
+ adj=(-e)%3;
+ if (adj!=0) adj=3-adj;
+ }
+ else { // e>0
+ adj=e%3;
+ }
+ e=e-adj;
+ // if dealing with zero still produce an exponent which is a
+ // multiple of three, as expected, but there will only be the
+ // one zero before the E, still. Otherwise note the padding.
+ if (!ISZERO(dn)) pre+=adj;
+ else { // is zero
+ if (adj!=0) { // 0.00Esnn needed
+ e=e+3;
+ pre=-(2-adj);
+ }
+ } // zero
+ } // eng
+ } // need exponent
+
+ /* lay out the digits of the coefficient, adding 0s and . as needed */
+ u=*up;
+ if (pre>0) { // xxx.xxx or xx00 (engineering) form
+ Int n=pre;
+ for (; pre>0; pre--, c++, cut--) {
+ if (cut<0) { // need new Unit
+ if (up==dn->lsu) break; // out of input digits (pre>digits)
+ up--;
+ cut=DECDPUN-1;
+ u=*up;
+ }
+ TODIGIT(u, cut, c, pow);
+ }
+ if (n<dn->digits) { // more to come, after '.'
+ *c='.'; c++;
+ for (;; c++, cut--) {
+ if (cut<0) { // need new Unit
+ if (up==dn->lsu) break; // out of input digits
+ up--;
+ cut=DECDPUN-1;
+ u=*up;
+ }
+ TODIGIT(u, cut, c, pow);
+ }
+ }
+ else for (; pre>0; pre--, c++) *c='0'; // 0 padding (for engineering) needed
+ }
+ else { // 0.xxx or 0.000xxx form
+ *c='0'; c++;
+ *c='.'; c++;
+ for (; pre<0; pre++, c++) *c='0'; // add any 0's after '.'
+ for (; ; c++, cut--) {
+ if (cut<0) { // need new Unit
+ if (up==dn->lsu) break; // out of input digits
+ up--;
+ cut=DECDPUN-1;
+ u=*up;
+ }
+ TODIGIT(u, cut, c, pow);
+ }
+ }
+
+ /* Finally add the E-part, if needed. It will never be 0, has a
+ base maximum and minimum of +999999999 through -999999999, but
+ could range down to -1999999998 for anormal numbers */
+ if (e!=0) {
+ Flag had=0; // 1=had non-zero
+ *c='E'; c++;
+ *c='+'; c++; // assume positive
+ u=e; // ..
+ if (e<0) {
+ *(c-1)='-'; // oops, need -
+ u=-e; // uInt, please
+ }
+ // layout the exponent [_itoa or equivalent is not ANSI C]
+ for (cut=9; cut>=0; cut--) {
+ TODIGIT(u, cut, c, pow);
+ if (*c=='0' && !had) continue; // skip leading zeros
+ had=1; // had non-0
+ c++; // step for next
+ } // cut
+ }
+ *c='\0'; // terminate the string (all paths)
+ return;
+} /* ___decToString */
+/* Internal function, no guard necessary */
+
+/* ------------------------------------------------------------------ */
+/* ___decAddOp -- add/subtract operation */
+/* */
+/* This computes C = A + B */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X+X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* negate is DECNEG if rhs should be negated, or 0 otherwise */
+/* status accumulates status for the caller */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+/* If possible, the coefficient is calculated directly into C. */
+/* However, if: */
+/* -- a digits+1 calculation is needed because the numbers are */
+/* unaligned and span more than set->digits digits */
+/* -- a carry to digits+1 digits looks possible */
+/* -- C is the same as A or B, and the result would destructively */
+/* overlap the A or B coefficient */
+/* then the result must be calculated into a temporary buffer. In */
+/* this case a local (stack) buffer is used if possible, and only if */
+/* too long for that does malloc become the last resort. */
+/* */
+/* Misalignment is handled as follows: */
+/* Apad: (AExp>BExp) Swap operands and proceed as for BExp>AExp. */
+/* BPad: Apply the padding by a combination of shifting (whole */
+/* units) and multiplication (part units). */
+/* */
+/* Addition, especially x=x+1, is speed-critical. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static decNumber * ___decAddOp(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set,
+ uByte negate, uInt *status) {
+#if DECSUBSET
+ decNumber *alloclhs=NULL; // non-NULL if rounded lhs allocated
+ decNumber *allocrhs=NULL; // .., rhs
+#endif
+ Int rhsshift; // working shift (in Units)
+ Int maxdigits; // longest logical length
+ Int mult; // multiplier
+ Int residue; // rounding accumulator
+ uByte bits; // result bits
+ Flag diffsign; // non-0 if arguments have different sign
+ Unit *acc; // accumulator for result
+ Unit accbuff[SD2U(DECBUFFER+20)]; // local buffer [+20 reduces many
+ // allocations when called from
+ // other operations]
+ Unit *allocacc=NULL; // -> allocated acc buffer, iff allocated
+ Int reqdigits=set->digits; // local copy; requested DIGITS
+ Int padding; // work
+
+#if DECCHECK
+ if (___decCheckOperands(res, lhs, rhs, set)) return res;
+#endif
+
+ do { // protect allocated storage
+#if DECSUBSET
+ if (!set->extended) {
+ // reduce operands and set lostDigits status, as needed
+ if (lhs->digits>reqdigits) {
+ alloclhs=___decRoundOperand(lhs, set, status);
+ if (alloclhs==NULL) break;
+ lhs=alloclhs;
+ }
+ if (rhs->digits>reqdigits) {
+ allocrhs=___decRoundOperand(rhs, set, status);
+ if (allocrhs==NULL) break;
+ rhs=allocrhs;
+ }
+ }
+#endif
+ // [following code does not require input rounding]
+
+ // note whether signs differ [used all paths]
+ diffsign=(Flag)((lhs->bits^rhs->bits^negate)&DECNEG);
+
+ // handle infinities and NaNs
+ if (SPECIALARGS) { // a special bit set
+ if (SPECIALARGS & (DECSNAN | DECNAN)) // a NaN
+ ___decNaNs(res, lhs, rhs, status);
+ else { // one or two infinities
+ if (___decNumberIsInfinite(lhs)) { // LHS is infinity
+ // two infinities with different signs is invalid
+ if (___decNumberIsInfinite(rhs) && diffsign) {
+ *status|=DEC_Invalid_operation;
+ break;
+ }
+ bits=lhs->bits & DECNEG; // get sign from LHS
+ }
+ else bits=(rhs->bits^negate) & DECNEG;// RHS must be Infinity
+ bits|=DECINF;
+ ___decNumberZero(res);
+ res->bits=bits; // set +/- infinity
+ } // an infinity
+ break;
+ }
+
+ // Quick exit for add 0s; return the non-0, modified as need be
+ if (ISZERO(lhs)) {
+ Int adjust; // work
+ Int lexp=lhs->exponent; // save in case LHS==RES
+ bits=lhs->bits; // ..
+ residue=0; // clear accumulator
+ ___decCopyFit(res, rhs, set, &residue, status); // copy (as needed)
+ res->bits^=negate; // flip if rhs was negated
+#if DECSUBSET
+ if (set->extended) { // exponents on zeros count
+#endif
+ // exponent will be the lower of the two
+ adjust=lexp-res->exponent; // adjustment needed [if -ve]
+ if (ISZERO(res)) { // both 0: special IEEE 854 rules
+ if (adjust<0) res->exponent=lexp; // set exponent
+ // 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0
+ if (diffsign) {
+ if (set->round!=DEC_ROUND_FLOOR) res->bits=0;
+ else res->bits=DECNEG; // preserve 0 sign
+ }
+ }
+ else { // non-0 res
+ if (adjust<0) { // 0-padding needed
+ if ((res->digits-adjust)>set->digits) {
+ adjust=res->digits-set->digits; // to fit exactly
+ *status|=DEC_Rounded; // [but exact]
+ }
+ res->digits=___decShiftToMost(res->lsu, res->digits, -adjust);
+ res->exponent+=adjust; // set the exponent.
+ }
+ } // non-0 res
+#if DECSUBSET
+ } // extended
+#endif
+ ___decFinish(res, set, &residue, status); // clean and finalize
+ break;}
+
+ if (ISZERO(rhs)) { // [lhs is non-zero]
+ Int adjust; // work
+ Int rexp=rhs->exponent; // save in case RHS==RES
+ bits=rhs->bits; // be clean
+ residue=0; // clear accumulator
+ ___decCopyFit(res, lhs, set, &residue, status); // copy (as needed)
+#if DECSUBSET
+ if (set->extended) { // exponents on zeros count
+#endif
+ // exponent will be the lower of the two
+ // [0-0 case handled above]
+ adjust=rexp-res->exponent; // adjustment needed [if -ve]
+ if (adjust<0) { // 0-padding needed
+ if ((res->digits-adjust)>set->digits) {
+ adjust=res->digits-set->digits; // to fit exactly
+ *status|=DEC_Rounded; // [but exact]
+ }
+ res->digits=___decShiftToMost(res->lsu, res->digits, -adjust);
+ res->exponent+=adjust; // set the exponent.
+ }
+#if DECSUBSET
+ } // extended
+#endif
+ ___decFinish(res, set, &residue, status); // clean and finalize
+ break;}
+ // [NB: both fastpath and mainpath code below assume these cases
+ // (notably 0-0) have already been handled]
+
+ // calculate the padding needed to align the operands
+ padding=rhs->exponent-lhs->exponent;
+
+ // Fastpath cases where the numbers are aligned and normal, the RHS
+ // is all in one unit, no operand rounding is needed, and no carry,
+ // lengthening, or borrow is needed
+ if (padding==0
+ && rhs->digits<=DECDPUN
+ && rhs->exponent>=set->emin // [some normals drop through]
+ && rhs->digits<=reqdigits
+ && lhs->digits<=reqdigits) {
+ Int partial=*lhs->lsu;
+ if (!diffsign) { // adding
+ partial+=*rhs->lsu;
+ if ((partial<=DECDPUNMAX) // result fits in unit
+ && (lhs->digits>=DECDPUN || // .. and no digits-count change
+ partial<(Int)__powers[lhs->digits])) { // ..
+ if (res!=lhs) ___decNumberCopy(res, lhs); // not in place
+ *res->lsu=(Unit)partial; // [copy could have overwritten RHS]
+ break;
+ }
+ // else drop out for careful add
+ } else { // signs differ
+ partial-=*rhs->lsu;
+ if (partial>0) { // no borrow needed, and non-0 result
+ if (res!=lhs) ___decNumberCopy(res, lhs); // not in place
+ *res->lsu=(Unit)partial;
+ // this could have reduced digits [but result>0]
+ res->digits=___decGetDigits(res->lsu, D2U(res->digits));
+ break;
+ }
+ // else drop out for careful subtract
+ }
+ }
+
+ // Now align (pad) the lhs or rhs so they can be added or
+ // subtracted, as necessary. If one number is much larger than
+ // the other (that is, if in plain form there is a least one
+ // digit between the lowest digit of one and the highest of the
+ // other) padding with up to DIGITS-1 trailing zeros may be
+ // needed; then apply rounding (as exotic rounding modes may be
+ // affected by the residue).
+ rhsshift=0; // rhs shift to left (padding) in Units
+ bits=lhs->bits; // assume sign is that of LHS
+ mult=1; // likely multiplier
+
+ // if padding==0 the operands are aligned; no padding needed
+ if (padding!=0) {
+ // some padding needed; always pad the RHS, as any required
+ // padding can then be effected by a simple combination of
+ // shifts and a multiply
+ Flag swapped=0;
+ if (padding<0) { // LHS needs the padding
+ const decNumber *t;
+ padding=-padding; // will be +ve
+ bits=(uByte)(rhs->bits^negate); // assumed sign is now that of RHS
+ t=lhs; lhs=rhs; rhs=t;
+ swapped=1;
+ }
+
+ // If, after pad, rhs would be longer than lhs by digits+1 or
+ // more then lhs cannot affect the answer, except as a residue,
+ // so only need to pad up to a length of DIGITS+1.
+ if (rhs->digits+padding > lhs->digits+reqdigits+1) {
+ // The RHS is sufficient
+ // for residue use the relative sign indication...
+ Int shift=reqdigits-rhs->digits; // left shift needed
+ residue=1; // residue for rounding
+ if (diffsign) residue=-residue; // signs differ
+ // copy, shortening if necessary
+ ___decCopyFit(res, rhs, set, &residue, status);
+ // if it was already shorter, then need to pad with zeros
+ if (shift>0) {
+ res->digits=___decShiftToMost(res->lsu, res->digits, shift);
+ res->exponent-=shift; // adjust the exponent.
+ }
+ // flip the result sign if unswapped and rhs was negated
+ if (!swapped) res->bits^=negate;
+ ___decFinish(res, set, &residue, status); // done
+ break;}
+
+ // LHS digits may affect result
+ rhsshift=D2U(padding+1)-1; // this much by Unit shift ..
+ mult=__powers[padding-(rhsshift*DECDPUN)]; // .. this by multiplication
+ } // padding needed
+
+ if (diffsign) mult=-mult; // signs differ
+
+ // determine the longer operand
+ maxdigits=rhs->digits+padding; // virtual length of RHS
+ if (lhs->digits>maxdigits) maxdigits=lhs->digits;
+
+ // Decide on the result buffer to use; if possible place directly
+ // into result.
+ acc=res->lsu; // assume add direct to result
+ // If destructive overlap, or the number is too long, or a carry or
+ // borrow to DIGITS+1 might be possible, a buffer must be used.
+ // [Might be worth more sophisticated tests when maxdigits==reqdigits]
+ if ((maxdigits>=reqdigits) // is, or could be, too large
+ || (res==rhs && rhsshift>0)) { // destructive overlap
+ // buffer needed, choose it; units for maxdigits digits will be
+ // needed, +1 Unit for carry or borrow
+ Int need=D2U(maxdigits)+1;
+ acc=accbuff; // assume use local buffer
+ if (need*sizeof(Unit)>sizeof(accbuff)) {
+ allocacc=(Unit *)malloc(need*sizeof(Unit));
+ if (allocacc==NULL) { // hopeless -- abandon
+ *status|=DEC_Insufficient_storage;
+ break;}
+ acc=allocacc;
+ }
+ }
+
+ res->bits=(uByte)(bits&DECNEG); // it's now safe to overwrite..
+ res->exponent=lhs->exponent; // .. operands (even if aliased)
+
+#if DECTRACE
+ ___decDumpAr('A', lhs->lsu, D2U(lhs->digits));
+ ___decDumpAr('B', rhs->lsu, D2U(rhs->digits));
+ printf(" :h: %d %d\n", rhsshift, mult);
+#endif
+
+ // add [A+B*m] or subtract [A+B*(-m)]
+ res->digits=___decUnitAddSub(lhs->lsu, D2U(lhs->digits),
+ rhs->lsu, D2U(rhs->digits),
+ rhsshift, acc, mult)
+ *DECDPUN; // [units -> digits]
+ if (res->digits<0) { // borrowed...
+ res->digits=-res->digits;
+ res->bits^=DECNEG; // flip the sign
+ }
+#if DECTRACE
+ ___decDumpAr('+', acc, D2U(res->digits));
+#endif
+
+ // If a buffer was used the result must be copied back, possibly
+ // shortening. (If no buffer was used then the result must have
+ // fit, so can't need rounding and residue must be 0.)
+ residue=0; // clear accumulator
+ if (acc!=res->lsu) {
+#if DECSUBSET
+ if (set->extended) { // round from first significant digit
+#endif
+ // remove leading zeros that were added due to rounding up to
+ // integral Units -- before the test for rounding.
+ if (res->digits>reqdigits)
+ res->digits=___decGetDigits(acc, D2U(res->digits));
+ ___decSetCoeff(res, set, acc, res->digits, &residue, status);
+#if DECSUBSET
+ }
+ else { // subset arithmetic rounds from original significant digit
+ // May have an underestimate. This only occurs when both
+ // numbers fit in DECDPUN digits and are padding with a
+ // negative multiple (-10, -100...) and the top digit(s) become
+ // 0. (This only matters when using X3.274 rules where the
+ // leading zero could be included in the rounding.)
+ if (res->digits<maxdigits) {
+ *(acc+D2U(res->digits))=0; // ensure leading 0 is there
+ res->digits=maxdigits;
+ }
+ else {
+ // remove leading zeros that added due to rounding up to
+ // integral Units (but only those in excess of the original
+ // maxdigits length, unless extended) before test for rounding.
+ if (res->digits>reqdigits) {
+ res->digits=___decGetDigits(acc, D2U(res->digits));
+ if (res->digits<maxdigits) res->digits=maxdigits;
+ }
+ }
+ ___decSetCoeff(res, set, acc, res->digits, &residue, status);
+ // Now apply rounding if needed before removing leading zeros.
+ // This is safe because subnormals are not a possibility
+ if (residue!=0) {
+ ___decApplyRound(res, set, residue, status);
+ residue=0; // did what needed to be done
+ }
+ } // subset
+#endif
+ } // used buffer
+
+ // strip leading zeros [these were left on in case of subset subtract]
+ res->digits=___decGetDigits(res->lsu, D2U(res->digits));
+
+ // apply checks and rounding
+ ___decFinish(res, set, &residue, status);
+
+ // "When the sum of two operands with opposite signs is exactly
+ // zero, the sign of that sum shall be '+' in all rounding modes
+ // except round toward -Infinity, in which mode that sign shall be
+ // '-'." [Subset zeros also never have '-', set by decFinish.]
+ if (ISZERO(res)
+ && diffsign
+#if DECSUBSET
+ && set->extended
+#endif
+ && (*status&DEC_Inexact)==0) {
+ if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG; // sign -
+ else res->bits&=~DECNEG; // sign +
+ }
+ } while(0); // end protected
+
+ if (allocacc!=NULL) free(allocacc); // drop any storage used
+#if DECSUBSET
+ if (allocrhs!=NULL) free(allocrhs); // ..
+ if (alloclhs!=NULL) free(alloclhs); // ..
+#endif
+ return res;
+} /* ___decAddOp */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decDivideOp -- division operation */
+/* */
+/* This routine performs the calculations for all four division */
+/* operators (divide, divideInteger, remainder, remainderNear). */
+/* */
+/* C=A op B */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X/X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* op is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively. */
+/* status is the usual accumulator */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* ------------------------------------------------------------------ */
+/* The underlying algorithm of this routine is the same as in the */
+/* 1981 S/370 implementation, that is, non-restoring long division */
+/* with bi-unit (rather than bi-digit) estimation for each unit */
+/* multiplier. In this pseudocode overview, complications for the */
+/* Remainder operators and division residues for exact rounding are */
+/* omitted for clarity. */
+/* */
+/* Prepare operands and handle special values */
+/* Test for x/0 and then 0/x */
+/* Exp =Exp1 - Exp2 */
+/* Exp =Exp +len(var1) -len(var2) */
+/* Sign=Sign1 * Sign2 */
+/* Pad accumulator (Var1) to double-length with 0's (pad1) */
+/* Pad Var2 to same length as Var1 */
+/* msu2pair/plus=1st 2 or 1 units of var2, +1 to allow for round */
+/* have=0 */
+/* Do until (have=digits+1 OR residue=0) */
+/* if exp<0 then if integer divide/residue then leave */
+/* this_unit=0 */
+/* Do forever */
+/* compare numbers */
+/* if <0 then leave inner_loop */
+/* if =0 then (* quick exit without subtract *) do */
+/* this_unit=this_unit+1; output this_unit */
+/* leave outer_loop; end */
+/* Compare lengths of numbers (mantissae): */
+/* If same then tops2=msu2pair -- {units 1&2 of var2} */
+/* else tops2=msu2plus -- {0, unit 1 of var2} */
+/* tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */
+/* mult=tops1/tops2 -- Good and safe guess at divisor */
+/* if mult=0 then mult=1 */
+/* this_unit=this_unit+mult */
+/* subtract */
+/* end inner_loop */
+/* if have\=0 | this_unit\=0 then do */
+/* output this_unit */
+/* have=have+1; end */
+/* var2=var2/10 */
+/* exp=exp-1 */
+/* end outer_loop */
+/* exp=exp+1 -- set the proper exponent */
+/* if have=0 then generate answer=0 */
+/* Return (Result is defined by Var1) */
+/* */
+/* ------------------------------------------------------------------ */
+/* Two working buffers are needed during the division; one (digits+ */
+/* 1) to accumulate the result, and the other (up to 2*digits+1) for */
+/* long subtractions. These are acc and var1 respectively. */
+/* var1 is a copy of the lhs coefficient, var2 is the rhs coefficient.*/
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static decNumber * ___decDivideOp(decNumber *res,
+ const decNumber *lhs, const decNumber *rhs,
+ decContext *set, Flag op, uInt *status) {
+#if DECSUBSET
+ decNumber *alloclhs=NULL; // non-NULL if rounded lhs allocated
+ decNumber *allocrhs=NULL; // .., rhs
+#endif
+ Unit accbuff[SD2U(DECBUFFER+DECDPUN)]; // local buffer
+ Unit *acc=accbuff; // -> accumulator array for result
+ Unit *allocacc=NULL; // -> allocated buffer, iff allocated
+ Unit *accnext; // -> where next digit will go
+ Int acclength; // length of acc needed [Units]
+ Int accunits; // count of units accumulated
+ Int accdigits; // count of digits accumulated
+
+ Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)*sizeof(Unit)]; // buffer for var1
+ Unit *var1=varbuff; // -> var1 array for long subtraction
+ Unit *varalloc=NULL; // -> allocated buffer, iff used
+ Unit *msu1; // -> msu of var1
+
+ const Unit *var2; // -> var2 array
+ const Unit *msu2; // -> msu of var2
+ Int msu2plus; // msu2 plus one [does not vary]
+ eInt msu2pair; // msu2 pair plus one [does not vary]
+
+ Int var1units, var2units; // actual lengths
+ Int var2ulen; // logical length (units)
+ Int var1initpad=0; // var1 initial padding (digits)
+ Int maxdigits; // longest LHS or required acc length
+ Int mult; // multiplier for subtraction
+ Unit thisunit; // current unit being accumulated
+ Int residue; // for rounding
+ Int reqdigits=set->digits; // requested DIGITS
+ Int exponent; // working exponent
+ Int maxexponent=0; // DIVIDE maximum exponent if unrounded
+ uByte bits; // working sign
+ Unit *target; // work
+ const Unit *source; // ..
+ uInt const *pow; // ..
+ Int shift, cut; // ..
+#if DECSUBSET
+ Int dropped; // work
+#endif
+
+#if DECCHECK
+ if (___decCheckOperands(res, lhs, rhs, set)) return res;
+#endif
+
+ do { // protect allocated storage
+#if DECSUBSET
+ if (!set->extended) {
+ // reduce operands and set lostDigits status, as needed
+ if (lhs->digits>reqdigits) {
+ alloclhs=___decRoundOperand(lhs, set, status);
+ if (alloclhs==NULL) break;
+ lhs=alloclhs;
+ }
+ if (rhs->digits>reqdigits) {
+ allocrhs=___decRoundOperand(rhs, set, status);
+ if (allocrhs==NULL) break;
+ rhs=allocrhs;
+ }
+ }
+#endif
+ // [following code does not require input rounding]
+
+ bits=(lhs->bits^rhs->bits)&DECNEG; // assumed sign for divisions
+
+ // handle infinities and NaNs
+ if (SPECIALARGS) { // a special bit set
+ if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
+ ___decNaNs(res, lhs, rhs, status);
+ break;
+ }
+ // one or two infinities
+ if (___decNumberIsInfinite(lhs)) { // LHS (dividend) is infinite
+ if (___decNumberIsInfinite(rhs) || // two infinities are invalid ..
+ op & (REMAINDER | REMNEAR)) { // as is remainder of infinity
+ *status|=DEC_Invalid_operation;
+ break;
+ }
+ // [Note that infinity/0 raises no exceptions]
+ ___decNumberZero(res);
+ res->bits=bits|DECINF; // set +/- infinity
+ break;
+ }
+ else { // RHS (divisor) is infinite
+ residue=0;
+ if (op&(REMAINDER|REMNEAR)) {
+ // result is [finished clone of] lhs
+ ___decCopyFit(res, lhs, set, &residue, status);
+ }
+ else { // a division
+ ___decNumberZero(res);
+ res->bits=bits; // set +/- zero
+ // for DIVIDEINT the exponent is always 0. For DIVIDE, result
+ // is a 0 with infinitely negative exponent, clamped to minimum
+ if (op&DIVIDE) {
+ res->exponent=set->emin-set->digits+1;
+ *status|=DEC_Clamped;
+ }
+ }
+ ___decFinish(res, set, &residue, status);
+ break;
+ }
+ }
+
+ // handle 0 rhs (x/0)
+ if (ISZERO(rhs)) { // x/0 is always exceptional
+ if (ISZERO(lhs)) {
+ ___decNumberZero(res); // [after lhs test]
+ *status|=DEC_Division_undefined;// 0/0 will become NaN
+ }
+ else {
+ ___decNumberZero(res);
+ if (op&(REMAINDER|REMNEAR)) *status|=DEC_Invalid_operation;
+ else {
+ *status|=DEC_Division_by_zero; // x/0
+ res->bits=bits|DECINF; // .. is +/- Infinity
+ }
+ }
+ break;}
+
+ // handle 0 lhs (0/x)
+ if (ISZERO(lhs)) { // 0/x [x!=0]
+#if DECSUBSET
+ if (!set->extended) ___decNumberZero(res);
+ else {
+#endif
+ if (op&DIVIDE) {
+ residue=0;
+ exponent=lhs->exponent-rhs->exponent; // ideal exponent
+ ___decNumberCopy(res, lhs); // [zeros always fit]
+ res->bits=bits; // sign as computed
+ res->exponent=exponent; // exponent, too
+ ___decFinalize(res, set, &residue, status); // check exponent
+ }
+ else if (op&DIVIDEINT) {
+ ___decNumberZero(res); // integer 0
+ res->bits=bits; // sign as computed
+ }
+ else { // a remainder
+ exponent=rhs->exponent; // [save in case overwrite]
+ ___decNumberCopy(res, lhs); // [zeros always fit]
+ if (exponent<res->exponent) res->exponent=exponent; // use lower
+ }
+#if DECSUBSET
+ }
+#endif
+ break;}
+
+ // Precalculate exponent. This starts off adjusted (and hence fits
+ // in 31 bits) and becomes the usual unadjusted exponent as the
+ // division proceeds. The order of evaluation is important, here,
+ // to avoid wrap.
+ exponent=(lhs->exponent+lhs->digits)-(rhs->exponent+rhs->digits);
+
+ // If the working exponent is -ve, then some quick exits are
+ // possible because the quotient is known to be <1
+ // [for REMNEAR, it needs to be < -1, as -0.5 could need work]
+ if (exponent<0 && !(op==DIVIDE)) {
+ if (op&DIVIDEINT) {
+ ___decNumberZero(res); // integer part is 0
+#if DECSUBSET
+ if (set->extended)
+#endif
+ res->bits=bits; // set +/- zero
+ break;}
+ // fastpath remainders so long as the lhs has the smaller
+ // (or equal) exponent
+ if (lhs->exponent<=rhs->exponent) {
+ if (op&REMAINDER || exponent<-1) {
+ // It is REMAINDER or safe REMNEAR; result is [finished
+ // clone of] lhs (r = x - 0*y)
+ residue=0;
+ ___decCopyFit(res, lhs, set, &residue, status);
+ ___decFinish(res, set, &residue, status);
+ break;
+ }
+ // [unsafe REMNEAR drops through]
+ }
+ } // fastpaths
+
+ /* Long (slow) division is needed; roll up the sleeves... */
+
+ // The accumulator will hold the quotient of the division.
+ // If it needs to be too long for stack storage, then allocate.
+ acclength=D2U(reqdigits+DECDPUN); // in Units
+ if (acclength*sizeof(Unit)>sizeof(accbuff)) {
+ allocacc=(Unit *)malloc(acclength*sizeof(Unit));
+ if (allocacc==NULL) { // hopeless -- abandon
+ *status|=DEC_Insufficient_storage;
+ break;}
+ acc=allocacc; // use the allocated space
+ }
+
+ // var1 is the padded LHS ready for subtractions.
+ // If it needs to be too long for stack storage, then allocate.
+ // The maximum units needed for var1 (long subtraction) is:
+ // Enough for
+ // (rhs->digits+reqdigits-1) -- to allow full slide to right
+ // or (lhs->digits) -- to allow for long lhs
+ // whichever is larger
+ // +1 -- for rounding of slide to right
+ // +1 -- for leading 0s
+ // +1 -- for pre-adjust if a remainder or DIVIDEINT
+ // [Note: unused units do not participate in decUnitAddSub data]
+ maxdigits=rhs->digits+reqdigits-1;
+ if (lhs->digits>maxdigits) maxdigits=lhs->digits;
+ var1units=D2U(maxdigits)+2;
+ // allocate a guard unit above msu1 for REMAINDERNEAR
+ if (!(op&DIVIDE)) var1units++;
+ if ((var1units+1)*sizeof(Unit)>sizeof(varbuff)) {
+ varalloc=(Unit *)malloc((var1units+1)*sizeof(Unit));
+ if (varalloc==NULL) { // hopeless -- abandon
+ *status|=DEC_Insufficient_storage;
+ break;}
+ var1=varalloc; // use the allocated space
+ }
+
+ // Extend the lhs and rhs to full long subtraction length. The lhs
+ // is truly extended into the var1 buffer, with 0 padding, so a
+ // subtract in place is always possible. The rhs (var2) has
+ // virtual padding (implemented by ___decUnitAddSub).
+ // One guard unit was allocated above msu1 for rem=rem+rem in
+ // REMAINDERNEAR.
+ msu1=var1+var1units-1; // msu of var1
+ source=lhs->lsu+D2U(lhs->digits)-1; // msu of input array
+ for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source;
+ for (; target>=var1; target--) *target=0;
+
+ // rhs (var2) is left-aligned with var1 at the start
+ var2ulen=var1units; // rhs logical length (units)
+ var2units=D2U(rhs->digits); // rhs actual length (units)
+ var2=rhs->lsu; // -> rhs array
+ msu2=var2+var2units-1; // -> msu of var2 [never changes]
+ // now set up the variables which will be used for estimating the
+ // multiplication factor. If these variables are not exact, add
+ // 1 to make sure that the multiplier is never overestimated.
+ msu2plus=*msu2; // it's value ..
+ if (var2units>1) msu2plus++; // .. +1 if any more
+ msu2pair=(eInt)*msu2*(DECDPUNMAX+1);// top two pair ..
+ if (var2units>1) { // .. [else treat 2nd as 0]
+ msu2pair+=*(msu2-1); // ..
+ if (var2units>2) msu2pair++; // .. +1 if any more
+ }
+
+ // The calculation is working in units, which may have leading zeros,
+ // but the exponent was calculated on the assumption that they are
+ // both left-aligned. Adjust the exponent to compensate: add the
+ // number of leading zeros in var1 msu and subtract those in var2 msu.
+ // [This is actually done by counting the digits and negating, as
+ // lead1=DECDPUN-digits1, and similarly for lead2.]
+ for (pow=&__powers[1]; *msu1>=*pow; pow++) exponent--;
+ for (pow=&__powers[1]; *msu2>=*pow; pow++) exponent++;
+
+ // Now, if doing an integer divide or remainder, ensure that
+ // the result will be Unit-aligned. To do this, shift the var1
+ // accumulator towards least if need be. (It's much easier to
+ // do this now than to reassemble the residue afterwards, if
+ // doing a remainder.) Also ensure the exponent is not negative.
+ if (!(op&DIVIDE)) {
+ Unit *u; // work
+ // save the initial 'false' padding of var1, in digits
+ var1initpad=(var1units-D2U(lhs->digits))*DECDPUN;
+ // Determine the shift to do.
+ if (exponent<0) cut=-exponent;
+ else cut=DECDPUN-exponent%DECDPUN;
+ ___decShiftToLeast(var1, var1units, cut);
+ exponent+=cut; // maintain numerical value
+ var1initpad-=cut; // .. and reduce padding
+ // clean any most-significant units which were just emptied
+ for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0;
+ } // align
+ else { // is DIVIDE
+ maxexponent=lhs->exponent-rhs->exponent; // save
+ // optimization: if the first iteration will just produce 0,
+ // preadjust to skip it [valid for DIVIDE only]
+ if (*msu1<*msu2) {
+ var2ulen--; // shift down
+ exponent-=DECDPUN; // update the exponent
+ }
+ }
+
+ // ---- start the long-division loops ------------------------------
+ accunits=0; // no units accumulated yet
+ accdigits=0; // .. or digits
+ accnext=acc+acclength-1; // -> msu of acc [NB: allows digits+1]
+ for (;;) { // outer forever loop
+ thisunit=0; // current unit assumed 0
+ // find the next unit
+ for (;;) { // inner forever loop
+ // strip leading zero units [from either pre-adjust or from
+ // subtract last time around]. Leave at least one unit.
+ for (; *msu1==0 && msu1>var1; msu1--) var1units--;
+
+ if (var1units<var2ulen) break; // var1 too low for subtract
+ if (var1units==var2ulen) { // unit-by-unit compare needed
+ // compare the two numbers, from msu
+ const Unit *pv1, *pv2;
+ Unit v2; // units to compare
+ pv2=msu2; // -> msu
+ for (pv1=msu1; ; pv1--, pv2--) {
+ // v1=*pv1 -- always OK
+ v2=0; // assume in padding
+ if (pv2>=var2) v2=*pv2; // in range
+ if (*pv1!=v2) break; // no longer the same
+ if (pv1==var1) break; // done; leave pv1 as is
+ }
+ // here when all inspected or a difference seen
+ if (*pv1<v2) break; // var1 too low to subtract
+ if (*pv1==v2) { // var1 == var2
+ // reach here if var1 and var2 are identical; subtraction
+ // would increase digit by one, and the residue will be 0 so
+ // the calculation is done; leave the loop with residue=0.
+ thisunit++; // as though subtracted
+ *var1=0; // set var1 to 0
+ var1units=1; // ..
+ break; // from inner
+ } // var1 == var2
+ // *pv1>v2. Prepare for real subtraction; the lengths are equal
+ // Estimate the multiplier (there's always a msu1-1)...
+ // Bring in two units of var2 to provide a good estimate.
+ mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2pair);
+ } // lengths the same
+ else { // var1units > var2ulen, so subtraction is safe
+ // The var2 msu is one unit towards the lsu of the var1 msu,
+ // so only one unit for var2 can be used.
+ mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2plus);
+ }
+ if (mult==0) mult=1; // must always be at least 1
+ // subtraction needed; var1 is > var2
+ thisunit=(Unit)(thisunit+mult); // accumulate
+ // subtract var1-var2, into var1; only the overlap needs
+ // processing, as this is an in-place calculation
+ shift=var2ulen-var2units;
+#if DECTRACE
+ ___decDumpAr('1', &var1[shift], var1units-shift);
+ ___decDumpAr('2', var2, var2units);
+ printf("m=%d\n", -mult);
+#endif
+ ___decUnitAddSub(&var1[shift], var1units-shift,
+ var2, var2units, 0,
+ &var1[shift], -mult);
+#if DECTRACE
+ ___decDumpAr('#', &var1[shift], var1units-shift);
+#endif
+ // var1 now probably has leading zeros; these are removed at the
+ // top of the inner loop.
+ } // inner loop
+
+ // The next unit has been calculated in full; unless it's a
+ // leading zero, add to acc
+ if (accunits!=0 || thisunit!=0) { // is first or non-zero
+ *accnext=thisunit; // store in accumulator
+ // account exactly for the new digits
+ if (accunits==0) {
+ accdigits++; // at least one
+ for (pow=&__powers[1]; thisunit>=*pow; pow++) accdigits++;
+ }
+ else accdigits+=DECDPUN;
+ accunits++; // update count
+ accnext--; // ready for next
+ if (accdigits>reqdigits) break; // have enough digits
+ }
+
+ // if the residue is zero, the operation is done (unless divide
+ // or divideInteger and still not enough digits yet)
+ if (*var1==0 && var1units==1) { // residue is 0
+ if (op&(REMAINDER|REMNEAR)) break;
+ if ((op&DIVIDE) && (exponent<=maxexponent)) break;
+ // [drop through if divideInteger]
+ }
+ // also done enough if calculating remainder or integer
+ // divide and just did the last ('units') unit
+ if (exponent==0 && !(op&DIVIDE)) break;
+
+ // to get here, var1 is less than var2, so divide var2 by the per-
+ // Unit power of ten and go for the next digit
+ var2ulen--; // shift down
+ exponent-=DECDPUN; // update the exponent
+ } // outer loop
+
+ // ---- division is complete ---------------------------------------
+ // here: acc has at least reqdigits+1 of good results (or fewer
+ // if early stop), starting at accnext+1 (its lsu)
+ // var1 has any residue at the stopping point
+ // accunits is the number of digits collected in acc
+ if (accunits==0) { // acc is 0
+ accunits=1; // show have a unit ..
+ accdigits=1; // ..
+ *accnext=0; // .. whose value is 0
+ }
+ else accnext++; // back to last placed
+ // accnext now -> lowest unit of result
+
+ residue=0; // assume no residue
+ if (op&DIVIDE) {
+ // record the presence of any residue, for rounding
+ if (*var1!=0 || var1units>1) residue=1;
+ else { // no residue
+ // Had an exact division; clean up spurious trailing 0s.
+ // There will be at most DECDPUN-1, from the final multiply,
+ // and then only if the result is non-0 (and even) and the
+ // exponent is 'loose'.
+#if DECDPUN>1
+ Unit lsu=*accnext;
+ if (!(lsu&0x01) && (lsu!=0)) {
+ // count the trailing zeros
+ Int drop=0;
+ for (;; drop++) { // [will terminate because lsu!=0]
+ if (exponent>=maxexponent) break; // don't chop real 0s
+#if DECDPUN<=4
+ if ((lsu-QUOT10(lsu, drop+1)
+ *__powers[drop+1])!=0) break; // found non-0 digit
+#else
+ if (lsu%__powers[drop+1]!=0) break; // found non-0 digit
+#endif
+ exponent++;
+ }
+ if (drop>0) {
+ accunits=___decShiftToLeast(accnext, accunits, drop);
+ accdigits=___decGetDigits(accnext, accunits);
+ accunits=D2U(accdigits);
+ // [exponent was adjusted in the loop]
+ }
+ } // neither odd nor 0
+#endif
+ } // exact divide
+ } // divide
+ else /* op!=DIVIDE */ {
+ // check for coefficient overflow
+ if (accdigits+exponent>reqdigits) {
+ *status|=DEC_Division_impossible;
+ break;
+ }
+ if (op & (REMAINDER|REMNEAR)) {
+ // [Here, the exponent will be 0, because var1 was adjusted
+ // appropriately.]
+ Int postshift; // work
+ Flag wasodd=0; // integer was odd
+ Unit *quotlsu; // for save
+ Int quotdigits; // ..
+
+ // Fastpath when residue is truly 0 is worthwhile [and
+ // simplifies the code below]
+ if (*var1==0 && var1units==1) { // residue is 0
+ Int exp=lhs->exponent; // save min(exponents)
+ if (rhs->exponent<exp) exp=rhs->exponent;
+ ___decNumberZero(res); // 0 coefficient
+#if DECSUBSET
+ if (set->extended)
+#endif
+ res->exponent=exp; // .. with proper exponent
+ break;
+ }
+ // note if the quotient was odd
+ if (*accnext & 0x01) wasodd=1; // acc is odd
+ quotlsu=accnext; // save in case need to reinspect
+ quotdigits=accdigits; // ..
+
+ // treat the residue, in var1, as the value to return, via acc
+ // calculate the unused zero digits. This is the smaller of:
+ // var1 initial padding (saved above)
+ // var2 residual padding, which happens to be given by:
+ postshift=var1initpad+exponent-lhs->exponent+rhs->exponent;
+ // [the 'exponent' term accounts for the shifts during divide]
+ if (var1initpad<postshift) postshift=var1initpad;
+
+ // shift var1 the requested amount, and adjust its digits
+ var1units=___decShiftToLeast(var1, var1units, postshift);
+ accnext=var1;
+ accdigits=___decGetDigits(var1, var1units);
+ accunits=D2U(accdigits);
+
+ exponent=lhs->exponent; // exponent is smaller of lhs & rhs
+ if (rhs->exponent<exponent) exponent=rhs->exponent;
+ bits=lhs->bits; // remainder sign is always as lhs
+
+ // Now correct the result if doing remainderNear; if it
+ // (looking just at coefficients) is > rhs/2, or == rhs/2 and
+ // the integer was odd then the result should be rem-rhs.
+ if (op&REMNEAR) {
+ Int compare, tarunits; // work
+ Unit *up; // ..
+
+
+ // calculate remainder*2 into the var1 buffer (which has
+ // 'headroom' of an extra unit and hence enough space)
+ // [a dedicated 'double' loop would be faster, here]
+ tarunits=___decUnitAddSub(accnext, accunits, accnext, accunits,
+ 0, accnext, 1);
+ // ___decDumpAr('r', accnext, tarunits);
+
+ // Here, accnext (var1) holds tarunits Units with twice the
+ // remainder's coefficient, which must now be compared to the
+ // RHS. The remainder's exponent may be smaller than the RHS's.
+ compare=___decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits),
+ rhs->exponent-exponent);
+ if (compare==BADINT) { // deep trouble
+ *status|=DEC_Insufficient_storage;
+ break;}
+
+ // now restore the remainder by dividing by two; the lsu
+ // is known to be even.
+ for (up=accnext; up<accnext+tarunits; up++) {
+ Int half; // half to add to lower unit
+ half=*up & 0x01;
+ *up/=2; // [shift]
+ if (!half) continue;
+ *(up-1)+=(DECDPUNMAX+1)/2;
+ }
+ // [accunits still describes the original remainder length]
+
+ if (compare>0 || (compare==0 && wasodd)) { // adjustment needed
+ Int exp, expunits, exprem; // work
+ // This is effectively causing round-up of the quotient,
+ // so if it was the rare case where it was full and all
+ // nines, it would overflow and hence division-impossible
+ // should be raised
+ Flag allnines=0; // 1 if quotient all nines
+ if (quotdigits==reqdigits) { // could be borderline
+ for (up=quotlsu; ; up++) {
+ if (quotdigits>DECDPUN) {
+ if (*up!=DECDPUNMAX) break;// non-nines
+ }
+ else { // this is the last Unit
+ if (*up==__powers[quotdigits]-1) allnines=1;
+ break;
+ }
+ quotdigits-=DECDPUN; // checked those digits
+ } // up
+ } // borderline check
+ if (allnines) {
+ *status|=DEC_Division_impossible;
+ break;}
+
+ // rem-rhs is needed; the sign will invert. Again, var1
+ // can safely be used for the working Units array.
+ exp=rhs->exponent-exponent; // RHS padding needed
+ // Calculate units and remainder from exponent.
+ expunits=exp/DECDPUN;
+ exprem=exp%DECDPUN;
+ // subtract [A+B*(-m)]; the result will always be negative
+ accunits=-___decUnitAddSub(accnext, accunits,
+ rhs->lsu, D2U(rhs->digits),
+ expunits, accnext, -(Int)__powers[exprem]);
+ accdigits=___decGetDigits(accnext, accunits); // count digits exactly
+ accunits=D2U(accdigits); // and recalculate the units for copy
+ // [exponent is as for original remainder]
+ bits^=DECNEG; // flip the sign
+ }
+ } // REMNEAR
+ } // REMAINDER or REMNEAR
+ } // not DIVIDE
+
+ // Set exponent and bits
+ res->exponent=exponent;
+ res->bits=(uByte)(bits&DECNEG); // [cleaned]
+
+ // Now the coefficient.
+ ___decSetCoeff(res, set, accnext, accdigits, &residue, status);
+
+ ___decFinish(res, set, &residue, status); // final cleanup
+
+#if DECSUBSET
+ // If a divide then strip trailing zeros if subset [after round]
+ if (!set->extended && (op==DIVIDE)) ___decTrim(res, 0, &dropped);
+#endif
+ } while(0); // end protected
+
+ if (varalloc!=NULL) free(varalloc); // drop any storage used
+ if (allocacc!=NULL) free(allocacc); // ..
+#if DECSUBSET
+ if (allocrhs!=NULL) free(allocrhs); // ..
+ if (alloclhs!=NULL) free(alloclhs); // ..
+#endif
+ return res;
+} /* ___decDivideOp */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decMultiplyOp -- multiplication operation */
+/* */
+/* This routine performs the multiplication C=A x B. */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X*X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* status is the usual accumulator */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* ------------------------------------------------------------------ */
+/* 'Classic' multiplication is used rather than Karatsuba, as the */
+/* latter would give only a minor improvement for the short numbers */
+/* expected to be handled most (and uses much more memory). */
+/* */
+/* There are two major paths here: the general-purpose ('old code') */
+/* path which handles all DECDPUN values, and a fastpath version */
+/* which is used if 64-bit ints are available, DECDPUN<=4, and more */
+/* than two calls to ___decUnitAddSub would be made. */
+/* */
+/* The fastpath version lumps units together into 8-digit or 9-digit */
+/* chunks, and also uses a lazy carry strategy to minimise expensive */
+/* 64-bit divisions. The chunks are then broken apart again into */
+/* units for continuing processing. Despite this overhead, the */
+/* fastpath can speed up some 16-digit operations by 10x (and much */
+/* more for higher-precision calculations). */
+/* */
+/* A buffer always has to be used for the accumulator; in the */
+/* fastpath, buffers are also always needed for the chunked copies of */
+/* of the operand coefficients. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+#define FASTMUL (DECUSE64 && DECDPUN<5)
+static decNumber * ___decMultiplyOp(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set,
+ uInt *status) {
+ Int accunits; // Units of accumulator in use
+ Int exponent; // work
+ Int residue=0; // rounding residue
+ uByte bits; // result sign
+ Unit *acc; // -> accumulator Unit array
+ Int needbytes; // size calculator
+ void *allocacc=NULL; // -> allocated accumulator, iff allocated
+ Unit accbuff[SD2U(DECBUFFER*2+5)]; // buffer (+1 for DECBUFFER==0,
+ // + 4 for calls from other operations)
+ const Unit *mer, *mermsup; // work
+ Int madlength; // Units in multiplicand
+ Int shift; // Units to shift multiplicand by
+
+ #if FASTMUL
+ // if DECDPUN is 1 or 3 work in base 10**9, otherwise
+ // (DECDPUN is 2 or 4) then work in base 10**8
+ #if DECDPUN & 1 // odd
+ #define FASTBASE 1000000000 // base
+ #define FASTDIGS 9 // digits in base
+ #define FASTLAZY 18 // carry resolution point [1->18]
+ #else
+ #define FASTBASE 100000000
+ #define FASTDIGS 8
+ #define FASTLAZY 1844 // carry resolution point [1->1844]
+ #endif
+ // three buffers are used, two for chunked copies of the operands
+ // (base 10**8 or base 10**9) and one base 2**64 accumulator with
+ // lazy carry evaluation
+ uInt zlhibuff[(DECBUFFER+7)/8+1]; // buffer (+1 for DECBUFFER==0)
+ uInt *zlhi=zlhibuff; // -> lhs array
+ uInt *alloclhi=NULL; // -> allocated buffer, iff allocated
+ uInt zrhibuff[(DECBUFFER+7)/8+1]; // buffer (+1 for DECBUFFER==0)
+ uInt *zrhi=zrhibuff; // -> rhs array
+ uInt *allocrhi=NULL; // -> allocated buffer, iff allocated
+ uLong zaccbuff[(DECBUFFER+3)/4+2]; // buffer (+1 for DECBUFFER==0)
+ // + 1 for calls from other operations)
+ // [allocacc is shared for both paths, as only one will run]
+ uLong *zacc=zaccbuff; // -> accumulator array for exact result
+ #if DECDPUN==1
+ Int zoff; // accumulator offset
+ #endif
+ uInt *lip, *rip; // item pointers
+ uInt *lmsi, *rmsi; // most significant items
+ Int ilhs, irhs, iacc; // item counts in the arrays
+ Int lazy; // lazy carry counter
+ uLong lcarry; // uLong carry
+ uInt carry; // carry (NB not uLong)
+ Int count; // work
+ const Unit *cup; // ..
+ Unit *up; // ..
+ uLong *lp; // ..
+ Int p; // ..
+ #endif
+
+ #if DECSUBSET
+ decNumber *alloclhs=NULL; // -> allocated buffer, iff allocated
+ decNumber *allocrhs=NULL; // -> allocated buffer, iff allocated
+ #endif
+
+ #if DECCHECK
+ if (___decCheckOperands(res, lhs, rhs, set)) return res;
+ #endif
+
+ // precalculate result sign
+ bits=(uByte)((lhs->bits^rhs->bits)&DECNEG);
+
+ // handle infinities and NaNs
+ if (SPECIALARGS) { // a special bit set
+ if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
+ ___decNaNs(res, lhs, rhs, status);
+ return res;}
+ // one or two infinities; Infinity * 0 is invalid
+ if (((lhs->bits & DECINF)==0 && ISZERO(lhs))
+ ||((rhs->bits & DECINF)==0 && ISZERO(rhs))) {
+ *status|=DEC_Invalid_operation;
+ return res;}
+ ___decNumberZero(res);
+ res->bits=bits|DECINF; // infinity
+ return res;}
+
+ // For best speed, as in DMSRCN [the original Rexx numerics
+ // module], use the shorter number as the multiplier (rhs) and
+ // the longer as the multiplicand (lhs) to minimise the number of
+ // adds (partial products)
+ if (lhs->digits<rhs->digits) { // swap...
+ const decNumber *hold=lhs;
+ lhs=rhs;
+ rhs=hold;
+ }
+
+ do { // protect allocated storage
+ #if DECSUBSET
+ if (!set->extended) {
+ // reduce operands and set lostDigits status, as needed
+ if (lhs->digits>set->digits) {
+ alloclhs=___decRoundOperand(lhs, set, status);
+ if (alloclhs==NULL) break;
+ lhs=alloclhs;
+ }
+ if (rhs->digits>set->digits) {
+ allocrhs=___decRoundOperand(rhs, set, status);
+ if (allocrhs==NULL) break;
+ rhs=allocrhs;
+ }
+ }
+ #endif
+ // [following code does not require input rounding]
+
+ #if FASTMUL // fastpath can be used
+ // use the fast path if there are enough digits in the shorter
+ // operand to make the setup and takedown worthwhile
+ #define NEEDTWO (DECDPUN*2) // within two ___decUnitAddSub calls
+ if (rhs->digits>NEEDTWO) { // use fastpath...
+ // calculate the number of elements in each array
+ ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; // [ceiling]
+ irhs=(rhs->digits+FASTDIGS-1)/FASTDIGS; // ..
+ iacc=ilhs+irhs;
+
+ // allocate buffers if required, as usual
+ needbytes=ilhs*sizeof(uInt);
+ if (needbytes>(Int)sizeof(zlhibuff)) {
+ alloclhi=(uInt *)malloc(needbytes);
+ zlhi=alloclhi;}
+ needbytes=irhs*sizeof(uInt);
+ if (needbytes>(Int)sizeof(zrhibuff)) {
+ allocrhi=(uInt *)malloc(needbytes);
+ zrhi=allocrhi;}
+
+ // Allocating the accumulator space needs a special case when
+ // DECDPUN=1 because when converting the accumulator to Units
+ // after the multiplication each 8-byte item becomes 9 1-byte
+ // units. Therefore iacc extra bytes are needed at the front
+ // (rounded up to a multiple of 8 bytes), and the uLong
+ // accumulator starts offset the appropriate number of units
+ // to the right to avoid overwrite during the unchunking.
+ needbytes=iacc*sizeof(uLong);
+ #if DECDPUN==1
+ zoff=(iacc+7)/8; // items to offset by
+ needbytes+=zoff*8;
+ #endif
+ if (needbytes>(Int)sizeof(zaccbuff)) {
+ allocacc=(uLong *)malloc(needbytes);
+ zacc=(uLong *)allocacc;}
+ if (zlhi==NULL||zrhi==NULL||zacc==NULL) {
+ *status|=DEC_Insufficient_storage;
+ break;}
+
+ acc=(Unit *)zacc; // -> target Unit array
+ #if DECDPUN==1
+ zacc+=zoff; // start uLong accumulator to right
+ #endif
+
+ // assemble the chunked copies of the left and right sides
+ for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++)
+ for (p=0, *lip=0; p<FASTDIGS && count>0;
+ p+=DECDPUN, cup++, count-=DECDPUN)
+ *lip+=*cup*__powers[p];
+ lmsi=lip-1; // save -> msi
+ for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++)
+ for (p=0, *rip=0; p<FASTDIGS && count>0;
+ p+=DECDPUN, cup++, count-=DECDPUN)
+ *rip+=*cup*__powers[p];
+ rmsi=rip-1; // save -> msi
+
+ // zero the accumulator
+ for (lp=zacc; lp<zacc+iacc; lp++) *lp=0;
+
+ /* Start the multiplication */
+ // Resolving carries can dominate the cost of accumulating the
+ // partial products, so this is only done when necessary.
+ // Each uLong item in the accumulator can hold values up to
+ // 2**64-1, and each partial product can be as large as
+ // (10**FASTDIGS-1)**2. When FASTDIGS=9, this can be added to
+ // itself 18.4 times in a uLong without overflowing, so during
+ // the main calculation resolution is carried out every 18th
+ // add -- every 162 digits. Similarly, when FASTDIGS=8, the
+ // partial products can be added to themselves 1844.6 times in
+ // a uLong without overflowing, so intermediate carry
+ // resolution occurs only every 14752 digits. Hence for common
+ // short numbers usually only the one final carry resolution
+ // occurs.
+ // (The count is set via FASTLAZY to simplify experiments to
+ // measure the value of this approach: a 35% improvement on a
+ // [34x34] multiply.)
+ lazy=FASTLAZY; // carry delay count
+ for (rip=zrhi; rip<=rmsi; rip++) { // over each item in rhs
+ lp=zacc+(rip-zrhi); // where to add the lhs
+ for (lip=zlhi; lip<=lmsi; lip++, lp++) { // over each item in lhs
+ *lp+=(uLong)(*lip)*(*rip); // [this should in-line]
+ } // lip loop
+ lazy--;
+ if (lazy>0 && rip!=rmsi) continue;
+ lazy=FASTLAZY; // reset delay count
+ // spin up the accumulator resolving overflows
+ for (lp=zacc; lp<zacc+iacc; lp++) {
+ if (*lp<FASTBASE) continue; // it fits
+ lcarry=*lp/FASTBASE; // top part [slow divide]
+ // lcarry can exceed 2**32-1, so check again; this check
+ // and occasional extra divide (slow) is well worth it, as
+ // it allows FASTLAZY to be increased to 18 rather than 4
+ // in the FASTDIGS=9 case
+ if (lcarry<FASTBASE) carry=(uInt)lcarry; // [usual]
+ else { // two-place carry [fairly rare]
+ uInt carry2=(uInt)(lcarry/FASTBASE); // top top part
+ *(lp+2)+=carry2; // add to item+2
+ *lp-=((uLong)FASTBASE*FASTBASE*carry2); // [slow]
+ carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); // [inline]
+ }
+ *(lp+1)+=carry; // add to item above [inline]
+ *lp-=((uLong)FASTBASE*carry); // [inline]
+ } // carry resolution
+ } // rip loop
+
+ // The multiplication is complete; time to convert back into
+ // units. This can be done in-place in the accumulator and in
+ // 32-bit operations, because carries were resolved after the
+ // final add. This needs N-1 divides and multiplies for
+ // each item in the accumulator (which will become up to N
+ // units, where 2<=N<=9).
+ for (lp=zacc, up=acc; lp<zacc+iacc; lp++) {
+ uInt item=(uInt)*lp; // decapitate to uInt
+ for (p=0; p<FASTDIGS-DECDPUN; p+=DECDPUN, up++) {
+ uInt part=item/(DECDPUNMAX+1);
+ *up=(Unit)(item-(part*(DECDPUNMAX+1)));
+ item=part;
+ } // p
+ *up=(Unit)item; up++; // [final needs no division]
+ } // lp
+ accunits=up-acc; // count of units
+ }
+ else { // here to use units directly, without chunking ['old code']
+ #endif
+
+ // if accumulator will be too long for local storage, then allocate
+ acc=accbuff; // -> assume buffer for accumulator
+ needbytes=(D2U(lhs->digits)+D2U(rhs->digits))*sizeof(Unit);
+ if (needbytes>(Int)sizeof(accbuff)) {
+ allocacc=(Unit *)malloc(needbytes);
+ if (allocacc==NULL) {*status|=DEC_Insufficient_storage; break;}
+ acc=(Unit *)allocacc; // use the allocated space
+ }
+
+ /* Now the main long multiplication loop */
+ // Unlike the equivalent in the IBM Java implementation, there
+ // is no advantage in calculating from msu to lsu. So, do it
+ // by the book, as it were.
+ // Each iteration calculates ACC=ACC+MULTAND*MULT
+ accunits=1; // accumulator starts at '0'
+ *acc=0; // .. (lsu=0)
+ shift=0; // no multiplicand shift at first
+ madlength=D2U(lhs->digits); // this won't change
+ mermsup=rhs->lsu+D2U(rhs->digits); // -> msu+1 of multiplier
+
+ for (mer=rhs->lsu; mer<mermsup; mer++) {
+ // Here, *mer is the next Unit in the multiplier to use
+ // If non-zero [optimization] add it...
+ if (*mer!=0) accunits=___decUnitAddSub(&acc[shift], accunits-shift,
+ lhs->lsu, madlength, 0,
+ &acc[shift], *mer)
+ + shift;
+ else { // extend acc with a 0; it will be used shortly
+ *(acc+accunits)=0; // [this avoids length of <=0 later]
+ accunits++;
+ }
+ // multiply multiplicand by 10**DECDPUN for next Unit to left
+ shift++; // add this for 'logical length'
+ } // n
+ #if FASTMUL
+ } // unchunked units
+ #endif
+ // common end-path
+ #if DECTRACE
+ ___decDumpAr('*', acc, accunits); // Show exact result
+ #endif
+
+ // acc now contains the exact result of the multiplication,
+ // possibly with a leading zero unit; build the decNumber from
+ // it, noting if any residue
+ res->bits=bits; // set sign
+ res->digits=___decGetDigits(acc, accunits); // count digits exactly
+
+ // There can be a 31-bit wrap in calculating the exponent.
+ // This can only happen if both input exponents are negative and
+ // both their magnitudes are large. If there was a wrap, set a
+ // safe very negative exponent, from which ___decFinalize() will
+ // raise a hard underflow shortly.
+ exponent=lhs->exponent+rhs->exponent; // calculate exponent
+ if (lhs->exponent<0 && rhs->exponent<0 && exponent>0)
+ exponent=-2*DECNUMMAXE; // force underflow
+ res->exponent=exponent; // OK to overwrite now
+
+ // Set the coefficient. If any rounding, residue records
+ ___decSetCoeff(res, set, acc, res->digits, &residue, status);
+ ___decFinish(res, set, &residue, status); // final cleanup
+ } while(0); // end protected
+
+ if (allocacc!=NULL) free(allocacc); // drop any storage used
+ #if DECSUBSET
+ if (allocrhs!=NULL) free(allocrhs); // ..
+ if (alloclhs!=NULL) free(alloclhs); // ..
+ #endif
+ #if FASTMUL
+ if (allocrhi!=NULL) free(allocrhi); // ..
+ if (alloclhi!=NULL) free(alloclhi); // ..
+ #endif
+ return res;
+} /* ___decMultiplyOp */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decExpOp -- effect exponentiation */
+/* */
+/* This computes C = exp(A) */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context; note that rounding mode has no effect */
+/* */
+/* C must have space for set->digits digits. status is updated but */
+/* not set. */
+/* */
+/* Restrictions: */
+/* */
+/* digits, emax, and -emin in the context must be less than */
+/* 2*DEC_MAX_MATH (1999998), and the rhs must be within these */
+/* bounds or a zero. This is an internal routine, so these */
+/* restrictions are contractual and not enforced. */
+/* */
+/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */
+/* almost always be correctly rounded, but may be up to 1 ulp in */
+/* error in rare cases. */
+/* */
+/* Finite results will always be full precision and Inexact, except */
+/* when A is a zero or -Infinity (giving 1 or 0 respectively). */
+/* ------------------------------------------------------------------ */
+/* This approach used here is similar to the algorithm described in */
+/* */
+/* Variable Precision Exponential Function, T. E. Hull and */
+/* A. Abrham, ACM Transactions on Mathematical Software, Vol 12 #2, */
+/* pp79-91, ACM, June 1986. */
+/* */
+/* with the main difference being that the iterations in the series */
+/* evaluation are terminated dynamically (which does not require the */
+/* extra variable-precision variables which are expensive in this */
+/* context). */
+/* */
+/* The error analysis in Hull & Abrham's paper applies except for the */
+/* round-off error accumulation during the series evaluation. This */
+/* code does not precalculate the number of iterations and so cannot */
+/* use Horner's scheme. Instead, the accumulation is done at double- */
+/* precision, which ensures that the additions of the terms are exact */
+/* and do not accumulate round-off (and any round-off errors in the */
+/* terms themselves move 'to the right' faster than they can */
+/* accumulate). This code also extends the calculation by allowing, */
+/* in the spirit of other decNumber operators, the input to be more */
+/* precise than the result (the precision used is based on the more */
+/* precise of the input or requested result). */
+/* */
+/* Implementation notes: */
+/* */
+/* 1. This is separated out as ___decExpOp so it can be called from */
+/* other Mathematical functions (notably Ln) with a wider range */
+/* than normal. In particular, it can handle the slightly wider */
+/* (double) range needed by Ln (which has to be able to calculate */
+/* exp(-x) where x can be the tiniest number (Ntiny). */
+/* */
+/* 2. Normalizing x to be <=0.1 (instead of <=1) reduces loop */
+/* iterations by appoximately a third with additional (although */
+/* diminishing) returns as the range is reduced to even smaller */
+/* fractions. However, h (the power of 10 used to correct the */
+/* result at the end, see below) must be kept <=8 as otherwise */
+/* the final result cannot be computed. Hence the leverage is a */
+/* sliding value (8-h), where potentially the range is reduced */
+/* more for smaller values. */
+/* */
+/* The leverage that can be applied in this way is severely */
+/* limited by the cost of the raise-to-the power at the end, */
+/* which dominates when the number of iterations is small (less */
+/* than ten) or when rhs is short. As an example, the adjustment */
+/* x**10,000,000 needs 31 multiplications, all but one full-width. */
+/* */
+/* 3. The restrictions (especially precision) could be raised with */
+/* care, but the full decNumber range seems very hard within the */
+/* 32-bit limits. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+decNumber * ___decExpOp(decNumber *res, const decNumber *rhs,
+ decContext *set, uInt *status) {
+ uInt ignore=0; // working status
+ Int h; // adjusted exponent for 0.xxxx
+ Int p; // working precision
+ Int residue; // rounding residue
+ uInt needbytes; // for space calculations
+ const decNumber *x=rhs; // (may point to safe copy later)
+ decContext aset, tset, dset; // working contexts
+
+ // the argument is often copied to normalize it, so (unusually) it
+ // is treated like other buffers, using DECBUFFER, +1 in case
+ // DECBUFFER is 0
+ decNumber bufr[D2N(DECBUFFER+1)];
+ decNumber *allocrhs=NULL; // non-NULL if rhs buffer allocated
+
+ // the working precision will be no more than set->digits+8+1
+ // so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER
+ // is 0 (and twice that for the accumulator)
+
+ // buffer for t, term (working precision plus)
+ decNumber buft[D2N(DECBUFFER+9+1)];
+ decNumber *allocbuft=NULL; // -> allocated buft, iff allocated
+ decNumber *t=buft; // term
+ // buffer for a, accumulator (working precision * 2), at least 9
+ decNumber bufa[D2N(DECBUFFER*2+18+1)];
+ decNumber *allocbufa=NULL; // -> allocated bufa, iff allocated
+ decNumber *a=bufa; // accumulator
+ // decNumber for the divisor term; this needs at most 9 digits
+ // and so can be fixed size [16 so can use standard context]
+ decNumber bufd[D2N(16)];
+ decNumber *d=bufd; // divisor
+ decNumber numone; // constant 1
+
+ #if DECCHECK
+ Int iterations=0; // for later sanity check
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ do { // protect allocated storage
+ if (SPECIALARG) { // handle infinities and NaNs
+ if (___decNumberIsInfinite(rhs)) { // an infinity
+ if (___decNumberIsNegative(rhs)) // -Infinity -> +0
+ ___decNumberZero(res);
+ else ___decNumberCopy(res, rhs); // +Infinity -> self
+ }
+ else ___decNaNs(res, rhs, NULL, status); // a NaN
+ break;
+ }
+
+ if (ISZERO(rhs)) { // zeros -> exact 1
+ ___decNumberZero(res); // make clean 1
+ *res->lsu=1; // ..
+ break; // [no status to set]
+ }
+
+ // e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path
+ // positive and negative tiny cases which will result in inexact
+ // 1. This also allows the later add-accumulate to always be
+ // exact (because its length will never be more than twice the
+ // working precision).
+ // The comparator (tiny) needs just one digit, so use the
+ // decNumber d for it (reused as the divisor, etc., below); its
+ // exponent is such that if x is positive it will have
+ // set->digits-1 zeros between the decimal point and the digit,
+ // which is 4, and if x is negative one more zero there as the
+ // more precise result will be of the form 0.9999999 rather than
+ // 1.0000001. Hence, tiny will be 0.0000004 if digits=7 and x>0
+ // or 0.00000004 if digits=7 and x<0. If RHS not larger than
+ // this then the result will be 1.000000
+ ___decNumberZero(d); // clean
+ *d->lsu=4; // set 4 ..
+ d->exponent=-set->digits; // * 10**(-d)
+ if (___decNumberIsNegative(rhs)) d->exponent--; // negative case
+ if (___decCompare(d, rhs, 1)>=0) { // signless compare
+ Int shift=set->digits-1;
+ ___decNumberZero(res); // set 1
+ *res->lsu=1; // ..
+ res->digits=___decShiftToMost(res->lsu, 1, shift);
+ res->exponent=-shift; // make 1.0000...
+ *status|=DEC_Inexact | DEC_Rounded; // .. inexactly
+ break; // tiny
+ }
+
+ // set up the context to be used for calculating a, as this is
+ // used on both paths below
+ ___decContextDefault(&aset, DEC_INIT_DECIMAL64);
+ // accumulator bounds are as requested (could underflow)
+ aset.emax=set->emax; // usual bounds
+ aset.emin=set->emin; // ..
+ aset.clamp=0; // and no concrete format
+
+ // calculate the adjusted (Hull & Abrham) exponent (where the
+ // decimal point is just to the left of the coefficient msd)
+ h=rhs->exponent+rhs->digits;
+ // if h>8 then 10**h cannot be calculated safely; however, when
+ // h=8 then exp(|rhs|) will be at least exp(1E+7) which is at
+ // least 6.59E+4342944, so (due to the restriction on Emax/Emin)
+ // overflow (or underflow to 0) is guaranteed -- so this case can
+ // be handled by simply forcing the appropriate excess
+ if (h>8) { // overflow/underflow
+ // set up here so Power call below will over or underflow to
+ // zero; set accumulator to either 2 or 0.02
+ // [stack buffer for a is always big enough for this]
+ ___decNumberZero(a);
+ *a->lsu=2; // not 1 but < exp(1)
+ if (___decNumberIsNegative(rhs)) a->exponent=-2; // make 0.02
+ h=8; // clamp so 10**h computable
+ p=9; // set a working precision
+ } else { // h<=8
+ Int maxlever=(rhs->digits>8?1:0);
+ // [could/should increase this for precisions >40 or so, too]
+
+ // if h is 8, cannot normalize to a lower upper limit because
+ // the final result will not be computable (see notes above),
+ // but leverage can be applied whenever h is less than 8.
+ // Apply as much as possible, up to a MAXLEVER digits, which
+ // sets the tradeoff against the cost of the later a**(10**h).
+ // As h is increased, the working precision below also
+ // increases to compensate for the "constant digits at the
+ // front" effect.
+ Int lever=MIN(8-h, maxlever); // leverage attainable
+ Int use=-rhs->digits-lever; // exponent to use for RHS
+ h+=lever; // apply leverage selected
+ if (h<0) { // clamp
+ use+=h; // [may end up subnormal]
+ h=0;
+ }
+ // Take a copy of RHS if it needs normalization (true whenever x>=1)
+ if (rhs->exponent!=use) {
+ decNumber *newrhs=bufr; // assume will fit on stack
+ needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
+ if (needbytes>sizeof(bufr)) { // need malloc space
+ allocrhs=(decNumber *)malloc(needbytes);
+ if (allocrhs==NULL) { // hopeless -- abandon
+ *status|=DEC_Insufficient_storage;
+ break;
+ }
+ newrhs=allocrhs; // use the allocated space
+ }
+ ___decNumberCopy(newrhs, rhs); // copy to safe space
+ newrhs->exponent=use; // normalize; now <1
+ x=newrhs; // ready for use
+ // ___decNumberShow(x);
+ }
+
+ // Now use the usual power series to evaluate exp(x). The
+ // series starts as 1 + x + x^2/2 ... so prime ready for the
+ // third term by setting the term variable t=x, the accumulator
+ // a=1, and the divisor d=2.
+
+ // First determine the working precision. From Hull & Abrham
+ // this is set->digits+h+2. However, if x is 'over-precise' we
+ // need to allow for all its digits to potentially participate
+ // (consider an x where all the excess digits are 9s) so in
+ // this case use x->digits+h+2
+ p=MAX(x->digits, set->digits)+h+2;
+
+ // a and t are variable precision, and depend on p, so space
+ // must be allocated for them if necessary
+
+ // the accumulator needs to be able to hold 2p digits so that
+ // the additions on the second and subsequent iterations are
+ // sufficiently exact.
+ needbytes=sizeof(decNumber)+(D2U(p*2)-1)*sizeof(Unit);
+ if (needbytes>sizeof(bufa)) { // need malloc space
+ allocbufa=(decNumber *)malloc(needbytes);
+ if (allocbufa==NULL) { // hopeless -- abandon
+ *status|=DEC_Insufficient_storage;
+ break;
+ }
+ a=allocbufa; // use the allocated space
+ }
+ // the term needs to be able to hold p digits (which is
+ // guaranteed to be larger than x->digits, so the initial copy
+ // is safe); it may also be used for the raise-to-power
+ // calculation below, which needs an extra two digits
+ needbytes=sizeof(decNumber)+(D2U(p+2)-1)*sizeof(Unit);
+ if (needbytes>sizeof(buft)) { // need malloc space
+ allocbuft=(decNumber *)malloc(needbytes);
+ if (allocbuft==NULL) { // hopeless -- abandon
+ *status|=DEC_Insufficient_storage;
+ break;
+ }
+ t=allocbuft; // use the allocated space
+ }
+
+ ___decNumberCopy(t, x); // term=x
+ ___decNumberZero(a); *a->lsu=1; // accumulator=1
+ ___decNumberZero(d); *d->lsu=2; // divisor=2
+ ___decNumberZero(&numone); *numone.lsu=1; // constant 1 for increment
+
+ // set up the contexts for calculating a, t, and d
+ ___decContextDefault(&tset, DEC_INIT_DECIMAL64);
+ dset=tset;
+ // accumulator bounds are set above, set precision now
+ aset.digits=p*2; // double
+ // term bounds avoid any underflow or overflow
+ tset.digits=p;
+ tset.emin=DEC_MIN_EMIN; // [emax is plenty]
+ // [dset.digits=16, etc., are sufficient]
+
+ // finally ready to roll
+ for (;;) {
+ #if DECCHECK
+ iterations++;
+ #endif
+ // only the status from the accumulation is interesting
+ // [but it should remain unchanged after first add]
+ ___decAddOp(a, a, t, &aset, 0, status); // a=a+t
+ ___decMultiplyOp(t, t, x, &tset, &ignore); // t=t*x
+ ___decDivideOp(t, t, d, &tset, DIVIDE, &ignore); // t=t/d
+ // the iteration ends when the term cannot affect the result,
+ // if rounded to p digits, which is when its value is smaller
+ // than the accumulator by p+1 digits. There must also be
+ // full precision in a.
+ if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1))
+ && (a->digits>=p)) break;
+ ___decAddOp(d, d, &numone, &dset, 0, &ignore); // d=d+1
+ } // iterate
+
+ #if DECCHECK
+ // just a sanity check; comment out test to show always
+ if (iterations>p+3)
+ printf("Exp iterations=%d, status=%08x, p=%d, d=%d\n",
+ iterations, *status, p, x->digits);
+ #endif
+ } // h<=8
+
+ // apply postconditioning: a=a**(10**h) -- this is calculated
+ // at a slightly higher precision than Hull & Abrham suggest
+ if (h>0) {
+ Int seenbit=0; // set once a 1-bit is seen
+ Int i; // counter
+ Int n=__powers[h]; // always positive
+ aset.digits=p+2; // sufficient precision
+ // avoid the overhead and many extra digits of ___decNumberPower
+ // as all that is needed is the short 'multipliers' loop; here
+ // accumulate the answer into t
+ ___decNumberZero(t); *t->lsu=1; // acc=1
+ for (i=1;;i++){ // for each bit [top bit ignored]
+ // abandon if have had overflow or terminal underflow
+ if (*status & (DEC_Overflow|DEC_Underflow)) { // interesting?
+ if (*status&DEC_Overflow || ISZERO(t)) break;
+ }
+ n=n<<1; // move next bit to testable position
+ if (n<0) { // top bit is set
+ seenbit=1; // OK, have a significant bit
+ ___decMultiplyOp(t, t, a, &aset, status); // acc=acc*x
+ }
+ if (i==31) break; // that was the last bit
+ if (!seenbit) continue; // no need to square 1
+ ___decMultiplyOp(t, t, t, &aset, status); // acc=acc*acc [square]
+ } /*i*/ // 32 bits
+ // ___decNumberShow(t);
+ a=t; // and carry on using t instead of a
+ }
+
+ // Copy and round the result to res
+ residue=1; // indicate dirt to right ..
+ if (ISZERO(a)) residue=0; // .. unless underflowed to 0
+ aset.digits=set->digits; // [use default rounding]
+ ___decCopyFit(res, a, &aset, &residue, status); // copy & shorten
+ ___decFinish(res, set, &residue, status); // cleanup/set flags
+ } while(0); // end protected
+
+ if (allocrhs !=NULL) free(allocrhs); // drop any storage used
+ if (allocbufa!=NULL) free(allocbufa); // ..
+ if (allocbuft!=NULL) free(allocbuft); // ..
+ // [status is handled by caller]
+ return res;
+} /* ___decExpOp */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* Initial-estimate natural logarithm table */
+/* */
+/* LNnn -- 90-entry 16-bit table for values from .10 through .99. */
+/* The result is a 4-digit encode of the coefficient (c=the */
+/* top 14 bits encoding 0-9999) and a 2-digit encode of the */
+/* exponent (e=the bottom 2 bits encoding 0-3) */
+/* */
+/* The resulting value is given by: */
+/* */
+/* v = -c * 10**(-e-3) */
+/* */
+/* where e and c are extracted from entry k = LNnn[x-10] */
+/* where x is truncated (NB) into the range 10 through 99, */
+/* and then c = k>>2 and e = k&3. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208,
+ 6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312,
+ 5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032,
+ 39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
+ 29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
+ 22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
+ 15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
+ 10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801,
+ 5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
+ 10130, 6046, 20055};
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decLnOp -- effect natural logarithm */
+/* */
+/* This computes C = ln(A) */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context; note that rounding mode has no effect */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* Notable cases: */
+/* A<0 -> Invalid */
+/* A=0 -> -Infinity (Exact) */
+/* A=+Infinity -> +Infinity (Exact) */
+/* A=1 exactly -> 0 (Exact) */
+/* */
+/* Restrictions (as for Exp): */
+/* */
+/* digits, emax, and -emin in the context must be less than */
+/* DEC_MAX_MATH+11 (1000010), and the rhs must be within these */
+/* bounds or a zero. This is an internal routine, so these */
+/* restrictions are contractual and not enforced. */
+/* */
+/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */
+/* almost always be correctly rounded, but may be up to 1 ulp in */
+/* error in rare cases. */
+/* ------------------------------------------------------------------ */
+/* The result is calculated using Newton's method, with each */
+/* iteration calculating a' = a + x * exp(-a) - 1. See, for example, */
+/* Epperson 1989. */
+/* */
+/* The iteration ends when the adjustment x*exp(-a)-1 is tiny enough. */
+/* This has to be calculated at the sum of the precision of x and the */
+/* working precision. */
+/* */
+/* Implementation notes: */
+/* */
+/* 1. This is separated out as ___decLnOp so it can be called from */
+/* other Mathematical functions (e.g., Log 10) with a wider range */
+/* than normal. In particular, it can handle the slightly wider */
+/* (+9+2) range needed by a power function. */
+/* */
+/* 2. The speed of this function is about 10x slower than exp, as */
+/* it typically needs 4-6 iterations for short numbers, and the */
+/* extra precision needed adds a squaring effect, twice. */
+/* */
+/* 3. Fastpaths are included for ln(10) and ln(2), up to length 40, */
+/* as these are common requests. ln(10) is used by log10(x). */
+/* */
+/* 4. An iteration might be saved by widening the LNnn table, and */
+/* would certainly save at least one if it were made ten times */
+/* bigger, too (for truncated fractions 0.100 through 0.999). */
+/* However, for most practical evaluations, at least four or five */
+/* iterations will be neede -- so this would only speed up by */
+/* 20-25% and that probably does not justify increasing the table */
+/* size. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+decNumber * ___decLnOp(decNumber *res, const decNumber *rhs,
+ decContext *set, uInt *status) {
+ uInt ignore=0; // working status accumulator
+ uInt needbytes; // for space calculations
+ Int residue; // rounding residue
+ Int r; // rhs=f*10**r [see below]
+ Int p; // working precision
+ Int pp; // precision for iteration
+ Int t; // work
+
+ // buffers for a (accumulator, typically precision+2) and b
+ // (adjustment calculator, same size)
+ decNumber bufa[D2N(DECBUFFER+2)];
+ decNumber *allocbufa=NULL; // -> allocated bufa, iff allocated
+ decNumber *a=bufa; // accumulator/work
+ decNumber bufb[D2N(DECBUFFER+2)];
+ decNumber *allocbufb=NULL; // -> allocated bufa, iff allocated
+ decNumber *b=bufb; // adjustment/work
+
+ decNumber numone; // constant 1
+ decNumber cmp; // work
+ decContext aset, bset; // working contexts
+
+ #if DECCHECK
+ Int iterations=0; // for later sanity check
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ do { // protect allocated storage
+ if (SPECIALARG) { // handle infinities and NaNs
+ if (___decNumberIsInfinite(rhs)) { // an infinity
+ if (___decNumberIsNegative(rhs)) // -Infinity -> error
+ *status|=DEC_Invalid_operation;
+ else ___decNumberCopy(res, rhs); // +Infinity -> self
+ }
+ else ___decNaNs(res, rhs, NULL, status); // a NaN
+ break;}
+
+ if (ISZERO(rhs)) { // +/- zeros -> -Infinity
+ ___decNumberZero(res); // make clean
+ res->bits=DECINF|DECNEG; // set - infinity
+ break;} // [no status to set]
+
+ // Non-zero negatives are bad...
+ if (___decNumberIsNegative(rhs)) { // -x -> error
+ *status|=DEC_Invalid_operation;
+ break;}
+
+ // Here, rhs is positive, finite, and in range
+
+ // lookaside fastpath code for ln(2) and ln(10) at common lengths
+ if (rhs->exponent==0 && set->digits<=40) {
+ #if DECDPUN==1
+ if (rhs->lsu[0]==0 && rhs->lsu[1]==1 && rhs->digits==2) { // ln(10)
+ #else
+ if (rhs->lsu[0]==10 && rhs->digits==2) { // ln(10)
+ #endif
+ aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
+ #define LN10 "2.302585092994045684017991454684364207601"
+ ___decNumberFromString(res, LN10, &aset);
+ *status|=(DEC_Inexact | DEC_Rounded); // is inexact
+ break;}
+ if (rhs->lsu[0]==2 && rhs->digits==1) { // ln(2)
+ aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
+ #define LN2 "0.6931471805599453094172321214581765680755"
+ ___decNumberFromString(res, LN2, &aset);
+ *status|=(DEC_Inexact | DEC_Rounded);
+ break;}
+ } // integer and short
+
+ // Determine the working precision. This is normally the
+ // requested precision + 2, with a minimum of 9. However, if
+ // the rhs is 'over-precise' then allow for all its digits to
+ // potentially participate (consider an rhs where all the excess
+ // digits are 9s) so in this case use rhs->digits+2.
+ p=MAX(rhs->digits, MAX(set->digits, 7))+2;
+
+ // Allocate space for the accumulator and the high-precision
+ // adjustment calculator, if necessary. The accumulator must
+ // be able to hold p digits, and the adjustment up to
+ // rhs->digits+p digits. They are also made big enough for 16
+ // digits so that they can be used for calculating the initial
+ // estimate.
+ needbytes=sizeof(decNumber)+(D2U(MAX(p,16))-1)*sizeof(Unit);
+ if (needbytes>sizeof(bufa)) { // need malloc space
+ allocbufa=(decNumber *)malloc(needbytes);
+ if (allocbufa==NULL) { // hopeless -- abandon
+ *status|=DEC_Insufficient_storage;
+ break;}
+ a=allocbufa; // use the allocated space
+ }
+ pp=p+rhs->digits;
+ needbytes=sizeof(decNumber)+(D2U(MAX(pp,16))-1)*sizeof(Unit);
+ if (needbytes>sizeof(bufb)) { // need malloc space
+ allocbufb=(decNumber *)malloc(needbytes);
+ if (allocbufb==NULL) { // hopeless -- abandon
+ *status|=DEC_Insufficient_storage;
+ break;}
+ b=allocbufb; // use the allocated space
+ }
+
+ // Prepare an initial estimate in acc. Calculate this by
+ // considering the coefficient of x to be a normalized fraction,
+ // f, with the decimal point at far left and multiplied by
+ // 10**r. Then, rhs=f*10**r and 0.1<=f<1, and
+ // ln(x) = ln(f) + ln(10)*r
+ // Get the initial estimate for ln(f) from a small lookup
+ // table (see above) indexed by the first two digits of f,
+ // truncated.
+
+ ___decContextDefault(&aset, DEC_INIT_DECIMAL64); // 16-digit extended
+ r=rhs->exponent+rhs->digits; // 'normalised' exponent
+ ___decPutInt(a, r); // a=r
+ ___decPutInt(b, 2302585); // b=ln(10) (2.302585)
+ b->exponent=-6; // ..
+ ___decMultiplyOp(a, a, b, &aset, &ignore); // a=a*b
+ // now get top two digits of rhs into b by simple truncate and
+ // force to integer
+ residue=0; // (no residue)
+ aset.digits=2; aset.round=DEC_ROUND_DOWN;
+ ___decCopyFit(b, rhs, &aset, &residue, &ignore); // copy & shorten
+ b->exponent=0; // make integer
+ t=___decGetInt(b); // [cannot fail]
+ if (t<10) t=X10(t); // adjust single-digit b
+ t=LNnn[t-10]; // look up ln(b)
+ ___decPutInt(b, t>>2); // b=ln(b) coefficient
+ b->exponent=-(t&3)-3; // set exponent
+ b->bits=DECNEG; // ln(0.10)->ln(0.99) always -ve
+ aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; // restore
+ ___decAddOp(a, a, b, &aset, 0, &ignore); // acc=a+b
+ // the initial estimate is now in a, with up to 4 digits correct.
+ // When rhs is at or near Nmax the estimate will be low, so we
+ // will approach it from below, avoiding overflow when calling exp.
+
+ ___decNumberZero(&numone); *numone.lsu=1; // constant 1 for adjustment
+
+ // accumulator bounds are as requested (could underflow, but
+ // cannot overflow)
+ aset.emax=set->emax;
+ aset.emin=set->emin;
+ aset.clamp=0; // no concrete format
+ // set up a context to be used for the multiply and subtract
+ bset=aset;
+ bset.emax=DEC_MAX_MATH*2; // use double bounds for the
+ bset.emin=-DEC_MAX_MATH*2; // adjustment calculation
+ // [see ___decExpOp call below]
+ // for each iteration double the number of digits to calculate,
+ // up to a maximum of p
+ pp=9; // initial precision
+ // [initially 9 as then the sequence starts 7+2, 16+2, and
+ // 34+2, which is ideal for standard-sized numbers]
+ aset.digits=pp; // working context
+ bset.digits=pp+rhs->digits; // wider context
+ for (;;) { // iterate
+ #if DECCHECK
+ iterations++;
+ if (iterations>24) break; // consider 9 * 2**24
+ #endif
+ // calculate the adjustment (exp(-a)*x-1) into b. This is a
+ // catastrophic subtraction but it really is the difference
+ // from 1 that is of interest.
+ // Use the internal entry point to Exp as it allows the double
+ // range for calculating exp(-a) when a is the tiniest subnormal.
+ a->bits^=DECNEG; // make -a
+ ___decExpOp(b, a, &bset, &ignore); // b=exp(-a)
+ a->bits^=DECNEG; // restore sign of a
+ // now multiply by rhs and subtract 1, at the wider precision
+ ___decMultiplyOp(b, b, rhs, &bset, &ignore); // b=b*rhs
+ ___decAddOp(b, b, &numone, &bset, DECNEG, &ignore); // b=b-1
+
+ // the iteration ends when the adjustment cannot affect the
+ // result by >=0.5 ulp (at the requested digits), which
+ // is when its value is smaller than the accumulator by
+ // set->digits+1 digits (or it is zero) -- this is a looser
+ // requirement than for Exp because all that happens to the
+ // accumulator after this is the final rounding (but note that
+ // there must also be full precision in a, or a=0).
+
+ if (___decNumberIsZero(b) ||
+ (a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) {
+ if (a->digits==p) break;
+ if (___decNumberIsZero(a)) {
+ ___decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore); // rhs=1 ?
+ if (cmp.lsu[0]==0) a->exponent=0; // yes, exact 0
+ else *status|=(DEC_Inexact | DEC_Rounded); // no, inexact
+ break;
+ }
+ // force padding if adjustment has gone to 0 before full length
+ if (___decNumberIsZero(b)) b->exponent=a->exponent-p;
+ }
+
+ // not done yet ...
+ ___decAddOp(a, a, b, &aset, 0, &ignore); // a=a+b for next estimate
+ if (pp==p) continue; // precision is at maximum
+ // lengthen the next calculation
+ pp=pp*2; // double precision
+ if (pp>p) pp=p; // clamp to maximum
+ aset.digits=pp; // working context
+ bset.digits=pp+rhs->digits; // wider context
+ } // Newton's iteration
+
+ #if DECCHECK
+ // just a sanity check; remove the test to show always
+ if (iterations>24)
+ printf("Ln iterations=%d, status=%08x, p=%d, d=%d\n",
+ iterations, *status, p, rhs->digits);
+ #endif
+
+ // Copy and round the result to res
+ residue=1; // indicate dirt to right
+ if (ISZERO(a)) residue=0; // .. unless underflowed to 0
+ aset.digits=set->digits; // [use default rounding]
+ ___decCopyFit(res, a, &aset, &residue, status); // copy & shorten
+ ___decFinish(res, set, &residue, status); // cleanup/set flags
+ } while(0); // end protected
+
+ if (allocbufa!=NULL) free(allocbufa); // drop any storage used
+ if (allocbufb!=NULL) free(allocbufb); // ..
+ // [status is handled by caller]
+ return res;
+} /* ___decLnOp */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decQuantizeOp -- force exponent to requested value */
+/* */
+/* This computes C = op(A, B), where op adjusts the coefficient */
+/* of C (by rounding or shifting) such that the exponent (-scale) */
+/* of C has the value B or matches the exponent of B. */
+/* The numerical value of C will equal A, except for the effects of */
+/* any rounding that occurred. */
+/* */
+/* res is C, the result. C may be A or B */
+/* lhs is A, the number to adjust */
+/* rhs is B, the requested exponent */
+/* set is the context */
+/* quant is 1 for quantize or 0 for rescale */
+/* status is the status accumulator (this can be called without */
+/* risk of control loss) */
+/* */
+/* C must have space for set->digits digits. */
+/* */
+/* Unless there is an error or the result is infinite, the exponent */
+/* after the operation is guaranteed to be that requested. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static decNumber * ___decQuantizeOp(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set,
+ Flag quant, uInt *status) {
+ #if DECSUBSET
+ decNumber *alloclhs=NULL; // non-NULL if rounded lhs allocated
+ decNumber *allocrhs=NULL; // .., rhs
+ #endif
+ const decNumber *inrhs=rhs; // save original rhs
+ Int reqdigits=set->digits; // requested DIGITS
+ Int reqexp; // requested exponent [-scale]
+ Int residue=0; // rounding residue
+ Int etiny=set->emin-(reqdigits-1);
+
+ #if DECCHECK
+ if (___decCheckOperands(res, lhs, rhs, set)) return res;
+ #endif
+
+ do { // protect allocated storage
+ #if DECSUBSET
+ if (!set->extended) {
+ // reduce operands and set lostDigits status, as needed
+ if (lhs->digits>reqdigits) {
+ alloclhs=___decRoundOperand(lhs, set, status);
+ if (alloclhs==NULL) break;
+ lhs=alloclhs;
+ }
+ if (rhs->digits>reqdigits) { // [this only checks lostDigits]
+ allocrhs=___decRoundOperand(rhs, set, status);
+ if (allocrhs==NULL) break;
+ rhs=allocrhs;
+ }
+ }
+ #endif
+ // [following code does not require input rounding]
+
+ // Handle special values
+ if (SPECIALARGS) {
+ // NaNs get usual processing
+ if (SPECIALARGS & (DECSNAN | DECNAN))
+ ___decNaNs(res, lhs, rhs, status);
+ // one infinity but not both is bad
+ else if ((lhs->bits ^ rhs->bits) & DECINF)
+ *status|=DEC_Invalid_operation;
+ // both infinity: return lhs
+ else ___decNumberCopy(res, lhs); // [nop if in place]
+ break;
+ }
+
+ // set requested exponent
+ if (quant) reqexp=inrhs->exponent; // quantize -- match exponents
+ else { // rescale -- use value of rhs
+ // Original rhs must be an integer that fits and is in range,
+ // which could be from -1999999997 to +999999999, thanks to
+ // subnormals
+ reqexp=___decGetInt(inrhs); // [cannot fail]
+ }
+
+ #if DECSUBSET
+ if (!set->extended) etiny=set->emin; // no subnormals
+ #endif
+
+ if (reqexp==BADINT // bad (rescale only) or ..
+ || reqexp==BIGODD || reqexp==BIGEVEN // very big (ditto) or ..
+ || (reqexp<etiny) // < lowest
+ || (reqexp>set->emax)) { // > emax
+ *status|=DEC_Invalid_operation;
+ break;}
+
+ // the RHS has been processed, so it can be overwritten now if necessary
+ if (ISZERO(lhs)) { // zero coefficient unchanged
+ ___decNumberCopy(res, lhs); // [nop if in place]
+ res->exponent=reqexp; // .. just set exponent
+ #if DECSUBSET
+ if (!set->extended) res->bits=0; // subset specification; no -0
+ #endif
+ }
+ else { // non-zero lhs
+ Int adjust=reqexp-lhs->exponent; // digit adjustment needed
+ // if adjusted coefficient will definitely not fit, give up now
+ if ((lhs->digits-adjust)>reqdigits) {
+ *status|=DEC_Invalid_operation;
+ break;
+ }
+
+ if (adjust>0) { // increasing exponent
+ // this will decrease the length of the coefficient by adjust
+ // digits, and must round as it does so
+ decContext workset; // work
+ workset=*set; // clone rounding, etc.
+ workset.digits=lhs->digits-adjust; // set requested length
+ // [note that the latter can be <1, here]
+ ___decCopyFit(res, lhs, &workset, &residue, status); // fit to result
+ ___decApplyRound(res, &workset, residue, status); // .. and round
+ residue=0; // [used]
+ // If just rounded a 999s case, exponent will be off by one;
+ // adjust back (after checking space), if so.
+ if (res->exponent>reqexp) {
+ // re-check needed, e.g., for quantize(0.9999, 0.001) under
+ // set->digits==3
+ if (res->digits==reqdigits) { // cannot shift by 1
+ *status&=~(DEC_Inexact | DEC_Rounded); // [clean these]
+ *status|=DEC_Invalid_operation;
+ break;
+ }
+ res->digits=___decShiftToMost(res->lsu, res->digits, 1); // shift
+ res->exponent--; // (re)adjust the exponent.
+ }
+ #if DECSUBSET
+ if (ISZERO(res) && !set->extended) res->bits=0; // subset; no -0
+ #endif
+ } // increase
+ else /* adjust<=0 */ { // decreasing or = exponent
+ // this will increase the length of the coefficient by -adjust
+ // digits, by adding zero or more trailing zeros; this is
+ // already checked for fit, above
+ ___decNumberCopy(res, lhs); // [it will fit]
+ // if padding needed (adjust<0), add it now...
+ if (adjust<0) {
+ res->digits=___decShiftToMost(res->lsu, res->digits, -adjust);
+ res->exponent+=adjust; // adjust the exponent
+ }
+ } // decrease
+ } // non-zero
+
+ // Check for overflow [do not use Finalize in this case, as an
+ // overflow here is a "don't fit" situation]
+ if (res->exponent>set->emax-res->digits+1) { // too big
+ *status|=DEC_Invalid_operation;
+ break;
+ }
+ else {
+ ___decFinalize(res, set, &residue, status); // set subnormal flags
+ *status&=~DEC_Underflow; // suppress Underflow [754r]
+ }
+ } while(0); // end protected
+
+ #if DECSUBSET
+ if (allocrhs!=NULL) free(allocrhs); // drop any storage used
+ if (alloclhs!=NULL) free(alloclhs); // ..
+ #endif
+ return res;
+} /* ___decQuantizeOp */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decCompareOp -- compare, min, or max two Numbers */
+/* */
+/* This computes C = A ? B and carries out one of four operations: */
+/* COMPARE -- returns the signum (as a number) giving the */
+/* result of a comparison unless one or both */
+/* operands is a NaN (in which case a NaN results) */
+/* COMPMAX -- returns the larger of the operands, using the */
+/* 754r maxnum operation */
+/* COMPMIN -- the 754r minnum operation */
+/* COMTOTAL -- returns the signum (as a number) giving the */
+/* result of a comparison using 754r total ordering */
+/* */
+/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
+/* lhs is A */
+/* rhs is B */
+/* set is the context */
+/* op is the operation flag */
+/* status is the usual accumulator */
+/* */
+/* C must have space for one digit for COMPARE or set->digits for */
+/* COMPMAX and COMPMIN. */
+/* ------------------------------------------------------------------ */
+/* The emphasis here is on speed for common cases, and avoiding */
+/* coefficient comparison if possible. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+decNumber * ___decCompareOp(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set,
+ Flag op, uInt *status) {
+ #if DECSUBSET
+ decNumber *alloclhs=NULL; // non-NULL if rounded lhs allocated
+ decNumber *allocrhs=NULL; // .., rhs
+ #endif
+ Int result=0; // default result value
+ uByte merged; // work
+
+ #if DECCHECK
+ if (___decCheckOperands(res, lhs, rhs, set)) return res;
+ #endif
+
+ do { // protect allocated storage
+ #if DECSUBSET
+ if (!set->extended) {
+ // reduce operands and set lostDigits status, as needed
+ if (lhs->digits>set->digits) {
+ alloclhs=___decRoundOperand(lhs, set, status);
+ if (alloclhs==NULL) {result=BADINT; break;}
+ lhs=alloclhs;
+ }
+ if (rhs->digits>set->digits) {
+ allocrhs=___decRoundOperand(rhs, set, status);
+ if (allocrhs==NULL) {result=BADINT; break;}
+ rhs=allocrhs;
+ }
+ }
+ #endif
+ // [following code does not require input rounding]
+
+ // If total ordering then handle differing signs 'up front'
+ if (op == COMPTOTAL) { // total ordering
+ if (___decNumberIsNegative(lhs) & !___decNumberIsNegative(rhs)) {
+ result=-1;
+ break;
+ }
+ if (!___decNumberIsNegative(lhs) & ___decNumberIsNegative(rhs)) {
+ result=+1;
+ break;
+ }
+ }
+
+ // handle NaNs specially; let infinities drop through
+ // This assumes sNaN (even just one) leads to NaN.
+ merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
+ if (merged) { // a NaN bit set
+ if (op == COMPARE); // result will be NaN
+ else if (op == COMPTOTAL) { // total ordering, always finite
+ // signs are known to be the same; compute the ordering here
+ // as if the signs are both positive, then invert for negatives
+ if (!___decNumberIsNaN(lhs)) result=-1;
+ else if (!___decNumberIsNaN(rhs)) result=+1;
+ // here if both NaNs
+ else if (___decNumberIsSNaN(lhs) && ___decNumberIsQNaN(rhs)) result=-1;
+ else if (___decNumberIsQNaN(lhs) && ___decNumberIsSNaN(rhs)) result=+1;
+ else { // both NaN or both sNaN
+ // now it just depends on the payload
+ result=___decUnitCompare(lhs->lsu, D2U(lhs->digits),
+ rhs->lsu, D2U(rhs->digits), 0);
+ // [Error not possible, as these are 'aligned']
+ } // both same NaNs
+ if (___decNumberIsNegative(lhs)) result=-result;
+ break;
+ } // total order
+
+ else if (merged & DECSNAN); // sNaN -> qNaN
+ else { // here if MIN or MAX and one or two quiet NaNs
+ // min or max -- 754r rules ignore single NaN
+ if (!___decNumberIsNaN(lhs) || !___decNumberIsNaN(rhs)) {
+ // just one NaN; force choice to be the non-NaN operand
+ op=COMPMAX;
+ if (lhs->bits & DECNAN) result=-1; // pick rhs
+ else result=+1; // pick lhs
+ break;
+ }
+ } // max or min
+ op = COMPNAN; // use special path
+ ___decNaNs(res, lhs, rhs, status);
+ break;
+ }
+ result=___decCompare(lhs, rhs, 0); // have numbers
+ } while(0); // end protected
+
+ if (result==BADINT) *status|=DEC_Insufficient_storage; // rare
+ else {
+ if (op == COMPARE || op == COMPTOTAL) { // returning signum
+ if (op == COMPTOTAL && result==0) {
+ // operands are numerically equal or same NaN (and same sign,
+ // tested first); if identical, leave result 0
+ if (lhs->exponent!=rhs->exponent) {
+ if (lhs->exponent<rhs->exponent) result=-1;
+ else result=+1;
+ if (___decNumberIsNegative(lhs)) result=-result;
+ } // lexp!=rexp
+ } // total-order by exponent
+ ___decNumberZero(res); // [always a valid result]
+ if (result!=0) { // must be -1 or +1
+ *res->lsu=1;
+ if (result<0) res->bits=DECNEG;
+ }
+ }
+ else if (op == COMPNAN); // special, drop through
+ else { // MAX or MIN, non-NaN result
+ Int residue=0; // rounding accumulator
+ // choose the operand for the result
+ const decNumber *choice;
+ if (result==0) { // operands are numerically equal
+ // choose according to sign then exponent (see 754r)
+ uByte slhs=(lhs->bits & DECNEG);
+ uByte srhs=(rhs->bits & DECNEG);
+ #if DECSUBSET
+ if (!set->extended) { // subset: force left-hand
+ op=COMPMAX;
+ result=+1;
+ }
+ else
+ #endif
+ if (slhs!=srhs) { // signs differ
+ if (slhs) result=-1; // rhs is max
+ else result=+1; // lhs is max
+ }
+ else if (slhs && srhs) { // both negative
+ if (lhs->exponent<rhs->exponent) result=+1;
+ else result=-1;
+ // [if equal, use lhs, technically identical]
+ }
+ else { // both positive
+ if (lhs->exponent>rhs->exponent) result=+1;
+ else result=-1;
+ // [ditto]
+ }
+ } // numerically equal
+ // here result will be non-0
+ if (op == COMPMIN) result=-result;// reverse if looking for MIN
+ choice=(result>0 ? lhs : rhs); // choose
+ // copy chosen to result, rounding if need be
+ ___decCopyFit(res, choice, set, &residue, status);
+ ___decFinish(res, set, &residue, status);
+ }
+ }
+ #if DECSUBSET
+ if (allocrhs!=NULL) free(allocrhs); // free any storage used
+ if (alloclhs!=NULL) free(alloclhs); // ..
+ #endif
+ return res;
+} /* ___decCompareOp */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decCompare -- compare two decNumbers by numerical value */
+/* */
+/* This routine compares A ? B without altering them. */
+/* */
+/* Arg1 is A, a decNumber which is not a NaN */
+/* Arg2 is B, a decNumber which is not a NaN */
+/* Arg3 is 1 for a sign-independent compare, 0 otherwise */
+/* */
+/* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */
+/* (the only possible failure is an allocation error) */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+/*static Int ___decCompare(const decNumber *lhs, const decNumber *rhs, */
+Int ___decCompare(const decNumber *lhs, const decNumber *rhs,
+ Flag abs) {
+ Int result; // result value
+ Int sigr; // rhs signum
+ Int compare; // work
+
+ result=1; // assume signum(lhs)
+ if (ISZERO(lhs)) result=0;
+ if (abs) {
+ if (!ISZERO(rhs)) result=1; // not both 0
+ }
+ else { // signs matter
+ if (result && ___decNumberIsNegative(lhs)) result=-1;
+ sigr=1; // compute signum(rhs)
+ if (ISZERO(rhs)) sigr=0;
+ else if (___decNumberIsNegative(rhs)) sigr=-1;
+ if (result > sigr) return +1; // L > R, return 1
+ if (result < sigr) return -1; // R < L, return -1
+ }
+
+ // signums are the same
+ if (result==0) return 0; // both 0
+ // Both non-zero
+ if ((lhs->bits | rhs->bits) & DECINF) { // one or more infinities
+ if (___decNumberIsInfinite(rhs)) {
+ if (___decNumberIsInfinite(lhs)) result=0;// both infinite
+ else result=-result; // only rhs infinite
+ }
+ return result;
+ }
+
+ // must compare the coefficients, allowing for exponents
+ if (lhs->exponent>rhs->exponent) { // LHS exponent larger
+ // swap sides, and sign
+ const decNumber *temp=lhs;
+ lhs=rhs;
+ rhs=temp;
+ result=-result;
+ }
+
+ compare=___decUnitCompare(lhs->lsu, D2U(lhs->digits),
+ rhs->lsu, D2U(rhs->digits),
+ rhs->exponent-lhs->exponent);
+
+ if (compare!=BADINT) compare*=result; // comparison succeeded
+ return compare;
+} /* ___decCompare */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decUnitCompare -- compare two >=0 integers in Unit arrays */
+/* */
+/* This routine compares A ? B*10**E where A and B are unit arrays */
+/* A is a plain integer */
+/* B has an exponent of E (which must be non-negative) */
+/* */
+/* Arg1 is A first Unit (lsu) */
+/* Arg2 is A length in Units */
+/* Arg3 is B first Unit (lsu) */
+/* Arg4 is B length in Units */
+/* Arg5 is E (0 if the units are aligned) */
+/* */
+/* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */
+/* (the only possible failure is an allocation error, which can */
+/* only occur if E!=0) */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Int ___decUnitCompare(const Unit *a, Int alength,
+ const Unit *b, Int blength, Int exp) {
+ Unit *acc; // accumulator for result
+ Unit accbuff[SD2U(DECBUFFER+1)];// local buffer
+ Unit *allocacc=NULL; // -> allocated acc buffer, iff allocated
+ Int accunits, need; // units in use or needed for acc
+ const Unit *l, *r, *u; // work
+ Int expunits, exprem, result; // ..
+
+ if (exp==0) { // aligned; fastpath
+ if (alength>blength) return 1;
+ if (alength<blength) return -1;
+ // same number of units in both -- need unit-by-unit compare
+ l=a+alength-1;
+ r=b+alength-1;
+ for (;l>=a; l--, r--) {
+ if (*l>*r) return 1;
+ if (*l<*r) return -1;
+ }
+ return 0; // all units match
+ } // aligned
+
+ // Unaligned. If one is >1 unit longer than the other, padded
+ // approximately, then can return easily
+ if (alength>blength+(Int)D2U(exp)) return 1;
+ if (alength+1<blength+(Int)D2U(exp)) return -1;
+
+ // Need to do a real subtract. For this, a result buffer is needed
+ // even though only the sign is of interest. Its length needs
+ // to be the larger of alength and padded blength, +2
+ need=blength+D2U(exp); // maximum real length of B
+ if (need<alength) need=alength;
+ need+=2;
+ acc=accbuff; // assume use local buffer
+ if (need*sizeof(Unit)>sizeof(accbuff)) {
+ allocacc=(Unit *)malloc(need*sizeof(Unit));
+ if (allocacc==NULL) return BADINT; // hopeless -- abandon
+ acc=allocacc;
+ }
+ // Calculate units and remainder from exponent.
+ expunits=exp/DECDPUN;
+ exprem=exp%DECDPUN;
+ // subtract [A+B*(-m)]
+ accunits=___decUnitAddSub(a, alength, b, blength, expunits, acc,
+ -(Int)__powers[exprem]);
+ // [UnitAddSub result may have leading zeros, even on zero]
+ if (accunits<0) result=-1; // negative result
+ else { // non-negative result
+ // check units of the result before freeing any storage
+ for (u=acc; u<acc+accunits-1 && *u==0;) u++;
+ result=(*u==0 ? 0 : +1);
+ }
+ // clean up and return the result
+ if (allocacc!=NULL) free(allocacc); // drop any storage used
+ return result;
+} /* ___decUnitCompare */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decUnitAddSub -- add or subtract two >=0 integers in Unit arrays */
+/* */
+/* This routine performs the calculation: */
+/* */
+/* C=A+(B*M) */
+/* */
+/* Where M is in the range -DECDPUNMAX through +DECDPUNMAX. */
+/* */
+/* A may be shorter or longer than B. */
+/* */
+/* Leading zeros are not removed after a calculation. The result is */
+/* either the same length as the longer of A and B (adding any */
+/* shift), or one Unit longer than that (if a Unit carry occurred). */
+/* */
+/* A and B content are not altered unless C is also A or B. */
+/* C may be the same array as A or B, but only if no zero padding is */
+/* requested (that is, C may be B only if bshift==0). */
+/* C is filled from the lsu; only those units necessary to complete */
+/* the calculation are referenced. */
+/* */
+/* Arg1 is A first Unit (lsu) */
+/* Arg2 is A length in Units */
+/* Arg3 is B first Unit (lsu) */
+/* Arg4 is B length in Units */
+/* Arg5 is B shift in Units (>=0; pads with 0 units if positive) */
+/* Arg6 is C first Unit (lsu) */
+/* Arg7 is M, the multiplier */
+/* */
+/* returns the count of Units written to C, which will be non-zero */
+/* and negated if the result is negative. That is, the sign of the */
+/* returned Int is the sign of the result (positive for zero) and */
+/* the absolute value of the Int is the count of Units. */
+/* */
+/* It is the caller's responsibility to make sure that C size is */
+/* safe, allowing space if necessary for a one-Unit carry. */
+/* */
+/* This routine is severely performance-critical; *any* change here */
+/* must be measured (timed) to assure no performance degradation. */
+/* In particular, trickery here tends to be counter-productive, as */
+/* increased complexity of code hurts register optimizations on */
+/* register-poor architectures. Avoiding divisions is nearly */
+/* always a Good Idea, however. */
+/* */
+/* Special thanks to Rick McGuire (IBM Cambridge, MA) and Dave Clark */
+/* (IBM Warwick, UK) for some of the ideas used in this routine. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Int ___decUnitAddSub(const Unit *a, Int alength,
+ const Unit *b, Int blength, Int bshift,
+ Unit *c, Int m) {
+ const Unit *alsu=a; // A lsu [need to remember it]
+ Unit *clsu=c; // C ditto
+ Unit *minC; // low water mark for C
+ Unit *maxC; // high water mark for C
+ eInt carry=0; // carry integer (could be Long)
+ Int add; // work
+ #if DECDPUN<=4 // myriadal, millenary, etc.
+ Int est; // estimated quotient
+ #endif
+
+ #if DECTRACE
+ if (alength<1 || blength<1)
+ printf("___decUnitAddSub: alen blen m %d %d [%d]\n", alength, blength, m);
+ #endif
+
+ maxC=c+alength; // A is usually the longer
+ minC=c+blength; // .. and B the shorter
+ if (bshift!=0) { // B is shifted; low As copy across
+ minC+=bshift;
+ // if in place [common], skip copy unless there's a gap [rare]
+ if (a==c && bshift<=alength) {
+ c+=bshift;
+ a+=bshift;
+ }
+ else for (; c<clsu+bshift; a++, c++) { // copy needed
+ if (a<alsu+alength) *c=*a;
+ else *c=0;
+ }
+ }
+ if (minC>maxC) { // swap
+ Unit *hold=minC;
+ minC=maxC;
+ maxC=hold;
+ }
+
+ // For speed, do the addition as two loops; the first where both A
+ // and B contribute, and the second (if necessary) where only one or
+ // other of the numbers contribute.
+ // Carry handling is the same (i.e., duplicated) in each case.
+ for (; c<minC; c++) {
+ carry+=*a;
+ a++;
+ carry+=((eInt)*b)*m; // [special-casing m=1/-1
+ b++; // here is not a win]
+ // here carry is new Unit of digits; it could be +ve or -ve
+ if ((ueInt)carry<=DECDPUNMAX) { // fastpath 0-DECDPUNMAX
+ *c=(Unit)carry;
+ carry=0;
+ continue;
+ }
+ #if DECDPUN==4 // use divide-by-multiply
+ if (carry>=0) {
+ est=(((ueInt)carry>>11)*53687)>>18;
+ *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
+ carry=est; // likely quotient [89%]
+ if (*c<DECDPUNMAX+1) continue; // estimate was correct
+ carry++;
+ *c-=DECDPUNMAX+1;
+ continue;
+ }
+ // negative case
+ carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
+ est=(((ueInt)carry>>11)*53687)>>18;
+ *c=(Unit)(carry-est*(DECDPUNMAX+1));
+ carry=est-(DECDPUNMAX+1); // correctly negative
+ if (*c<DECDPUNMAX+1) continue; // was OK
+ carry++;
+ *c-=DECDPUNMAX+1;
+ #elif DECDPUN==3
+ if (carry>=0) {
+ est=(((ueInt)carry>>3)*16777)>>21;
+ *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
+ carry=est; // likely quotient [99%]
+ if (*c<DECDPUNMAX+1) continue; // estimate was correct
+ carry++;
+ *c-=DECDPUNMAX+1;
+ continue;
+ }
+ // negative case
+ carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
+ est=(((ueInt)carry>>3)*16777)>>21;
+ *c=(Unit)(carry-est*(DECDPUNMAX+1));
+ carry=est-(DECDPUNMAX+1); // correctly negative
+ if (*c<DECDPUNMAX+1) continue; // was OK
+ carry++;
+ *c-=DECDPUNMAX+1;
+ #elif DECDPUN<=2
+ // Can use QUOT10 as carry <= 4 digits
+ if (carry>=0) {
+ est=QUOT10(carry, DECDPUN);
+ *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
+ carry=est; // quotient
+ continue;
+ }
+ // negative case
+ carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
+ est=QUOT10(carry, DECDPUN);
+ *c=(Unit)(carry-est*(DECDPUNMAX+1));
+ carry=est-(DECDPUNMAX+1); // correctly negative
+ #else
+ // remainder operator is undefined if negative, so must test
+ if ((ueInt)carry<(DECDPUNMAX+1)*2) { // fastpath carry +1
+ *c=(Unit)(carry-(DECDPUNMAX+1)); // [helps additions]
+ carry=1;
+ continue;
+ }
+ if (carry>=0) {
+ *c=(Unit)(carry%(DECDPUNMAX+1));
+ carry=carry/(DECDPUNMAX+1);
+ continue;
+ }
+ // negative case
+ carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
+ *c=(Unit)(carry%(DECDPUNMAX+1));
+ carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
+ #endif
+ } // c
+
+ // now may have one or other to complete
+ // [pretest to avoid loop setup/shutdown]
+ if (c<maxC) for (; c<maxC; c++) {
+ if (a<alsu+alength) { // still in A
+ carry+=*a;
+ a++;
+ }
+ else { // inside B
+ carry+=((eInt)*b)*m;
+ b++;
+ }
+ // here carry is new Unit of digits; it could be +ve or -ve and
+ // magnitude up to DECDPUNMAX squared
+ if ((ueInt)carry<=DECDPUNMAX) { // fastpath 0-DECDPUNMAX
+ *c=(Unit)carry;
+ carry=0;
+ continue;
+ }
+ // result for this unit is negative or >DECDPUNMAX
+ #if DECDPUN==4 // use divide-by-multiply
+ if (carry>=0) {
+ est=(((ueInt)carry>>11)*53687)>>18;
+ *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
+ carry=est; // likely quotient [79.7%]
+ if (*c<DECDPUNMAX+1) continue; // estimate was correct
+ carry++;
+ *c-=DECDPUNMAX+1;
+ continue;
+ }
+ // negative case
+ carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
+ est=(((ueInt)carry>>11)*53687)>>18;
+ *c=(Unit)(carry-est*(DECDPUNMAX+1));
+ carry=est-(DECDPUNMAX+1); // correctly negative
+ if (*c<DECDPUNMAX+1) continue; // was OK
+ carry++;
+ *c-=DECDPUNMAX+1;
+ #elif DECDPUN==3
+ if (carry>=0) {
+ est=(((ueInt)carry>>3)*16777)>>21;
+ *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
+ carry=est; // likely quotient [99%]
+ if (*c<DECDPUNMAX+1) continue; // estimate was correct
+ carry++;
+ *c-=DECDPUNMAX+1;
+ continue;
+ }
+ // negative case
+ carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
+ est=(((ueInt)carry>>3)*16777)>>21;
+ *c=(Unit)(carry-est*(DECDPUNMAX+1));
+ carry=est-(DECDPUNMAX+1); // correctly negative
+ if (*c<DECDPUNMAX+1) continue; // was OK
+ carry++;
+ *c-=DECDPUNMAX+1;
+ #elif DECDPUN<=2
+ if (carry>=0) {
+ est=QUOT10(carry, DECDPUN);
+ *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
+ carry=est; // quotient
+ continue;
+ }
+ // negative case
+ carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
+ est=QUOT10(carry, DECDPUN);
+ *c=(Unit)(carry-est*(DECDPUNMAX+1));
+ carry=est-(DECDPUNMAX+1); // correctly negative
+ #else
+ if ((ueInt)carry<(DECDPUNMAX+1)*2){ // fastpath carry 1
+ *c=(Unit)(carry-(DECDPUNMAX+1));
+ carry=1;
+ continue;
+ }
+ // remainder operator is undefined if negative, so must test
+ if (carry>=0) {
+ *c=(Unit)(carry%(DECDPUNMAX+1));
+ carry=carry/(DECDPUNMAX+1);
+ continue;
+ }
+ // negative case
+ carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
+ *c=(Unit)(carry%(DECDPUNMAX+1));
+ carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
+ #endif
+ } // c
+
+ // OK, all A and B processed; might still have carry or borrow
+ // return number of Units in the result, negated if a borrow
+ if (carry==0) return c-clsu; // no carry, so no more to do
+ if (carry>0) { // positive carry
+ *c=(Unit)carry; // place as new unit
+ c++; // ..
+ return c-clsu;
+ }
+ // -ve carry: it's a borrow; complement needed
+ add=1; // temporary carry...
+ for (c=clsu; c<maxC; c++) {
+ add=DECDPUNMAX+add-*c;
+ if (add<=DECDPUNMAX) {
+ *c=(Unit)add;
+ add=0;
+ }
+ else {
+ *c=0;
+ add=1;
+ }
+ }
+ // add an extra unit iff it would be non-zero
+ #if DECTRACE
+ printf("UAS borrow: add %d, carry %d\n", add, carry);
+ #endif
+ if ((add-carry-1)!=0) {
+ *c=(Unit)(add-carry-1);
+ c++; // interesting, include it
+ }
+ return clsu-c; // -ve result indicates borrowed
+} /* ___decUnitAddSub */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decTrim -- trim trailing zeros or normalize */
+/* */
+/* dn is the number to trim or normalize */
+/* all is 1 to remove all trailing zeros, 0 for just fraction ones */
+/* dropped returns the number of discarded trailing zeros */
+/* returns dn */
+/* */
+/* All fields are updated as required. This is a utility operation, */
+/* so special values are unchanged and no error is possible. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static decNumber * ___decTrim(decNumber *dn, Flag all, Int *dropped) {
+ Int d, exp; // work
+ uInt cut; // ..
+ Unit *up; // -> current Unit
+
+ #if DECCHECK
+ if (___decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNUSED)) return dn;
+ #endif
+
+ *dropped=0; // assume no zeros dropped
+ if ((dn->bits & DECSPECIAL) // fast exit if special ..
+ || (*dn->lsu & 0x01)) return dn; // .. or odd
+ if (ISZERO(dn)) { // .. or 0
+ dn->exponent=0; // (sign is preserved)
+ return dn;
+ }
+
+ // have a finite number which is even
+ exp=dn->exponent;
+ cut=1; // digit (1-DECDPUN) in Unit
+ up=dn->lsu; // -> current Unit
+ for (d=0; d<dn->digits-1; d++) { // [don't strip the final digit]
+ // slice by powers
+ #if DECDPUN<=4
+ uInt quot=QUOT10(*up, cut);
+ if ((*up-quot*__powers[cut])!=0) break; // found non-0 digit
+ #else
+ if (*up%__powers[cut]!=0) break; // found non-0 digit
+ #endif
+ // have a trailing 0
+ if (!all) { // trimming
+ // [if exp>0 then all trailing 0s are significant for trim]
+ if (exp<=0) { // if digit might be significant
+ if (exp==0) break; // then quit
+ exp++; // next digit might be significant
+ }
+ }
+ cut++; // next power
+ if (cut>DECDPUN) { // need new Unit
+ up++;
+ cut=1;
+ }
+ } // d
+ if (d==0) return dn; // none dropped
+
+ // effect the drop
+ ___decShiftToLeast(dn->lsu, D2U(dn->digits), d);
+ dn->exponent+=d; // maintain numerical value
+ dn->digits-=d; // new length
+ *dropped=d; // report the count
+ return dn;
+} /* ___decTrim */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decShiftToMost -- shift digits in array towards most significant */
+/* */
+/* uar is the array */
+/* digits is the count of digits in use in the array */
+/* shift is the number of zeros to pad with (least significant); */
+/* it must be zero or positive */
+/* */
+/* returns the new length of the integer in the array, in digits */
+/* */
+/* No overflow is permitted (that is, the uar array must be known to */
+/* be large enough to hold the result, after shifting). */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Int ___decShiftToMost(Unit *uar, Int digits, Int shift) {
+ Unit *target, *source, *first; // work
+ Int cut; // odd 0's to add
+ uInt next; // work
+
+ if (shift==0) return digits; // [fastpath] nothing to do
+ if ((digits+shift)<=DECDPUN) { // [fastpath] single-unit case
+ *uar=(Unit)(*uar*__powers[shift]);
+ return digits+shift;
+ }
+
+ next=0; // all paths
+ source=uar+D2U(digits)-1; // where msu comes from
+ target=source+D2U(shift); // where upper part of first cut goes
+ cut=DECDPUN-MSUDIGITS(shift); // where to slice
+ if (cut==0) { // unit-boundary case
+ for (; source>=uar; source--, target--) *target=*source;
+ }
+ else {
+ first=uar+D2U(digits+shift)-1; // where msu of source will end up
+ for (; source>=uar; source--, target--) {
+ // split the source Unit and accumulate remainder for next
+ #if DECDPUN<=4
+ uInt quot=QUOT10(*source, cut);
+ uInt rem=*source-quot*__powers[cut];
+ next+=quot;
+ #else
+ uInt rem=*source%__powers[cut];
+ next+=*source/__powers[cut];
+ #endif
+ if (target<=first) *target=(Unit)next; // write to target iff valid
+ next=rem*__powers[DECDPUN-cut]; // save remainder for next Unit
+ }
+ } // shift-move
+
+ // propagate any partial unit to one below and clear the rest
+ for (; target>=uar; target--) {
+ *target=(Unit)next;
+ next=0;
+ }
+ return digits+shift;
+} /* ___decShiftToMost */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decShiftToLeast -- shift digits in array towards least significant */
+/* */
+/* uar is the array */
+/* units is length of the array, in units */
+/* shift is the number of digits to remove from the lsu end; it */
+/* must be zero or positive and less than units*DECDPUN. */
+/* */
+/* returns the new length of the integer in the array, in units */
+/* */
+/* Removed digits are discarded (lost). Units not required to hold */
+/* the final result are unchanged. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Int ___decShiftToLeast(Unit *uar, Int units, Int shift) {
+ Unit *target, *up; // work
+ Int cut, count; // work
+ Int quot, rem; // for division
+
+ if (shift==0) return units; // [fastpath] nothing to do
+
+ target=uar; // both paths
+ cut=MSUDIGITS(shift);
+ if (cut==DECDPUN) { // unit-boundary case; easy
+ up=uar+D2U(shift);
+ for (; up<uar+units; target++, up++) *target=*up;
+ return target-uar;
+ }
+
+ // messier
+ up=uar+D2U(shift-cut); // source; correct to whole Units
+ count=units*DECDPUN-shift; // the maximum new length
+ #if DECDPUN<=4
+ quot=QUOT10(*up, cut);
+ #else
+ quot=*up/__powers[cut];
+ #endif
+ for (; ; target++) {
+ *target=(Unit)quot;
+ count-=(DECDPUN-cut);
+ if (count<=0) break;
+ up++;
+ quot=*up;
+ #if DECDPUN<=4
+ quot=QUOT10(quot, cut);
+ rem=*up-quot*__powers[cut];
+ #else
+ rem=quot%__powers[cut];
+ quot=quot/__powers[cut];
+ #endif
+ *target=(Unit)(*target+rem*__powers[DECDPUN-cut]);
+ count-=cut;
+ if (count<=0) break;
+ }
+ return target-uar+1;
+} /* ___decShiftToLeast */
+#endif /* NOT_IN_libc */
+
+#if DECSUBSET
+/* ------------------------------------------------------------------ */
+/* ___decRoundOperand -- round an operand [used for subset only] */
+/* */
+/* dn is the number to round (dn->digits is > set->digits) */
+/* set is the relevant context */
+/* status is the status accumulator */
+/* */
+/* returns an allocated decNumber with the rounded result. */
+/* */
+/* lostDigits and other status may be set by this. */
+/* */
+/* Since the input is an operand, it must not be modified. */
+/* Instead, return an allocated decNumber, rounded as required. */
+/* It is the caller's responsibility to free the allocated storage. */
+/* */
+/* If no storage is available then the result cannot be used, so NULL */
+/* is returned. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static decNumber *___decRoundOperand(const decNumber *dn, decContext *set,
+ uInt *status) {
+ decNumber *res; // result structure
+ uInt newstatus=0; // status from round
+ Int residue=0; // rounding accumulator
+
+ // Allocate storage for the returned decNumber, big enough for the
+ // length specified by the context
+ res=(decNumber *)malloc(sizeof(decNumber)
+ +(D2U(set->digits)-1)*sizeof(Unit));
+ if (res==NULL) {
+ *status|=DEC_Insufficient_storage;
+ return NULL;
+ }
+ ___decCopyFit(res, dn, set, &residue, &newstatus);
+ ___decApplyRound(res, set, residue, &newstatus);
+
+ // If that set Inexact then "lost digits" is raised...
+ if (newstatus & DEC_Inexact) newstatus|=DEC_Lost_digits;
+ *status|=newstatus;
+ return res;
+} /* ___decRoundOperand */
+#endif /* NOT_IN_libc */
+#endif /* DECSUBSET */
+
+/* ------------------------------------------------------------------ */
+/* ___decCopyFit -- copy a number, truncating the coefficient if needed */
+/* */
+/* dest is the target decNumber */
+/* src is the source decNumber */
+/* set is the context [used for length (digits) and rounding mode] */
+/* residue is the residue accumulator */
+/* status contains the current status to be updated */
+/* */
+/* (dest==src is allowed and will be a no-op if fits) */
+/* All fields are updated as required. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static void ___decCopyFit(decNumber *dest, const decNumber *src,
+ decContext *set, Int *residue, uInt *status) {
+ dest->bits=src->bits;
+ dest->exponent=src->exponent;
+ ___decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
+} /* ___decCopyFit */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decSetCoeff -- set the coefficient of a number */
+/* */
+/* dn is the number whose coefficient array is to be set. */
+/* It must have space for set->digits digits */
+/* set is the context [for size] */
+/* lsu -> lsu of the source coefficient [may be dn->lsu] */
+/* len is digits in the source coefficient [may be dn->digits] */
+/* residue is the residue accumulator. This has values as in */
+/* ___decApplyRound, and will be unchanged unless the */
+/* target size is less than len. In this case, the */
+/* coefficient is truncated and the residue is updated to */
+/* reflect the previous residue and the dropped digits. */
+/* status is the status accumulator, as usual */
+/* */
+/* The coefficient may already be in the number, or it can be an */
+/* external intermediate array. If it is in the number, lsu must == */
+/* dn->lsu and len must == dn->digits. */
+/* */
+/* Note that the coefficient length (len) may be < set->digits, and */
+/* in this case this merely copies the coefficient (or is a no-op */
+/* if dn->lsu==lsu). */
+/* */
+/* Note also that (only internally, from ___decQuantizeOp and */
+/* ___decSetSubnormal) the value of set->digits may be less than one, */
+/* indicating a round to left. This routine handles that case */
+/* correctly; caller ensures space. */
+/* */
+/* dn->digits, dn->lsu (and as required), and dn->exponent are */
+/* updated as necessary. dn->bits (sign) is unchanged. */
+/* */
+/* DEC_Rounded status is set if any digits are discarded. */
+/* DEC_Inexact status is set if any non-zero digits are discarded, or */
+/* incoming residue was non-0 (implies rounded) */
+/* ------------------------------------------------------------------ */
+// mapping array: maps 0-9 to canonical residues, so that a residue
+// can be adjusted in the range [-1, +1] and achieve correct rounding
+// 0 1 2 3 4 5 6 7 8 9
+#if defined NOT_IN_libc /* Not needed in libc. */
+static const uByte resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7};
+/*static void ___decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, */
+void ___decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu,
+ Int len, Int *residue, uInt *status) {
+ Int discard; // number of digits to discard
+ uInt cut; // cut point in Unit
+ const Unit *up; // work
+ Unit *target; // ..
+ Int count; // ..
+ #if DECDPUN<=4
+ uInt temp; // ..
+ #endif
+
+ discard=len-set->digits; // digits to discard
+ if (discard<=0) { // no digits are being discarded
+ if (dn->lsu!=lsu) { // copy needed
+ // copy the coefficient array to the result number; no shift needed
+ count=len; // avoids D2U
+ up=lsu;
+ for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
+ *target=*up;
+ dn->digits=len; // set the new length
+ }
+ // dn->exponent and residue are unchanged, record any inexactitude
+ if (*residue!=0) *status|=(DEC_Inexact | DEC_Rounded);
+ return;
+ }
+
+ // some digits must be discarded ...
+ dn->exponent+=discard; // maintain numerical value
+ *status|=DEC_Rounded; // accumulate Rounded status
+ if (*residue>1) *residue=1; // previous residue now to right, so reduce
+
+ if (discard>len) { // everything, +1, is being discarded
+ // guard digit is 0
+ // residue is all the number [NB could be all 0s]
+ if (*residue<=0) { // not already positive
+ count=len; // avoids D2U
+ for (up=lsu; count>0; up++, count-=DECDPUN) if (*up!=0) { // found non-0
+ *residue=1;
+ break; // no need to check any others
+ }
+ }
+ if (*residue!=0) *status|=DEC_Inexact; // record inexactitude
+ *dn->lsu=0; // coefficient will now be 0
+ dn->digits=1; // ..
+ return;
+ } // total discard
+
+ // partial discard [most common case]
+ // here, at least the first (most significant) discarded digit exists
+
+ // spin up the number, noting residue during the spin, until get to
+ // the Unit with the first discarded digit. When reach it, extract
+ // it and remember its position
+ count=0;
+ for (up=lsu;; up++) {
+ count+=DECDPUN;
+ if (count>=discard) break; // full ones all checked
+ if (*up!=0) *residue=1;
+ } // up
+
+ // here up -> Unit with first discarded digit
+ cut=discard-(count-DECDPUN)-1;
+ if (cut==DECDPUN-1) { // unit-boundary case (fast)
+ Unit half=(Unit)__powers[DECDPUN]>>1;
+ // set residue directly
+ if (*up>=half) {
+ if (*up>half) *residue=7;
+ else *residue+=5; // add sticky bit
+ }
+ else { // <half
+ if (*up!=0) *residue=3; // [else is 0, leave as sticky bit]
+ }
+ if (set->digits<=0) { // special for Quantize/Subnormal :-(
+ *dn->lsu=0; // .. result is 0
+ dn->digits=1; // ..
+ }
+ else { // shift to least
+ count=set->digits; // now digits to end up with
+ dn->digits=count; // set the new length
+ up++; // move to next
+ // on unit boundary, so shift-down copy loop is simple
+ for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
+ *target=*up;
+ }
+ } // unit-boundary case
+
+ else { // discard digit is in low digit(s), and not top digit
+ uInt discard1; // first discarded digit
+ uInt quot, rem; // for divisions
+ if (cut==0) quot=*up; // is at bottom of unit
+ else /* cut>0 */ { // it's not at bottom of unit
+ #if DECDPUN<=4
+ quot=QUOT10(*up, cut);
+ rem=*up-quot*__powers[cut];
+ #else
+ rem=*up%__powers[cut];
+ quot=*up/__powers[cut];
+ #endif
+ if (rem!=0) *residue=1;
+ }
+ // discard digit is now at bottom of quot
+ #if DECDPUN<=4
+ temp=(quot*6554)>>16; // fast /10
+ // Vowels algorithm here not a win (9 instructions)
+ discard1=quot-X10(temp);
+ quot=temp;
+ #else
+ discard1=quot%10;
+ quot=quot/10;
+ #endif
+ // here, discard1 is the guard digit, and residue is everything
+ // else [use mapping array to accumulate residue safely]
+ *residue+=resmap[discard1];
+ cut++; // update cut
+ // here: up -> Unit of the array with bottom digit
+ // cut is the division point for each Unit
+ // quot holds the uncut high-order digits for the current unit
+ if (set->digits<=0) { // special for Quantize/Subnormal :-(
+ *dn->lsu=0; // .. result is 0
+ dn->digits=1; // ..
+ }
+ else { // shift to least needed
+ count=set->digits; // now digits to end up with
+ dn->digits=count; // set the new length
+ // shift-copy the coefficient array to the result number
+ for (target=dn->lsu; ; target++) {
+ *target=(Unit)quot;
+ count-=(DECDPUN-cut);
+ if (count<=0) break;
+ up++;
+ quot=*up;
+ #if DECDPUN<=4
+ quot=QUOT10(quot, cut);
+ rem=*up-quot*__powers[cut];
+ #else
+ rem=quot%__powers[cut];
+ quot=quot/__powers[cut];
+ #endif
+ *target=(Unit)(*target+rem*__powers[DECDPUN-cut]);
+ count-=cut;
+ if (count<=0) break;
+ } // shift-copy loop
+ } // shift to least
+ } // not unit boundary
+
+ if (*residue!=0) *status|=DEC_Inexact; // record inexactitude
+ return;
+} /* ___decSetCoeff */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decApplyRound -- apply pending rounding to a number */
+/* */
+/* dn is the number, with space for set->digits digits */
+/* set is the context [for size and rounding mode] */
+/* residue indicates pending rounding, being any accumulated */
+/* guard and sticky information. It may be: */
+/* 6-9: rounding digit is >5 */
+/* 5: rounding digit is exactly half-way */
+/* 1-4: rounding digit is <5 and >0 */
+/* 0: the coefficient is exact */
+/* -1: as 1, but the hidden digits are subtractive, that */
+/* is, of the opposite sign to dn. In this case the */
+/* coefficient must be non-0. */
+/* status is the status accumulator, as usual */
+/* */
+/* This routine applies rounding while keeping the length of the */
+/* coefficient constant. The exponent and status are unchanged */
+/* except if: */
+/* */
+/* -- the coefficient was increased and is all nines (in which */
+/* case Overflow could occur, and is handled directly here so */
+/* the caller does not need to re-test for overflow) */
+/* */
+/* -- the coefficient was decreased and becomes all nines (in which */
+/* case Underflow could occur, and is also handled directly). */
+/* */
+/* All fields in dn are updated as required. */
+/* */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static void ___decApplyRound(decNumber *dn, decContext *set, Int residue,
+ uInt *status) {
+ Int bump; // 1 if coefficient needs to be incremented
+ // -1 if coefficient needs to be decremented
+
+ if (residue==0) return; // nothing to apply
+
+ bump=0; // assume a smooth ride
+
+ // now decide whether, and how, to round, depending on mode
+ switch (set->round) {
+ case DEC_ROUND_DOWN: {
+ // no change, except if negative residue
+ if (residue<0) bump=-1;
+ break;} // r-d
+
+ case DEC_ROUND_HALF_DOWN: {
+ if (residue>5) bump=1;
+ break;} // r-h-d
+
+ case DEC_ROUND_HALF_EVEN: {
+ if (residue>5) bump=1; // >0.5 goes up
+ else if (residue==5) { // exactly 0.5000...
+ // 0.5 goes up iff [new] lsd is odd
+ if (*dn->lsu & 0x01) bump=1;
+ }
+ break;} // r-h-e
+
+ case DEC_ROUND_HALF_UP: {
+ if (residue>=5) bump=1;
+ break;} // r-h-u
+
+ case DEC_ROUND_UP: {
+ if (residue>0) bump=1;
+ break;} // r-u
+
+ case DEC_ROUND_CEILING: {
+ // same as _UP for positive numbers, and as _DOWN for negatives
+ // [negative residue cannot occur on 0]
+ if (___decNumberIsNegative(dn)) {
+ if (residue<0) bump=-1;
+ }
+ else {
+ if (residue>0) bump=1;
+ }
+ break;} // r-c
+
+ case DEC_ROUND_FLOOR: {
+ // same as _UP for negative numbers, and as _DOWN for positive
+ // [negative residue cannot occur on 0]
+ if (!___decNumberIsNegative(dn)) {
+ if (residue<0) bump=-1;
+ }
+ else {
+ if (residue>0) bump=1;
+ }
+ break;} // r-f
+
+ default: { // e.g., DEC_ROUND_MAX
+ *status|=DEC_Invalid_context;
+ #if DECTRACE
+ printf("Unknown rounding mode: %d\n", set->round);
+ #endif
+ break;}
+ } // switch
+
+ // now bump the number, up or down, if need be
+ if (bump==0) return; // no action required
+
+ // Simply use ___decUnitAddSub unless bumping up and the number is
+ // all nines. In this special case set to 100... explicitly
+ // and adjust the exponent by one (as otherwise could overflow
+ // the array)
+ // Similarly handle all-nines result if bumping down.
+ if (bump>0) {
+ Unit *up; // work
+ uInt count=dn->digits; // digits to be checked
+ for (up=dn->lsu; ; up++) {
+ if (count<=DECDPUN) {
+ // this is the last Unit (the msu)
+ if (*up!=__powers[count]-1) break; // not still 9s
+ // here if it, too, is all nines
+ *up=(Unit)__powers[count-1]; // here 999 -> 100 etc.
+ for (up=up-1; up>=dn->lsu; up--) *up=0; // others all to 0
+ dn->exponent++; // and bump exponent
+ // [which, very rarely, could cause Overflow...]
+ if ((dn->exponent+dn->digits)>set->emax+1) {
+ ___decSetOverflow(dn, set, status);
+ }
+ return; // done
+ }
+ // a full unit to check, with more to come
+ if (*up!=DECDPUNMAX) break; // not still 9s
+ count-=DECDPUN;
+ } // up
+ } // bump>0
+ else { // -1
+ // here checking for a pre-bump of 1000... (leading 1, all
+ // other digits zero)
+ Unit *up, *sup; // work
+ uInt count=dn->digits; // digits to be checked
+ for (up=dn->lsu; ; up++) {
+ if (count<=DECDPUN) {
+ // this is the last Unit (the msu)
+ if (*up!=__powers[count-1]) break; // not 100..
+ // here if have the 1000... case
+ sup=up; // save msu pointer
+ *up=(Unit)__powers[count]-1; // here 100 in msu -> 999
+ // others all to all-nines, too
+ for (up=up-1; up>=dn->lsu; up--) *up=(Unit)__powers[DECDPUN]-1;
+ dn->exponent--; // and bump exponent
+
+ // iff the number was at the subnormal boundary (exponent=etiny)
+ // then the exponent is now out of range, so it will in fact get
+ // clamped to etiny and the final 9 dropped.
+ // printf(">> emin=%d exp=%d sdig=%d\n", set->emin,
+ // dn->exponent, set->digits);
+ if (dn->exponent+1==set->emin-set->digits+1) {
+ if (count==1 && dn->digits==1) *sup=0; // here 9 -> 0[.9]
+ else {
+ *sup=(Unit)__powers[count-1]-1; // here 999.. in msu -> 99..
+ dn->digits--;
+ }
+ dn->exponent++;
+ *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
+ }
+ return; // done
+ }
+
+ // a full unit to check, with more to come
+ if (*up!=0) break; // not still 0s
+ count-=DECDPUN;
+ } // up
+
+ } // bump<0
+
+ // Actual bump needed. Do it.
+ ___decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);
+} /* ___decApplyRound */
+#endif /* NOT_IN_libc */
+
+#if DECSUBSET
+/* ------------------------------------------------------------------ */
+/* ___decFinish -- finish processing a number */
+/* */
+/* dn is the number */
+/* set is the context */
+/* residue is the rounding accumulator (as in ___decApplyRound) */
+/* status is the accumulator */
+/* */
+/* This finishes off the current number by: */
+/* 1. If not extended: */
+/* a. Converting a zero result to clean '0' */
+/* b. Reducing positive exponents to 0, if would fit in digits */
+/* 2. Checking for overflow and subnormals (always) */
+/* Note this is just Finalize when no subset arithmetic. */
+/* All fields are updated as required. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static void ___decFinish(decNumber *dn, decContext *set, Int *residue,
+ uInt *status) {
+ if (!set->extended) {
+ if ISZERO(dn) { // value is zero
+ dn->exponent=0; // clean exponent ..
+ dn->bits=0; // .. and sign
+ return; // no error possible
+ }
+ if (dn->exponent>=0) { // non-negative exponent
+ // >0; reduce to integer if possible
+ if (set->digits >= (dn->exponent+dn->digits)) {
+ dn->digits=___decShiftToMost(dn->lsu, dn->digits, dn->exponent);
+ dn->exponent=0;
+ }
+ }
+ } // !extended
+
+ ___decFinalize(dn, set, residue, status);
+} /* ___decFinish */
+#endif /* NOT_IN_libc */
+#endif /* DECSUBSET */
+
+/* ------------------------------------------------------------------ */
+/* ___decFinalize -- final check, clamp, and round of a number */
+/* */
+/* dn is the number */
+/* set is the context */
+/* residue is the rounding accumulator (as in ___decApplyRound) */
+/* status is the status accumulator */
+/* */
+/* This finishes off the current number by checking for subnormal */
+/* results, applying any pending rounding, checking for overflow, */
+/* and applying any clamping. */
+/* Underflow and overflow conditions are raised as appropriate. */
+/* All fields are updated as required. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+/*static void ___decFinalize(decNumber *dn, decContext *set, Int *residue, */
+void ___decFinalize(decNumber *dn, decContext *set, Int *residue,
+ uInt *status) {
+ Int shift; // shift needed if clamping
+ Int tinyexp=set->emin-dn->digits+1; // precalculate subnormal boundary
+
+ // Must be careful, here, when checking the exponent as the
+ // adjusted exponent could overflow 31 bits [because it may already
+ // be up to twice the expected].
+
+ // First test for subnormal. This must be done before any final
+ // round as the result could be rounded to Nmin or 0.
+ if (dn->exponent<=tinyexp) { // prefilter
+ decNumber nmin;
+ // A very nasty case here is dn == Nmin and residue<0
+ if (dn->exponent<tinyexp) {
+ // Go handle subnormals; this will apply round if needed.
+ ___decSetSubnormal(dn, set, residue, status);
+ return;
+ }
+ // Equals case: only subnormal if dn=Nmin and negative residue
+ ___decNumberZero(&nmin);
+ nmin.lsu[0]=1;
+ nmin.exponent=set->emin;
+ if (*residue<0 && ___decCompare(dn, &nmin, 1)==0) { // (signless compare)
+ ___decApplyRound(dn, set, *residue, status); // might force down
+ ___decSetSubnormal(dn, set, residue, status);
+ return;
+ }
+ }
+
+ // now apply any pending round (this could raise overflow).
+ if (*residue!=0) ___decApplyRound(dn, set, *residue, status);
+
+ // Check for overflow [redundant in the 'rare' case] or clamp
+ if (dn->exponent<=set->emax-set->digits+1) return; // neither needed
+
+ // here when might have an overflow or clamp to do
+ if (dn->exponent>set->emax-dn->digits+1) { // too big
+ ___decSetOverflow(dn, set, status);
+ return;
+ }
+ // here when the result is normal but in clamp range
+ if (!set->clamp) return;
+
+ // here when need to apply the IEEE exponent clamp (fold-down)
+ shift=dn->exponent-(set->emax-set->digits+1);
+
+ // shift coefficient (if non-zero)
+ if (!ISZERO(dn)) {
+ dn->digits=___decShiftToMost(dn->lsu, dn->digits, shift);
+ }
+ dn->exponent-=shift; // adjust the exponent to match
+ *status|=DEC_Clamped; // and record the dirty deed
+ return;
+} /* ___decFinalize */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decSetOverflow -- set number to proper overflow value */
+/* */
+/* dn is the number (used for sign [only] and result) */
+/* set is the context [used for the rounding mode] */
+/* status contains the current status to be updated */
+/* */
+/* This sets the sign of a number and sets its value to either */
+/* Infinity or the maximum finite value, depending on the sign of */
+/* dn and therounding mode, following IEEE 854 rules. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static void ___decSetOverflow(decNumber *dn, decContext *set, uInt *status) {
+ Flag needmax=0; // result is maximum finite value
+ uByte sign=dn->bits&DECNEG; // clean and save sign bit
+
+ if (ISZERO(dn)) { // zero does not overflow magnitude
+ Int emax=set->emax; // limit value
+ if (set->clamp) emax-=set->digits-1; // lower if clamping
+ if (dn->exponent>emax) { // clamp required
+ dn->exponent=emax;
+ *status|=DEC_Clamped;
+ }
+ return;
+ }
+
+ ___decNumberZero(dn);
+ switch (set->round) {
+ case DEC_ROUND_DOWN: {
+ needmax=1; // never Infinity
+ break;} // r-d
+ case DEC_ROUND_CEILING: {
+ if (sign) needmax=1; // Infinity if non-negative
+ break;} // r-c
+ case DEC_ROUND_FLOOR: {
+ if (!sign) needmax=1; // Infinity if negative
+ break;} // r-f
+ default: break; // Infinity in all other cases
+ }
+ if (needmax) {
+ Unit *up; // work
+ Int count=set->digits; // nines to add
+ dn->digits=count;
+ // fill in all nines to set maximum value
+ for (up=dn->lsu; ; up++) {
+ if (count>DECDPUN) *up=DECDPUNMAX; // unit full o'nines
+ else { // this is the msu
+ *up=(Unit)(__powers[count]-1);
+ break;
+ }
+ count-=DECDPUN; // filled those digits
+ } // up
+ dn->bits=sign; // sign
+ dn->exponent=set->emax-set->digits+1;
+ }
+ else dn->bits=sign|DECINF; // Value is +/-Infinity
+ *status|=DEC_Overflow | DEC_Inexact | DEC_Rounded;
+} /* ___decSetOverflow */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decSetSubnormal -- process value whose exponent is <Emin */
+/* */
+/* dn is the number (used as input as well as output; it may have */
+/* an allowed subnormal value, which may need to be rounded) */
+/* set is the context [used for the rounding mode] */
+/* residue is any pending residue */
+/* status contains the current status to be updated */
+/* */
+/* If subset mode, set result to zero and set Underflow flags. */
+/* */
+/* Value may be zero with a low exponent; this does not set Subnormal */
+/* but the exponent will be clamped to Etiny. */
+/* */
+/* Otherwise ensure exponent is not out of range, and round as */
+/* necessary. Underflow is set if the result is Inexact. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static void ___decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
+ uInt *status) {
+ Int dnexp; // saves original exponent
+ decContext workset; // work
+ Int etiny, adjust; // ..
+
+ #if DECSUBSET
+ // simple set to zero and 'hard underflow' for subset
+ if (!set->extended) {
+ ___decNumberZero(dn);
+ // always full overflow
+ *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
+ return;
+ }
+ #endif
+
+ // Full arithmetic -- allow subnormals, rounded to minimum exponent
+ // (Etiny) if needed
+ etiny=set->emin-(set->digits-1); // smallest allowed exponent
+
+ if ISZERO(dn) { // value is zero
+ // residue can never be non-zero here
+ #if DECCHECK
+ if (*residue!=0) {
+ printf("++ Subnormal 0 residue %d\n", *residue);
+ *status|=DEC_Invalid_operation;
+ }
+ #endif
+ if (dn->exponent<etiny) { // clamp required
+ dn->exponent=etiny;
+ *status|=DEC_Clamped;
+ }
+ return;
+ }
+
+ *status|=DEC_Subnormal; // have a non-zero subnormal
+ adjust=etiny-dn->exponent; // calculate digits to remove
+ if (adjust<=0) { // not out of range; unrounded
+ // residue can never be non-zero here, except in the Nmin-residue
+ // case (which is a subnormal result), so can take fast-path here
+ // it may already be inexact (from setting the coefficient)
+ if (*status&DEC_Inexact) *status|=DEC_Underflow;
+ return;
+ }
+
+ // adjust>0, so need to rescale the result so exponent becomes Etiny
+ // [this code is similar to that in rescale]
+ dnexp=dn->exponent; // save exponent
+ workset=*set; // clone rounding, etc.
+ workset.digits=dn->digits-adjust; // set requested length
+ workset.emin-=adjust; // and adjust emin to match
+ // [note that the latter can be <1, here, similar to Rescale case]
+ ___decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
+ ___decApplyRound(dn, &workset, *residue, status);
+
+ // Use 754R/854 default rule: Underflow is set iff Inexact
+ // [independent of whether trapped]
+ if (*status&DEC_Inexact) *status|=DEC_Underflow;
+
+ // if rounded up a 999s case, exponent will be off by one; adjust
+ // back if so [it will fit, because it was shortened earlier]
+ if (dn->exponent>etiny) {
+ dn->digits=___decShiftToMost(dn->lsu, dn->digits, 1);
+ dn->exponent--; // (re)adjust the exponent.
+ }
+
+ // if rounded to zero, it is by definition clamped...
+ if (ISZERO(dn)) *status|=DEC_Clamped;
+} /* ___decSetSubnormal */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decCheckMath - check entry conditions for a math function */
+/* */
+/* This checks the context and the operand */
+/* */
+/* rhs is the operand to check */
+/* set is the context to check */
+/* status is unchanged if both are good */
+/* */
+/* returns non-zero if status is changed, 0 otherwise */
+/* */
+/* Restrictions enforced: */
+/* */
+/* digits, emax, and -emin in the context must be less than */
+/* DEC_MAX_MATH (999999), and A must be within these bounds if */
+/* non-zero. Invalid_operation is set in the status if a */
+/* restriction is violated. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static uInt ___decCheckMath(const decNumber *rhs, decContext *set,
+ uInt *status) {
+ uInt save=*status; // record
+ if (set->digits>DEC_MAX_MATH
+ || set->emax>DEC_MAX_MATH
+ || -set->emin>DEC_MAX_MATH) *status|=DEC_Invalid_context;
+ else if ((rhs->digits>DEC_MAX_MATH
+ || rhs->exponent+rhs->digits>DEC_MAX_MATH+1
+ || rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH))
+ && !ISZERO(rhs)) *status|=DEC_Invalid_operation;
+ return (*status!=save);
+} /* ___decCheckMath */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decGetInt -- get integer from a number */
+/* */
+/* dn is the number [which will not be altered] */
+/* */
+/* returns one of: */
+/* BADINT if there is a non-zero fraction */
+/* the converted integer */
+/* BIGEVEN if the integer is even and > 2*10**9 */
+/* BIGODD if the integer is odd and > 2*10**9 */
+/* */
+/* This checks and gets a whole number from the input decNumber. */
+/* The sign can be determined from dn by the caller when BIGEVEN or */
+/* BIGODD is returned. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Int ___decGetInt(const decNumber *dn) {
+ Int theInt; // result accumulator
+ const Unit *up; // work
+ Int got; // digits (real or not) processed
+ Int ilength=dn->digits+dn->exponent; // integral length
+ Flag neg=___decNumberIsNegative(dn); // 1 if -ve
+
+ // The number must be an integer that fits in 10 digits
+ // Assert, here, that 10 is enough for any rescale Etiny
+ #if DEC_MAX_EMAX > 999999999
+ #error GetInt may need updating [for Emax]
+ #endif
+ #if DEC_MIN_EMIN < -999999999
+ #error GetInt may need updating [for Emin]
+ #endif
+ if (ISZERO(dn)) return 0; // zeros are OK, with any exponent
+
+ up=dn->lsu; // ready for lsu
+ theInt=0; // ready to accumulate
+ if (dn->exponent>=0) { // relatively easy
+ // no fractional part [usual]; allow for positive exponent
+ got=dn->exponent;
+ }
+ else { // -ve exponent; some fractional part to check and discard
+ Int count=-dn->exponent; // digits to discard
+ // spin up whole units until reach the Unit with the unit digit
+ for (; count>=DECDPUN; up++) {
+ if (*up!=0) return BADINT; // non-zero Unit to discard
+ count-=DECDPUN;
+ }
+ if (count==0) got=0; // [a multiple of DECDPUN]
+ else { // [not multiple of DECDPUN]
+ Int rem; // work
+ // slice off fraction digits and check for non-zero
+ #if DECDPUN<=4
+ theInt=QUOT10(*up, count);
+ rem=*up-theInt*__powers[count];
+ #else
+ rem=*up%__powers[count]; // slice off discards
+ theInt=*up/__powers[count];
+ #endif
+ if (rem!=0) return BADINT; // non-zero fraction
+ // it looks good
+ got=DECDPUN-count; // number of digits so far
+ up++; // ready for next
+ }
+ }
+ // now it's known there's no fractional part
+
+ // tricky code now, to accumulate up to 9.3 digits
+ if (got==0) {theInt=*up; got+=DECDPUN; up++;} // ensure lsu is there
+
+ if (ilength<11) {
+ Int save=theInt;
+ // collect any remaining unit(s)
+ for (; got<ilength; up++) {
+ theInt+=*up*__powers[got];
+ got+=DECDPUN;
+ }
+ if (ilength==10) { // need to check for wrap
+ if (theInt/(Int)__powers[got-DECDPUN]!=(Int)*(up-1)) ilength=11;
+ // [that test also disallows the BADINT result case]
+ else if (neg && theInt>1999999997) ilength=11;
+ else if (!neg && theInt>999999999) ilength=11;
+ if (ilength==11) theInt=save; // restore correct low bit
+ }
+ }
+
+ if (ilength>10) { // too big
+ if (theInt&1) return BIGODD; // bottom bit 1
+ return BIGEVEN; // bottom bit 0
+ }
+
+ if (neg) theInt=-theInt; // apply sign
+ return theInt;
+} /* ___decGetInt */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decPutInt -- put integer into a number */
+/* */
+/* res is the target number, with enough space for the biggest */
+/* integer that the second argument will be */
+/* in is the input integer */
+/* */
+/* Returns res, an integral value; no error is possible. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static decNumber *___decPutInt(decNumber *res, Int in) {
+ Unit *up; // work pointer
+
+ ___decNumberZero(res); // clean
+ if (in<=0) { // handle sign, 0, and BADINT
+ if (in==0) return res; // easy
+ else if (in!=BADINT) {
+ res->bits=DECNEG; // set sign
+ in=-in; // invert and drop through
+ }
+ else { // BADINT: invert would fail
+ decContext set;
+ ___decContextDefault(&set, DEC_INIT_DECIMAL64); // 16 digits
+ ___decNumberFromString(res, "-2147483648", &set); // ugh
+ return res;
+ }
+ }
+ // in is now positive
+ for (up=res->lsu; in>0; up++) {
+ *up=(Unit)(in%(DECDPUNMAX+1));
+ in=in/(DECDPUNMAX+1);
+ }
+ res->digits=___decGetDigits(res->lsu, up-res->lsu);
+ return res;
+} /* ___decPutInt */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decBiStr -- compare string with pairwise options */
+/* */
+/* targ is the string to compare */
+/* str1 is one of the strings to compare against (length may be 0) */
+/* str2 is the other; it must be the same length as str1 */
+/* */
+/* returns 1 if strings compare equal, (that is, it is the same */
+/* length as str1 and str2, and each character of targ is in either */
+/* str1 or str2 in the corresponding position), or 0 otherwise */
+/* */
+/* This is used for generic caseless compare, including the awkward */
+/* case of the Turkish dotted and dotless Is. Use as (for example): */
+/* if (___decBiStr(test, "mike", "MIKE")) ... */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Flag ___decBiStr(const char *targ, const char *str1, const char *str2) {
+ for (;;targ++, str1++, str2++) {
+ if (*targ!=*str1 && *targ!=*str2) return 0;
+ // *targ has a match in one (or both, if terminator)
+ if (*targ=='\0') break;
+ } // forever
+ return 1;
+} /* ___decBiStr */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decNaNs -- handle NaN operand or operands */
+/* */
+/* res is the result number */
+/* lhs is the first operand */
+/* rhs is the second operand, or NULL if none */
+/* status contains the current status */
+/* returns res in case convenient */
+/* */
+/* Called when one or both operands is a NaN, and propagates the */
+/* appropriate result to res. When an sNaN is found, it is changed */
+/* to a qNaN and Invalid operation is set. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static decNumber * ___decNaNs(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, uInt *status) {
+ // This decision tree ends up with LHS being the source pointer,
+ // and status updated if need be
+ if (lhs->bits & DECSNAN)
+ *status|=DEC_Invalid_operation | DEC_sNaN;
+ else if (rhs==NULL);
+ else if (rhs->bits & DECSNAN) {
+ lhs=rhs;
+ *status|=DEC_Invalid_operation | DEC_sNaN;
+ }
+ else if (lhs->bits & DECNAN);
+ else lhs=rhs;
+
+ ___decNumberCopy(res, lhs);
+ res->bits&=~DECSNAN; // convert any sNaN to NaN, while
+ res->bits|=DECNAN; // .. preserving sign
+ res->exponent=0; // clean exponent
+ // [coefficient was copied]
+ return res;
+} /* ___decNaNs */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decStatus -- apply non-zero status */
+/* */
+/* dn is the number to set if error */
+/* status contains the current status (not yet in context) */
+/* set is the context */
+/* */
+/* If the status is an error status, the number is set to a NaN, */
+/* unless the error was an overflow, divide-by-zero, or underflow, */
+/* in which case the number will have already been set. */
+/* */
+/* The context status is then updated with the new status. Note that */
+/* this may raise a signal, so control may never return from this */
+/* routine (hence resources must be recovered before it is called). */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+/* static void ___decStatus(decNumber *dn, uInt status, decContext *set) { */
+void ___decStatus(decNumber *dn, uInt status, decContext *set) {
+ if (status & DEC_NaNs) { // error status -> NaN
+ // if cause was an sNaN, clear and propagate [NaN is already set up]
+ if (status & DEC_sNaN) status&=~DEC_sNaN;
+ else {
+ ___decNumberZero(dn); // other error: clean throughout
+ dn->bits=DECNAN; // and make a quiet NaN
+ }
+ }
+ ___decContextSetStatus(set, status); // [may not return]
+ return;
+} /* ___decStatus */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decGetDigits -- count digits in a Units array */
+/* */
+/* uar is the Unit array holding the number (this is often an */
+/* accumulator of some sort) */
+/* len is the length of the array in units */
+/* */
+/* returns the number of (significant) digits in the array */
+/* */
+/* All leading zeros are excluded, except the last if the array has */
+/* only zero Units. */
+/* ------------------------------------------------------------------ */
+// This may be called twice during some operations.
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Int ___decGetDigits(Unit *uar, Int len) {
+ Unit *up=uar+(len-1); // -> msu
+ Int digits=(len-1)*DECDPUN+1; // possible digits excluding msu
+ // (at least 1 in final msu)
+ #if DECDPUN>4
+ uInt const *pow; // work
+ #endif
+
+ for (; up>=uar; up--) {
+ if (*up==0) { // unit is all 0s
+ if (digits==1) break; // a zero has one digit
+ digits-=DECDPUN; // adjust for 0 unit
+ continue;}
+ // found the first (most significant) non-zero Unit
+ #if DECDPUN>1 // not done yet
+ if (*up<10) break; // is 1-9
+ digits++;
+ #if DECDPUN>2 // not done yet
+ if (*up<100) break; // is 10-99
+ digits++;
+ #if DECDPUN>3 // not done yet
+ if (*up<1000) break; // is 100-999
+ digits++;
+ #if DECDPUN>4 // count the rest ...
+ for (pow=&__powers[4]; *up>=*pow; pow++) digits++;
+ #endif
+ #endif
+ #endif
+ #endif
+ break;
+ } // up
+ return digits;
+} /* ___decGetDigits */
+#endif /* NOT_IN_libc */
+
+#if DECTRACE | DECCHECK
+/* ------------------------------------------------------------------ */
+/* ___decNumberShow -- display a number [debug aid] */
+/* dn is the number to show */
+/* */
+/* Shows: sign, exponent, coefficient (msu first), digits */
+/* or: sign, special-value */
+/* ------------------------------------------------------------------ */
+// this is public so other modules can use it
+#if defined NOT_IN_libc /* Not needed in libc. */
+void ___decNumberShow(const decNumber *dn) {
+ const Unit *up; // work
+ uInt u, d; // ..
+ Int cut; // ..
+ char isign='+'; // main sign
+ if (dn==NULL) {
+ printf("NULL\n");
+ return;}
+ if (___decNumberIsNegative(dn)) isign='-';
+ printf(" >> %c ", isign);
+ if (dn->bits&DECSPECIAL) { // Is a special value
+ if (___decNumberIsInfinite(dn)) printf("Infinity");
+ else { // a NaN
+ if (dn->bits&DECSNAN) printf("sNaN"); // signalling NaN
+ else printf("NaN");
+ }
+ // if coefficient and exponent are 0, no more to do
+ if (dn->exponent==0 && dn->digits==1 && *dn->lsu==0) {
+ printf("\n");
+ return;}
+ // drop through to report other information
+ printf(" ");
+ }
+
+ // now carefully display the coefficient
+ up=dn->lsu+D2U(dn->digits)-1; // msu
+ printf("%d", *up);
+ for (up=up-1; up>=dn->lsu; up--) {
+ u=*up;
+ printf(":");
+ for (cut=DECDPUN-1; cut>=0; cut--) {
+ d=u/__powers[cut];
+ u-=d*__powers[cut];
+ printf("%d", d);
+ } // cut
+ } // up
+ if (dn->exponent!=0) {
+ char esign='+';
+ if (dn->exponent<0) esign='-';
+ printf(" E%c%d", esign, abs(dn->exponent));
+ }
+ printf(" [%d]\n", dn->digits);
+} /* ___decNumberShow */
+#endif /* NOT_IN_libc */
+#endif /* DECTRACE || DECCHECK */
+
+#if DECTRACE || DECCHECK
+/* ------------------------------------------------------------------ */
+/* ___decDumpAr -- display a unit array [debug aid] */
+/* name is a single-character tag name */
+/* ar is the array to display */
+/* len is the length of the array in Units */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static void ___decDumpAr(char name, const Unit *ar, Int len) {
+ Int i;
+ #if DECDPUN==9
+ char *spec="%09d ";
+ #elif DECDPUN==8
+ char *spec="%08d ";
+ #elif DECDPUN==7
+ char *spec="%07d ";
+ #elif DECDPUN==6
+ char *spec="%06d ";
+ #elif DECDPUN==5
+ char *spec="%05d ";
+ #elif DECDPUN==4
+ char *spec="%04d ";
+ #elif DECDPUN==3
+ char *spec="%03d ";
+ #elif DECDPUN==2
+ char *spec="%02d ";
+ #else
+ char *spec="%d ";
+ #endif
+ printf(" :%c: ", name);
+ for (i=len-1; i>=0; i--) {
+ if (i==len-1) printf("%d ", ar[i]);
+ else printf(spec, ar[i]);
+ }
+ printf("\n");
+ return;
+} /* ___decDumpAr */
+#endif /* NOT_IN_libc */
+#endif /* DECTRACE || DECCHECK */
+
+#if DECCHECK
+/* ------------------------------------------------------------------ */
+/* ___decCheckOperands -- check operand(s) to a routine */
+/* res is the result structure (not checked; it will be set to */
+/* quiet NaN if error found (and it is not NULL)) */
+/* lhs is the first operand (may be DECUNUSED) */
+/* rhs is the second (may be DECUNUSED) */
+/* set is the context (may be DECUNUSED) */
+/* returns 0 if both operands, and the context are clean, or 1 */
+/* otherwise (in which case the context will show an error, */
+/* unless NULL). Note that res is not cleaned; caller should */
+/* handle this so res=NULL case is safe. */
+/* The caller is expected to abandon immediately if 1 is returned. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Flag ___decCheckOperands(decNumber *res, const decNumber *lhs,
+ const decNumber *rhs, decContext *set) {
+ Flag bad=0;
+ if (set==NULL) { // oops; hopeless
+ #if DECTRACE
+ printf("Context is NULL.\n");
+ #endif
+ bad=1;
+ return 1;}
+ else if (set!=DECUNUSED
+ && (set->digits<1 || set->round<0 || set->round>=DEC_ROUND_MAX)) {
+ bad=1;
+ #if DECTRACE
+ printf("Bad context [digits=%d round=%d].\n", set->digits, set->round);
+ #endif
+ }
+ else {
+ if (res==NULL) {
+ bad=1;
+ #if DECTRACE
+ printf("Bad result [is NULL].\n");
+ #endif
+ }
+ if (!bad && lhs!=DECUNUSED) bad=(___decCheckNumber(lhs, set));
+ if (!bad && rhs!=DECUNUSED) bad=(___decCheckNumber(rhs, set));
+ }
+ if (bad) {
+ if (set!=DECUNUSED) ___decContextSetStatus(set, DEC_Invalid_operation);
+ if (res!=DECUNUSED && res!=NULL) {
+ ___decNumberZero(res);
+ res->bits=DECNAN; // qNaN
+ }
+ }
+ return bad;
+} /* ___decCheckOperands */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decCheckNumber -- check a number */
+/* dn is the number to check */
+/* set is the context (may be DECUNUSED) */
+/* returns 0 if the number is clean, or 1 otherwise */
+/* */
+/* The number is considered valid if it could be a result from some */
+/* operation in some valid context (not necessarily the current one). */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static Flag ___decCheckNumber(const decNumber *dn, decContext *set) {
+ const Unit *up; // work
+ uInt maxuint; // ..
+ Int ae, d, digits; // ..
+ Int emin, emax; // ..
+
+ if (dn==NULL) { // hopeless
+ #if DECTRACE
+ printf("Reference to decNumber is NULL.\n");
+ #endif
+ return 1;}
+
+ // check special values
+ if (dn->bits & DECSPECIAL) {
+ if (dn->exponent!=0) {
+ #if DECTRACE
+ printf("Exponent %d (not 0) for a special value.\n", dn->exponent);
+ #endif
+ return 1;}
+
+ // 2003.09.08: NaNs may now have coefficients, so next tests Inf only
+ if (___decNumberIsInfinite(dn)) {
+ if (dn->digits!=1) {
+ #if DECTRACE
+ printf("Digits %d (not 1) for an infinity.\n", dn->digits);
+ #endif
+ return 1;}
+ if (*dn->lsu!=0) {
+ #if DECTRACE
+ printf("LSU %d (not 0) for an infinity.\n", *dn->lsu);
+ #endif
+ return 1;}
+ } // Inf
+ // 2002.12.26: negative NaNs can now appear through proposed IEEE
+ // concrete formats (decimal64, etc.), though they are
+ // never visible in strings.
+ return 0;
+
+ // if ((dn->bits & DECINF) || (dn->bits & DECNEG)==0) return 0;
+ // #if DECTRACE
+ // printf("Negative NaN in number.\n");
+ // #endif
+ // return 1;
+ }
+
+ // check the coefficient
+ if (dn->digits<1 || dn->digits>DECNUMMAXP) {
+ #if DECTRACE
+ printf("Digits %d in number.\n", dn->digits);
+ #endif
+ return 1;}
+
+ d=dn->digits;
+
+ for (up=dn->lsu; d>0; up++) {
+ if (d>DECDPUN) maxuint=DECDPUNMAX;
+ else { // reached the msu
+ maxuint=__powers[d]-1;
+ if (dn->digits>1 && *up<__powers[d-1]) {
+ #if DECTRACE
+ printf("Leading 0 in number.\n");
+ ___decNumberShow(dn);
+ #endif
+ return 1;}
+ }
+ if (*up>maxuint) {
+ #if DECTRACE
+ printf("Bad Unit [%08x] in %d-digit number at offset %d [maxuint %d].\n",
+ *up, dn->digits, up-dn->lsu, maxuint);
+ #endif
+ return 1;}
+ d-=DECDPUN;
+ }
+
+ // check the exponent. Note that input operands can have exponents
+ // which are out of the set->emin/set->emax and set->digits range
+ // (just as they can have more digits than set->digits).
+ ae=dn->exponent+dn->digits-1; // adjusted exponent
+ emax=DECNUMMAXE;
+ emin=DECNUMMINE;
+ digits=DECNUMMAXP;
+ if (ae<emin-(digits-1)) {
+ #if DECTRACE
+ printf("Adjusted exponent underflow [%d].\n", ae);
+ ___decNumberShow(dn);
+ #endif
+ return 1;}
+ if (ae>+emax) {
+ #if DECTRACE
+ printf("Adjusted exponent overflow [%d].\n", ae);
+ ___decNumberShow(dn);
+ #endif
+ return 1;}
+
+ return 0; // it's OK
+} /* ___decCheckNumber */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decCheckInexact -- check a normal finite inexact result has digits */
+/* dn is the number to check */
+/* set is the context (for status and precision) */
+/* sets Invalid operation, etc., if some digits are missing */
+/* [this check is not made for DECSUBSET compilation] */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static void ___decCheckInexact(const decNumber *dn, decContext *set) {
+ #if !DECSUBSET
+ if ((set->status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact
+ && (set->digits!=dn->digits) && !(dn->bits & DECSPECIAL)) {
+ ___decContextSetStatus(set, DEC_Invalid_operation);
+ #if DECTRACE
+ printf("Insufficient digits [%d] on normal Inexact result.\n", dn->digits);
+ ___decNumberShow(dn);
+ #endif
+ }
+ #endif
+ return;
+} /* ___decCheckInexact */
+#endif /* NOT_IN_libc */
+#endif /* DECCHECK */
+
+#if DECALLOC
+#undef malloc
+#undef free
+/* ------------------------------------------------------------------ */
+/* ___decMalloc -- accountable allocation routine */
+/* n is the number of bytes to allocate */
+/* */
+/* Semantics is the same as the stdlib malloc routine, but bytes */
+/* allocated are accounted for globally, and corruption fences are */
+/* added before and after the 'actual' storage. */
+/* ------------------------------------------------------------------ */
+/* This routine allocates storage with an extra twelve bytes; 8 are */
+/* at the start and hold: */
+/* 0-3 the original length requested */
+/* 4-7 buffer corruption detection fence (DECFENCE, x4) */
+/* The 4 bytes at the end also hold a corruption fence (DECFENCE, x4) */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static void *___decMalloc(size_t n) {
+ uInt size=n+12; // true size
+ void *alloc; // -> allocated storage
+ uInt *j; // work
+ uByte *b, *b0; // ..
+
+ alloc=malloc(size); // -> allocated storage
+ if (alloc==NULL) return NULL; // out of strorage
+ b0=(uByte *)alloc; // as bytes
+ decAllocBytes+=n; // account for storage
+ j=(uInt *)alloc; // -> first four bytes
+ *j=n; // save n
+ // printf(" allo ++ dAB: %d (%d)\n", decAllocBytes, n);
+ for (b=b0+4; b<b0+8; b++) *b=DECFENCE;
+ for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE;
+ return b0+8; // -> play area
+} /* ___decMalloc */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___decFree -- accountable free routine */
+/* alloc is the storage to free */
+/* */
+/* Semantics is the same as the stdlib malloc routine, except that */
+/* the global storage accounting is updated and the fences are */
+/* checked to ensure that no routine has written 'out of bounds'. */
+/* ------------------------------------------------------------------ */
+/* This routine first checks that the fences have not been corrupted. */
+/* It then frees the storage using the 'truw' storage address (that */
+/* is, offset by 8). */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Not needed in libc. */
+static void ___decFree(void *alloc) {
+ uInt *j, n; // pointer, original length
+ uByte *b, *b0; // work
+
+ if (alloc==NULL) return; // allowed; it's a nop
+ b0=(uByte *)alloc; // as bytes
+ b0-=8; // -> true start of storage
+ j=(uInt *)b0; // -> first four bytes
+ n=*j; // lift
+ for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE)
+ printf("=== Corrupt byte [%02x] at offset %d from %d ===\n", *b,
+ b-b0-8, (Int)b0);
+ for (b=b0+n+8; b<b0+n+12; b++) if (*b!=DECFENCE)
+ printf("=== Corrupt byte [%02x] at offset +%d from %d, n=%d ===\n", *b,
+ b-b0-8, (Int)b0, n);
+ free(b0); // drop the storage
+ decAllocBytes-=n; // account for storage
+ // printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n);
+} /* decFree */
+#endif /* NOT_IN_libc */
+#define malloc(a) ___decMalloc(a)
+#define free(a) ___decFree(a)
+#endif /* DECALLOC */
diff --git a/libc/dfp/decNumber.h b/libc/dfp/decNumber.h
new file mode 100644
index 000000000..e6131d71a
--- /dev/null
+++ b/libc/dfp/decNumber.h
@@ -0,0 +1,164 @@
+/* ------------------------------------------------------------------ */
+/* Decimal Number arithmetic module header */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#if !defined(DECNUMBER)
+ #define DECNUMBER
+ #define DECNAME "decNumber" /* Short name */
+ #define DECVERSION "decNumber 3.37" /* Version [16 max.] */
+ #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 in
+ // range 1-9; 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 decNumberUnits needed is ceil(DECNUMDIGITS/DECDPUN)
+ #define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN)
+
+ #include "decNumberLocal.h"
+
+ // 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)
+ decNumberUnit lsu[DECNUMUNITS];// Coefficient, from least significant unit
+ } 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 */
+ /* ------------------------------------------------------------------ */
+ // Conversions
+#if defined NOT_IN_libc
+ decNumber * ___decNumberFromString(decNumber *, const char *, decContext *);
+ char * ___decNumberToString(const decNumber *, char *);
+#endif
+ char * ___decNumberToEngString(const decNumber *, char *);
+ libc_hidden_proto (___decNumberToEngString)
+
+#if defined NOT_IN_libc
+ // Operators and elementary functions
+ decNumber * ___decNumberAbs(decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberAdd(decNumber *, const decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberCompare(decNumber *, const decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberCompareTotal(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 * ___decNumberLn(decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberLog10(decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberMax(decNumber *, const decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberMin(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 * ___decNumberPlus(decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberPower(decNumber *, const decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberQuantize(decNumber *, const 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 * ___decNumberSameQuantum(decNumber *, const decNumber *, const decNumber *);
+ decNumber * ___decNumberSquareRoot(decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberSubtract(decNumber *, const decNumber *, const decNumber *, decContext *);
+ decNumber * ___decNumberToIntegralValue(decNumber *, const decNumber *, decContext *);
+#endif /* NOT_IN_libc */
+
+ // Utilities
+#if defined NOT_IN_libc /* Not needed in libc. */
+ decNumber * ___decNumberCopy(decNumber *, const decNumber *);
+ decNumber * ___decNumberTrim(decNumber *);
+ const char * ___decNumberVersion(void);
+
+ void ___decFinalize(decNumber *, decContext *, Int *, uInt *);
+ void ___decSetCoeff(decNumber *, decContext *, const Unit *,
+ Int, Int *, uInt *);
+ void ___decStatus(decNumber *, uInt, decContext *);
+ Int ___decCompare(const decNumber *lhs, const decNumber *rhs, Flag);
+#endif
+
+ decNumber * ___decNumberZero(decNumber *);
+ libc_hidden_proto (___decNumberZero) /* Used by decimal to string functions. */
+
+ // Macros for testing decNumbers
+ #define ___decNumberIsZero(dn) (*(dn)->lsu==0 \
+ && (dn)->digits==1 \
+ && (((dn)->bits&DECSPECIAL)==0))
+ #define ___decNumberIsNegative(dn) (((dn)->bits&DECNEG)!=0)
+ #define ___decNumberIsNaN(dn) (((dn)->bits&(DECNAN|DECSNAN))!=0)
+ #define ___decNumberIsQNaN(dn) (((dn)->bits&(DECNAN))!=0)
+ #define ___decNumberIsSNaN(dn) (((dn)->bits&(DECSNAN))!=0)
+ #define ___decNumberIsInfinite(dn) (((dn)->bits&DECINF)!=0)
+ #define ___decNumberIsSpecial(dn) (((dn)->bits&DECSPECIAL)!=0)
+
+#endif
diff --git a/libc/dfp/decNumberLocal.h b/libc/dfp/decNumberLocal.h
new file mode 100644
index 000000000..311f7c2d9
--- /dev/null
+++ b/libc/dfp/decNumberLocal.h
@@ -0,0 +1,211 @@
+/* ------------------------------------------------------------------ */
+/* decNumber package local type, tuning, and macro definitions */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* ------------------------------------------------------------------ */
+/* This header file is included by all modules in the decNumber */
+/* library, and contains local type definitions, tuning parameters, */
+/* etc. It must only be included once, and should not need to be */
+/* used by application programs. decNumber.h must be included first. */
+/* ------------------------------------------------------------------ */
+
+
+#ifndef _DEC_NUMBER_LOCAL_H
+#define _DEC_NUMBER_LOCAL_H 1
+
+
+ /* Tuning parameter */
+ #define DECBUFFER 36 /* Maximum size basis for local buffers.
+ * Should be a common maximum precision
+ * rounded up to a multiple of 4; must
+ * be zero or positive. */
+
+ /* Conditional code flags -- set these to 1 for best performance */
+ #define DECENDIAN 1 /* 1=concrete formats are endian */
+ #define DECUSE64 1 /* 1 to allow use of 64-bit integers */
+
+ /* 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 allocation accounting */
+ #define DECTRACE 0 /* 1 to trace critical intermediates, etc. */
+
+ /* 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 defines */
+ #if DECALLOC
+ // if these interfere with your C includes, just comment them out
+ #define int ? // enable to ensure that plain C 'int' or
+ #define long ?? // .. 'long' types are not used
+ #endif
+
+ /* 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 powers of of ten array (__powers[n]==10**n, 0<=n<=10) */
+ extern const uInt __powers[];
+ libc_hidden_proto (__powers) /* Needed by decDigitsFromDPD in libc. */
+
+ /* Public lookup table used by the D2U macro (see below) */
+ #define DECMAXD2U 49
+ extern const uByte d2utable[DECMAXD2U+1];
+ libc_hidden_proto (d2utable) /* Needed by decToString via D2U macro. */
+
+ /* ----- 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 */
+
+ /* 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))
+
+ /* 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, 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=__powers[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;} \
+ }
+
+ /* MAX and MIN -- general max & min (not in ANSI) */
+/* #ifndef MAX
+ #define MAX(x,y) ((x)<(y)?(y):(x))
+ #endif
+ #ifndef MIN
+ #define MIN(x,y) ((x)>(y)?(y):(x))
+ #endif */
+
+#endif /* _DEC_NUMBER_LOCAL_H */
diff --git a/libc/dfp/decNumberMath.c b/libc/dfp/decNumberMath.c
new file mode 100644
index 000000000..17afe95c9
--- /dev/null
+++ b/libc/dfp/decNumberMath.c
@@ -0,0 +1,727 @@
+/* Decimal Number Library - Math Functions
+ Copyright (C) 2006 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define DECNUMDIGITS 60
+#include "decNumber.h" // base number library
+#include "decNumberMath.h"
+#include "decNumberLocal.h"
+#include "decContext.h"
+#include <stdio.h> // for printf
+#include <stdlib.h> // for malloc/free
+#include <ctype.h> // for tolower
+#include <assert.h>
+
+#define E "2.7182818284590452353602874713526624977572470936999595749669676277240766303535"
+#define PI "3.1415926535897932384626433832795028841971693993751058209749445923078164062862"
+
+//Flags
+#define DIVIDE 0x80
+#define REMAINDER 0x40
+#define DIVIDEINT 0x20
+#define REMNEAR 0x10
+#define COMPARE 0x01
+#define COMPMAX 0x02
+#define COMPMIN 0x03
+#define COMPNAN 0x04
+
+#define BADINT (Int)0x80000000
+
+#define DIVIDE_BY_10(x) x.exponent--
+
+#if defined NOT_IN_libc /* We don't want any of this in libc. */
+// ----------------------------------------------------------------------
+// Basic Functions
+// ----------------------------------------------------------------------
+
+// Return the largest integer less than or equal to x
+static decNumber* ___decNumberFloor (decNumber *result, decNumber *x,
+ decContext *set)
+{
+ int round = set->round;
+
+ set->round = DEC_ROUND_DOWN;
+ ___decNumberToIntegralValue (result, x, set);
+ set->round = round;
+ return result;
+} /* ___decNumberFloor */
+
+static int ___decNumberIsEqual (decNumber *x, decNumber *y, decContext *set)
+{
+ decNumber diff;
+ ___decNumberSubtract (&diff, x, y, set);
+ return ___decNumberIsZero (&diff);
+} /* ___decNumberIsEqual */
+
+static int ___decNumberIsInteger (decNumber *x, decContext *set)
+{
+ decNumber y;
+
+ ___decNumberToIntegralValue (&y, x, set);
+ return ___decNumberIsEqual (x, &y, set);
+} /* ___decNumberIsInteger */
+
+// Modulo function
+static decNumber* ___decNumberMod (decNumber *result, decNumber *x, decNumber *y,
+ decContext *set)
+{
+ // x mod y = x - k*y where k = floor(x/y)
+ decNumber k;
+
+ ___decNumberDivide (&k, x, y, set);
+ ___decNumberFloor (&k, &k, set);
+ ___decNumberMultiply (&k, &k, y, set);
+ ___decNumberSubtract (result, x, &k, set);
+ return result;
+} /* ___decNumberMod */
+
+// ----------------------------------------------------------------------
+// Exponential Function
+// ----------------------------------------------------------------------
+
+decNumber* ___decNumberPow (decNumber *result, decNumber *x, decNumber *y,
+ decContext *set)
+{
+ decNumber tmp;
+
+ if (___decNumberIsInteger (y, set)) {
+ return ___decNumberPower (result, x, y, set);
+ }
+ // y is not an integer.
+ if (___decNumberIsNegative (x)) {
+ // result would be a complex number.
+ ___decNumberFromString (result, "NaN", set);
+ return result;
+ }
+ // x^y = exp (y*ln(x))
+ ___decNumberLn(&tmp, x, set);
+ ___decNumberMultiply (&tmp, &tmp, y, set);
+ ___decNumberExp (result, &tmp, set);
+ return result;
+} /* ___decNumberPow */
+
+/* ------------------------------------------------------------------ */
+/* decNumberSquareRoot -- square root operator */
+/* */
+/* This computes C = squareroot(A) */
+/* */
+/* res is C, the result. C may be A */
+/* rhs is A */
+/* set is the context; note that rounding mode has no effect */
+/* */
+/* C must have space for set->digits digits. */
+/* ------------------------------------------------------------------ */
+/* This uses the following varying-precision algorithm in: */
+/* */
+/* Properly Rounded Variable Precision Square Root, T. E. Hull and */
+/* A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */
+/* pp229-237, ACM, September 1985. */
+/* */
+/* % [Reformatted original Numerical Turing source code follows.] */
+/* function sqrt(x : real) : real */
+/* % sqrt(x) returns the properly rounded approximation to the square */
+/* % root of x, in the precision of the calling environment, or it */
+/* % fails if x < 0. */
+/* % t e hull and a abrham, august, 1984 */
+/* if x <= 0 then */
+/* if x < 0 then */
+/* assert false */
+/* else */
+/* result 0 */
+/* end if */
+/* end if */
+/* var f := setexp(x, 0) % fraction part of x [0.1 <= x < 1] */
+/* var e := getexp(x) % exponent part of x */
+/* var approx : real */
+/* if e mod 2 = 0 then */
+/* approx := .259 + .819 * f % approx to root of f */
+/* else */
+/* f := f/l0 % adjustments */
+/* e := e + 1 % for odd */
+/* approx := .0819 + 2.59 * f % exponent */
+/* end if */
+/* */
+/* var p:= 3 */
+/* const maxp := currentprecision + 2 */
+/* loop */
+/* p := min(2*p - 2, maxp) % p = 4,6,10, . . . , maxp */
+/* precision p */
+/* approx := .5 * (approx + f/approx) */
+/* exit when p = maxp */
+/* end loop */
+/* */
+/* % approx is now within 1 ulp of the properly rounded square root */
+/* % of f; to ensure proper rounding, compare squares of (approx - */
+/* % l/2 ulp) and (approx + l/2 ulp) with f. */
+/* p := currentprecision */
+/* begin */
+/* precision p + 2 */
+/* const approxsubhalf := approx - setexp(.5, -p) */
+/* if mulru(approxsubhalf, approxsubhalf) > f then */
+/* approx := approx - setexp(.l, -p + 1) */
+/* else */
+/* const approxaddhalf := approx + setexp(.5, -p) */
+/* if mulrd(approxaddhalf, approxaddhalf) < f then */
+/* approx := approx + setexp(.l, -p + 1) */
+/* end if */
+/* end if */
+/* end */
+/* result setexp(approx, e div 2) % fix exponent */
+/* end sqrt */
+/* ------------------------------------------------------------------ */
+/*decNumber * ___decNumberSquareRoot(decNumber *res, decNumber *rhs,
+ decContext *set) {
+ decContext workset, approxset; // work contexts
+ decNumber dzero; // used for constant zero
+ Int maxp=set->digits+2; // largest working precision
+ Int residue=0; // rounding residue
+ uInt status=0, ignore=0; // status accumulators
+ Int exp; // working exponent
+ Int ideal; // ideal (preferred) exponent
+ Int needbytes; // work
+ Int dropped; // ..
+
+ decNumber *allocrhs=NULL; // non-NULL if rounded rhs allocated
+ // buffer for f [needs +1 in case DECBUFFER 0]
+ uByte buff[sizeof(decNumber)+(D2U(DECBUFFER+1)-1)*sizeof(Unit)];
+ // buffer for a [needs +2 to match maxp]
+ uByte bufa[sizeof(decNumber)+(D2U(DECBUFFER+2)-1)*sizeof(Unit)];
+ // buffer for temporary, b [must be same size as a]
+ uByte bufb[sizeof(decNumber)+(D2U(DECBUFFER+2)-1)*sizeof(Unit)];
+ decNumber *allocbuff=NULL; // -> allocated buff, iff allocated
+ decNumber *allocbufa=NULL; // -> allocated bufa, iff allocated
+ decNumber *allocbufb=NULL; // -> allocated bufb, iff allocated
+ decNumber *f=(decNumber *)buff; // reduced fraction
+ decNumber *a=(decNumber *)bufa; // approximation to result
+ decNumber *b=(decNumber *)bufb; // intermediate result
+ // buffer for temporary variable, up to 3 digits
+ uByte buft[sizeof(decNumber)+(D2U(3)-1)*sizeof(Unit)];
+ decNumber *t=(decNumber *)buft; // up-to-3-digit constant or work
+
+ #if DECCHECK
+ if (___decCheckOperands(res, DECUNUSED, rhs, set)) return res;
+ #endif
+
+ do { // protect allocated storage
+ #if DECSUBSET
+ if (!set->extended) {
+ // reduce operand and set lostDigits status, as needed
+ if (rhs->digits>set->digits) {
+ allocrhs=___decRoundOperand(rhs, set, &status);
+ if (allocrhs==NULL) break;
+ // [Note: 'f' allocation below could reuse this buffer if
+ // used, but as this is rare we keep them separate for clarity.]
+ rhs=allocrhs;
+ }
+ }
+ #endif
+ // [following code does not require input rounding]
+
+ // handle infinities and NaNs
+ if (rhs->bits & DECSPECIAL) {
+ if (___decNumberIsInfinite(rhs)) { // an infinity
+ if (___decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;
+ else ___decNumberCopy(res, rhs); // +Infinity
+ }
+ else ___decNaNs(res, rhs, NULL, &status); // a NaN
+ break;
+ }
+
+ // calculate the ideal (preferred) exponent [floor(exp/2)]
+ // [We would like to write: ideal=rhs->exponent>>1, but this
+ // generates a compiler warning. Generated code is the same.]
+ ideal=(rhs->exponent&~1)/2; // target
+
+ // handle zeros
+ if (ISZERO(rhs)) {
+ ___decNumberCopy(res, rhs); // could be 0 or -0
+ res->exponent=ideal; // use the ideal [safe]
+ break;
+ }
+
+ // any other -x is an oops
+ if (___decNumberIsNegative(rhs)) {
+ status|=DEC_Invalid_operation;
+ break;
+ }
+
+ // we need space for three working variables
+ // f -- the same precision as the RHS, reduced to 0.01->0.99...
+ // a -- Hull's approx -- precision, when assigned, is
+ // currentprecision (we allow +2 for use as temporary)
+ // b -- intermediate temporary result
+ // if any is too long for local storage, then allocate
+ needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
+ if (needbytes>sizeof(buff)) {
+ allocbuff=(decNumber *)malloc(needbytes);
+ if (allocbuff==NULL) { // hopeless -- abandon
+ status|=DEC_Insufficient_storage;
+ break;}
+ f=allocbuff; // use the allocated space
+ }
+ // a and b both need to be able to hold a maxp-length number
+ needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);
+ if (needbytes>sizeof(bufa)) { // [same applies to b]
+ allocbufa=(decNumber *)malloc(needbytes);
+ allocbufb=(decNumber *)malloc(needbytes);
+ if (allocbufa==NULL || allocbufb==NULL) { // hopeless
+ status|=DEC_Insufficient_storage;
+ break;}
+ a=allocbufa; // use the allocated space
+ b=allocbufb; // ..
+ }
+
+ // copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1
+ ___decNumberCopy(f, rhs);
+ exp=f->exponent+f->digits; // adjusted to Hull rules
+ f->exponent=-(f->digits); // to range
+
+ // set up working contexts (the second is used for Numerical
+ // Turing assignment)
+ ___decContextDefault(&workset, DEC_INIT_DECIMAL64);
+ ___decContextDefault(&approxset, DEC_INIT_DECIMAL64);
+ approxset.digits=set->digits; // approx's length
+
+ // [Until further notice, no error is possible and status bits
+ // (Rounded, etc.) should be ignored, not accumulated.]
+
+ // Calculate initial approximation, and allow for odd exponent
+ workset.digits=set->digits; // p for initial calculation
+ t->bits=0; t->digits=3;
+ a->bits=0; a->digits=3;
+ if ((exp & 1)==0) { // even exponent
+ // Set t=0.259, a=0.819
+ t->exponent=-3;
+ a->exponent=-3;
+ #if DECDPUN>=3
+ t->lsu[0]=259;
+ a->lsu[0]=819;
+ #elif DECDPUN==2
+ t->lsu[0]=59; t->lsu[1]=2;
+ a->lsu[0]=19; a->lsu[1]=8;
+ #else
+ t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
+ a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
+ #endif
+ }
+ else { // odd exponent
+ // Set t=0.0819, a=2.59
+ f->exponent--; // f=f/10
+ exp++; // e=e+1
+ t->exponent=-4;
+ a->exponent=-2;
+ #if DECDPUN>=3
+ t->lsu[0]=819;
+ a->lsu[0]=259;
+ #elif DECDPUN==2
+ t->lsu[0]=19; t->lsu[1]=8;
+ a->lsu[0]=59; a->lsu[1]=2;
+ #else
+ t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
+ a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
+ #endif
+ }
+ ___decMultiplyOp(a, a, f, &workset, &ignore); // a=a*f
+ ___decAddOp(a, a, t, &workset, 0, &ignore); // ..+t
+ // [a is now the initial approximation for sqrt(f), calculated with
+ // currentprecision, which is also a's precision.]
+
+ // the main calculation loop
+ ___decNumberZero(&dzero); // make 0
+ ___decNumberZero(t); // set t = 0.5
+ t->lsu[0]=5; // ..
+ t->exponent=-1; // ..
+ workset.digits=3; // initial p
+ for (;;) {
+ // set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp]
+ workset.digits=workset.digits*2-2;
+ if (workset.digits>maxp) workset.digits=maxp;
+ // a = 0.5 * (a + f/a)
+ // [calculated at p then rounded to currentprecision]
+ ___decDivideOp(b, f, a, &workset, DIVIDE, &ignore); // b=f/a
+ ___decAddOp(b, b, a, &workset, 0, &ignore); // b=b+a
+ ___decMultiplyOp(a, b, t, &workset, &ignore);// a=b*0.5
+ // assign to approx [round to length]
+ ___decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+ if (workset.digits==maxp) break; // just did final
+ } // loop
+
+ // a is now at currentprecision and within 1 ulp of the properly
+ // rounded square root of f; to ensure proper rounding, compare
+ // squares of (a - l/2 ulp) and (a + l/2 ulp) with f.
+ // Here workset.digits=maxp and t=0.5
+ workset.digits--; // maxp-1 is OK now
+ t->exponent=-set->digits-1; // make 0.5 ulp
+ ___decNumberCopy(b, a);
+ ___decAddOp(b, b, t, &workset, DECNEG, &ignore); // b = a - 0.5 ulp
+ workset.round=DEC_ROUND_UP;
+ ___decMultiplyOp(b, b, b, &workset, &ignore); // b = mulru(b, b)
+ ___decCompareOp(b, f, b, &workset, COMPARE, &ignore); // b ? f, reversed
+ if (___decNumberIsNegative(b)) { // f < b [i.e., b > f]
+ // this is the more common adjustment, though both are rare
+ t->exponent++; // make 1.0 ulp
+ t->lsu[0]=1; // ..
+ ___decAddOp(a, a, t, &workset, DECNEG, &ignore); // a = a - 1 ulp
+ // assign to approx [round to length]
+ ___decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+ }
+ else {
+ ___decNumberCopy(b, a);
+ ___decAddOp(b, b, t, &workset, 0, &ignore); // b = a + 0.5 ulp
+ workset.round=DEC_ROUND_DOWN;
+ ___decMultiplyOp(b, b, b, &workset, &ignore);// b = mulrd(b, b)
+ ___decCompareOp(b, b, f, &workset, COMPARE, &ignore); // b ? f
+ if (___decNumberIsNegative(b)) { // b < f
+ t->exponent++; // make 1.0 ulp
+ t->lsu[0]=1; // ..
+ ___decAddOp(a, a, t, &workset, 0, &ignore);// a = a + 1 ulp
+ // assign to approx [round to length]
+ ___decAddOp(a, &dzero, a, &approxset, 0, &ignore);
+ }
+ }
+ // [no errors are possible in the above, and rounding/inexact during
+ // estimation are irrelevant, so status was not accumulated]
+
+ // Here, 0.1 <= a < 1 [Hull]
+ a->exponent+=exp/2; // set correct exponent
+
+ // Process Subnormals
+ ___decFinalize(a, set, &residue, &status);
+
+ // count dropable zeros [after any subnormal rounding]
+ ___decNumberCopy(b, a);
+ ___decTrim(b, 1, &dropped); // [drops trailing zeros]
+
+ // Finally set Inexact and Rounded. The answer can only be exact if
+ // it is short enough so that squaring it could fit in set->digits,
+ // so this is the only (relatively rare) time we have to check
+ // carefully
+ if (b->digits*2-1 > set->digits) { // cannot fit
+ status|=DEC_Inexact|DEC_Rounded;
+ }
+ else { // could be exact/unrounded
+ uInt mstatus=0; // local status
+ ___decMultiplyOp(b, b, b, &workset, &mstatus); // try the multiply
+ if (mstatus!=0) { // result won't fit
+ status|=DEC_Inexact|DEC_Rounded;
+ }
+ else { // plausible
+ ___decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); // b ? rhs
+ if (!ISZERO(t)) {
+ status|=DEC_Inexact|DEC_Rounded;
+ }
+ else { // is Exact
+ // here, dropped is the count of trailing zeros in 'a'
+ // use closest exponent to ideal...
+ Int todrop=ideal-a->exponent; // most we can drop
+
+ if (todrop<0) { // ideally would add 0s
+ status|=DEC_Rounded;
+ }
+ else { // unrounded
+ if (dropped<todrop) todrop=dropped; // clamp to those available
+ if (todrop>0) { // OK, some to drop
+ ___decShiftToLeast(a->lsu, D2U(a->digits), todrop);
+ a->exponent+=todrop; // maintain numerical value
+ a->digits-=todrop; // new length
+ }
+ }
+ }
+ }
+ }
+ ___decNumberCopy(res, a); // assume this is the result
+ } while(0); // end protected
+
+ if (allocbuff!=NULL) free(allocbuff); // drop any storage we used
+ if (allocbufa!=NULL) free(allocbufa); // ..
+ if (allocbufb!=NULL) free(allocbufb); // ..
+ if (allocrhs !=NULL) free(allocrhs); // ..
+ if (status!=0) ___decStatus(res, status, set);// then report status
+ return res;
+}*/ /* decNumberSquareRoot */
+
+// ----------------------------------------------------------------------
+// Hyperbolic Functions
+// ----------------------------------------------------------------------
+
+decNumber* ___decNumberSinh (decNumber *result, decNumber *x, decContext *set)
+{
+ // sinh x = (e^x - e^-x)/2
+ decNumber ex, emx, mx, two;
+
+ ___decNumberExp (&ex, x, set);
+ ___decNumberMinus (&mx, x, set);
+ ___decNumberExp (&emx, &mx, set);
+ ___decNumberSubtract (result, &ex, &emx, set);
+ ___decNumberFromString (&two, "2", set);
+ ___decNumberDivide (result, result, &two, set);
+ return result;
+}
+
+decNumber* ___decNumberCosh (decNumber *result, decNumber *x, decContext *set)
+{
+ // cosh x = (e^x + e^-x)/2
+ decNumber ex, emx, mx, two;
+
+ ___decNumberExp (&ex, x, set);
+ ___decNumberMinus (&mx, x, set);
+ ___decNumberExp (&emx, &mx, set);
+ ___decNumberAdd (result, &ex, &emx, set);
+ ___decNumberFromString (&two, "2", set);
+ ___decNumberDivide (result, result, &two, set);
+ return result;
+} /* ___decNumberCosh */
+
+decNumber* ___decNumberTanh (decNumber *result, decNumber *x, decContext *set)
+{
+ // tanh x = sinh x / cosh x = (e^x - e^-x) / (e^x + e^-x)
+ decNumber ex, emx, mx, denominator;
+ ___decNumberExp (&ex, x, set);
+ ___decNumberMinus (&mx, x, set);
+ ___decNumberExp (&emx, &mx, set);
+ ___decNumberSubtract (result, &ex, &emx, set);
+ ___decNumberAdd (&denominator, &ex, &emx, set);
+ ___decNumberDivide (result, result, &denominator, set);
+ return result;
+} /* ___decNumberTanh */
+
+// ----------------------------------------------------------------------
+// Trigonometric Functions
+// ----------------------------------------------------------------------
+
+decNumber* ___decNumberSin (decNumber *result, decNumber *y, decContext *set)
+{
+ decNumber pi, pi2, zero, one, two, x, cnt, term;
+ int i;
+ int negate = 0;
+
+ ___decNumberFromString (&zero,"0", set);
+ ___decNumberFromString (&one, "1", set);
+ ___decNumberFromString (&two, "2", set);
+ ___decNumberFromString (&pi, PI , set);
+
+ // Copy the argument y, so we can modify it.
+ ___decNumberCopy (&x, y);
+ // sin -x = - sin x
+ /* if (___decCompare (&x, &zero) < 0) { */
+ if (___decCompare (&x, &zero, 0) < 0) {
+ ___decNumberMinus (&x, &x, set);
+ negate = 1;
+ }
+ // We now have x >= 0
+ ___decNumberMultiply (&pi2, &pi, &two, set); // pi2 = 2*pi
+ ___decNumberMod (&x, &x, &pi2, set);
+ // We now have 0 <= x < 2*pi
+ /*if (___decCompare (&x, &pi) >= 0) {*/
+ if (___decCompare (&x, &pi,0) >= 0) {
+ // x >= pi
+ ___decNumberSubtract (&x, &x, &pi, set);
+ negate = 1-negate;
+ }
+ // We now have 0 <= x < pi
+ ___decNumberDivide (&pi2, &pi, &two, set); // pi2 = pi/2
+ /*if (___decCompare (&x, &pi2) >= 0) {*/
+ if (___decCompare (&x, &pi2,0) >= 0) {
+ // x >= pi/2, so let x = pi-x
+ ___decNumberSubtract (&x, &pi, &x, set);
+ }
+ // We now have 0 <= x <= pi/2.
+
+ // x^3 x^5 x^7
+ // sin x = x - --- + --- - ---- + ...
+ // 6 120 5040
+ //
+ // term(0) = x
+ // term(i) = - term(i-1) * x^2 / ((2*i)*(2*i+1))
+
+ ___decNumberCopy (&cnt, &two);
+ ___decNumberCopy (&term, &x);
+ ___decNumberCopy (result, &x);
+ // DECNUMDIGITS+3 terms are enough to achieve the required precision.
+ for (i=0; i<DECNUMDIGITS+3; i++) {
+ // term = -term * x^2 / (cnt*(cnt+1))
+ // cnt = cnt+2
+ ___decNumberMinus (&term, &term, set);
+ ___decNumberMultiply (&term, &term, &x, set);
+ ___decNumberMultiply (&term, &term, &x, set);
+ ___decNumberDivide (&term, &term, &cnt, set);
+ ___decNumberAdd (&cnt, &cnt, &one, set);
+ ___decNumberDivide (&term, &term, &cnt, set);
+ ___decNumberAdd (&cnt, &cnt, &one, set);
+ // sum = sum + term
+ ___decNumberAdd (result, result, &term, set);
+ }
+ if (negate) {
+ ___decNumberMinus (result, result, set);
+ }
+ return result;
+} /* ___decNumberSin */
+
+decNumber* ___decNumberCos (decNumber *result, decNumber *y, decContext *set)
+{
+ decNumber pi, pi2, zero, one, two, x, cnt, term;
+ int i;
+ int negate = 0;
+
+ ___decNumberFromString (&zero,"0", set);
+ ___decNumberFromString (&one, "1", set);
+ ___decNumberFromString (&two, "2", set);
+ ___decNumberFromString (&pi, PI , set);
+
+ // Copy the argument y, so we can modify it.
+ ___decNumberCopy (&x, y);
+ // cos -y = cos y
+ /*if (___decCompare (&x, &zero) < 0) {*/
+ if (___decCompare (&x, &zero,0) < 0) {
+ ___decNumberMinus (&x, &x, set);
+ }
+ // We now have x >= 0
+ ___decNumberMultiply (&pi2, &pi, &two, set); // pi2 = 2*pi
+ ___decNumberMod (&x, &x, &pi2, set);
+ // We now have 0 <= x < 2*pi
+ /*if (___decCompare (&x, &pi) >= 0) {*/
+ if (___decCompare (&x, &pi,0) >= 0) {
+ // x >= pi
+ ___decNumberSubtract (&x, &pi2, &x, set);
+ }
+ // We now have 0 <= x < pi
+ ___decNumberDivide (&pi2, &pi, &two, set); // pi2 = pi/2
+ /*if (___decCompare (&x, &pi2) >= 0) {*/
+ if (___decCompare (&x, &pi2,0) >= 0) {
+ // x >= pi/2, so let x = pi-x
+ ___decNumberSubtract (&x, &pi, &x, set);
+ negate = 1;
+ }
+ // We now have 0 <= x <= pi/2.
+
+ // x^2 x^4 x^6
+ // cos x = 1 - --- + --- - --- + ...
+ // 2 24 720
+ //
+ // term(0) = 1
+ // term(i) = - term(i-1) * x^2 / ((2*i-1)*(2*i))
+ ___decNumberCopy (&cnt, &one);
+ ___decNumberCopy (&term, &one);
+ ___decNumberCopy (result, &one);
+ // DECNUMDIGITS+3 terms are enough to achieve the required precision.
+ for (i=0; i<DECNUMDIGITS+3; i++) {
+ // term = -term * x^2 / (cnt*(cnt+1))
+ // cnt = cnt+2
+ ___decNumberMinus (&term, &term, set);
+ ___decNumberMultiply (&term, &term, &x, set);
+ ___decNumberMultiply (&term, &term, &x, set);
+ ___decNumberDivide (&term, &term, &cnt, set);
+ ___decNumberAdd (&cnt, &cnt, &one, set);
+ ___decNumberDivide (&term, &term, &cnt, set);
+ ___decNumberAdd (&cnt, &cnt, &one, set);
+ // sum = sum + term
+ ___decNumberAdd (result, result, &term, set);
+ }
+ if (negate) {
+ ___decNumberMinus (result, result, set);
+ }
+ return result;
+} /* ___decNumberCos */
+
+decNumber* ___decNumberTan (decNumber *result, decNumber *y, decContext *set)
+{
+ // tan x = sin x / cos x
+ decNumber denominator;
+
+ ___decNumberSin (result, y, set);
+ ___decNumberCos (&denominator, y, set);
+ if (___decNumberIsZero (&denominator))
+ ___decNumberFromString (result, "NaN", set);
+ else
+ ___decNumberDivide (result, result, &denominator, set);
+ return result;
+} /* ___decNumberTan */
+
+decNumber* ___decNumberAtan (decNumber *result, decNumber *x, decContext *set)
+{
+ // x^3 x^5 x^7
+ // arctan(x) = x - --- + --- - --- + ...
+ // 3 5 7
+ //
+ // This power series works well, if x is close to zero (|x|<0.5).
+ // If x is larger, the series converges too slowly,
+ // so in order to get a smaller x, we apply the identity
+ //
+ // sqrt(1+x^2) - 1
+ // arctan(x) = 2*arctan ---------------
+ // x
+ //
+ // twice. The first application gives us a new x with x < 1.
+ // The second application gives us a new x with x < 0.4142136.
+ // For that x, we use the power series and multiply the result by four.
+
+ decNumber f, g, mx2, one, two, term;
+ int i;
+
+ ___decNumberFromString (&one, "1", set);
+ ___decNumberFromString (&two, "2", set);
+
+ if (___decNumberIsZero (x)) {
+ ___decNumberCopy (result, x);
+ return result;
+ }
+
+ for (i=0; i<2; i++) {
+ decNumber y;
+ ___decNumberMultiply (&y, x, x, set); // y = x^2
+ ___decNumberAdd (&y, &y, &one, set); // y = y+1
+ ___decNumberSquareRoot (&y, &y, set); // y = sqrt(y)
+ ___decNumberSubtract (&y, &y, &one, set); // y = y-1
+ ___decNumberDivide (x, &y, x, set); // x = y/x
+ }
+ // f(0) = x
+ // f(i) = f(i-1) * (-x^2)
+ //
+ // g(0) = 1
+ // g(i) = g(i-1) + 2
+ //
+ // term(i) = f(i) / g(i)
+ ___decNumberCopy (&f, x); // f(0) = x
+ ___decNumberCopy (&g, &one); // g(0) = 1
+ ___decNumberCopy (&term, x); // term = x
+ ___decNumberCopy (result, x); // sum = x
+ ___decNumberMultiply (&mx2, x, x, set); // mx2 = x^2
+ ___decNumberMinus (&mx2, &mx2, set); // mx2 = -x^2
+ // Since x is less than sqrt(2)-1 = 0.4142...,
+ // each term is smaller than the previous term by a factor of about 6,
+ // so two iterations are more than enough to increase the precision
+ // by one digit.
+ // 2*DECNUMDIGITS terms are enough to achieve the required precision.
+ for (i=0; i<2*DECNUMDIGITS; i++) {
+ // f = f * (-x^2)
+ ___decNumberMultiply (&f, &f, &mx2, set);
+ // g = g+2
+ ___decNumberAdd (&g, &g, &two, set);
+ // term = f/g
+ ___decNumberDivide (&term, &f, &g, set);
+ // sum = sum + term
+ ___decNumberAdd (result, result, &term, set);
+ }
+ // Multiply result by four.
+ ___decNumberAdd (result, result, result, set);
+ ___decNumberAdd (result, result, result, set);
+ return result;
+} /* ___decNumberAtan */
+
+#endif /* NOT_IN_libc */
diff --git a/libc/dfp/decNumberMath.h b/libc/dfp/decNumberMath.h
new file mode 100644
index 000000000..7549c6d33
--- /dev/null
+++ b/libc/dfp/decNumberMath.h
@@ -0,0 +1,41 @@
+/* Advanced decNumber functions
+ Copyright (C) 2006 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECNUMBERMATH_H
+#define _DECNUMBERMATH_H
+
+#if defined NOT_IN_libc /* We don't want these in libc. */
+
+extern decNumber* ___decNumberPow (decNumber *, decNumber *, decNumber *, decContext *);
+
+/* Hyperbolic Functions */
+extern decNumber* ___decNumberSinh (decNumber *, decNumber *, decContext *);
+extern decNumber* ___decNumberCosh (decNumber *, decNumber *, decContext *);
+extern decNumber* ___decNumberTanh (decNumber *, decNumber *, decContext *);
+
+/* Trigonometric Functions */
+extern decNumber* ___decNumberSin (decNumber *, decNumber *, decContext *);
+extern decNumber* ___decNumberCos (decNumber *, decNumber *, decContext *);
+extern decNumber* ___decNumberTan (decNumber *, decNumber *, decContext *);
+extern decNumber* ___decNumberAtan (decNumber *, decNumber *, decContext *);
+
+#endif /* NOT_IN_libc */
+
+#endif /* _DECNUMBERMATH_H */
diff --git a/libc/dfp/decimal128.c b/libc/dfp/decimal128.c
new file mode 100644
index 000000000..639d8878e
--- /dev/null
+++ b/libc/dfp/decimal128.c
@@ -0,0 +1,589 @@
+/* ------------------------------------------------------------------ */
+/* Decimal 128-bit format module */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* ------------------------------------------------------------------ */
+/* This module comprises the routines for decimal128 format numbers. */
+/* Conversions are supplied to and from decNumber and String. */
+/* */
+/* No arithmetic routines are included; decNumber provides these. */
+/* */
+/* Error handling is the same as decNumber (qv.). */
+/* ------------------------------------------------------------------ */
+#include <string.h> // [for memset/memcpy]
+#include <stdio.h> // [for printf]
+
+#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] */
+extern const uInt COMBEXP[32], COMBMSD[32];
+libc_hidden_proto (COMBEXP)
+libc_hidden_proto (COMBMSD)
+
+extern const uShort DPD2BIN[1024];
+/*libc_hidden_proto (DPD2BIN) */
+extern const uShort __BIND2DPD[1000]; // [not used]
+/*libc_hidden_proto (__BIND2DPD) */
+extern const uByte BIN2CHAR[4001];
+/*libc_hidden_proto (BIN2CHAR) */
+
+#if defined NOT_IN_libc /* Don't build this into libc */
+extern void ___decDigitsToDPD(const decNumber *, uInt *, Int);
+#endif
+
+extern void ___decDigitsFromDPD(decNumber *, const uInt *, Int);
+libc_hidden_proto (___decDigitsFromDPD)
+
+#if defined NOT_IN_libc /* We don't want this in libc. */
+#if DECTRACE || DECCHECK
+void ___decimal128Show(const decimal128 *); // for debug
+extern void ___decNumberShow(const decNumber *); // ..
+#endif /* DECTRACE || DECCHECK */
+#endif /* NOT_IN_libc */
+
+/* compile-time endian tester [assumes sizeof(int)>1] */
+static const Int mfcone=1; // constant 1
+/*libc_hidden_data_def (mfcone) */
+static const Flag *mfctop=(Flag *)&mfcone; // -> top byte
+/* libc_hidden_data_def (mfctop) */
+#define LITEND mfctop[0] // named flag; 1=little-endian
+
+/* 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. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Don't build this into libc */
+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 may be endian, or not
+ #if DECENDIAN
+ // DECENDIAN -- direct store, in the right order
+ pu=(uInt *)d128->bytes; // overlay
+ if (LITEND) {
+ 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
+ }
+ #else
+ // not DECENDIAN -- use network byte order
+ if (LITEND) { // little-endian needs reversal
+ uByte *pb; // work
+ Int off; // ..
+ for (pb=&d128->bytes[15]; pb>=d128->bytes; pb--) {
+ off=3-((pb-d128->bytes)>>2); // 0, then 1, 2, 3
+ *pb=(uByte)(targar[off]&0xff);
+ targar[off]>>=8;
+ } // i
+ }
+ else { // big-endian; it's the right way round already
+ pu=(uInt *)d128->bytes; // overlay
+ 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
+ }
+ #endif
+
+ if (status!=0) ___decContextSetStatus(set, status); // pass on status
+ // ___decimal128Show(d128);
+ return d128;
+} /* ___decimal128FromNumber */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___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
+ 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 may be endian, or not
+ #if DECENDIAN
+ // DECENDIAN -- direct load, in the right order
+ pu=(uInt *)d128->bytes; // overlay
+ if (LITEND) {
+ 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
+ }
+ #else
+ // not DECENDIAN -- use network byte order
+ if (LITEND) { // little-endian needs reversal
+ const uByte *pb; // work
+ Int off; // ..
+ for (pb=d128->bytes; pb<=&d128->bytes[15]; pb++) {
+ off=3-((pb-d128->bytes)>>2); // 3, then 2, 1, 0
+ sourar[off]<<=8;
+ sourar[off]|=*pb;
+ } // i
+ }
+ else { // big-endian; it's the right way round already
+ pu=(uInt *)d128->bytes; // overlay
+ 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
+ }
+ #endif
+
+ 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 */
+libc_hidden_def (___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 */
+libc_hidden_def (___decimal128ToEngString) /* Used internally in libc for printf. */
+
+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
+ 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 may be endian, or not
+ #if DECENDIAN
+ // DECENDIAN -- direct load, in the right order
+ pu=(uInt *)d128->bytes; // overlay
+ if (LITEND) {
+ 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
+ }
+ #else
+ // not DECENDIAN -- use network byte order
+ if (LITEND) { // little-endian needs reversal
+ const uByte *pb; // work
+ Int off; // ..
+ for (pb=d128->bytes; pb<=&d128->bytes[15]; pb++) {
+ off=3-((pb-d128->bytes)>>2); // 3, then 2, 1, 0
+ sourar[off]<<=8;
+ sourar[off]|=*pb;
+ } // i
+ }
+ else { // big-endian; it's the right way round already
+ pu=(uInt *)d128->bytes; // overlay
+ 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
+ }
+ #endif
+
+ 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, "Infinity");
+ 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 */
+libc_hidden_def (___decimal128ToString) /* Used internally in libc for printf. */
+
+/* ------------------------------------------------------------------ */
+/* 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. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Don't build this into libc */
+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 */
+#endif
+
+//#if DECTRACE || DECCHECK
+/* ------------------------------------------------------------------ */
+/* ___decimal128Show -- display a decimal128 in hexadecimal [debug aid]*/
+/* d128 -- the number to show */
+/* ------------------------------------------------------------------ */
+// Also shows sign/cob/expconfields extracted
+#if defined NOT_IN_libc /* We don't want this in libc. */
+void ___decimal128Show(const decimal128 *d128) {
+ char buf[DECIMAL128_Bytes*2+1];
+ Int i, j=0;
+
+ #if DECENDIAN
+ if (LITEND) {
+ 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 {
+ #endif
+ 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));
+ #if DECENDIAN
+ }
+ #endif
+} /* ___decimal128Show */
+#endif /* NOT_IN_libc */
diff --git a/libc/dfp/decimal128.h b/libc/dfp/decimal128.h
new file mode 100644
index 000000000..e1ce94214
--- /dev/null
+++ b/libc/dfp/decimal128.h
@@ -0,0 +1,113 @@
+/* ------------------------------------------------------------------ */
+/* Decimal 128-bit format module header */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#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 // exponent 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
+
+ /* 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);}
+
+ /* ------------------------------------------------------------------ */
+ /* Routines */
+ /* ------------------------------------------------------------------ */
+ // String conversions
+#if defined NOT_IN_libc /* Don't build this into libc */
+ decimal128 * ___decimal128FromString(decimal128 *, const char *, decContext *);
+#endif
+ char * ___decimal128ToString(const decimal128 *, char *);
+ libc_hidden_proto (___decimal128ToString)
+ char * ___decimal128ToEngString(const decimal128 *, char *);
+ libc_hidden_proto (___decimal128ToEngString)
+
+ // decNumber conversions
+#if defined NOT_IN_libc /* Don't build this into libc */
+ decimal128 * ___decimal128FromNumber(decimal128 *, const decNumber *,
+ decContext *);
+#endif
+ decNumber * ___decimal128ToNumber(const decimal128 *, decNumber *);
+ libc_hidden_proto (___decimal128ToNumber)
+
+#endif
diff --git a/libc/dfp/decimal32.c b/libc/dfp/decimal32.c
new file mode 100644
index 000000000..9aad081aa
--- /dev/null
+++ b/libc/dfp/decimal32.c
@@ -0,0 +1,505 @@
+/* ------------------------------------------------------------------ */
+/* Decimal 32-bit format module */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* ------------------------------------------------------------------ */
+/* This module comprises the routines for decimal32 format numbers. */
+/* Conversions are supplied to and from decNumber and String. */
+/* */
+/* No arithmetic routines are included; decNumber provides these. */
+/* */
+/* Error handling is the same as decNumber (qv.). */
+/* ------------------------------------------------------------------ */
+#include <string.h> // [for memset/memcpy]
+#include <stdio.h> // [for printf]
+
+#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] */
+extern const uInt COMBEXP[32], COMBMSD[32];
+libc_hidden_proto (COMBEXP)
+libc_hidden_proto (COMBMSD)
+extern const uShort DPD2BIN[1024];
+/* libc_hidden_proto (DPD2BIN) */
+extern const uShort __BIND2DPD[1000];
+/* libc_hidden_proto (__BIND2DPD) */
+extern const uByte BIN2CHAR[4001];
+/* libc_hidden_proto (BIN2CHAR) */
+
+#if defined NOT_IN_libc /* Don't build this into libc. */
+extern void ___decDigitsToDPD(const decNumber *, uInt *, Int);
+#endif
+
+extern void ___decDigitsFromDPD(decNumber *, const uInt *, Int);
+libc_hidden_proto (___decDigitsFromDPD)
+
+#if DECTRACE || DECCHECK
+#if defined NOT_IN_libc /* Don't build this into libc. */
+void ___decimal32Show(const decimal32 *); // for debug
+extern void ___decNumberShow(const decNumber *); // ..
+#endif /* NOT_IN_libc */
+#endif
+
+/* Useful macro */
+// Clear a structure (e.g., a decNumber)
+#define DEC_clear(d) memset(d, 0, sizeof(*d))
+
+#if !DECENDIAN || DECTRACE || DECCHECK
+/* compile-time endian tester [assumes sizeof(int)>1] */
+static const Int mfcone=1; // constant 1
+/* libc_hidden_data_def (mfcone) */
+static const Flag *mfctop=(Flag *)&mfcone; // -> top byte
+/* libc_hidden_data_def (mfctop) */
+#define LITEND mfctop[0] // named flag; 1=little-endian
+#endif
+
+#if defined NOT_IN_libc /* Don't build this into libc */
+/* ------------------------------------------------------------------ */
+/* ___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=__BIND2DPD[dn->lsu[0]];
+ if (dn->digits>3) targ|=(uInt)(__BIND2DPD[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 may be endian, or not
+ #if DECENDIAN
+ // DECENDIAN -- direct store
+ pu=(uInt *)d32->bytes; // overlay
+ *pu=targ; // directly store the int
+ #else
+ // not DECENDIAN -- use network byte order
+ if (LITEND) { // little-endian needs reversal
+ uByte *pb; // work
+ for (pb=&d32->bytes[3]; pb>=d32->bytes; pb--) {
+ *pb=(uByte)(targ&0xff);
+ targ>>=8;
+ } // i
+ }
+ else { // big-endian; it's the right way round already
+ pu=(uInt *)d32->bytes; // overlay
+ *pu=targ; // directly store the int
+ }
+ #endif
+
+ if (status!=0) ___decContextSetStatus(set, status); // pass on status
+ // ___decimal32Show(d32);
+ return d32;
+} /* ___decimal32FromNumber */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___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 *pu; // work
+ uInt sour; // source 32-bit
+
+ // load source from storage; this may be endian, or not
+ #if DECENDIAN
+ // DECENDIAN -- direct load
+ pu=(uInt *)d32->bytes; // overlay
+ sour=*pu; // directly load the int
+ #else
+ // not DECENDIAN -- use network byte order
+ if (LITEND) { // little-endian needs reversal
+ const uByte *pb; // work
+ sour=0; // [keep compiler quiet]
+ for (pb=d32->bytes; pb<=&d32->bytes[3]; pb++) {
+ sour<<=8;
+ sour|=*pb;
+ } // i
+ }
+ else { // big-endian; it's the right way round already
+ pu=(uInt *)d32->bytes; // overlay
+ sour=*pu; // directly load the int
+ }
+ #endif
+
+ 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 */
+libc_hidden_def(___decimal32ToNumber) /* Used internally in libc for printf. */
+
+/* ------------------------------------------------------------------ */
+/* 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
+libc_hidden_def(___decimal32ToEngString) /* Used internally in libc for printf. */
+
+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
+ uInt *pu; // work
+ char *s, *t; // .. (source, target)
+ Int dpd; // ..
+ Int pre, e; // ..
+ const uByte *u; // ..
+ uInt sour; // source 32-bit
+
+ // load source from storage; this may be endian, or not
+ #if DECENDIAN
+ // DECENDIAN -- direct load
+ pu=(uInt *)d32->bytes; // overlay
+ sour=*pu; // directly load the int
+ #else
+ // not DECENDIAN -- use network byte order
+ if (LITEND) { // little-endian needs reversal
+ const uByte *pb; // work
+ sour=0; // [keep compiler quiet]
+ for (pb=d32->bytes; pb<=&d32->bytes[3]; pb++) {
+ sour<<=8;
+ sour|=*pb;
+ } // i
+ }
+ else { // big-endian; it's the right way round already
+ pu=(uInt *)d32->bytes; // overlay
+ sour=*pu; // directly load the int
+ }
+ #endif
+
+ 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, "Infinity");
+ 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 */
+libc_hidden_def (___decimal32ToString) /* Used internally in libc for printf. */
+
+/* ------------------------------------------------------------------ */
+/* 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. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+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 */
+#endif /* NOT_IN_libc */
+
+#if DECTRACE || DECCHECK
+/* ------------------------------------------------------------------ */
+/* ___decimal32Show -- display a decimal32 in hexadecimal [debug aid] */
+/* d32 -- the number to show */
+/* ------------------------------------------------------------------ */
+// Also shows sign/cob/expconfields extracted - valid bigendian only
+#if defined NOT_IN_libc /* Don't build this into libc. */
+void ___decimal32Show(const decimal32 *d32) {
+ char buf[DECIMAL32_Bytes*2+1];
+ Int i, j=0;
+
+ #if DECENDIAN
+ if (LITEND) {
+ 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 {
+ #endif
+ 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));
+ #if DECENDIAN
+ }
+ #endif
+} /* ___decimal32Show */
+#endif /* NOT_IN_libc */
+#endif /* DECTRACE || DECCHECK */
diff --git a/libc/dfp/decimal32.h b/libc/dfp/decimal32.h
new file mode 100644
index 000000000..dfcb8ba2e
--- /dev/null
+++ b/libc/dfp/decimal32.h
@@ -0,0 +1,111 @@
+/* ------------------------------------------------------------------ */
+/* Decimal 32-bit format module header */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#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 // exponent 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
+
+ /* 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);}
+
+ /* ------------------------------------------------------------------ */
+ /* Routines */
+ /* ------------------------------------------------------------------ */
+ // String conversions
+#if defined NOT_IN_libc
+ decimal32 * ___decimal32FromString(decimal32 *, const char *, decContext *);
+#endif
+ char * ___decimal32ToString(const decimal32 *, char *);
+ libc_hidden_proto (___decimal32ToString)
+ char * ___decimal32ToEngString(const decimal32 *, char *);
+ libc_hidden_proto (___decimal32ToEngString)
+
+ // decNumber conversions
+#if defined NOT_IN_libc /* Don't build this into libc */
+ decimal32 * ___decimal32FromNumber(decimal32 *, const decNumber *,
+ decContext *);
+#endif
+ decNumber * ___decimal32ToNumber(const decimal32 *, decNumber *);
+ libc_hidden_proto (___decimal32ToNumber)
+
+#endif /* DECIMAL32 */
diff --git a/libc/dfp/decimal64.c b/libc/dfp/decimal64.c
new file mode 100644
index 000000000..37ceb4117
--- /dev/null
+++ b/libc/dfp/decimal64.c
@@ -0,0 +1,865 @@
+/* ------------------------------------------------------------------ */
+/* Decimal 64-bit format module */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* ------------------------------------------------------------------ */
+/* This module comprises the routines for decimal64 format numbers. */
+/* Conversions are supplied to and from decNumber and String. */
+/* */
+/* No arithmetic routines are included; decNumber provides these. */
+/* */
+/* Error handling is the same as decNumber (qv.). */
+/* ------------------------------------------------------------------ */
+#include <string.h> // [for memset/memcpy]
+#include <stdio.h> // [for printf]
+
+#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] */
+extern const uInt COMBEXP[32], COMBMSD[32];
+libc_hidden_proto (COMBEXP)
+libc_hidden_proto (COMBMSD)
+
+#if defined NOT_IN_libc /* Don't build this into libc */
+extern void ___decDigitsToDPD(const decNumber *, uInt *, Int);
+#endif
+
+extern void ___decDigitsFromDPD(decNumber *, const uInt *, Int);
+libc_hidden_proto (___decDigitsFromDPD)
+
+#if DECTRACE || DECCHECK
+#if defined NOT_IN_libc /* We don't want this in libc. */
+void ___decimal64Show(const decimal64 *); // for debug
+extern void ___decNumberShow(const decNumber *); // ..
+#endif /* NOT_IN_libc */
+#endif
+
+/* compile-time endian tester [assumes sizeof(Int)>1] */
+static const Int mfcone=1; // constant 1
+/* libc_hidden_data_def (mfcone) */
+static const Flag *mfctop=(Flag *)&mfcone; // -> top byte
+/* libc_hidden_data_def (mfctop) */
+#define LITEND *mfctop // named flag; 1=little-endian
+
+/* 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___BIND2DPD 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. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc /* Don't build this into libc */
+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]=__BIND2DPD[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 may be endian, or not
+ #if DECENDIAN
+ // DECENDIAN -- direct store, in the right order
+ pu=(uInt *)d64->bytes; // overlay
+ if (LITEND) {
+ 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
+ }
+ #else
+ // not DECENDIAN -- use network byte order
+ if (LITEND) { // little-endian needs reversal
+ uByte *pb; // work
+ Int off; // ..
+ for (pb=&d64->bytes[7]; pb>=d64->bytes; pb--) {
+ off=1-((pb-d64->bytes)>>2); // 0 then 1
+ *pb=(uByte)(targar[off]&0xff);
+ targar[off]>>=8;
+ } // i
+ }
+ else { // big-endian; it's the right way round already
+ pu=(uInt *)d64->bytes; // overlay
+ pu[0]=targar[1]; // directly store the high int
+ pu[1]=targar[0]; // then the low int
+ }
+ #endif
+
+ if (status!=0) ___decContextSetStatus(set, status); // pass on status
+ // ___decimal64Show(d64);
+ return d64;
+} /* ___decimal64FromNumber */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___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
+ 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 may be endian, or not
+ #if DECENDIAN
+ // DECENDIAN -- direct load, in the right order
+ pu=(uInt *)d64->bytes; // overlay
+ if (LITEND) {
+ 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
+ }
+ #else
+ // not DECENDIAN -- use network byte order
+ if (LITEND) { // little-endian needs reversal
+ const uByte *pb; // work
+ Int off; // ..
+ for (pb=d64->bytes; pb<=&d64->bytes[7]; pb++) {
+ off=1-((pb-d64->bytes)>>2); // 1 then 0
+ sourar[off]<<=8;
+ sourar[off]|=*pb;
+ } // i
+ }
+ else { // big-endian; it's the right way round already
+ pu=(uInt *)d64->bytes; // overlay
+ sourhi=pu[0]; // directly load the high int
+ sourlo=pu[1]; // then the low int
+ }
+ #endif
+
+ 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 */
+libc_hidden_def (___decimal64ToNumber) /* Used internally in libc for printf. */
+
+/* ------------------------------------------------------------------ */
+/* 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 */
+libc_hidden_def (___decimal64ToEngString) /* Used internally in libc for printf. */
+
+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
+ 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 may be endian, or not
+ #if DECENDIAN
+ // DECENDIAN -- direct load, in the right order
+ pu=(uInt *)d64->bytes; // overlay
+ if (LITEND) {
+ 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
+ }
+ #else
+ // not DECENDIAN -- use network byte order
+ if (LITEND) { // little-endian needs reversal
+ const uByte *pb; // work
+ Int off; // ..
+ for (pb=d64->bytes; pb<=&d64->bytes[7]; pb++) {
+ off=1-((pb-d64->bytes)>>2); // 1 then 0
+ sourar[off]<<=8;
+ sourar[off]|=*pb;
+ } // i
+ }
+ else { // big-endian; it's the right way round already
+ pu=(uInt *)d64->bytes; // overlay
+ sourhi=pu[0]; // directly load the high int
+ sourlo=pu[1]; // then the low int
+ }
+ #endif
+
+ 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, "Infinity");
+ 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 */
+libc_hidden_def(___decimal64ToString) /* Used internally in libc for printf. */
+
+/* ------------------------------------------------------------------ */
+/* 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. */
+/* ------------------------------------------------------------------ */
+#if defined NOT_IN_libc
+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 */
+#endif
+
+#if DECTRACE || DECCHECK
+/* ------------------------------------------------------------------ */
+/* ___decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
+/* d64 -- the number to show */
+/* ------------------------------------------------------------------ */
+// Also shows sign/cob/expconfields extracted
+#if defined NOT_IN_libc /* We don't want this in libc. */
+void ___decimal64Show(const decimal64 *d64) {
+ char buf[DECIMAL64_Bytes*2+1];
+ Int i, j=0;
+
+ #if DECENDIAN
+ if (LITEND) {
+ 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 {
+ #endif
+ 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));
+ #if DECENDIAN
+ }
+ #endif
+} /* ___decimal64Show */
+#endif /* NOT_IN_libc */
+#endif /* DECTRACE || DECCHECK */
+
+/* ================================================================== */
+/* 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};
+libc_hidden_data_def (COMBEXP)
+libc_hidden_data_def (COMBMSD)
+
+/* ------------------------------------------------------------------ */
+/* ___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)
+
+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*__powers[cut];
+ next+=quot;
+ #else
+ uInt rem=*source%__powers[cut];
+ next+=*source/__powers[cut];
+ #endif
+ if (target<=first) *target=(Unit)next; // write to target iff valid
+ next=rem*__powers[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=__BIND2DPD[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 */
+#endif /* NOT_IN_libc */
+
+/* ------------------------------------------------------------------ */
+/* ___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*__powers[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*__powers[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*__powers[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=&__powers[4]; *last>=*pow; pow++) dn->digits++;
+ #endif
+ #endif
+ #endif
+ #endif
+ return;
+} /* ___decDigitsFromDPD */
+libc_hidden_def(___decDigitsFromDPD) /* Used in libc by decimal string functions. */
diff --git a/libc/dfp/decimal64.h b/libc/dfp/decimal64.h
new file mode 100644
index 000000000..721b26dc0
--- /dev/null
+++ b/libc/dfp/decimal64.h
@@ -0,0 +1,113 @@
+/* ------------------------------------------------------------------ */
+/* Decimal 64-bit format module header */
+/* ------------------------------------------------------------------ */
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Contributed by IBM Corporation.
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#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 // exponent 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
+
+ /* 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);}
+
+ /* ------------------------------------------------------------------ */
+ /* Routines */
+ /* ------------------------------------------------------------------ */
+ // String conversions
+#if defined NOT_IN_libc /* Don't build this into libc */
+ decimal64 * ___decimal64FromString(decimal64 *, const char *, decContext *);
+#endif /* NOT_IN_libc */
+ char * ___decimal64ToString(const decimal64 *, char *);
+ libc_hidden_proto (___decimal64ToString)
+ char * ___decimal64ToEngString(const decimal64 *, char *);
+ libc_hidden_proto (___decimal64ToEngString)
+
+ // decNumber conversions
+#if defined NOT_IN_libc /* Don't build this into libc */
+ decimal64 * ___decimal64FromNumber(decimal64 *, const decNumber *,
+ decContext *);
+#endif
+ decNumber * ___decimal64ToNumber(const decimal64 *, decNumber *);
+ libc_hidden_proto (___decimal64ToNumber)
+
+#endif
diff --git a/libc/dfp/decode-decimal.c b/libc/dfp/decode-decimal.c
new file mode 100644
index 000000000..a417d846b
--- /dev/null
+++ b/libc/dfp/decode-decimal.c
@@ -0,0 +1,50 @@
+/* Functions to print the HOST _Decimal information to use with printf %Z
+ This is the default no-op version.
+ Copyright (C) 2006, 2007 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#include <decode-decimal.h>
+
+char * __decoded32 (_Decimal32 a, char * str)
+{
+ return str;
+}
+#if defined NOT_IN_libc
+ weak_alias (__decoded32, decoded32)
+#endif
+libc_hidden_def(__decoded32)
+
+char * __decoded64 ( _Decimal64 a, char * str )
+{
+ return str;
+}
+#if defined NOT_IN_libc
+ weak_alias (__decoded64, decoded64)
+#endif
+libc_hidden_def(__decoded64)
+
+char * __decoded128 ( _Decimal128 a, char * str )
+{
+ return str;
+}
+#if defined NOT_IN_libc
+ weak_alias (__decoded128, decoded128)
+#endif
+libc_hidden_def(__decoded128)
diff --git a/libc/dfp/decode-decimal.h b/libc/dfp/decode-decimal.h
new file mode 100644
index 000000000..7c940507b
--- /dev/null
+++ b/libc/dfp/decode-decimal.h
@@ -0,0 +1,42 @@
+/* Prototype for converting a _Decimal* number into a string
+
+ Copyright (C) 2007 IBM Corporation.
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DISP_DECIMAL_H
+#define _DISP_DECIMAL_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* char * should ref 14 bytes, +0,000,000E+0\0 */
+extern char * __decoded32 (_Decimal32, char*);
+/* char * should ref 26 bytes, +0,000,000,000,000,000E+0\0 */
+extern char * __decoded64 (_Decimal64, char*);
+/* char * should ref 50 bytes, * +0,000,000,000,000,000,000,000,000,000,000,000E+0\0 */
+extern char * __decoded128 (_Decimal128, char*);
+
+libc_hidden_proto(__decoded32)
+libc_hidden_proto(__decoded64)
+libc_hidden_proto(__decoded128)
+
+__END_DECLS
+
+#endif
diff --git a/libc/dfp/dfpfenv_private.h b/libc/dfp/dfpfenv_private.h
new file mode 100644
index 000000000..7d3db38e3
--- /dev/null
+++ b/libc/dfp/dfpfenv_private.h
@@ -0,0 +1,28 @@
+/* Internal prototypes for fetching/changing the decimal rounding mode
+
+ Copyright (C) 2006 IBM Corporation.
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DFPFENV_PRIVATE_
+#define _DFPFENV_PRIVATE_
+
+extern int __fe_dec_setround(int __rounding_direction);
+extern int __fe_dec_getround(void);
+
+#endif /* _DFPFENV_PRIVATE_ */
diff --git a/libc/dfp/dfptypeconv.c b/libc/dfp/dfptypeconv.c
new file mode 100644
index 000000000..915368696
--- /dev/null
+++ b/libc/dfp/dfptypeconv.c
@@ -0,0 +1,131 @@
+/* DFP_C_TYPE to/from IEEE DFP type conversion routines definitions
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#include "dfptypeconv128.h"
+#include "dfptypeconv64.h"
+#include "dfptypeconv32.h"
+#include <string.h>
+#include <endian.h>
+
+typedef struct {
+ char elem[4];
+} bytes32;
+
+#define SWAPBYTES(s,d) \
+ (d)->elem[0] = (s)->elem[3]; \
+ (d)->elem[1] = (s)->elem[2]; \
+ (d)->elem[2] = (s)->elem[1]; \
+ (d)->elem[3] = (s)->elem[0];
+
+
+void ___host_to_ieee_32 (_Decimal32 *src, decimal32 *dest) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(dest, src, 4);
+#else
+ bytes32 *s, *d;
+ s = (bytes32*) src;
+ d = (bytes32*) dest;
+ SWAPBYTES(s,d);
+#endif
+}
+
+void ___host_to_ieee_64 (_Decimal64 *src, decimal64 *dest) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(dest, src, 8);
+#else
+ bytes32 *s, *d;
+ s = (bytes32*) src;
+ d = (bytes32*) dest;
+ ++d;
+ SWAPBYTES(s,d);
+ --d; ++s;
+ SWAPBYTES(s,d);
+#endif
+}
+
+void ___host_to_ieee_128 (_Decimal128 *src, decimal128 *dest) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(dest, src, 16);
+#else
+ bytes32 *s, *d;
+ s = (bytes32*) src;
+ d = (bytes32*) dest;
+ d += 3;
+ SWAPBYTES(s,d);
+ --d; ++s;
+ SWAPBYTES(s,d);
+ --d; ++s;
+ SWAPBYTES(s,d);
+ --d; ++s;
+ SWAPBYTES(s,d);
+#endif
+}
+
+void ___ieee_32_to_host (decimal32 *src, _Decimal32 *dest) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(dest, src, 4);
+#else
+ bytes32 *s, *d;
+ s = (bytes32*) src;
+ d = (bytes32*) dest;
+ SWAPBYTES(s,d);
+#endif
+}
+
+void ___ieee_64_to_host (decimal64 *src, _Decimal64 *dest) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(dest, src, 8);
+#else
+ bytes32 *s, *d;
+ s = (bytes32*) src;
+ d = (bytes32*) dest;
+ ++d;
+ SWAPBYTES(s,d);
+ --d; ++s;
+ SWAPBYTES(s,d);
+#endif
+}
+
+void ___ieee_128_to_host (decimal128 *src, _Decimal128 *dest) {
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy(dest, src, 16);
+#else
+ bytes32 *s, *d;
+ s = (bytes32*) src;
+ d = (bytes32*) dest;
+ d += 3;
+ SWAPBYTES(s,d);
+ --d; ++s;
+ SWAPBYTES(s,d);
+ --d; ++s;
+ SWAPBYTES(s,d);
+ --d; ++s;
+ SWAPBYTES(s,d);
+#endif
+}
+
+libc_hidden_def(___host_to_ieee_32)
+libc_hidden_def(___host_to_ieee_64)
+libc_hidden_def(___host_to_ieee_128)
+libc_hidden_def(___ieee_32_to_host)
+libc_hidden_def(___ieee_64_to_host)
+libc_hidden_def(___ieee_128_to_host)
diff --git a/libc/dfp/dfptypeconv128.h b/libc/dfp/dfptypeconv128.h
new file mode 100644
index 000000000..381317d86
--- /dev/null
+++ b/libc/dfp/dfptypeconv128.h
@@ -0,0 +1,44 @@
+/* DFP_C_TYPE to/from IEEE DFP type conversion routine prototypes
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/*
+ The decNumber library utilizes the IEEE 754r proposed types of
+ decimal32, decimal64, and decimal128 which are structs of byte
+ arrays. The GLIBC supported types are based upon the ANSI C
+ Standards body WG14 1176 Technical Report and are types
+ _Decimal32, _Decimal64, _Decimal128. This header files provides
+ prototypes for converting to and from both types. */
+
+#ifndef _DFP_TYPE_CONV128_H
+#define _DFP_TYPE_CONV128_H 1
+
+#include <decimal128.h>
+
+/* These shouldn't be exposed externally. The users shouldn't
+ care about the IEEE 754r types. */
+extern void ___host_to_ieee_128 (_Decimal128 *, decimal128 *);
+extern void ___ieee_128_to_host (decimal128 *, _Decimal128 *);
+
+libc_hidden_proto(___host_to_ieee_128)
+libc_hidden_proto(___ieee_128_to_host)
+
+#endif /* _DFP_TYPE_CONV128_H */
diff --git a/libc/dfp/dfptypeconv32.h b/libc/dfp/dfptypeconv32.h
new file mode 100644
index 000000000..3d31b74c5
--- /dev/null
+++ b/libc/dfp/dfptypeconv32.h
@@ -0,0 +1,44 @@
+/* DFP_C_TYPE to/from IEEE DFP type conversion routine prototypes
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/*
+ The decNumber library utilizes the IEEE 754r proposed types of
+ decimal32, decimal64, and decimal128 which are structs of byte
+ arrays. The GLIBC supported types are based upon the ANSI C
+ Standards body WG14 1176 Technical Report and are types
+ _Decimal32, _Decimal64, _Decimal128. This header files provides
+ prototypes for converting to and from both types. */
+
+#ifndef _DFP_TYPE_CONV32_H
+#define _DFP_TYPE_CONV32_H 1
+
+#include <decimal32.h>
+
+/* These shouldn't be exposed externally. The users shouldn't
+ care about the IEEE 754r types. */
+extern void ___host_to_ieee_32 (_Decimal32 *, decimal32 *);
+extern void ___ieee_32_to_host (decimal32 *, _Decimal32 *);
+
+libc_hidden_proto(___host_to_ieee_32)
+libc_hidden_proto(___ieee_32_to_host)
+
+#endif /* _DFP_TYPE_CONV32_H */
diff --git a/libc/dfp/dfptypeconv64.h b/libc/dfp/dfptypeconv64.h
new file mode 100644
index 000000000..095055a0f
--- /dev/null
+++ b/libc/dfp/dfptypeconv64.h
@@ -0,0 +1,44 @@
+/* DFP_C_TYPE to/from IEEE DFP type conversion routine prototypes
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/*
+ The decNumber library utilizes the IEEE 754r proposed types of
+ decimal32, decimal64, and decimal128 which are structs of byte
+ arrays. The GLIBC supported types are based upon the ANSI C
+ Standards body WG14 1176 Technical Report and are types
+ _Decimal32, _Decimal64, _Decimal128. This header files provides
+ prototypes for converting to and from both types. */
+
+#ifndef _DFP_TYPE_CONV64_H
+#define _DFP_TYPE_CONV64_H 1
+
+#include <decimal64.h>
+
+/* These shouldn't be exposed externally. The users shouldn't
+ care about the IEEE 754r types. */
+extern void ___host_to_ieee_64 (_Decimal64 *, decimal64 *);
+extern void ___ieee_64_to_host (decimal64 *, _Decimal64 *);
+
+libc_hidden_proto(___host_to_ieee_64)
+libc_hidden_proto(___ieee_64_to_host)
+
+#endif /* _DFP_TYPE_CONV64_H */
diff --git a/libc/dfp/fmt_d128.c b/libc/dfp/fmt_d128.c
new file mode 100644
index 000000000..2fd0d1716
--- /dev/null
+++ b/libc/dfp/fmt_d128.c
@@ -0,0 +1,25 @@
+/* Macroized version of the decimal floatiing point string formatting functions.
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+#include <dfptypeconv128.h>
+#include "fmt_d32.c"
diff --git a/libc/dfp/fmt_d32.c b/libc/dfp/fmt_d32.c
new file mode 100644
index 000000000..a05f3eb9f
--- /dev/null
+++ b/libc/dfp/fmt_d32.c
@@ -0,0 +1,181 @@
+/* Macroized version of the decimal floatiing point string formatting functions.
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+# include <dfptypeconv32.h>
+#endif
+
+#include <fmt_dfp.h>
+
+#define FUNCTION_NAME fmt_
+
+#include <dfpmacro.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+/* DECIMAL128_Pmax + 14 (where '14' represents all the extra characters present
+ * in the output string). Defined here so we avoid including <decimal128.h>. */
+#define MAX_DECIMAL128_STRING 48
+
+/* Thirty-five array indices will account for the available number of digits of
+ * precision for a _Decimal128. */
+static _Decimal128 powof10 [] =
+ { 1.e0dl, 1.e1dl, 1.e2dl, 1.e3dl,
+ 1.e4dl, 1.e5dl, 1.e6dl, 1.e7dl,
+ 1.e8dl, 1.e9dl, 1.e10dl, 1.e11dl,
+ 1.e12dl, 1.e13dl, 1.e14dl, 1.e15dl,
+ 1.e16dl, 1.e17dl, 1.e18dl, 1.e19dl,
+ 1.e20dl, 1.e21dl, 1.e22dl, 1.e23dl,
+ 1.e24dl, 1.e25dl, 1.e26dl, 1.e27dl,
+ 1.e28dl, 1.e29dl, 1.e30dl, 1.e31dl,
+ 1.e32dl, 1.e33dl, 1.e34dl };
+
+static _Decimal128 negpowof10 [] =
+ { 1.e0dl, 1.e-1dl, 1.e-2dl, 1.e-3dl,
+ 1.e-4dl, 1.e-5dl, 1.e-6dl, 1.e-7dl,
+ 1.e-8dl, 1.e-9dl, 1.e-10dl, 1.e-11dl,
+ 1.e-12dl, 1.e-13dl, 1.e-14dl, 1.e-15dl,
+ 1.e-16dl, 1.e-17dl, 1.e-18dl, 1.e-19dl,
+ 1.e-20dl, 1.e-21dl, 1.e-22dl, 1.e-23dl,
+ 1.e-24dl, 1.e-25dl, 1.e-26dl, 1.e-27dl,
+ 1.e-28dl, 1.e-29dl, 1.e-30dl, 1.e-31dl,
+ 1.e-32dl, 1.e-33dl, 1.e-34dl };
+
+/* Stripped down ldexpd128 without NaN or Infinity detection. */
+static _Decimal128
+__dfp_printf_ldexpd128 (_Decimal128 x, int y)
+{
+ if (y == 0)
+ return x;
+ if (y > 0)
+ return (x * (10 * powof10[y]));
+ else
+ return (x * (10 * negpowof10[-(y)]));
+}
+
+static _Decimal128 __dfp_adjust_precision(_Decimal128 x, int prec)
+{
+ _Decimal128 deconst;
+ _Decimal128 y = x;
+ int powof10 = (34 - prec);
+
+ if (x==0.0DL || __builtin_isnand128(x) || __builtin_isinfd128(x))
+ return x;
+
+ /* Get a number which, when added to 'x' causes the bits outside of the
+ * desired precision to be outside of the representable number of digits
+ * for a _Decimal128 (i.e. 34 digits). e.g.
+ * 0.01235 with a requested precision of '4' expects 0.0124
+ * 100000000000000000000000000000.0000|<- precision boundary for _Decimal128
+ * + 0.01235<- guard digit causes rounding
+ * -----------------------------------
+ * 100000000000000000000000000000.0124
+ * - 100000000000000000000000000000.0000
+ * -----------------------------------
+ * 0.0124
+ */
+ deconst = __dfp_printf_ldexpd128(0.01DL, powof10);
+ if (x<0.0DL)
+ deconst = -(deconst); /* reverse the forthcoming operation. */
+
+ /* exceed the number of available digits, the guard digit causes rounding. */
+ x += deconst;
+ x -= deconst;
+
+ if (x==0.0DL && y < 0.0DL)
+ return (-0.0DL); /* Explicitly return -0.0 because GCC is too smart. */
+ return x;
+}
+
+/* slen should be DECIMAL128_Pmax + 14 + info->width + 1 (for '\0') */
+char * INTERNAL_FUNCTION_NAME ( const struct printf_info *info,
+ const void *const *args,
+ char * str,
+ int slen)
+{
+ DEC_TYPE *y = (DEC_TYPE *)args[0];
+ DEC_TYPE z; /* Used if we need to adjust the precision. */
+ char dtos[MAX_DECIMAL128_STRING];
+ uint32_t dtoslen = 0;
+ char * padded = str; /* Used if there is extra width padding necessary. */
+
+ if (!str || slen <= 0)
+ return NULL;
+
+ memset(dtos, 0x0, MAX_DECIMAL128_STRING);
+
+ /* Overwrite 'z' with a precision adjusted _Decimal[32|64|128] per the printf
+ * format precision flag. */
+ if (info->prec > 0)
+ z = (DEC_TYPE)__dfp_adjust_precision((DEC_TYPE)*y, info->prec);
+ else
+ z = *y;
+
+ if (info->spec == 'E' || info->spec == 'e')
+ {
+ IEEE_DECIMAL_TO_ENG_STRING(&z, dtos);
+ }
+ else
+ IEEE_DECIMAL_TO_STRING(&z, dtos);
+
+ dtoslen = strlen(dtos);
+
+ /* We don't need to pad if dtoslen exceeds the width flag, or if no width flag
+ * is set. */
+ if (info->width && (dtoslen < info->width))
+ {
+ wchar_t pad = ' '; /* default padding */
+ int padnum;
+
+ if (info->pad)
+ pad = info->pad;
+
+ padnum = info->width - dtoslen;
+
+ /* Justification indicates where padding is placed. */
+ if (!info->left)
+ {
+ memset(str, pad, padnum);
+ padded = str + padnum;
+ }
+ else
+ memset(str + dtoslen, pad, padnum);
+ /* No need in this case to adjust 'padded' from the beginning of 'str'. */
+
+ str[info->width] = 0x0;
+ }
+ else /* Set the null terminator before copying the string. */
+ str[dtoslen] = 0x0;
+
+ strncpy(padded, dtos, dtoslen);
+ memset(dtos, 0x0, MAX_DECIMAL128_STRING);
+
+ return str;
+}
+#if defined NOT_IN_libc
+ weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
+#endif
+libc_hidden_def(INTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/fmt_d64.c b/libc/dfp/fmt_d64.c
new file mode 100644
index 000000000..854e88d80
--- /dev/null
+++ b/libc/dfp/fmt_d64.c
@@ -0,0 +1,25 @@
+/* Macroized version of the decimal floating point string formatting functions.
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+#include <dfptypeconv64.h>
+#include "fmt_d32.c"
diff --git a/libc/dfp/fmt_dfp.h b/libc/dfp/fmt_dfp.h
new file mode 100644
index 000000000..3ef93098e
--- /dev/null
+++ b/libc/dfp/fmt_dfp.h
@@ -0,0 +1,51 @@
+/* Prototype for converting a _Decimal* number into a string
+
+ Copyright (C) 2006 IBM Corporation.
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _FMT_DFP_H
+#define _FMT_DFP_H 1
+
+#include <features.h>
+#include <printf.h>
+
+__BEGIN_DECLS
+
+extern char * __fmt_d32 ( const struct printf_info *info,
+ const void *const *args,
+ char * str,
+ int slen);
+
+extern char * __fmt_d64 ( const struct printf_info *info,
+ const void *const *args,
+ char * str,
+ int slen);
+
+extern char * __fmt_d128 ( const struct printf_info *info,
+ const void *const *args,
+ char * str,
+ int slen);
+
+libc_hidden_proto(__fmt_d32)
+libc_hidden_proto(__fmt_d64)
+libc_hidden_proto(__fmt_d128)
+
+__END_DECLS
+
+#endif
diff --git a/libc/dfp/gen-libdfp-test.pl b/libc/dfp/gen-libdfp-test.pl
new file mode 100755
index 000000000..7de91052c
--- /dev/null
+++ b/libc/dfp/gen-libdfp-test.pl
@@ -0,0 +1,917 @@
+#!/usr/bin/perl -w
+# Copyright (C) 1999, 2006, 2007 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+# Modified for Decimal Floating Point by:
+# Ryan S. Arnold <rsa@us.ibm.com>, 2007
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+# This file needs to be tidied up
+# Note that functions and tests share the same namespace.
+
+# Information about tests are stored in: %results
+# $results{$test}{"kind"} is either "fct" or "test" and flags whether this
+# is a maximal error of a function or a single test.
+# $results{$test}{"type"} is the result type, e.g. normal or complex.
+# $results{$test}{"has_ulps"} is set if deltas exist.
+# $results{$test}{"has_fails"} is set if expected failures exist.
+# In the following description $type and $float are:
+# - $type is either "normal", "real" (for the real part of a complex number)
+# or "imag" (for the imaginary part # of a complex number).
+# - $float is either of float, ifloat, double, idouble, ldouble, ildouble;
+# It represents the underlying floating point type (float, double or long
+# double) and if inline functions (the leading i stands for inline)
+# are used.
+# $results{$test}{$type}{"fail"}{$float} is defined and has a 1 if
+# the test is expected to fail
+# $results{$test}{$type}{"ulp"}{$float} is defined and has a delta as value
+
+
+use Getopt::Std;
+
+use strict;
+
+use vars qw ($input $output);
+use vars qw (%results);
+use vars qw (@tests @functions);
+use vars qw ($count);
+use vars qw (%beautify @all_floats);
+use vars qw ($output_dir $ulps_file);
+
+# all_floats is sorted and contains all recognised float types
+@all_floats = ('double', 'float', 'idouble',
+ 'ifloat', 'ildouble', 'ldouble',
+ 'd128', 'd64', 'd32');
+
+%beautify =
+ ( "minus_zero" => "-0",
+ "plus_zero" => "+0",
+ "minus_infty" => "-inf",
+ "plus_infty" => "inf",
+ "nan_value" => "NaN",
+ "M_El" => "e",
+ "M_E2l" => "e^2",
+ "M_E3l" => "e^3",
+ "M_LOG10El", "log10(e)",
+ "M_PIl" => "pi",
+ "M_PI_34l" => "3/4 pi",
+ "M_PI_2l" => "pi/2",
+ "M_PI_4l" => "pi/4",
+ "M_PI_6l" => "pi/6",
+ "M_PI_34_LOG10El" => "3/4 pi*log10(e)",
+ "M_PI_LOG10El" => "pi*log10(e)",
+ "M_PI2_LOG10El" => "pi/2*log10(e)",
+ "M_PI4_LOG10El" => "pi/4*log10(e)",
+ "M_LOG_SQRT_PIl" => "log(sqrt(pi))",
+ "M_LOG_2_SQRT_PIl" => "log(2*sqrt(pi))",
+ "M_2_SQRT_PIl" => "2 sqrt (pi)",
+ "M_SQRT_PIl" => "sqrt (pi)",
+ "INVALID_EXCEPTION" => "invalid exception",
+ "DIVIDE_BY_ZERO_EXCEPTION" => "division by zero exception",
+ "INVALID_EXCEPTION_OK" => "invalid exception allowed",
+ "DIVIDE_BY_ZERO_EXCEPTION_OK" => "division by zero exception allowed",
+ "EXCEPTIONS_OK" => "exceptions allowed",
+ "IGNORE_ZERO_INF_SIGN" => "sign of zero/inf not specified",
+ "INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN" => "invalid exception and sign of zero/inf not specified"
+ );
+
+
+# get Options
+# Options:
+# u: ulps-file
+# h: help
+# o: output-directory
+# n: generate new ulps file
+use vars qw($opt_u $opt_h $opt_o $opt_n);
+getopts('u:o:nh');
+
+$ulps_file = 'libdfp-test-ulps';
+$output_dir = '';
+
+if ($opt_h) {
+ print "Usage: gen-libdfp-test.pl [OPTIONS]\n";
+ print " -h print this help, then exit\n";
+ print " -o DIR directory where generated files will be placed\n";
+ print " -n only generate sorted file NewUlps from libm-test-ulps\n";
+ print " -u FILE input file with ulps\n";
+ exit 0;
+}
+
+$ulps_file = $opt_u if ($opt_u);
+$output_dir = $opt_o if ($opt_o);
+
+$input = "libdfp-test.inc";
+$output = "${output_dir}libdfp-test.c";
+
+$count = 0;
+
+&parse_ulps ($ulps_file);
+&generate_testfile ($input, $output) unless ($opt_n);
+&output_ulps ("${output_dir}libdfp-test-ulps.h", $ulps_file) unless ($opt_n);
+&print_ulps_file ("${output_dir}NewUlps") if ($opt_n);
+
+# Return a nicer representation
+sub beautify {
+ my ($arg) = @_;
+ my ($tmp);
+
+ if (exists $beautify{$arg}) {
+ return $beautify{$arg};
+ }
+ if ($arg =~ /^-/) {
+ $tmp = $arg;
+ $tmp =~ s/^-//;
+ if (exists $beautify{$tmp}) {
+ return '-' . $beautify{$tmp};
+ }
+ }
+ # NEW
+ # Check to see if there are multiple args arithmetically joined together that each need
+ # beautification e.g. M_PI6l*2.0 -> pi/6*2.0, M_PI6l-4.0
+ if ((($arg =~ /\*/) || ($arg =~ /-/) || ($arg =~ /\+/) || ($arg =~ /\//) )) {
+ my $tmpret;
+ my @tmpargs = split(/([\*\/\+-])/,$arg);
+ for (my $i = 0; $i <= $#tmpargs; $i++) {
+ $tmpargs[$i] =~ s/^\s*(.*?)\s*$/$1/; # Eat spaces
+ if ((($tmpargs[$i] =~ /\*/) || ($tmpargs[$i] =~ /-/) || ($tmpargs[$i] =~ /\+/) || ($tmpargs[$i] =~ /\//) )) {
+ $tmpret .= $tmpargs[$i];
+ } else {
+ $tmpret .= beautify($tmpargs[$i]);
+ }
+ }
+ return $tmpret;
+ }
+ # END NEW
+ if ($arg =~ /[0-9]L$/) {
+ $arg =~ s/L$//;
+ }
+ return $arg;
+}
+
+# Return a nicer representation of a complex number
+sub build_complex_beautify {
+ my ($r, $i) = @_;
+ my ($str1, $str2);
+
+ $str1 = &beautify ($r);
+ $str2 = &beautify ($i);
+ if ($str2 =~ /^-/) {
+ $str2 =~ s/^-//;
+ $str1 .= ' - ' . $str2;
+ } else {
+ $str1 .= ' + ' . $str2;
+ }
+ $str1 .= ' i';
+ return $str1;
+}
+
+# Return name of a variable
+sub get_variable {
+ my ($number) = @_;
+
+ return "x" if ($number == 1);
+ return "y" if ($number == 2);
+ return "z" if ($number == 3);
+ # return x1,x2,...
+ $number =-3;
+ return "x$number";
+}
+
+# Add a new test to internal data structures and fill in the
+# ulps, failures and exception information for the C line.
+sub new_test {
+ my ($test, $exception) = @_;
+ my $rest;
+
+ # Add ulp, xfail
+ if (exists $results{$test}{'has_ulps'}) {
+ $rest = ", DELTA$count";
+ } else {
+ $rest = ', 0';
+ }
+ if (exists $results{$test}{'has_fails'}) {
+ $rest .= ", FAIL$count";
+ } else {
+ $rest .= ', 0';
+ }
+ if (defined $exception) {
+ $rest .= ", $exception";
+ } else {
+ $rest .= ', 0';
+ }
+ $rest .= ");\n";
+ # We must increment here to keep @tests and count in sync
+ push @tests, $test;
+ ++$count;
+ return $rest;
+}
+
+# Treat some functions especially.
+# Currently only sincos needs extra treatment.
+sub special_functions {
+ my ($file, $args) = @_;
+ my (@args, $str, $test, $cline);
+
+ @args = split /,\s*/, $args;
+
+ unless ($args[0] =~ /sincos/) {
+ die ("Don't know how to handle $args[0] extra.");
+ }
+ print $file " FUNC (sincos) ($args[1], &sin_res, &cos_res);\n";
+
+ $str = 'sincos (' . &beautify ($args[1]) . ', &sin_res, &cos_res)';
+ # handle sin
+ $test = $str . ' puts ' . &beautify ($args[2]) . ' in sin_res';
+ if ($#args == 4) {
+ $test .= " plus " . &beautify ($args[4]);
+ }
+
+ $cline = " check_float (\"$test\", sin_res, $args[2]";
+ $cline .= &new_test ($test, $args[4]);
+ print $file $cline;
+
+ # handle cos
+ $test = $str . ' puts ' . &beautify ($args[3]) . ' in cos_res';
+ $cline = " check_float (\"$test\", cos_res, $args[3]";
+ # only tests once for exception
+ $cline .= &new_test ($test, undef);
+ print $file $cline;
+}
+
+sub macroize_args {
+ # Macros
+ #_F(x) | Floating suffix if any, e.g. 1.0, 1.0DL
+ #_L(x) | Long double floating suffix if any, e.g. 1.0L, 1.0DL
+ #_LC(x) | Long double constant suffix if any, e.g. M_PIl, M_PIdl
+ #_C(x) | Floating constant suffix if any, e.g. M_SQRT, M_SQRTdl
+
+ # Macro | e.g. # | Description:
+ #-------------------------------------------------------------------------
+ # x | nan_value | variable
+ # -x | -nan_value | negated variable
+ # x | 0 | Non negative or Positive Zero
+ # -x | -0 | Negative Zero
+ # _F(x) | 0.0 | Positive Zero Float
+ # -_F(x) | -0.0 | Negative Zero Float
+ # x | 1 | Positive Integer
+ # -x | -1 | Negative Integer
+ # x | 145L | Positive 'Long' integer
+ # -x | -145L | Negative 'Long' integer
+ # x | 145LL | Positive 'Long Long' integer
+ # -x | -145LL | Negative 'Long Long' integer
+ # _F(x) | 65.2342 |
+ # _L(x) | 0.12394345L |
+ # -_L(x) | -0.1239345L |
+ # -_L(x) | -12.390625L |
+ # -_L(x) | -5.7e7L | Negated explicit floating point 'e' form
+ # _L(x) | 5.7e7L | Explicit floating point 'e' form
+ # -_F(x) | -7.4e+33 | Negated, Explicit floating point, explicit positive exponent
+ # -_F(x) | -7.4e-33 | Negated, Explicit floating point, negative exponent
+ # _F(x) | 1e6 | 'e' implies floating point
+ # -_F(x) | -1e6 | Negated, 'e' implies floating point
+ # -_L(x) | -1e-7L | Negated, 'e' implies floating point, negative exponent, 'L' suffix
+ # -_L(x) | 1e-7L | 'e' implies floating point, negative exponent, 'L' suffix
+ # _L(x) | 0x1p72L | Hex representation, where 'p' implies floating point, 'L' suffix
+ # _L(x) | 0x1p-72L | Hex representation, where 'p' implies floating point, negative exponent, 'L' suffix
+ # _LC(x) | M_PI_2l | 'M_PI_2' with 'l' suffix
+ # -_LC(x) | -M_PI_4l | Negated 'M_PI_2' with 'l' suffix
+ # _C(x) | M_SQRT_2_2 | Constant with no suffix
+ # -_C(x) | -M_SQRT_2_2 | Negated constant with no suffix
+ # -x * _LC(y) | -3 * M_PI_4l | Preceeding integer multiplied by constant with l suffix
+ # -_F(x) * _LC(y) | -3.0 * M_PI_4l | Preceeding negated float multiplied by constant with l suffix
+ # -x * _C(y) | -3 * M_SQRT_2_2 | Preceeding integer multiplied by constant with no suffix
+ # -_F(x) * _LC(y) | -3.0 * M_SQRT_2_2 | Preceeding negated float multiplied by constant with no suffix
+ # _LC(x) * _F(x) | M_PI_2l*2.0 |
+ # _LC(x) * _L(x) | M_PI_2l*2.0L |
+
+ my $arg = shift;
+
+ my @args;
+ # Check to see if there are multiple args that're lumped together with an
+ # arithmetic operation that each need to be broken apart. Notice the [^eE]
+ # qualifier. It excludes - and + that trail the 'e' form of notation.
+ if ((($arg =~ /\*/) || ($arg =~ /[^eE]-/) || ($arg =~ /[^eE]\+/) || ($arg =~ /\//) )) {
+ my @tmpargs = split(/([\*\/\+-])/,$arg);
+ for (my $i = 0; $i <= $#tmpargs; $i++) {
+ push(@args, $tmpargs[$i]);
+# if ($i != $#tmpargs) {
+# # Push a '*' between all the args but not after the last arg.
+# push(@args, '*');
+# }
+ }
+ } else {
+ push(@args, "$arg");
+ }
+
+ my $out="";
+ for (my $i = 0; $i <= $#args; $i++) {
+ $args[$i] =~ s/^\s*(.*?)\s*$/$1/; # Eat spaces
+
+ my $constant=""; # Check if it is a constant. This will help determine
+ # the macro that is used.
+ if($args[$i] =~ /M_/) {
+ $constant="yes";
+ } elsif ((!($args[$i] =~ /^0x/))
+ && (!($args[$i] =~ /\de/))
+ && (!($args[$i] =~ /\./))) {
+ # If it isn't a constant, isn't in the 'e' form or the '0x' hex form, or
+ # doesn't include a period to indicate that it is a floating point value
+ # then it is an integer or a multiplication sign and doesn't get
+ # macroized.
+ $out .= "$args[$i]";
+ next;
+ }
+
+ my $sign="";
+ # Check for an explicit sign. This will precede any macro. Don't match
+ # on the - operator.
+ if($args[$i] =~ /^\-.+/){
+ # We made sure we only captured the first '-' sign, e.g. -1.2e-7
+ $sign="-";
+ $args[$i] =~ s/^\-?(.*)/$1/;
+ } elsif ($args[$i] =~ /^\+.+/) { # Don't match on the + operator.
+ # We made sure we only captured the first '+' sign e.g. +1.2e+7
+ $sign="+";
+ $args[$i] =~ s/^\+?(.*)/$1/;
+ }
+
+ my $L=""; # Check for the 'L' float-suffix or the 'l' constant suffix.
+ # This will determine the macro that is used.
+ if($args[$i] =~ /[lL]$/) {
+ $L="yes";
+ $args[$i] =~ s/(.*)[lL]$/$1/;
+ }
+
+ if(($L eq "yes") && ($constant eq "yes")) {
+ $out .= $sign . "_LC($args[$i])";
+ } elsif (($L ne "yes") && ($constant eq "yes")) {
+ $out .= $sign . "_C($args[$i])";
+ } elsif (($L eq "yes") && ($constant ne "yes")) {
+ $out .= $sign . "_L($args[$i])";
+ } elsif (($L ne "yes") && ($constant ne "yes")) {
+ $out .= $sign . "_F($args[$i])";
+ } else {
+ $out .= "$args[$i]";
+ }
+ }
+ return $out;
+}
+
+# Parse and macroize the arguments to FUNC(x) (x, ...)
+sub parse_then_macroize_args {
+}
+
+# Parse the arguments to TEST_x_y
+sub parse_args {
+ my ($file, $descr, $fct, $args) = @_;
+ my (@args, $str, $descr_args, $descr_res, @descr);
+ my ($current_arg, $cline, $i);
+ my ($pre, $post, @special);
+ my ($extra_var, $call, $c_call);
+
+ if ($descr eq 'extra') {
+ &special_functions ($file, $args);
+ return;
+ }
+ ($descr_args, $descr_res) = split /_/,$descr, 2;
+
+ @args = split /,\s*/, $args;
+
+ $call = "$fct (";
+
+ # Generate first the string that's shown to the user
+ $current_arg = 1;
+ $extra_var = 0;
+ @descr = split //,$descr_args;
+ for ($i = 0; $i <= $#descr; $i++) {
+ if ($i >= 1) {
+ $call .= ', ';
+ }
+ # FLOAT, int, long int, long long int
+ if ($descr[$i] =~ /f|i|l|L/) {
+ $call .= &beautify ($args[$current_arg]);
+ ++$current_arg;
+ next;
+ }
+ # &FLOAT, &int - argument is added here
+ if ($descr[$i] =~ /F|I/) {
+ ++$extra_var;
+ $call .= '&' . &get_variable ($extra_var);
+ next;
+ }
+ # complex
+ if ($descr[$i] eq 'c') {
+ $call .= &build_complex_beautify ($args[$current_arg], $args[$current_arg+1]);
+ $current_arg += 2;
+ next;
+ }
+
+ die ("$descr[$i] is unknown");
+ }
+ $call .= ')';
+ $str = "$call == ";
+
+ # Result
+ @descr = split //,$descr_res;
+ foreach (@descr) {
+ if ($_ =~ /f|i|l|L/) {
+ $str .= &beautify ($args[$current_arg]);
+ ++$current_arg;
+ } elsif ($_ eq 'c') {
+ $str .= &build_complex_beautify ($args[$current_arg], $args[$current_arg+1]);
+ $current_arg += 2;
+ } elsif ($_ eq 'b') {
+ # boolean
+ $str .= ($args[$current_arg] == 0) ? "false" : "true";
+ ++$current_arg;
+ } elsif ($_ eq '1') {
+ ++$current_arg;
+ } else {
+ die ("$_ is unknown");
+ }
+ }
+ # consistency check
+ if ($current_arg == $#args) {
+ die ("wrong number of arguments")
+ unless ($args[$current_arg] =~ /EXCEPTION|IGNORE_ZERO_INF_SIGN/);
+ } elsif ($current_arg < $#args) {
+ die ("wrong number of arguments");
+ } elsif ($current_arg > ($#args+1)) {
+ die ("wrong number of arguments");
+ }
+
+
+ # check for exceptions
+ if ($current_arg <= $#args) {
+ $str .= " plus " . &beautify ($args[$current_arg]);
+ }
+
+ # Put the C program line together
+ # Reset some variables to start again
+ $current_arg = 1;
+ $extra_var = 0;
+ if (substr($descr_res,0,1) eq 'f') {
+ $cline = 'check_float'
+ } elsif (substr($descr_res,0,1) eq 'b') {
+ $cline = 'check_bool';
+ } elsif (substr($descr_res,0,1) eq 'c') {
+ $cline = 'check_complex';
+ } elsif (substr($descr_res,0,1) eq 'i') {
+ $cline = 'check_int';
+ } elsif (substr($descr_res,0,1) eq 'l') {
+ $cline = 'check_long';
+ } elsif (substr($descr_res,0,1) eq 'L') {
+ $cline = 'check_longlong';
+ }
+ # Special handling for some macros:
+ $cline .= " (\"$str\", ";
+ if ($args[0] =~ /fpclassify|isnormal|isfinite|signbit/) {
+ $c_call = "$args[0] (";
+ } else {
+ $c_call = " FUNC($args[0]) (";
+ }
+ @descr = split //,$descr_args;
+ for ($i=0; $i <= $#descr; $i++) {
+ if ($i >= 1) {
+ $c_call .= ', ';
+ }
+ # FLOAT, int, long int, long long int
+ if ($descr[$i] =~ /f|i|l|L/) {
+ #$c_call .= $args[$current_arg];
+ $c_call .= &macroize_args($args[$current_arg]);
+ $current_arg++;
+ next;
+ }
+ # &FLOAT, &int
+ if ($descr[$i] =~ /F|I/) {
+ ++$extra_var;
+ $c_call .= '&' . &get_variable ($extra_var);
+ next;
+ }
+ # complex
+ if ($descr[$i] eq 'c') {
+ my $targ1 = &macroize_args($args[$current_arg]);
+ my $targ2 = &macroize_args($args[$current_arg+1]);
+ #$c_call .= "BUILD_COMPLEX ($args[$current_arg], $args[$current_arg+1])";
+ $c_call .= "BUILD_COMPLEX ($targ1, $targ2)";
+ $current_arg += 2;
+ next;
+ }
+ }
+ $c_call .= ')';
+ $cline .= "$c_call, ";
+
+ @descr = split //,$descr_res;
+ foreach (@descr) {
+ if ($_ =~ /b|f|i|l|L/ ) {
+ #$cline .= $args[$current_arg];
+ $cline .= &macroize_args($args[$current_arg]);
+ $current_arg++;
+ } elsif ($_ eq 'c') {
+ my $targ1 = &macroize_args($args[$current_arg]);
+ my $targ2 = &macroize_args($args[$current_arg+1]);
+ #$cline .= "BUILD_COMPLEX ($args[$current_arg], $args[$current_arg+1])";
+ $cline .= "BUILD_COMPLEX ($targ1, $targ2)";
+ $current_arg += 2;
+ } elsif ($_ eq '1') {
+ push @special, &macroize_args($args[$current_arg]);
+ #push @special, $args[$current_arg];
+ ++$current_arg;
+ }
+ }
+ # Add ulp, xfail
+ $cline .= &new_test ($str, ($current_arg <= $#args) ? $args[$current_arg] : undef);
+
+ # special treatment for some functions
+ if ($args[0] eq 'frexp') {
+ if (defined $special[0] && $special[0] ne "IGNORE") {
+ my ($str) = "$call sets x to $special[0]";
+ $post = " check_int (\"$str\", x, $special[0]";
+ $post .= &new_test ($str, undef);
+ }
+ } elsif ($args[0] eq 'gamma' || $args[0] eq 'lgamma') {
+ $pre = " signgam = 0;\n";
+ if (defined $special[0] && $special[0] ne "IGNORE") {
+ my ($str) = "$call sets signgam to $special[0]";
+ $post = " check_int (\"$str\", signgam, $special[0]";
+ $post .= &new_test ($str, undef);
+ }
+ } elsif ($args[0] eq 'modf') {
+ if (defined $special[0] && $special[0] ne "IGNORE") {
+ my ($str) = "$call sets x to $special[0]";
+ $post = " check_float (\"$str\", x, $special[0]";
+ $post .= &new_test ($str, undef);
+ }
+ } elsif ($args[0] eq 'remquo') {
+ if (defined $special[0] && $special[0] ne "IGNORE") {
+ my ($str) = "$call sets x to $special[0]";
+ $post = " check_int (\"$str\", x, $special[0]";
+ $post .= &new_test ($str, undef);
+ }
+ }
+
+ print $file $pre if (defined $pre);
+
+ print $file " $cline";
+
+ print $file $post if (defined $post);
+}
+
+# Generate libm-test.c
+sub generate_testfile {
+ my ($input, $output) = @_;
+ my ($lasttext);
+ my (@args, $i, $str, $thisfct);
+
+ open INPUT, $input or die ("Can't open $input: $!");
+ open OUTPUT, ">$output" or die ("Can't open $output: $!");
+
+ # Replace the special macros
+ while (<INPUT>) {
+
+ my ($descr, $args);
+ # FUNC but exclude the comment FUNC(function)
+ # Macroize the parameters
+ if (/^\s*FUNC\(/ && !(/^\s*FUNC\(function\)/)) {
+ ($descr, $args) = ($_ =~ /FUNC\((\w+)\)\s\((.*)\)/);
+ #print "\$_: $_ \$descr: $descr, \$args: $args\n";
+ my @args = split(/(,\s*)/, $args);
+ my $out="";
+ foreach (@args) {
+ if ($_ =~ /,/) {
+ $out .= ", "
+ } else {
+ $out .= &macroize_args($_);
+ }
+ }
+ print OUTPUT " FUNC($descr) ($out);\n";
+ next;
+ }
+
+ # TEST_...
+ if (/^\s*TEST_/) {
+ chop;
+ ($descr, $args) = ($_ =~ /TEST_(\w+)\s*\((.*)\)/);
+ &parse_args (\*OUTPUT, $descr, $thisfct, $args);
+ next;
+ }
+ # START (function)
+ if (/START/) {
+ ($thisfct) = ($_ =~ /START\s*\((.*)\)/);
+ print OUTPUT " init_max_error ();\n";
+ next;
+ }
+ # END (function)
+ if (/END/) {
+ my ($fct, $line, $type);
+ if (/complex/) {
+ s/,\s*complex\s*//;
+ $type = 'complex';
+ } else {
+ $type = 'normal';
+ }
+ ($fct) = ($_ =~ /END\s*\((.*)\)/);
+ if ($type eq 'complex') {
+ $line = " print_complex_max_error (\"$fct\", ";
+ } else {
+ $line = " print_max_error (\"$fct\", ";
+ }
+ if (exists $results{$fct}{'has_ulps'}) {
+ $line .= "DELTA$fct";
+ } else {
+ $line .= '0';
+ }
+ if (exists $results{$fct}{'has_fails'}) {
+ $line .= ", FAIL$fct";
+ } else {
+ $line .= ', 0';
+ }
+ $line .= ");\n";
+ print OUTPUT $line;
+ push @functions, $fct;
+ next;
+ }
+ print OUTPUT;
+ }
+ close INPUT;
+ close OUTPUT;
+}
+
+
+
+# Parse ulps file
+sub parse_ulps {
+ my ($file) = @_;
+ my ($test, $type, $float, $eps, $kind);
+
+ # $type has the following values:
+ # "normal": No complex variable
+ # "real": Real part of complex result
+ # "imag": Imaginary part of complex result
+ open ULP, $file or die ("Can't open $file: $!");
+ while (<ULP>) {
+ chop;
+ # ignore comments and empty lines
+ next if /^#/;
+ next if /^\s*$/;
+ if (/^Test/) {
+ if (/Real part of:/) {
+ s/Real part of: //;
+ $type = 'real';
+ } elsif (/Imaginary part of:/) {
+ s/Imaginary part of: //;
+ $type = 'imag';
+ } else {
+ $type = 'normal';
+ }
+ s/^.+\"(.*)\".*$/$1/;
+ $test = $_;
+ $kind = 'test';
+ next;
+ }
+ if (/^Function: /) {
+ if (/Real part of/) {
+ s/Real part of //;
+ $type = 'real';
+ } elsif (/Imaginary part of/) {
+ s/Imaginary part of //;
+ $type = 'imag';
+ } else {
+ $type = 'normal';
+ }
+ ($test) = ($_ =~ /^Function:\s*\"([a-zA-Z0-9_]+)\"/);
+ $kind = 'fct';
+ next;
+ }
+ #if (/^i?(float|double|ldouble):/) {
+ if (/^i?(float|double|ldouble|d128|d64|d32):/) {
+ ($float, $eps) = split /\s*:\s*/,$_,2;
+
+ if ($eps eq 'fail') {
+ $results{$test}{$type}{'fail'}{$float} = 1;
+ $results{$test}{'has_fails'} = 1;
+ } elsif ($eps eq "0") {
+ # ignore
+ next;
+ } else {
+ $results{$test}{$type}{'ulp'}{$float} = $eps;
+ $results{$test}{'has_ulps'} = 1;
+ }
+ if ($type =~ /^real|imag$/) {
+ $results{$test}{'type'} = 'complex';
+ } elsif ($type eq 'normal') {
+ $results{$test}{'type'} = 'normal';
+ }
+ $results{$test}{'kind'} = $kind;
+ next;
+ }
+ print "Skipping unknown entry: `$_'\n";
+ }
+ close ULP;
+}
+
+
+# Clean up a floating point number
+sub clean_up_number {
+ my ($number) = @_;
+
+ # Remove trailing zeros
+ $number =~ s/0+$//;
+ $number =~ s/\.$//;
+ return $number;
+}
+
+# Output a file which can be read in as ulps file.
+sub print_ulps_file {
+ my ($file) = @_;
+ my ($test, $type, $float, $eps, $fct, $last_fct);
+
+ $last_fct = '';
+ open NEWULP, ">$file" or die ("Can't open $file: $!");
+ print NEWULP "# Begin of automatic generation\n";
+ # first the function calls
+ foreach $test (sort keys %results) {
+ next if ($results{$test}{'kind'} ne 'test');
+ foreach $type ('real', 'imag', 'normal') {
+ if (exists $results{$test}{$type}) {
+ if (defined $results{$test}) {
+ ($fct) = ($test =~ /^(\w+)\s/);
+ if ($fct ne $last_fct) {
+ $last_fct = $fct;
+ print NEWULP "\n# $fct\n";
+ }
+ }
+ if ($type eq 'normal') {
+ print NEWULP "Test \"$test\":\n";
+ } elsif ($type eq 'real') {
+ print NEWULP "Test \"Real part of: $test\":\n";
+ } elsif ($type eq 'imag') {
+ print NEWULP "Test \"Imaginary part of: $test\":\n";
+ }
+ foreach $float (@all_floats) {
+ if (exists $results{$test}{$type}{'ulp'}{$float}) {
+ print NEWULP "$float: ",
+ &clean_up_number ($results{$test}{$type}{'ulp'}{$float}),
+ "\n";
+ }
+ if (exists $results{$test}{$type}{'fail'}{$float}) {
+ print NEWULP "$float: fail\n";
+ }
+ }
+ }
+ }
+ }
+ print NEWULP "\n# Maximal error of functions:\n";
+
+ foreach $fct (sort keys %results) {
+ next if ($results{$fct}{'kind'} ne 'fct');
+ foreach $type ('real', 'imag', 'normal') {
+ if (exists $results{$fct}{$type}) {
+ if ($type eq 'normal') {
+ print NEWULP "Function: \"$fct\":\n";
+ } elsif ($type eq 'real') {
+ print NEWULP "Function: Real part of \"$fct\":\n";
+ } elsif ($type eq 'imag') {
+ print NEWULP "Function: Imaginary part of \"$fct\":\n";
+ }
+ foreach $float (@all_floats) {
+ if (exists $results{$fct}{$type}{'ulp'}{$float}) {
+ print NEWULP "$float: ",
+ &clean_up_number ($results{$fct}{$type}{'ulp'}{$float}),
+ "\n";
+ }
+ if (exists $results{$fct}{$type}{'fail'}{$float}) {
+ print NEWULP "$float: fail\n";
+ }
+ }
+ print NEWULP "\n";
+ }
+ }
+ }
+ print NEWULP "# end of automatic generation\n";
+ close NEWULP;
+}
+
+sub get_ulps {
+ my ($test, $type, $float) = @_;
+
+ if ($type eq 'complex') {
+ my ($res);
+ # Return 0 instead of BUILD_COMPLEX (0,0)
+ if (!exists $results{$test}{'real'}{'ulp'}{$float} &&
+ !exists $results{$test}{'imag'}{'ulp'}{$float}) {
+ return "0";
+ }
+ $res = 'BUILD_COMPLEX (';
+ $res .= (exists $results{$test}{'real'}{'ulp'}{$float}
+ ? $results{$test}{'real'}{'ulp'}{$float} : "0");
+ $res .= ', ';
+ $res .= (exists $results{$test}{'imag'}{'ulp'}{$float}
+ ? $results{$test}{'imag'}{'ulp'}{$float} : "0");
+ $res .= ')';
+ return $res;
+ }
+ return (exists $results{$test}{'normal'}{'ulp'}{$float}
+ ? $results{$test}{'normal'}{'ulp'}{$float} : "0");
+}
+
+sub get_failure {
+ my ($test, $type, $float) = @_;
+ if ($type eq 'complex') {
+ # return x,y
+ my ($res);
+ # Return 0 instead of BUILD_COMPLEX_INT (0,0)
+ if (!exists $results{$test}{'real'}{'ulp'}{$float} &&
+ !exists $results{$test}{'imag'}{'ulp'}{$float}) {
+ return "0";
+ }
+ $res = 'BUILD_COMPLEX_INT (';
+ $res .= (exists $results{$test}{'real'}{'fail'}{$float}
+ ? $results{$test}{'real'}{'fail'}{$float} : "0");
+ $res .= ', ';
+ $res .= (exists $results{$test}{'imag'}{'fail'}{$float}
+ ? $results{$test}{'imag'}{'fail'}{$float} : "0");
+ $res .= ')';
+ return $res;
+ }
+ return (exists $results{$test}{'normal'}{'fail'}{$float}
+ ? $results{$test}{'normal'}{'fail'}{$float} : "0");
+
+}
+
+# Output the defines for a single test
+sub output_test {
+ my ($file, $test, $name) = @_;
+ my ($ldouble, $double, $float, $ildouble, $idouble, $ifloat, $d128, $d64, $d32);
+ my ($type);
+
+ # Do we have ulps/failures?
+ if (!exists $results{$test}{'type'}) {
+ return;
+ }
+ $type = $results{$test}{'type'};
+ if (exists $results{$test}{'has_ulps'}) {
+ # XXX use all_floats (change order!)
+ $ldouble = &get_ulps ($test, $type, "ldouble");
+ $double = &get_ulps ($test, $type, "double");
+ $float = &get_ulps ($test, $type, "float");
+ $ildouble = &get_ulps ($test, $type, "ildouble");
+ $idouble = &get_ulps ($test, $type, "idouble");
+ $ifloat = &get_ulps ($test, $type, "ifloat");
+ $d128 = &get_ulps ($test, $type, "d128");
+ $d64 = &get_ulps ($test, $type, "d64");
+ $d32 = &get_ulps ($test, $type, "d32");
+ print $file "#define DELTA$name CHOOSE($ldouble, $double, $float, $ildouble, $idouble, $ifloat, $d128, $d64, $d32)\t/* $test */\n";
+ }
+
+ if (exists $results{$test}{'has_fails'}) {
+ $ldouble = &get_failure ($test, "ldouble");
+ $double = &get_failure ($test, "double");
+ $float = &get_failure ($test, "float");
+ $ildouble = &get_failure ($test, "ildouble");
+ $idouble = &get_failure ($test, "idouble");
+ $ifloat = &get_failure ($test, "ifloat");
+ $d128 = &get_failure ($test, $type, "d128");
+ $d64 = &get_failure ($test, $type, "d64");
+ $d32 = &get_failure ($test, $type, "d32");
+ print $file "#define FAIL$name CHOOSE($ldouble, $double, $float, $ildouble, $idouble, $ifloat, $d128, $d64, $d32)\t/* $test */\n";
+ }
+}
+
+# Print include file
+sub output_ulps {
+ my ($file, $ulps_filename) = @_;
+ my ($i, $fct);
+
+ open ULP, ">$file" or die ("Can't open $file: $!");
+
+ print ULP "/* This file is automatically generated\n";
+ print ULP " from $ulps_filename with gen-libm-test.pl.\n";
+ print ULP " Don't change it - change instead the master files. */\n\n";
+
+ print ULP "\n/* Maximal error of functions. */\n";
+ foreach $fct (@functions) {
+ output_test (\*ULP, $fct, $fct);
+ }
+
+ print ULP "\n/* Error of single function calls. */\n";
+ for ($i = 0; $i < $count; $i++) {
+ output_test (\*ULP, $tests[$i], $i);
+ }
+ close ULP;
+}
diff --git a/libc/dfp/libdfp-test-ulps b/libc/dfp/libdfp-test-ulps
new file mode 100644
index 000000000..c6c751251
--- /dev/null
+++ b/libc/dfp/libdfp-test-ulps
@@ -0,0 +1,1541 @@
+# Begin of automatic generation
+
+# acos
+Test "acos (2e-17) == 1.57079632679489659923132169163975144":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# asin
+Test "asin (0.75) == 0.848062078981481008052944338998418080":
+ildouble: 2
+ldouble: 2
+d128: 1
+d64: 1
+d32: 1
+
+# atan2
+Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+
+# cabs
+Test "cabs (0.75 + 1.25 i) == 1.45773797371132511771853821938639577":
+ildouble: 1
+ldouble: 1
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+# casin
+Test "Real part of: casin (-2 - 3 i) == -0.57065278432109940071028387968566963 - 1.9833870299165354323470769028940395 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 1
+ldouble: 1
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+float: 4
+ifloat: 4
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+ifloat: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+float: 6
+ifloat: 6
+
+# cbrt
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+d128: 1
+d64: 1
+d32: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+idouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# ccos
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+float: 1
+ifloat: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+# cexp
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+ildouble: 1
+ldouble: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+ildouble: 1
+ldouble: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "cos (16.0) == -0.9576594803233846418996372326511034717803"
+ildouble: 2
+ldouble: 2
+d128: 1
+d64: 1
+d32: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i":
+ildouble: 2
+ldouble: 2
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+# csinh
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+idouble: 1
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# erfc
+Test "erfc (0.75) == 0.288844366346484868401062165408589223":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+d128: 1
+d64: 1
+d32: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# exp
+Test "exp (0.75) == 2.11700001661267466854536981983709561":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+Test "exp (50.0) == 5184705528587072464087.45332293348538":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 8
+ldouble: 8
+
+# exp2
+Test "exp2 (10) == 1024":
+ildouble: 2
+ldouble: 2
+d128: 1
+d64: 1
+d32: 1
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+idouble: 1
+d128: 1
+d64: 1
+d32: 1
+Test "expm1 (1) == M_El - 1.0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "hypot (0.75, 1.25) == 1.45773797371132511771853821938639577":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# j1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9":
+ildouble: 1
+ldouble: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+float: 1
+ifloat: 1
+ildouble: 4
+ldouble: 4
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 4
+ifloat: 4
+Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+idouble: 1
+Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083":
+ildouble: 1
+ldouble: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+# lgamma
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+d128: 1
+d64: 1
+d32: 1
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+d128: 1
+d64: 1
+d32: 1
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+
+# log1p
+Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+
+# log2
+Test "log2 (e) == M_LOG2El":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# sin
+Test "sin (16.0) == -0.2879033166650652947844562482186175296207"
+ildouble: 2
+ldouble: 2
+d128: 1
+d64: 1
+d32: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+ifloat: 1
+
+# sinh
+Test "sinh (0.75) == 0.822316731935829980703661634446913849":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# tanh
+Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+Test "tanh (0.75) == 0.635148952387287319214434357312496495":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+
+# y0
+Test "y0 (0.75) == -0.137172769385772397522814379396581855":
+ildouble: 1
+ldouble: 1
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "y0 (2.0) == 0.510375672649745119596606592727157873":
+double: 1
+idouble: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 2
+ifloat: 2
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+# yn
+Test "yn (0, 0.75) == -0.137172769385772397522814379396581855":
+ildouble: 1
+ldouble: 1
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (0, 2.0) == 0.510375672649745119596606592727157873":
+double: 1
+idouble: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+float: 2
+ifloat: 2
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+float: 2
+ifloat: 2
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+float: 1
+ifloat: 1
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "acos":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "acosh":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "asin":
+ildouble: 2
+ldouble: 2
+d128: 1
+d64: 1
+d32: 1
+
+Function: "asinh":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "atan2":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "atanh":
+float: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "cabs":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cacos":
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cacos":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+idouble: 1
+ifloat: 7
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+idouble: 1
+ifloat: 3
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "casin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catan":
+float: 4
+ifloat: 4
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+
+Function: Imaginary part of "catanh":
+float: 6
+ifloat: 6
+
+Function: "cbrt":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccosh":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cexp":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "clog":
+float: 3
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "clog10":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+idouble: 1
+ifloat: 5
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "cosh":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 5
+idouble: 2
+ifloat: 5
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cproj":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csin":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csqrt":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "csqrt":
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ctan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ctanh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctanh":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "erf":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "erfc":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "exp":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 8
+ldouble: 8
+
+Function: "exp2":
+ildouble: 2
+ldouble: 2
+d128: 1
+d64: 1
+d32: 1
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "gamma":
+ildouble: 1
+ldouble: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "j0":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "jn":
+double: 3
+float: 4
+idouble: 3
+ifloat: 4
+ildouble: 4
+ldouble: 4
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 3
+ldouble: 3
+d128: 1
+d64: 1
+d32: 1
+
+Function: "log":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "log10":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "log1p":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "log2":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "pow":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "sin":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "sinh":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "tanh":
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+d128: 1
+d64: 1
+d32: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+# end of automatic generation
diff --git a/libc/dfp/libdfp-test.inc b/libc/dfp/libdfp-test.inc
new file mode 100644
index 000000000..dab4282d7
--- /dev/null
+++ b/libc/dfp/libdfp-test.inc
@@ -0,0 +1,6150 @@
+/* Copyright (C) 1997-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1997.
+
+ Modified for Decimal Floating Point by:
+ Ryan S. Arnold <rsa@us.ibm.com>, 2007
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Part of testsuite for libm.
+
+ This file is processed by a perl script. The resulting file has to
+ be included by a master file that defines:
+
+ Macros:
+ FUNC(function): converts general function name (like cos) to
+ name with correct suffix (e.g. cosl or cosf)
+ MATHCONST(x): like FUNC but for constants (e.g convert 0.0 to 0.0L)
+ FLOAT: floating point type to test
+ - TEST_MSG: informal message to be displayed
+ CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat,C_Decimal128,C_Decimal64,C_Decimal32):
+ chooses one of the parameters as delta for testing
+ equality
+ PRINTF_EXPR Floating point conversion specification to print a variable
+ of type FLOAT with printf. PRINTF_EXPR just contains
+ the specifier, not the percent and width arguments,
+ e.g. "f".
+ PRINTF_XEXPR Like PRINTF_EXPR, but print in hexadecimal format.
+ PRINTF_NEXPR Like PRINTF_EXPR, but print nice. */
+
+/* This testsuite has currently tests for:
+ acos, acosh, asin, asinh, atan, atan2, atanh,
+ cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, exp10, exp2, expm1,
+ fabs, fdim, floor, fma, fmax, fmin, fmod, fpclassify,
+ frexp, gamma, hypot,
+ ilogb, isfinite, isinf, isnan, isnormal,
+ isless, islessequal, isgreater, isgreaterequal, islessgreater, isunordered,
+ j0, j1, jn,
+ ldexp, lgamma, log, log10, log1p, log2, logb,
+ modf, nearbyint, nextafter,
+ pow, remainder, remquo, rint, lrint, llrint,
+ round, lround, llround,
+ scalb, scalbn, scalbln, signbit, sin, sincos, sinh, sqrt, tan, tanh, tgamma, trunc,
+ y0, y1, yn, significand
+
+ and for the following complex math functions:
+ cabs, cacos, cacosh, carg, casin, casinh, catan, catanh,
+ ccos, ccosh, cexp, clog, cpow, cproj, csin, csinh, csqrt, ctan, ctanh.
+
+ At the moment the following functions aren't tested:
+ drem, nan
+
+ Parameter handling is primitive in the moment:
+ --verbose=[0..3] for different levels of output:
+ 0: only error count
+ 1: basic report on failed tests (default)
+ 2: full report on all tests
+ -v for full output (equals --verbose=3)
+ -u for generation of an ULPs file
+ */
+
+/* "Philosophy":
+
+ This suite tests some aspects of the correct implementation of
+ mathematical functions in libm. Some simple, specific parameters
+ are tested for correctness but there's no exhaustive
+ testing. Handling of specific inputs (e.g. infinity, not-a-number)
+ is also tested. Correct handling of exceptions is checked
+ against. These implemented tests should check all cases that are
+ specified in ISO C99.
+
+ Exception testing: At the moment only divide-by-zero and invalid
+ exceptions are tested. Overflow/underflow and inexact exceptions
+ aren't checked at the moment.
+
+ NaN values: There exist signalling and quiet NaNs. This implementation
+ only uses quiet NaN as parameter but does not differenciate
+ between the two kinds of NaNs as result.
+
+ Inline functions: Inlining functions should give an improvement in
+ speed - but not in precission. The inlined functions return
+ reasonable values for a reasonable range of input values. The
+ result is not necessarily correct for all values and exceptions are
+ not correctly raised in all cases. Problematic input and return
+ values are infinity, not-a-number and minus zero. This suite
+ therefore does not check these specific inputs and the exception
+ handling for inlined mathematical functions - just the "reasonable"
+ values are checked.
+
+ Beware: The tests might fail for any of the following reasons:
+ - Tests are wrong
+ - Functions are wrong
+ - Floating Point Unit not working properly
+ - Compiler has errors
+
+ With e.g. gcc 2.7.2.2 the test for cexp fails because of a compiler error.
+
+
+ To Do: All parameter should be numbers that can be represented as
+ exact floating point values. Currently some values cannot be
+ represented exactly and therefore the result is not the expected
+ result. For this we will use 36 digits so that numbers can be
+ represented exactly. */
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#ifdef __STDC_WANT_DEC_FP__
+ #include "libdfp-test-ulps.h"
+#else
+ #include "libm-test-ulps.h"
+#endif
+
+#ifndef __STDC_WANT_DEC_FP__
+ #include <complex.h>
+#endif
+#include <math.h>
+#include <float.h>
+#include <fenv.h>
+#include <limits.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <argp.h>
+
+/* These may be overridden by a file which includes this .c file. */
+#ifndef _F
+#define _F(x) x /* Binary floating suffix, e.g. 1.0 */
+#endif
+#ifndef _L
+#define _L(x) x##L /* Binary long double floating suffix */
+#endif
+#ifndef _LC
+#define _LC(x) x##l /* Binary long double constant suffix, e.g. M_PIl */
+#endif
+#ifndef _C
+#define _C(x) x /* Binary floating constant suffix, e.g. M_PI */
+#endif
+
+#ifndef SETROUND
+#define SETROUND(x) fesetround(x)
+#endif
+#ifndef GETROUND
+#define GETROUND(x) fegetround(x)
+#endif
+#ifndef TONEAREST
+#define TONEAREST FE_TONEAREST
+#endif
+#ifndef TOWARDZERO
+#define TOWARDZERO FE_TOWARDZERO
+#endif
+#ifndef DOWNWARD
+#define DOWNWARD FE_DOWNWARD
+#endif
+#ifndef UPWARD
+#define UPWARD FE_UPWARD
+#endif
+
+/* Possible exceptions */
+#define NO_EXCEPTION 0x0
+#define INVALID_EXCEPTION 0x1
+#define DIVIDE_BY_ZERO_EXCEPTION 0x2
+/* The next flags signals that those exceptions are allowed but not required. */
+#define INVALID_EXCEPTION_OK 0x4
+#define DIVIDE_BY_ZERO_EXCEPTION_OK 0x8
+#define EXCEPTIONS_OK INVALID_EXCEPTION_OK+DIVIDE_BY_ZERO_EXCEPTION_OK
+/* Some special test flags, passed togther with exceptions. */
+#define IGNORE_ZERO_INF_SIGN 0x10
+
+/* Various constants (we must supply them precalculated for accuracy). */
+#define M_PI_6l .52359877559829887307710723054658383L
+#define M_E2l 7.389056098930650227230427460575008L
+#define M_E3l 20.085536923187667740928529654581719L
+#define M_2_SQRT_PIl 3.5449077018110320545963349666822903L /* 2 sqrt (M_PIl) */
+#define M_SQRT_PIl 1.7724538509055160272981674833411451L /* sqrt (M_PIl) */
+#define M_LOG_SQRT_PIl 0.57236494292470008707171367567652933L /* log(sqrt(M_PIl)) */
+#define M_LOG_2_SQRT_PIl 1.265512123484645396488945797134706L /* log(2*sqrt(M_PIl)) */
+#define M_PI_34l (M_PIl - M_PI_4l) /* 3*pi/4 */
+#define M_PI_34_LOG10El (M_PIl - M_PI_4l) * M_LOG10El
+#define M_PI2_LOG10El M_PI_2l * M_LOG10El
+#define M_PI4_LOG10El M_PI_4l * M_LOG10El
+#define M_PI_LOG10El M_PIl * M_LOG10El
+#define M_SQRT_2_2 0.70710678118654752440084436210484903L /* sqrt (2) / 2 */
+
+static FILE *ulps_file; /* File to document difference. */
+static int output_ulps; /* Should ulps printed? */
+
+static int noErrors; /* number of errors */
+static int noTests; /* number of tests (without testing exceptions) */
+static int noExcTests; /* number of tests for exception flags */
+static int noXFails; /* number of expected failures. */
+static int noXPasses; /* number of unexpected passes. */
+
+static int verbose;
+static int output_max_error; /* Should the maximal errors printed? */
+static int output_points; /* Should the single function results printed? */
+static int ignore_max_ulp; /* Should we ignore max_ulp? */
+
+static FLOAT minus_zero, plus_zero;
+static FLOAT plus_infty, minus_infty, nan_value, max_value, min_value;
+
+static FLOAT max_error, real_max_error, imag_max_error;
+
+#ifndef __STDC_WANT_DEC_FP__
+#define BUILD_COMPLEX(real, imag) \
+ ({ __complex__ FLOAT __retval; \
+ __real__ __retval = (real); \
+ __imag__ __retval = (imag); \
+ __retval; })
+
+#define BUILD_COMPLEX_INT(real, imag) \
+ ({ __complex__ int __retval; \
+ __real__ __retval = (real); \
+ __imag__ __retval = (imag); \
+ __retval; })
+#endif
+
+
+/*#define MANT_DIG CHOOSE ((LDBL_MANT_DIG-1), (DBL_MANT_DIG-1), (FLT_MANT_DIG-1), \
+ (LDBL_MANT_DIG-1), (DBL_MANT_DIG-1), (FLT_MANT_DIG-1)) */
+
+#define MANT_DIG CHOOSE ((LDBL_MANT_DIG-1), (DBL_MANT_DIG-1), (FLT_MANT_DIG-1), \
+ (LDBL_MANT_DIG-1), (DBL_MANT_DIG-1), (FLT_MANT_DIG-1), \
+ (DEC128_MANT_DIG-1), (DEC64_MANT_DIG-1), (DEC32_MANT_DIG-1))
+
+static void
+init_max_error (void)
+{
+ max_error = 0;
+ real_max_error = 0;
+ imag_max_error = 0;
+ feclearexcept (FE_ALL_EXCEPT);
+}
+
+static void
+set_max_error (FLOAT current, FLOAT *curr_max_error)
+{
+ if (current > *curr_max_error)
+ *curr_max_error = current;
+}
+
+
+/* Should the message print to screen? This depends on the verbose flag,
+ and the test status. */
+static int
+print_screen (int ok, int xfail)
+{
+ if (output_points
+ && (verbose > 1
+ || (verbose == 1 && ok == xfail)))
+ return 1;
+ return 0;
+}
+
+
+/* Should the message print to screen? This depends on the verbose flag,
+ and the test status. */
+static int
+print_screen_max_error (int ok, int xfail)
+{
+ if (output_max_error
+ && (verbose > 1
+ || ((verbose == 1) && (ok == xfail))))
+ return 1;
+ return 0;
+}
+
+/* Update statistic counters. */
+static void
+update_stats (int ok, int xfail)
+{
+ ++noTests;
+ if (ok && xfail)
+ ++noXPasses;
+ else if (!ok && xfail)
+ ++noXFails;
+ else if (!ok && !xfail)
+ ++noErrors;
+}
+
+static void
+print_ulps (const char *test_name, FLOAT ulp)
+{
+ if (output_ulps)
+ {
+ fprintf (ulps_file, "Test \"%s\":\n", test_name);
+ fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n",
+ CHOOSE("ldouble", "double", "float",
+ "ildouble", "idouble", "ifloat",
+ "_Decimal128", "_Decimal64", "_Decimal32"),
+ FUNC(ceil) (ulp));
+ }
+}
+
+static void
+print_function_ulps (const char *function_name, FLOAT ulp)
+{
+ if (output_ulps)
+ {
+ fprintf (ulps_file, "Function: \"%s\":\n", function_name);
+ fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n",
+ CHOOSE("ldouble", "double", "float",
+ "ildouble", "idouble", "ifloat",
+ "_Decimal128", "_Decimal64", "_Decimal32"),
+ FUNC(ceil) (ulp));
+ }
+}
+
+
+#ifndef __STDC_WANT_DEC_FP__
+static void
+print_complex_function_ulps (const char *function_name, FLOAT real_ulp,
+ FLOAT imag_ulp)
+{
+ if (output_ulps)
+ {
+ if (real_ulp != _F(0.0))
+ {
+ fprintf (ulps_file, "Function: Real part of \"%s\":\n", function_name);
+ fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n",
+ CHOOSE("ldouble", "double", "float",
+ "ildouble", "idouble", "ifloat",
+ "_Decimal128", "_Decimal64", "_Decimal32"),
+ FUNC(ceil) (real_ulp));
+ }
+ if (imag_ulp != _F(0.0))
+ {
+ fprintf (ulps_file, "Function: Imaginary part of \"%s\":\n", function_name);
+ fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n",
+ CHOOSE("ldouble", "double", "float",
+ "ildouble", "idouble", "ifloat",
+ "_Decimal128", "_Decimal64", "_Decimal32"),
+ FUNC(ceil) (imag_ulp));
+ }
+
+
+ }
+}
+#endif
+
+
+/* Test if Floating-Point stack hasn't changed */
+static void
+fpstack_test (const char *test_name)
+{
+#ifdef i386
+ static int old_stack;
+ int sw;
+
+ asm ("fnstsw" : "=a" (sw));
+ sw >>= 11;
+ sw &= 7;
+
+ if (sw != old_stack)
+ {
+ printf ("FP-Stack wrong after test %s (%d, should be %d)\n",
+ test_name, sw, old_stack);
+ ++noErrors;
+ old_stack = sw;
+ }
+#endif
+}
+
+
+static void
+print_max_error (const char *func_name, FLOAT allowed, int xfail)
+{
+ int ok = 0;
+
+ if (max_error == _F(0.0) || (max_error <= allowed && !ignore_max_ulp))
+ {
+ ok = 1;
+ }
+
+ if (!ok)
+ print_function_ulps (func_name, max_error);
+
+
+ if (print_screen_max_error (ok, xfail))
+ {
+ printf ("Maximal error of `%s'\n", func_name);
+ printf (" is : %.0" PRINTF_NEXPR " ulp\n", FUNC(ceil) (max_error));
+ printf (" accepted: %.0" PRINTF_NEXPR " ulp\n", FUNC(ceil) (allowed));
+ }
+
+ update_stats (ok, xfail);
+}
+
+
+#ifndef __STDC_WANT_DEC_FP__
+static void
+print_complex_max_error (const char *func_name, __complex__ FLOAT allowed,
+ __complex__ int xfail)
+{
+ int ok = 0;
+
+ if ((real_max_error == 0 && imag_max_error == 0)
+ || (real_max_error <= __real__ allowed
+ && imag_max_error <= __imag__ allowed
+ && !ignore_max_ulp))
+ {
+ ok = 1;
+ }
+
+ if (!ok)
+ print_complex_function_ulps (func_name, real_max_error, imag_max_error);
+
+
+ if (print_screen_max_error (ok, xfail))
+ {
+ printf ("Maximal error of real part of: %s\n", func_name);
+ printf (" is : %.0" PRINTF_NEXPR " ulp\n",
+ FUNC(ceil) (real_max_error));
+ printf (" accepted: %.0" PRINTF_NEXPR " ulp\n",
+ FUNC(ceil) (__real__ allowed));
+ printf ("Maximal error of imaginary part of: %s\n", func_name);
+ printf (" is : %.0" PRINTF_NEXPR " ulp\n",
+ FUNC(ceil) (imag_max_error));
+ printf (" accepted: %.0" PRINTF_NEXPR " ulp\n",
+ FUNC(ceil) (__imag__ allowed));
+ }
+
+ update_stats (ok, xfail);
+}
+#endif
+
+
+/* Test whether a given exception was raised. */
+static void
+test_single_exception (const char *test_name,
+ int exception,
+ int exc_flag,
+ int fe_flag,
+ const char *flag_name)
+{
+#ifndef TEST_INLINE
+ int ok = 1;
+ if (exception & exc_flag)
+ {
+ if (fetestexcept (fe_flag))
+ {
+ if (print_screen (1, 0))
+ printf ("Pass: %s: Exception \"%s\" set\n", test_name, flag_name);
+ }
+ else
+ {
+ ok = 0;
+ if (print_screen (0, 0))
+ printf ("Failure: %s: Exception \"%s\" not set\n",
+ test_name, flag_name);
+ }
+ }
+ else
+ {
+ if (fetestexcept (fe_flag))
+ {
+ ok = 0;
+ if (print_screen (0, 0))
+ printf ("Failure: %s: Exception \"%s\" set\n",
+ test_name, flag_name);
+ }
+ else
+ {
+ if (print_screen (1, 0))
+ printf ("%s: Exception \"%s\" not set\n", test_name,
+ flag_name);
+ }
+ }
+ if (!ok)
+ ++noErrors;
+
+#endif
+}
+
+
+/* Test whether exceptions given by EXCEPTION are raised. Ignore thereby
+ allowed but not required exceptions.
+*/
+static void
+test_exceptions (const char *test_name, int exception)
+{
+ ++noExcTests;
+#ifdef FE_DIVBYZERO
+ if ((exception & DIVIDE_BY_ZERO_EXCEPTION_OK) == 0)
+ test_single_exception (test_name, exception,
+ DIVIDE_BY_ZERO_EXCEPTION, FE_DIVBYZERO,
+ "Divide by zero");
+#endif
+#ifdef FE_INVALID
+ if ((exception & INVALID_EXCEPTION_OK) == 0)
+ test_single_exception (test_name, exception, INVALID_EXCEPTION, FE_INVALID,
+ "Invalid operation");
+#endif
+ feclearexcept (FE_ALL_EXCEPT);
+}
+
+
+static void
+check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
+ FLOAT max_ulp, int xfail, int exceptions,
+ FLOAT *curr_max_error)
+{
+ int ok = 0;
+ int print_diff = 0;
+ FLOAT diff = 0;
+ FLOAT ulp = 0;
+
+ test_exceptions (test_name, exceptions);
+ if (isnan (computed) && isnan (expected))
+ ok = 1;
+ else if (isinf (computed) && isinf (expected))
+ {
+ /* Test for sign of infinities. */
+ if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0
+ && signbit (computed) != signbit (expected))
+ {
+ ok = 0;
+ printf ("infinity has wrong sign.\n");
+ }
+ else
+ ok = 1;
+ }
+ /* Don't calc ulp for NaNs or infinities. */
+ else if (isinf (computed) || isnan (computed) || isinf (expected) || isnan (expected))
+ ok = 0;
+ else
+ {
+ diff = FUNC(fabs) (computed - expected);
+ /* ilogb (0) isn't allowed. */
+ if (expected == _F(0.0))
+ ulp = diff / FUNC(ldexp) (_F(1.0), - MANT_DIG);
+ else
+ ulp = diff / FUNC(ldexp) (_F(1.0), FUNC(ilogb) (expected) - MANT_DIG);
+ set_max_error (ulp, curr_max_error);
+ print_diff = 1;
+ if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0
+ && computed == _F(0.0) && expected == _F(0.0)
+ && signbit(computed) != signbit (expected))
+ ok = 0;
+ else if (ulp <= _F(0.5) || (ulp <= max_ulp && !ignore_max_ulp))
+ ok = 1;
+ else
+ {
+ ok = 0;
+ print_ulps (test_name, ulp);
+ }
+
+ }
+ if (print_screen (ok, xfail))
+ {
+ if (!ok)
+ printf ("Failure: ");
+ printf ("Test: %s\n", test_name);
+ printf ("Result:\n");
+ printf (" is: % .20" PRINTF_EXPR " % .20" PRINTF_XEXPR "\n",
+ computed, computed);
+ printf (" should be: % .20" PRINTF_EXPR " % .20" PRINTF_XEXPR "\n",
+ expected, expected);
+ if (print_diff)
+ {
+ printf (" difference: % .20" PRINTF_EXPR " % .20" PRINTF_XEXPR
+ "\n", diff, diff);
+ printf (" ulp : % .4" PRINTF_NEXPR "\n", ulp);
+ printf (" max.ulp : % .4" PRINTF_NEXPR "\n", max_ulp);
+ }
+ }
+ update_stats (ok, xfail);
+
+ fpstack_test (test_name);
+}
+
+
+static void
+check_float (const char *test_name, FLOAT computed, FLOAT expected,
+ FLOAT max_ulp, int xfail, int exceptions)
+{
+ check_float_internal (test_name, computed, expected, max_ulp, xfail,
+ exceptions, &max_error);
+}
+
+
+#ifndef __STDC_WANT_DEC_FP__
+static void
+check_complex (const char *test_name, __complex__ FLOAT computed,
+ __complex__ FLOAT expected,
+ __complex__ FLOAT max_ulp, __complex__ int xfail,
+ int exception)
+{
+ FLOAT part_comp, part_exp, part_max_ulp;
+ int part_xfail;
+ char str[200];
+
+ sprintf (str, "Real part of: %s", test_name);
+ part_comp = __real__ computed;
+ part_exp = __real__ expected;
+ part_max_ulp = __real__ max_ulp;
+ part_xfail = __real__ xfail;
+
+ check_float_internal (str, part_comp, part_exp, part_max_ulp, part_xfail,
+ exception, &real_max_error);
+
+ sprintf (str, "Imaginary part of: %s", test_name);
+ part_comp = __imag__ computed;
+ part_exp = __imag__ expected;
+ part_max_ulp = __imag__ max_ulp;
+ part_xfail = __imag__ xfail;
+
+ /* Don't check again for exceptions, just pass through the
+ zero/inf sign test. */
+ check_float_internal (str, part_comp, part_exp, part_max_ulp, part_xfail,
+ exception & IGNORE_ZERO_INF_SIGN,
+ &imag_max_error);
+}
+#endif
+
+
+/* Check that computed and expected values are equal (int values). */
+static void
+check_int (const char *test_name, int computed, int expected, int max_ulp,
+ int xfail, int exceptions)
+{
+ int diff = computed - expected;
+ int ok = 0;
+
+ test_exceptions (test_name, exceptions);
+ noTests++;
+ if (abs (diff) <= max_ulp)
+ ok = 1;
+
+ if (!ok)
+ print_ulps (test_name, diff);
+
+ if (print_screen (ok, xfail))
+ {
+ if (!ok)
+ printf ("Failure: ");
+ printf ("Test: %s\n", test_name);
+ printf ("Result:\n");
+ printf (" is: %d\n", computed);
+ printf (" should be: %d\n", expected);
+ }
+
+ update_stats (ok, xfail);
+ fpstack_test (test_name);
+}
+
+
+/* Check that computed and expected values are equal (long int values). */
+static void
+check_long (const char *test_name, long int computed, long int expected,
+ long int max_ulp, int xfail, int exceptions)
+{
+ long int diff = computed - expected;
+ int ok = 0;
+
+ test_exceptions (test_name, exceptions);
+ noTests++;
+ if (labs (diff) <= max_ulp)
+ ok = 1;
+
+ if (!ok)
+ print_ulps (test_name, diff);
+
+ if (print_screen (ok, xfail))
+ {
+ if (!ok)
+ printf ("Failure: ");
+ printf ("Test: %s\n", test_name);
+ printf ("Result:\n");
+ printf (" is: %ld\n", computed);
+ printf (" should be: %ld\n", expected);
+ }
+
+ update_stats (ok, xfail);
+ fpstack_test (test_name);
+}
+
+
+/* Check that computed value is true/false. */
+static void
+check_bool (const char *test_name, int computed, int expected,
+ long int max_ulp, int xfail, int exceptions)
+{
+ int ok = 0;
+
+ test_exceptions (test_name, exceptions);
+ noTests++;
+ if ((computed == 0) == (expected == 0))
+ ok = 1;
+
+ if (print_screen (ok, xfail))
+ {
+ if (!ok)
+ printf ("Failure: ");
+ printf ("Test: %s\n", test_name);
+ printf ("Result:\n");
+ printf (" is: %d\n", computed);
+ printf (" should be: %d\n", expected);
+ }
+
+ update_stats (ok, xfail);
+ fpstack_test (test_name);
+}
+
+
+/* check that computed and expected values are equal (long int values) */
+static void
+check_longlong (const char *test_name, long long int computed,
+ long long int expected,
+ long long int max_ulp, int xfail,
+ int exceptions)
+{
+ long long int diff = computed - expected;
+ int ok = 0;
+
+ test_exceptions (test_name, exceptions);
+ noTests++;
+ if (llabs (diff) <= max_ulp)
+ ok = 1;
+
+ if (!ok)
+ print_ulps (test_name, diff);
+
+ if (print_screen (ok, xfail))
+ {
+ if (!ok)
+ printf ("Failure:");
+ printf ("Test: %s\n", test_name);
+ printf ("Result:\n");
+ printf (" is: %lld\n", computed);
+ printf (" should be: %lld\n", expected);
+ }
+
+ update_stats (ok, xfail);
+ fpstack_test (test_name);
+}
+
+
+
+/* This is to prevent messages from the SVID libm emulation. */
+int
+matherr (struct exception *x __attribute__ ((unused)))
+{
+ return 1;
+}
+
+
+/****************************************************************************
+ Tests for single functions of libm.
+ Please keep them alphabetically sorted!
+****************************************************************************/
+
+static void
+acos_test (void)
+{
+ errno = 0;
+ FUNC(acos) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (acos);
+
+ TEST_f_f (acos, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (acos, minus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (acos, nan_value, nan_value);
+
+ /* |x| > 1: */
+ TEST_f_f (acos, 1.125L, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (acos, -1.125L, nan_value, INVALID_EXCEPTION);
+
+ TEST_f_f (acos, 0, M_PI_2l);
+ TEST_f_f (acos, minus_zero, M_PI_2l);
+ TEST_f_f (acos, 1, 0);
+ TEST_f_f (acos, -1, M_PIl);
+ TEST_f_f (acos, 0.5, M_PI_6l * 2.0);
+ TEST_f_f (acos, -0.5, M_PI_6l * 4.0);
+ TEST_f_f (acos, 0.75L, 0.722734247813415611178377352641333362L);
+ TEST_f_f (acos, 2e-17L, 1.57079632679489659923132169163975144L);
+ TEST_f_f (acos, 0.0625L, 1.50825556499840522843072005474337068L);
+ END (acos);
+}
+
+static void
+acosh_test (void)
+{
+ errno = 0;
+ FUNC(acosh) (7);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (acosh);
+
+ TEST_f_f (acosh, plus_infty, plus_infty);
+ TEST_f_f (acosh, minus_infty, nan_value, INVALID_EXCEPTION);
+
+ /* x < 1: */
+ TEST_f_f (acosh, -1.125L, nan_value, INVALID_EXCEPTION);
+
+ TEST_f_f (acosh, 1, 0);
+ TEST_f_f (acosh, 7, 2.63391579384963341725009269461593689L);
+
+ END (acosh);
+}
+
+static void
+asin_test (void)
+{
+ errno = 0;
+ FUNC(asin) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (asin);
+
+ TEST_f_f (asin, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (asin, minus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (asin, nan_value, nan_value);
+
+ /* asin x == NaN plus invalid exception for |x| > 1. */
+ TEST_f_f (asin, 1.125L, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (asin, -1.125L, nan_value, INVALID_EXCEPTION);
+
+ TEST_f_f (asin, 0, 0);
+ TEST_f_f (asin, minus_zero, minus_zero);
+ TEST_f_f (asin, 0.5, M_PI_6l);
+ TEST_f_f (asin, -0.5, -M_PI_6l);
+ TEST_f_f (asin, 1.0, M_PI_2l);
+ TEST_f_f (asin, -1.0, -M_PI_2l);
+ TEST_f_f (asin, 0.75L, 0.848062078981481008052944338998418080L);
+
+ END (asin);
+}
+
+static void
+asinh_test (void)
+{
+ errno = 0;
+ FUNC(asinh) (0.7L);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (asinh);
+
+ TEST_f_f (asinh, 0, 0);
+ TEST_f_f (asinh, minus_zero, minus_zero);
+#ifndef TEST_INLINE
+ TEST_f_f (asinh, plus_infty, plus_infty);
+ TEST_f_f (asinh, minus_infty, minus_infty);
+#endif
+ TEST_f_f (asinh, nan_value, nan_value);
+ TEST_f_f (asinh, 0.75L, 0.693147180559945309417232121458176568L);
+
+ END (asinh);
+}
+
+static void
+atan_test (void)
+{
+ errno = 0;
+ FUNC(atan) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (atan);
+
+ TEST_f_f (atan, 0, 0);
+ TEST_f_f (atan, minus_zero, minus_zero);
+
+ TEST_f_f (atan, plus_infty, M_PI_2l);
+ TEST_f_f (atan, minus_infty, -M_PI_2l);
+ TEST_f_f (atan, nan_value, nan_value);
+
+ TEST_f_f (atan, 1, M_PI_4l);
+ TEST_f_f (atan, -1, -M_PI_4l);
+
+ TEST_f_f (atan, 0.75L, 0.643501108793284386802809228717322638L);
+
+ END (atan);
+}
+
+
+
+static void
+atanh_test (void)
+{
+ errno = 0;
+ FUNC(atanh) (0.7L);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (atanh);
+
+
+ TEST_f_f (atanh, 0, 0);
+ TEST_f_f (atanh, minus_zero, minus_zero);
+
+ TEST_f_f (atanh, 1, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (atanh, -1, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (atanh, nan_value, nan_value);
+
+ /* atanh (x) == NaN plus invalid exception if |x| > 1. */
+ TEST_f_f (atanh, 1.125L, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (atanh, -1.125L, nan_value, INVALID_EXCEPTION);
+
+ TEST_f_f (atanh, 0.75L, 0.972955074527656652552676371721589865L);
+
+ END (atanh);
+}
+
+static void
+atan2_test (void)
+{
+ errno = 0;
+ FUNC(atan2) (-0, 1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (atan2);
+
+ /* atan2 (0,x) == 0 for x > 0. */
+ TEST_ff_f (atan2, 0, 1, 0);
+
+ /* atan2 (-0,x) == -0 for x > 0. */
+ TEST_ff_f (atan2, minus_zero, 1, minus_zero);
+
+ TEST_ff_f (atan2, 0, 0, 0);
+ TEST_ff_f (atan2, minus_zero, 0, minus_zero);
+
+ /* atan2 (+0,x) == +pi for x < 0. */
+ TEST_ff_f (atan2, 0, -1, M_PIl);
+
+ /* atan2 (-0,x) == -pi for x < 0. */
+ TEST_ff_f (atan2, minus_zero, -1, -M_PIl);
+
+ TEST_ff_f (atan2, 0, minus_zero, M_PIl);
+ TEST_ff_f (atan2, minus_zero, minus_zero, -M_PIl);
+
+ /* atan2 (y,+0) == pi/2 for y > 0. */
+ TEST_ff_f (atan2, 1, 0, M_PI_2l);
+
+ /* atan2 (y,-0) == pi/2 for y > 0. */
+ TEST_ff_f (atan2, 1, minus_zero, M_PI_2l);
+
+ /* atan2 (y,+0) == -pi/2 for y < 0. */
+ TEST_ff_f (atan2, -1, 0, -M_PI_2l);
+
+ /* atan2 (y,-0) == -pi/2 for y < 0. */
+ TEST_ff_f (atan2, -1, minus_zero, -M_PI_2l);
+
+ /* atan2 (y,inf) == +0 for finite y > 0. */
+ TEST_ff_f (atan2, 1, plus_infty, 0);
+
+ /* atan2 (y,inf) == -0 for finite y < 0. */
+ TEST_ff_f (atan2, -1, plus_infty, minus_zero);
+
+ /* atan2(+inf, x) == pi/2 for finite x. */
+ TEST_ff_f (atan2, plus_infty, -1, M_PI_2l);
+
+ /* atan2(-inf, x) == -pi/2 for finite x. */
+ TEST_ff_f (atan2, minus_infty, 1, -M_PI_2l);
+
+ /* atan2 (y,-inf) == +pi for finite y > 0. */
+ TEST_ff_f (atan2, 1, minus_infty, M_PIl);
+
+ /* atan2 (y,-inf) == -pi for finite y < 0. */
+ TEST_ff_f (atan2, -1, minus_infty, -M_PIl);
+
+ TEST_ff_f (atan2, plus_infty, plus_infty, M_PI_4l);
+ TEST_ff_f (atan2, minus_infty, plus_infty, -M_PI_4l);
+ TEST_ff_f (atan2, plus_infty, minus_infty, M_PI_34l);
+ TEST_ff_f (atan2, minus_infty, minus_infty, -M_PI_34l);
+ TEST_ff_f (atan2, nan_value, nan_value, nan_value);
+
+ TEST_ff_f (atan2, 0.75L, 1, 0.643501108793284386802809228717322638L);
+ TEST_ff_f (atan2, -0.75L, 1.0L, -0.643501108793284386802809228717322638L);
+ TEST_ff_f (atan2, 0.75L, -1.0L, 2.49809154479650885165983415456218025L);
+ TEST_ff_f (atan2, -0.75L, -1.0L, -2.49809154479650885165983415456218025L);
+ TEST_ff_f (atan2, 0.390625L, .00029L, 1.57005392693128974780151246612928941L);
+ TEST_ff_f (atan2, 1.390625L, 0.9296875L, 0.981498387184244311516296577615519772L);
+
+ TEST_ff_f (atan2, -0.00756827042671106339L, -.001792735857538728036L, -1.80338464113663849327153994379639112L);
+
+ END (atan2);
+}
+
+
+#ifndef __STDC_WANT_DEC_FP__
+static void
+cabs_test (void)
+{
+ errno = 0;
+ FUNC(cabs) (BUILD_COMPLEX (0.7L, 12.4L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (cabs);
+
+ /* cabs (x + iy) is specified as hypot (x,y) */
+
+ /* cabs (+inf + i x) == +inf. */
+ TEST_c_f (cabs, plus_infty, 1.0, plus_infty);
+ /* cabs (-inf + i x) == +inf. */
+ TEST_c_f (cabs, minus_infty, 1.0, plus_infty);
+
+ TEST_c_f (cabs, minus_infty, nan_value, plus_infty);
+ TEST_c_f (cabs, minus_infty, nan_value, plus_infty);
+
+ TEST_c_f (cabs, nan_value, nan_value, nan_value);
+
+ /* cabs (x,y) == cabs (y,x). */
+ TEST_c_f (cabs, 0.75L, 12.390625L, 12.4133028598606664302388810868156657L);
+ /* cabs (x,y) == cabs (-x,y). */
+ TEST_c_f (cabs, -12.390625L, 0.75L, 12.4133028598606664302388810868156657L);
+ /* cabs (x,y) == cabs (-y,x). */
+ TEST_c_f (cabs, -0.75L, 12.390625L, 12.4133028598606664302388810868156657L);
+ /* cabs (x,y) == cabs (-x,-y). */
+ TEST_c_f (cabs, -12.390625L, -0.75L, 12.4133028598606664302388810868156657L);
+ /* cabs (x,y) == cabs (-y,-x). */
+ TEST_c_f (cabs, -0.75L, -12.390625L, 12.4133028598606664302388810868156657L);
+ /* cabs (x,0) == fabs (x). */
+ TEST_c_f (cabs, -0.75L, 0, 0.75L);
+ TEST_c_f (cabs, 0.75L, 0, 0.75L);
+ TEST_c_f (cabs, -1.0L, 0, 1.0L);
+ TEST_c_f (cabs, 1.0L, 0, 1.0L);
+ TEST_c_f (cabs, -5.7e7L, 0, 5.7e7L);
+ TEST_c_f (cabs, 5.7e7L, 0, 5.7e7L);
+
+ TEST_c_f (cabs, 0.75L, 1.25L, 1.45773797371132511771853821938639577L);
+
+ END (cabs);
+}
+
+
+static void
+cacos_test (void)
+{
+ errno = 0;
+ FUNC(cacos) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (cacos);
+
+
+ TEST_c_c (cacos, 0, 0, M_PI_2l, minus_zero);
+ TEST_c_c (cacos, minus_zero, 0, M_PI_2l, minus_zero);
+ TEST_c_c (cacos, minus_zero, minus_zero, M_PI_2l, 0.0);
+ TEST_c_c (cacos, 0, minus_zero, M_PI_2l, 0.0);
+
+ TEST_c_c (cacos, minus_infty, plus_infty, M_PI_34l, minus_infty);
+ TEST_c_c (cacos, minus_infty, minus_infty, M_PI_34l, plus_infty);
+
+ TEST_c_c (cacos, plus_infty, plus_infty, M_PI_4l, minus_infty);
+ TEST_c_c (cacos, plus_infty, minus_infty, M_PI_4l, plus_infty);
+
+ TEST_c_c (cacos, -10.0, plus_infty, M_PI_2l, minus_infty);
+ TEST_c_c (cacos, -10.0, minus_infty, M_PI_2l, plus_infty);
+ TEST_c_c (cacos, 0, plus_infty, M_PI_2l, minus_infty);
+ TEST_c_c (cacos, 0, minus_infty, M_PI_2l, plus_infty);
+ TEST_c_c (cacos, 0.1L, plus_infty, M_PI_2l, minus_infty);
+ TEST_c_c (cacos, 0.1L, minus_infty, M_PI_2l, plus_infty);
+
+ TEST_c_c (cacos, minus_infty, 0, M_PIl, minus_infty);
+ TEST_c_c (cacos, minus_infty, minus_zero, M_PIl, plus_infty);
+ TEST_c_c (cacos, minus_infty, 100, M_PIl, minus_infty);
+ TEST_c_c (cacos, minus_infty, -100, M_PIl, plus_infty);
+
+ TEST_c_c (cacos, plus_infty, 0, 0.0, minus_infty);
+ TEST_c_c (cacos, plus_infty, minus_zero, 0.0, plus_infty);
+ TEST_c_c (cacos, plus_infty, 0.5, 0.0, minus_infty);
+ TEST_c_c (cacos, plus_infty, -0.5, 0.0, plus_infty);
+
+ TEST_c_c (cacos, plus_infty, nan_value, nan_value, plus_infty, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (cacos, minus_infty, nan_value, nan_value, plus_infty, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (cacos, 0, nan_value, M_PI_2l, nan_value);
+ TEST_c_c (cacos, minus_zero, nan_value, M_PI_2l, nan_value);
+
+ TEST_c_c (cacos, nan_value, plus_infty, nan_value, minus_infty);
+ TEST_c_c (cacos, nan_value, minus_infty, nan_value, plus_infty);
+
+ TEST_c_c (cacos, 10.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (cacos, -10.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (cacos, nan_value, 0.75, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (cacos, nan_value, -0.75, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (cacos, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (cacos, 0.75L, 1.25L, 1.11752014915610270578240049553777969L, -1.13239363160530819522266333696834467L);
+ TEST_c_c (cacos, -2, -3, 2.1414491111159960199416055713254211L, 1.9833870299165354323470769028940395L);
+
+ END (cacos, complex);
+}
+
+static void
+cacosh_test (void)
+{
+ errno = 0;
+ FUNC(cacosh) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (cacosh);
+
+
+ TEST_c_c (cacosh, 0, 0, 0.0, M_PI_2l);
+ TEST_c_c (cacosh, minus_zero, 0, 0.0, M_PI_2l);
+ TEST_c_c (cacosh, 0, minus_zero, 0.0, -M_PI_2l);
+ TEST_c_c (cacosh, minus_zero, minus_zero, 0.0, -M_PI_2l);
+ TEST_c_c (cacosh, minus_infty, plus_infty, plus_infty, M_PI_34l);
+ TEST_c_c (cacosh, minus_infty, minus_infty, plus_infty, -M_PI_34l);
+
+ TEST_c_c (cacosh, plus_infty, plus_infty, plus_infty, M_PI_4l);
+ TEST_c_c (cacosh, plus_infty, minus_infty, plus_infty, -M_PI_4l);
+
+ TEST_c_c (cacosh, -10.0, plus_infty, plus_infty, M_PI_2l);
+ TEST_c_c (cacosh, -10.0, minus_infty, plus_infty, -M_PI_2l);
+ TEST_c_c (cacosh, 0, plus_infty, plus_infty, M_PI_2l);
+ TEST_c_c (cacosh, 0, minus_infty, plus_infty, -M_PI_2l);
+ TEST_c_c (cacosh, 0.1L, plus_infty, plus_infty, M_PI_2l);
+ TEST_c_c (cacosh, 0.1L, minus_infty, plus_infty, -M_PI_2l);
+
+ TEST_c_c (cacosh, minus_infty, 0, plus_infty, M_PIl);
+ TEST_c_c (cacosh, minus_infty, minus_zero, plus_infty, -M_PIl);
+ TEST_c_c (cacosh, minus_infty, 100, plus_infty, M_PIl);
+ TEST_c_c (cacosh, minus_infty, -100, plus_infty, -M_PIl);
+
+ TEST_c_c (cacosh, plus_infty, 0, plus_infty, 0.0);
+ TEST_c_c (cacosh, plus_infty, minus_zero, plus_infty, minus_zero);
+ TEST_c_c (cacosh, plus_infty, 0.5, plus_infty, 0.0);
+ TEST_c_c (cacosh, plus_infty, -0.5, plus_infty, minus_zero);
+
+ TEST_c_c (cacosh, plus_infty, nan_value, plus_infty, nan_value);
+ TEST_c_c (cacosh, minus_infty, nan_value, plus_infty, nan_value);
+
+ TEST_c_c (cacosh, 0, nan_value, nan_value, nan_value);
+ TEST_c_c (cacosh, minus_zero, nan_value, nan_value, nan_value);
+
+ TEST_c_c (cacosh, nan_value, plus_infty, plus_infty, nan_value);
+ TEST_c_c (cacosh, nan_value, minus_infty, plus_infty, nan_value);
+
+ TEST_c_c (cacosh, 10.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (cacosh, -10.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (cacosh, nan_value, 0.75, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (cacosh, nan_value, -0.75, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (cacosh, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (cacosh, 0.75L, 1.25L, 1.13239363160530819522266333696834467L, 1.11752014915610270578240049553777969L);
+ TEST_c_c (cacosh, -2, -3, 1.9833870299165354323470769028940395L, -2.1414491111159960199416055713254211L);
+
+ END (cacosh, complex);
+}
+
+
+static void
+carg_test (void)
+{
+ START (carg);
+
+ /* carg (x + iy) is specified as atan2 (y, x) */
+
+ /* carg (x + i 0) == 0 for x > 0. */
+ TEST_c_f (carg, 2.0, 0, 0);
+ /* carg (x - i 0) == -0 for x > 0. */
+ TEST_c_f (carg, 2.0, minus_zero, minus_zero);
+
+ TEST_c_f (carg, 0, 0, 0);
+ TEST_c_f (carg, 0, minus_zero, minus_zero);
+
+ /* carg (x + i 0) == +pi for x < 0. */
+ TEST_c_f (carg, -2.0, 0, M_PIl);
+
+ /* carg (x - i 0) == -pi for x < 0. */
+ TEST_c_f (carg, -2.0, minus_zero, -M_PIl);
+
+ TEST_c_f (carg, minus_zero, 0, M_PIl);
+ TEST_c_f (carg, minus_zero, minus_zero, -M_PIl);
+
+ /* carg (+0 + i y) == pi/2 for y > 0. */
+ TEST_c_f (carg, 0, 2.0, M_PI_2l);
+
+ /* carg (-0 + i y) == pi/2 for y > 0. */
+ TEST_c_f (carg, minus_zero, 2.0, M_PI_2l);
+
+ /* carg (+0 + i y) == -pi/2 for y < 0. */
+ TEST_c_f (carg, 0, -2.0, -M_PI_2l);
+
+ /* carg (-0 + i y) == -pi/2 for y < 0. */
+ TEST_c_f (carg, minus_zero, -2.0, -M_PI_2l);
+
+ /* carg (inf + i y) == +0 for finite y > 0. */
+ TEST_c_f (carg, plus_infty, 2.0, 0);
+
+ /* carg (inf + i y) == -0 for finite y < 0. */
+ TEST_c_f (carg, plus_infty, -2.0, minus_zero);
+
+ /* carg(x + i inf) == pi/2 for finite x. */
+ TEST_c_f (carg, 10.0, plus_infty, M_PI_2l);
+
+ /* carg(x - i inf) == -pi/2 for finite x. */
+ TEST_c_f (carg, 10.0, minus_infty, -M_PI_2l);
+
+ /* carg (-inf + i y) == +pi for finite y > 0. */
+ TEST_c_f (carg, minus_infty, 10.0, M_PIl);
+
+ /* carg (-inf + i y) == -pi for finite y < 0. */
+ TEST_c_f (carg, minus_infty, -10.0, -M_PIl);
+
+ TEST_c_f (carg, plus_infty, plus_infty, M_PI_4l);
+
+ TEST_c_f (carg, plus_infty, minus_infty, -M_PI_4l);
+
+ TEST_c_f (carg, minus_infty, plus_infty, 3 * M_PI_4l);
+
+ TEST_c_f (carg, minus_infty, minus_infty, -3 * M_PI_4l);
+
+ TEST_c_f (carg, nan_value, nan_value, nan_value);
+
+ END (carg);
+}
+
+static void
+casin_test (void)
+{
+ errno = 0;
+ FUNC(casin) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (casin);
+
+ TEST_c_c (casin, 0, 0, 0.0, 0.0);
+ TEST_c_c (casin, minus_zero, 0, minus_zero, 0.0);
+ TEST_c_c (casin, 0, minus_zero, 0.0, minus_zero);
+ TEST_c_c (casin, minus_zero, minus_zero, minus_zero, minus_zero);
+
+ TEST_c_c (casin, plus_infty, plus_infty, M_PI_4l, plus_infty);
+ TEST_c_c (casin, plus_infty, minus_infty, M_PI_4l, minus_infty);
+ TEST_c_c (casin, minus_infty, plus_infty, -M_PI_4l, plus_infty);
+ TEST_c_c (casin, minus_infty, minus_infty, -M_PI_4l, minus_infty);
+
+ TEST_c_c (casin, -10.0, plus_infty, minus_zero, plus_infty);
+ TEST_c_c (casin, -10.0, minus_infty, minus_zero, minus_infty);
+ TEST_c_c (casin, 0, plus_infty, 0.0, plus_infty);
+ TEST_c_c (casin, 0, minus_infty, 0.0, minus_infty);
+ TEST_c_c (casin, minus_zero, plus_infty, minus_zero, plus_infty);
+ TEST_c_c (casin, minus_zero, minus_infty, minus_zero, minus_infty);
+ TEST_c_c (casin, 0.1L, plus_infty, 0.0, plus_infty);
+ TEST_c_c (casin, 0.1L, minus_infty, 0.0, minus_infty);
+
+ TEST_c_c (casin, minus_infty, 0, -M_PI_2l, plus_infty);
+ TEST_c_c (casin, minus_infty, minus_zero, -M_PI_2l, minus_infty);
+ TEST_c_c (casin, minus_infty, 100, -M_PI_2l, plus_infty);
+ TEST_c_c (casin, minus_infty, -100, -M_PI_2l, minus_infty);
+
+ TEST_c_c (casin, plus_infty, 0, M_PI_2l, plus_infty);
+ TEST_c_c (casin, plus_infty, minus_zero, M_PI_2l, minus_infty);
+ TEST_c_c (casin, plus_infty, 0.5, M_PI_2l, plus_infty);
+ TEST_c_c (casin, plus_infty, -0.5, M_PI_2l, minus_infty);
+
+ TEST_c_c (casin, nan_value, plus_infty, nan_value, plus_infty);
+ TEST_c_c (casin, nan_value, minus_infty, nan_value, minus_infty);
+
+ TEST_c_c (casin, 0.0, nan_value, 0.0, nan_value);
+ TEST_c_c (casin, minus_zero, nan_value, minus_zero, nan_value);
+
+ TEST_c_c (casin, plus_infty, nan_value, nan_value, plus_infty, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (casin, minus_infty, nan_value, nan_value, plus_infty, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (casin, nan_value, 10.5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (casin, nan_value, -10.5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (casin, 0.75, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (casin, -0.75, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (casin, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (casin, 0.75L, 1.25L, 0.453276177638793913448921196101971749L, 1.13239363160530819522266333696834467L);
+ TEST_c_c (casin, -2, -3, -0.57065278432109940071028387968566963L, -1.9833870299165354323470769028940395L);
+
+ END (casin, complex);
+}
+
+
+static void
+casinh_test (void)
+{
+ errno = 0;
+ FUNC(casinh) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (casinh);
+
+ TEST_c_c (casinh, 0, 0, 0.0, 0.0);
+ TEST_c_c (casinh, minus_zero, 0, minus_zero, 0);
+ TEST_c_c (casinh, 0, minus_zero, 0.0, minus_zero);
+ TEST_c_c (casinh, minus_zero, minus_zero, minus_zero, minus_zero);
+
+ TEST_c_c (casinh, plus_infty, plus_infty, plus_infty, M_PI_4l);
+ TEST_c_c (casinh, plus_infty, minus_infty, plus_infty, -M_PI_4l);
+ TEST_c_c (casinh, minus_infty, plus_infty, minus_infty, M_PI_4l);
+ TEST_c_c (casinh, minus_infty, minus_infty, minus_infty, -M_PI_4l);
+
+ TEST_c_c (casinh, -10.0, plus_infty, minus_infty, M_PI_2l);
+ TEST_c_c (casinh, -10.0, minus_infty, minus_infty, -M_PI_2l);
+ TEST_c_c (casinh, 0, plus_infty, plus_infty, M_PI_2l);
+ TEST_c_c (casinh, 0, minus_infty, plus_infty, -M_PI_2l);
+ TEST_c_c (casinh, minus_zero, plus_infty, minus_infty, M_PI_2l);
+ TEST_c_c (casinh, minus_zero, minus_infty, minus_infty, -M_PI_2l);
+ TEST_c_c (casinh, 0.1L, plus_infty, plus_infty, M_PI_2l);
+ TEST_c_c (casinh, 0.1L, minus_infty, plus_infty, -M_PI_2l);
+
+ TEST_c_c (casinh, minus_infty, 0, minus_infty, 0.0);
+ TEST_c_c (casinh, minus_infty, minus_zero, minus_infty, minus_zero);
+ TEST_c_c (casinh, minus_infty, 100, minus_infty, 0.0);
+ TEST_c_c (casinh, minus_infty, -100, minus_infty, minus_zero);
+
+ TEST_c_c (casinh, plus_infty, 0, plus_infty, 0.0);
+ TEST_c_c (casinh, plus_infty, minus_zero, plus_infty, minus_zero);
+ TEST_c_c (casinh, plus_infty, 0.5, plus_infty, 0.0);
+ TEST_c_c (casinh, plus_infty, -0.5, plus_infty, minus_zero);
+
+ TEST_c_c (casinh, plus_infty, nan_value, plus_infty, nan_value);
+ TEST_c_c (casinh, minus_infty, nan_value, minus_infty, nan_value);
+
+ TEST_c_c (casinh, nan_value, 0, nan_value, 0.0);
+ TEST_c_c (casinh, nan_value, minus_zero, nan_value, minus_zero);
+
+ TEST_c_c (casinh, nan_value, plus_infty, plus_infty, nan_value, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (casinh, nan_value, minus_infty, plus_infty, nan_value, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (casinh, 10.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (casinh, -10.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (casinh, nan_value, 0.75, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (casinh, -0.75, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (casinh, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (casinh, 0.75L, 1.25L, 1.03171853444778027336364058631006594L, 0.911738290968487636358489564316731207L);
+ TEST_c_c (casinh, -2, -3, -1.9686379257930962917886650952454982L, -0.96465850440760279204541105949953237L);
+
+ END (casinh, complex);
+}
+
+
+static void
+catan_test (void)
+{
+ errno = 0;
+ FUNC(catan) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (catan);
+
+ TEST_c_c (catan, 0, 0, 0, 0);
+ TEST_c_c (catan, minus_zero, 0, minus_zero, 0);
+ TEST_c_c (catan, 0, minus_zero, 0, minus_zero);
+ TEST_c_c (catan, minus_zero, minus_zero, minus_zero, minus_zero);
+
+ TEST_c_c (catan, plus_infty, plus_infty, M_PI_2l, 0);
+ TEST_c_c (catan, plus_infty, minus_infty, M_PI_2l, minus_zero);
+ TEST_c_c (catan, minus_infty, plus_infty, -M_PI_2l, 0);
+ TEST_c_c (catan, minus_infty, minus_infty, -M_PI_2l, minus_zero);
+
+
+ TEST_c_c (catan, plus_infty, -10.0, M_PI_2l, minus_zero);
+ TEST_c_c (catan, minus_infty, -10.0, -M_PI_2l, minus_zero);
+ TEST_c_c (catan, plus_infty, minus_zero, M_PI_2l, minus_zero);
+ TEST_c_c (catan, minus_infty, minus_zero, -M_PI_2l, minus_zero);
+ TEST_c_c (catan, plus_infty, 0.0, M_PI_2l, 0);
+ TEST_c_c (catan, minus_infty, 0.0, -M_PI_2l, 0);
+ TEST_c_c (catan, plus_infty, 0.1L, M_PI_2l, 0);
+ TEST_c_c (catan, minus_infty, 0.1L, -M_PI_2l, 0);
+
+ TEST_c_c (catan, 0.0, minus_infty, M_PI_2l, minus_zero);
+ TEST_c_c (catan, minus_zero, minus_infty, -M_PI_2l, minus_zero);
+ TEST_c_c (catan, 100.0, minus_infty, M_PI_2l, minus_zero);
+ TEST_c_c (catan, -100.0, minus_infty, -M_PI_2l, minus_zero);
+
+ TEST_c_c (catan, 0.0, plus_infty, M_PI_2l, 0);
+ TEST_c_c (catan, minus_zero, plus_infty, -M_PI_2l, 0);
+ TEST_c_c (catan, 0.5, plus_infty, M_PI_2l, 0);
+ TEST_c_c (catan, -0.5, plus_infty, -M_PI_2l, 0);
+
+ TEST_c_c (catan, nan_value, 0.0, nan_value, 0);
+ TEST_c_c (catan, nan_value, minus_zero, nan_value, minus_zero);
+
+ TEST_c_c (catan, nan_value, plus_infty, nan_value, 0);
+ TEST_c_c (catan, nan_value, minus_infty, nan_value, minus_zero);
+
+ TEST_c_c (catan, 0.0, nan_value, nan_value, nan_value);
+ TEST_c_c (catan, minus_zero, nan_value, nan_value, nan_value);
+
+ TEST_c_c (catan, plus_infty, nan_value, M_PI_2l, 0, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (catan, minus_infty, nan_value, -M_PI_2l, 0, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (catan, nan_value, 10.5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (catan, nan_value, -10.5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (catan, 0.75, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (catan, -0.75, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (catan, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (catan, 0.75L, 1.25L, 1.10714871779409050301706546017853704L, 0.549306144334054845697622618461262852L);
+ TEST_c_c (catan, -2, -3, -1.4099210495965755225306193844604208L, -0.22907268296853876629588180294200276L);
+
+ END (catan, complex);
+}
+
+static void
+catanh_test (void)
+{
+ errno = 0;
+ FUNC(catanh) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (catanh);
+
+ TEST_c_c (catanh, 0, 0, 0.0, 0.0);
+ TEST_c_c (catanh, minus_zero, 0, minus_zero, 0.0);
+ TEST_c_c (catanh, 0, minus_zero, 0.0, minus_zero);
+ TEST_c_c (catanh, minus_zero, minus_zero, minus_zero, minus_zero);
+
+ TEST_c_c (catanh, plus_infty, plus_infty, 0.0, M_PI_2l);
+ TEST_c_c (catanh, plus_infty, minus_infty, 0.0, -M_PI_2l);
+ TEST_c_c (catanh, minus_infty, plus_infty, minus_zero, M_PI_2l);
+ TEST_c_c (catanh, minus_infty, minus_infty, minus_zero, -M_PI_2l);
+
+ TEST_c_c (catanh, -10.0, plus_infty, minus_zero, M_PI_2l);
+ TEST_c_c (catanh, -10.0, minus_infty, minus_zero, -M_PI_2l);
+ TEST_c_c (catanh, minus_zero, plus_infty, minus_zero, M_PI_2l);
+ TEST_c_c (catanh, minus_zero, minus_infty, minus_zero, -M_PI_2l);
+ TEST_c_c (catanh, 0, plus_infty, 0.0, M_PI_2l);
+ TEST_c_c (catanh, 0, minus_infty, 0.0, -M_PI_2l);
+ TEST_c_c (catanh, 0.1L, plus_infty, 0.0, M_PI_2l);
+ TEST_c_c (catanh, 0.1L, minus_infty, 0.0, -M_PI_2l);
+
+ TEST_c_c (catanh, minus_infty, 0, minus_zero, M_PI_2l);
+ TEST_c_c (catanh, minus_infty, minus_zero, minus_zero, -M_PI_2l);
+ TEST_c_c (catanh, minus_infty, 100, minus_zero, M_PI_2l);
+ TEST_c_c (catanh, minus_infty, -100, minus_zero, -M_PI_2l);
+
+ TEST_c_c (catanh, plus_infty, 0, 0.0, M_PI_2l);
+ TEST_c_c (catanh, plus_infty, minus_zero, 0.0, -M_PI_2l);
+ TEST_c_c (catanh, plus_infty, 0.5, 0.0, M_PI_2l);
+ TEST_c_c (catanh, plus_infty, -0.5, 0.0, -M_PI_2l);
+
+ TEST_c_c (catanh, 0, nan_value, 0.0, nan_value);
+ TEST_c_c (catanh, minus_zero, nan_value, minus_zero, nan_value);
+
+ TEST_c_c (catanh, plus_infty, nan_value, 0.0, nan_value);
+ TEST_c_c (catanh, minus_infty, nan_value, minus_zero, nan_value);
+
+ TEST_c_c (catanh, nan_value, 0, nan_value, nan_value);
+ TEST_c_c (catanh, nan_value, minus_zero, nan_value, nan_value);
+
+ TEST_c_c (catanh, nan_value, plus_infty, 0.0, M_PI_2l, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (catanh, nan_value, minus_infty, 0.0, -M_PI_2l, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (catanh, 10.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (catanh, -10.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (catanh, nan_value, 0.75, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (catanh, nan_value, -0.75, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (catanh, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (catanh, 0.75L, 1.25L, 0.261492138795671927078652057366532140L, 0.996825126463918666098902241310446708L);
+ TEST_c_c (catanh, -2, -3, -0.14694666622552975204743278515471595L, -1.3389725222944935611241935759091443L);
+
+ END (catanh, complex);
+}
+
+static void
+cbrt_test (void)
+{
+ errno = 0;
+ FUNC(cbrt) (8);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (cbrt);
+
+ TEST_f_f (cbrt, 0.0, 0.0);
+ TEST_f_f (cbrt, minus_zero, minus_zero);
+
+ TEST_f_f (cbrt, plus_infty, plus_infty);
+ TEST_f_f (cbrt, minus_infty, minus_infty);
+ TEST_f_f (cbrt, nan_value, nan_value);
+
+ TEST_f_f (cbrt, -0.001L, -0.1L);
+ TEST_f_f (cbrt, 8, 2);
+ TEST_f_f (cbrt, -27.0, -3.0);
+ TEST_f_f (cbrt, 0.9921875L, 0.997389022060725270579075195353955217L);
+ TEST_f_f (cbrt, 0.75L, 0.908560296416069829445605878163630251L);
+
+ END (cbrt);
+}
+
+
+static void
+ccos_test (void)
+{
+ errno = 0;
+ FUNC(ccos) (BUILD_COMPLEX (0, 0));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (ccos);
+
+ TEST_c_c (ccos, 0.0, 0.0, 1.0, minus_zero);
+ TEST_c_c (ccos, minus_zero, 0.0, 1.0, 0.0);
+ TEST_c_c (ccos, 0.0, minus_zero, 1.0, 0.0);
+ TEST_c_c (ccos, minus_zero, minus_zero, 1.0, minus_zero);
+
+ TEST_c_c (ccos, plus_infty, 0.0, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccos, plus_infty, minus_zero, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccos, minus_infty, 0.0, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccos, minus_infty, minus_zero, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (ccos, 0.0, plus_infty, plus_infty, minus_zero);
+ TEST_c_c (ccos, 0.0, minus_infty, plus_infty, 0.0);
+ TEST_c_c (ccos, minus_zero, plus_infty, plus_infty, 0.0);
+ TEST_c_c (ccos, minus_zero, minus_infty, plus_infty, minus_zero);
+
+ TEST_c_c (ccos, plus_infty, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccos, minus_infty, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccos, plus_infty, minus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccos, minus_infty, minus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (ccos, 4.625, plus_infty, minus_infty, plus_infty);
+ TEST_c_c (ccos, 4.625, minus_infty, minus_infty, minus_infty);
+ TEST_c_c (ccos, -4.625, plus_infty, minus_infty, minus_infty);
+ TEST_c_c (ccos, -4.625, minus_infty, minus_infty, plus_infty);
+
+ TEST_c_c (ccos, plus_infty, 6.75, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccos, plus_infty, -6.75, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccos, minus_infty, 6.75, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccos, minus_infty, -6.75, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (ccos, nan_value, 0.0, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccos, nan_value, minus_zero, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (ccos, nan_value, plus_infty, plus_infty, nan_value);
+ TEST_c_c (ccos, nan_value, minus_infty, plus_infty, nan_value);
+
+ TEST_c_c (ccos, nan_value, 9.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ccos, nan_value, -9.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ccos, 0.0, nan_value, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccos, minus_zero, nan_value, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (ccos, 10.0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ccos, -10.0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ccos, plus_infty, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ccos, minus_infty, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ccos, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (ccos, 0.75L, 1.25L, 1.38173873063425888530729933139078645L, -1.09193013555397466170919531722024128L);
+ TEST_c_c (ccos, -2, -3, -4.18962569096880723013255501961597373L, -9.10922789375533659797919726277886212L);
+
+ END (ccos, complex);
+}
+
+
+static void
+ccosh_test (void)
+{
+ errno = 0;
+ FUNC(ccosh) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (ccosh);
+
+ TEST_c_c (ccosh, 0.0, 0.0, 1.0, 0.0);
+ TEST_c_c (ccosh, minus_zero, 0.0, 1.0, minus_zero);
+ TEST_c_c (ccosh, 0.0, minus_zero, 1.0, minus_zero);
+ TEST_c_c (ccosh, minus_zero, minus_zero, 1.0, 0.0);
+
+ TEST_c_c (ccosh, 0.0, plus_infty, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccosh, minus_zero, plus_infty, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccosh, 0.0, minus_infty, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccosh, minus_zero, minus_infty, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (ccosh, plus_infty, 0.0, plus_infty, 0.0);
+ TEST_c_c (ccosh, minus_infty, 0.0, plus_infty, minus_zero);
+ TEST_c_c (ccosh, plus_infty, minus_zero, plus_infty, minus_zero);
+ TEST_c_c (ccosh, minus_infty, minus_zero, plus_infty, 0.0);
+
+ TEST_c_c (ccosh, plus_infty, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccosh, minus_infty, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccosh, plus_infty, minus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccosh, minus_infty, minus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (ccosh, plus_infty, 4.625, minus_infty, minus_infty);
+ TEST_c_c (ccosh, minus_infty, 4.625, minus_infty, plus_infty);
+ TEST_c_c (ccosh, plus_infty, -4.625, minus_infty, plus_infty);
+ TEST_c_c (ccosh, minus_infty, -4.625, minus_infty, minus_infty);
+
+ TEST_c_c (ccosh, 6.75, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccosh, -6.75, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccosh, 6.75, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ccosh, -6.75, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (ccosh, 0.0, nan_value, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccosh, minus_zero, nan_value, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (ccosh, plus_infty, nan_value, plus_infty, nan_value);
+ TEST_c_c (ccosh, minus_infty, nan_value, plus_infty, nan_value);
+
+ TEST_c_c (ccosh, 9.0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ccosh, -9.0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ccosh, nan_value, 0.0, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ccosh, nan_value, minus_zero, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (ccosh, nan_value, 10.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ccosh, nan_value, -10.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ccosh, nan_value, plus_infty, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ccosh, nan_value, minus_infty, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ccosh, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (ccosh, 0.75L, 1.25L, 0.408242591877968807788852146397499084L, 0.780365930845853240391326216300863152L);
+
+ TEST_c_c (ccosh, -2, -3, -3.72454550491532256547397070325597253L, 0.511822569987384608834463849801875634L);
+
+ END (ccosh, complex);
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+
+static void
+ceil_test (void)
+{
+ START (ceil);
+
+ TEST_f_f (ceil, 0.0, 0.0);
+ TEST_f_f (ceil, minus_zero, minus_zero);
+ TEST_f_f (ceil, plus_infty, plus_infty);
+ TEST_f_f (ceil, minus_infty, minus_infty);
+ TEST_f_f (ceil, nan_value, nan_value);
+
+ TEST_f_f (ceil, M_PIl, 4.0);
+ TEST_f_f (ceil, -M_PIl, -3.0);
+ TEST_f_f (ceil, 0.1, 1.0);
+ TEST_f_f (ceil, 0.25, 1.0);
+ TEST_f_f (ceil, 0.625, 1.0);
+ TEST_f_f (ceil, -0.1, minus_zero);
+ TEST_f_f (ceil, -0.25, minus_zero);
+ TEST_f_f (ceil, -0.625, minus_zero);
+
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (ceil, 4503599627370495.5L, 4503599627370496.0L);
+ TEST_f_f (ceil, 4503599627370496.25L, 4503599627370497.0L);
+ TEST_f_f (ceil, 4503599627370496.5L, 4503599627370497.0L);
+ TEST_f_f (ceil, 4503599627370496.75L, 4503599627370497.0L);
+ TEST_f_f (ceil, 4503599627370497.5L, 4503599627370498.0L);
+
+ TEST_f_f (ceil, -4503599627370495.5L, -4503599627370495.0L);
+ TEST_f_f (ceil, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (ceil, -4503599627370496.5L, -4503599627370496.0L);
+ TEST_f_f (ceil, -4503599627370496.75L, -4503599627370496.0L);
+ TEST_f_f (ceil, -4503599627370497.5L, -4503599627370497.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (ceil, 4503599627370494.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (ceil, 4503599627370495.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (ceil, 4503599627370496.5000000000001L, 4503599627370497.0L);
+ TEST_f_f (ceil, -4503599627370494.5000000000001L, -4503599627370494.0L);
+ TEST_f_f (ceil, -4503599627370495.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (ceil, -4503599627370496.5000000000001L, -4503599627370496.0L);
+# endif
+
+ TEST_f_f (ceil, 9007199254740991.5L, 9007199254740992.0L);
+ TEST_f_f (ceil, 9007199254740992.25L, 9007199254740993.0L);
+ TEST_f_f (ceil, 9007199254740992.5L, 9007199254740993.0L);
+ TEST_f_f (ceil, 9007199254740992.75L, 9007199254740993.0L);
+ TEST_f_f (ceil, 9007199254740993.5L, 9007199254740994.0L);
+
+ TEST_f_f (ceil, -9007199254740991.5L, -9007199254740991.0L);
+ TEST_f_f (ceil, -9007199254740992.25L, -9007199254740992.0L);
+ TEST_f_f (ceil, -9007199254740992.5L, -9007199254740992.0L);
+ TEST_f_f (ceil, -9007199254740992.75L, -9007199254740992.0L);
+ TEST_f_f (ceil, -9007199254740993.5L, -9007199254740993.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (ceil, 9007199254740991.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (ceil, 9007199254740992.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (ceil, 9007199254740993.0000000000001L, 9007199254740994.0L);
+ TEST_f_f (ceil, 9007199254740991.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (ceil, 9007199254740992.5000000000001L, 9007199254740993.0L);
+ TEST_f_f (ceil, 9007199254740993.5000000000001L, 9007199254740994.0L);
+
+ TEST_f_f (ceil, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (ceil, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (ceil, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (ceil, -9007199254740991.5000000000001L, -9007199254740991.0L);
+ TEST_f_f (ceil, -9007199254740992.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (ceil, -9007199254740993.5000000000001L, -9007199254740993.0L);
+# endif
+
+ TEST_f_f (ceil, 72057594037927935.5L, 72057594037927936.0L);
+ TEST_f_f (ceil, 72057594037927936.25L, 72057594037927937.0L);
+ TEST_f_f (ceil, 72057594037927936.5L, 72057594037927937.0L);
+ TEST_f_f (ceil, 72057594037927936.75L, 72057594037927937.0L);
+ TEST_f_f (ceil, 72057594037927937.5L, 72057594037927938.0L);
+
+ TEST_f_f (ceil, -72057594037927935.5L, -72057594037927935.0L);
+ TEST_f_f (ceil, -72057594037927936.25L, -72057594037927936.0L);
+ TEST_f_f (ceil, -72057594037927936.5L, -72057594037927936.0L);
+ TEST_f_f (ceil, -72057594037927936.75L, -72057594037927936.0L);
+ TEST_f_f (ceil, -72057594037927937.5L, -72057594037927937.0L);
+
+ TEST_f_f (ceil, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L);
+ TEST_f_f (ceil, 10141204801825835211973625643008.25L, 10141204801825835211973625643009.0L);
+ TEST_f_f (ceil, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L);
+ TEST_f_f (ceil, 10141204801825835211973625643008.75L, 10141204801825835211973625643009.0L);
+ TEST_f_f (ceil, 10141204801825835211973625643009.5L, 10141204801825835211973625643010.0L);
+#endif
+
+ END (ceil);
+}
+
+
+#ifndef __STDC_WANT_DEC_FP__
+static void
+cexp_test (void)
+{
+ errno = 0;
+ FUNC(cexp) (BUILD_COMPLEX (0, 0));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (cexp);
+
+ TEST_c_c (cexp, plus_zero, plus_zero, 1, 0.0);
+ TEST_c_c (cexp, minus_zero, plus_zero, 1, 0.0);
+ TEST_c_c (cexp, plus_zero, minus_zero, 1, minus_zero);
+ TEST_c_c (cexp, minus_zero, minus_zero, 1, minus_zero);
+
+ TEST_c_c (cexp, plus_infty, plus_zero, plus_infty, 0.0);
+ TEST_c_c (cexp, plus_infty, minus_zero, plus_infty, minus_zero);
+
+ TEST_c_c (cexp, minus_infty, plus_zero, 0.0, 0.0);
+ TEST_c_c (cexp, minus_infty, minus_zero, 0.0, minus_zero);
+
+ TEST_c_c (cexp, 0.0, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (cexp, minus_zero, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (cexp, 0.0, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (cexp, minus_zero, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (cexp, 100.0, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (cexp, -100.0, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (cexp, 100.0, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (cexp, -100.0, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (cexp, minus_infty, 2.0, minus_zero, 0.0);
+ TEST_c_c (cexp, minus_infty, 4.0, minus_zero, minus_zero);
+ TEST_c_c (cexp, plus_infty, 2.0, minus_infty, plus_infty);
+ TEST_c_c (cexp, plus_infty, 4.0, minus_infty, minus_infty);
+
+ TEST_c_c (cexp, plus_infty, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (cexp, plus_infty, minus_infty, plus_infty, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (cexp, minus_infty, plus_infty, 0.0, 0.0, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (cexp, minus_infty, minus_infty, 0.0, minus_zero, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (cexp, minus_infty, nan_value, 0, 0, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (cexp, plus_infty, nan_value, plus_infty, nan_value);
+
+ TEST_c_c (cexp, nan_value, 0.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (cexp, nan_value, 1.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (cexp, nan_value, plus_infty, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (cexp, 0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (cexp, 1, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (cexp, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (cexp, 0.75L, 1.25L, 0.667537446429131586942201977015932112L, 2.00900045494094876258347228145863909L);
+ TEST_c_c (cexp, -2.0, -3.0, -0.13398091492954261346140525546115575L, -0.019098516261135196432576240858800925L);
+
+ END (cexp, complex);
+}
+
+
+static void
+cimag_test (void)
+{
+ START (cimag);
+ TEST_c_f (cimag, 1.0, 0.0, 0.0);
+ TEST_c_f (cimag, 1.0, minus_zero, minus_zero);
+ TEST_c_f (cimag, 1.0, nan_value, nan_value);
+ TEST_c_f (cimag, nan_value, nan_value, nan_value);
+ TEST_c_f (cimag, 1.0, plus_infty, plus_infty);
+ TEST_c_f (cimag, 1.0, minus_infty, minus_infty);
+ TEST_c_f (cimag, 2.0, 3.0, 3.0);
+
+ END (cimag);
+}
+
+static void
+clog_test (void)
+{
+ errno = 0;
+ FUNC(clog) (BUILD_COMPLEX (-2, -3));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (clog);
+
+ TEST_c_c (clog, minus_zero, 0, minus_infty, M_PIl, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_c_c (clog, minus_zero, minus_zero, minus_infty, -M_PIl, DIVIDE_BY_ZERO_EXCEPTION);
+
+ TEST_c_c (clog, 0, 0, minus_infty, 0.0, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_c_c (clog, 0, minus_zero, minus_infty, minus_zero, DIVIDE_BY_ZERO_EXCEPTION);
+
+ TEST_c_c (clog, minus_infty, plus_infty, plus_infty, M_PI_34l);
+ TEST_c_c (clog, minus_infty, minus_infty, plus_infty, -M_PI_34l);
+
+ TEST_c_c (clog, plus_infty, plus_infty, plus_infty, M_PI_4l);
+ TEST_c_c (clog, plus_infty, minus_infty, plus_infty, -M_PI_4l);
+
+ TEST_c_c (clog, 0, plus_infty, plus_infty, M_PI_2l);
+ TEST_c_c (clog, 3, plus_infty, plus_infty, M_PI_2l);
+ TEST_c_c (clog, minus_zero, plus_infty, plus_infty, M_PI_2l);
+ TEST_c_c (clog, -3, plus_infty, plus_infty, M_PI_2l);
+ TEST_c_c (clog, 0, minus_infty, plus_infty, -M_PI_2l);
+ TEST_c_c (clog, 3, minus_infty, plus_infty, -M_PI_2l);
+ TEST_c_c (clog, minus_zero, minus_infty, plus_infty, -M_PI_2l);
+ TEST_c_c (clog, -3, minus_infty, plus_infty, -M_PI_2l);
+
+ TEST_c_c (clog, minus_infty, 0, plus_infty, M_PIl);
+ TEST_c_c (clog, minus_infty, 1, plus_infty, M_PIl);
+ TEST_c_c (clog, minus_infty, minus_zero, plus_infty, -M_PIl);
+ TEST_c_c (clog, minus_infty, -1, plus_infty, -M_PIl);
+
+ TEST_c_c (clog, plus_infty, 0, plus_infty, 0.0);
+ TEST_c_c (clog, plus_infty, 1, plus_infty, 0.0);
+ TEST_c_c (clog, plus_infty, minus_zero, plus_infty, minus_zero);
+ TEST_c_c (clog, plus_infty, -1, plus_infty, minus_zero);
+
+ TEST_c_c (clog, plus_infty, nan_value, plus_infty, nan_value);
+ TEST_c_c (clog, minus_infty, nan_value, plus_infty, nan_value);
+
+ TEST_c_c (clog, nan_value, plus_infty, plus_infty, nan_value);
+ TEST_c_c (clog, nan_value, minus_infty, plus_infty, nan_value);
+
+ TEST_c_c (clog, 0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog, 3, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog, minus_zero, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog, -3, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (clog, nan_value, 0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog, nan_value, 5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog, nan_value, minus_zero, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog, nan_value, -5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (clog, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (clog, 0.75L, 1.25L, 0.376885901188190075998919126749298416L, 1.03037682652431246378774332703115153L);
+ TEST_c_c (clog, -2, -3, 1.2824746787307683680267437207826593L, -2.1587989303424641704769327722648368L);
+
+ END (clog, complex);
+}
+
+
+static void
+clog10_test (void)
+{
+ errno = 0;
+ FUNC(clog10) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (clog10);
+
+ TEST_c_c (clog10, minus_zero, 0, minus_infty, M_PIl, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_c_c (clog10, minus_zero, minus_zero, minus_infty, -M_PIl, DIVIDE_BY_ZERO_EXCEPTION);
+
+ TEST_c_c (clog10, 0, 0, minus_infty, 0.0, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_c_c (clog10, 0, minus_zero, minus_infty, minus_zero, DIVIDE_BY_ZERO_EXCEPTION);
+
+ TEST_c_c (clog10, minus_infty, plus_infty, plus_infty, M_PI_34_LOG10El);
+
+ TEST_c_c (clog10, plus_infty, plus_infty, plus_infty, M_PI4_LOG10El);
+ TEST_c_c (clog10, plus_infty, minus_infty, plus_infty, -M_PI4_LOG10El);
+
+ TEST_c_c (clog10, 0, plus_infty, plus_infty, M_PI2_LOG10El);
+ TEST_c_c (clog10, 3, plus_infty, plus_infty, M_PI2_LOG10El);
+ TEST_c_c (clog10, minus_zero, plus_infty, plus_infty, M_PI2_LOG10El);
+ TEST_c_c (clog10, -3, plus_infty, plus_infty, M_PI2_LOG10El);
+ TEST_c_c (clog10, 0, minus_infty, plus_infty, -M_PI2_LOG10El);
+ TEST_c_c (clog10, 3, minus_infty, plus_infty, -M_PI2_LOG10El);
+ TEST_c_c (clog10, minus_zero, minus_infty, plus_infty, -M_PI2_LOG10El);
+ TEST_c_c (clog10, -3, minus_infty, plus_infty, -M_PI2_LOG10El);
+
+ TEST_c_c (clog10, minus_infty, 0, plus_infty, M_PI_LOG10El);
+ TEST_c_c (clog10, minus_infty, 1, plus_infty, M_PI_LOG10El);
+ TEST_c_c (clog10, minus_infty, minus_zero, plus_infty, -M_PI_LOG10El);
+ TEST_c_c (clog10, minus_infty, -1, plus_infty, -M_PI_LOG10El);
+
+ TEST_c_c (clog10, plus_infty, 0, plus_infty, 0.0);
+ TEST_c_c (clog10, plus_infty, 1, plus_infty, 0.0);
+ TEST_c_c (clog10, plus_infty, minus_zero, plus_infty, minus_zero);
+ TEST_c_c (clog10, plus_infty, -1, plus_infty, minus_zero);
+
+ TEST_c_c (clog10, plus_infty, nan_value, plus_infty, nan_value);
+ TEST_c_c (clog10, minus_infty, nan_value, plus_infty, nan_value);
+
+ TEST_c_c (clog10, nan_value, plus_infty, plus_infty, nan_value);
+ TEST_c_c (clog10, nan_value, minus_infty, plus_infty, nan_value);
+
+ TEST_c_c (clog10, 0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog10, 3, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog10, minus_zero, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog10, -3, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (clog10, nan_value, 0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog10, nan_value, 5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog10, nan_value, minus_zero, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (clog10, nan_value, -5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (clog10, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (clog10, 0.75L, 1.25L, 0.163679467193165171449476605077428975L, 0.447486970040493067069984724340855636L);
+ TEST_c_c (clog10, -2, -3, 0.556971676153418384603252578971164214L, -0.937554462986374708541507952140189646L);
+
+ END (clog10, complex);
+}
+
+
+static void
+conj_test (void)
+{
+ START (conj);
+ TEST_c_c (conj, 0.0, 0.0, 0.0, minus_zero);
+ TEST_c_c (conj, 0.0, minus_zero, 0.0, 0.0);
+ TEST_c_c (conj, nan_value, nan_value, nan_value, nan_value);
+ TEST_c_c (conj, plus_infty, minus_infty, plus_infty, plus_infty);
+ TEST_c_c (conj, plus_infty, plus_infty, plus_infty, minus_infty);
+ TEST_c_c (conj, 1.0, 2.0, 1.0, -2.0);
+ TEST_c_c (conj, 3.0, -4.0, 3.0, 4.0);
+
+ END (conj, complex);
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+
+static void
+copysign_test (void)
+{
+ START (copysign);
+
+ TEST_ff_f (copysign, 0, 4, 0);
+ TEST_ff_f (copysign, 0, -4, minus_zero);
+ TEST_ff_f (copysign, minus_zero, 4, 0);
+ TEST_ff_f (copysign, minus_zero, -4, minus_zero);
+
+ TEST_ff_f (copysign, plus_infty, 0, plus_infty);
+ TEST_ff_f (copysign, plus_infty, minus_zero, minus_infty);
+ TEST_ff_f (copysign, minus_infty, 0, plus_infty);
+ TEST_ff_f (copysign, minus_infty, minus_zero, minus_infty);
+
+ TEST_ff_f (copysign, 0, plus_infty, 0);
+ TEST_ff_f (copysign, 0, minus_zero, minus_zero);
+ TEST_ff_f (copysign, minus_zero, plus_infty, 0);
+ TEST_ff_f (copysign, minus_zero, minus_zero, minus_zero);
+
+ /* XXX More correctly we would have to check the sign of the NaN. */
+ TEST_ff_f (copysign, nan_value, 0, nan_value);
+ TEST_ff_f (copysign, nan_value, minus_zero, nan_value);
+ TEST_ff_f (copysign, -nan_value, 0, nan_value);
+ TEST_ff_f (copysign, -nan_value, minus_zero, nan_value);
+
+ END (copysign);
+}
+
+
+static void
+cos_test (void)
+{
+ errno = 0;
+ FUNC(cos) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (cos);
+
+ TEST_f_f (cos, 0, 1);
+ TEST_f_f (cos, minus_zero, 1);
+ TEST_f_f (cos, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (cos, minus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (cos, nan_value, nan_value);
+
+ TEST_f_f (cos, M_PI_6l * 2.0, 0.5);
+ TEST_f_f (cos, M_PI_6l * 4.0, -0.5);
+ TEST_f_f (cos, M_PI_2l, 0);
+
+ TEST_f_f (cos, 0.75L, 0.731688868873820886311838753000084544L);
+
+#ifdef TEST_DOUBLE
+ TEST_f_f (cos, 0.80190127184058835, 0.69534156199418473);
+#endif
+
+ END (cos);
+}
+
+
+static void
+cosh_test (void)
+{
+ errno = 0;
+ FUNC(cosh) (0.7L);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (cosh);
+ TEST_f_f (cosh, 0, 1);
+ TEST_f_f (cosh, minus_zero, 1);
+
+#ifndef TEST_INLINE
+ TEST_f_f (cosh, plus_infty, plus_infty);
+ TEST_f_f (cosh, minus_infty, plus_infty);
+#endif
+ TEST_f_f (cosh, nan_value, nan_value);
+
+ TEST_f_f (cosh, 0.75L, 1.29468328467684468784170818539018176L);
+
+ END (cosh);
+}
+
+
+#ifndef __STDC_WANT_DEC_FP__
+static void
+cpow_test (void)
+{
+ errno = 0;
+ FUNC(cpow) (BUILD_COMPLEX (1, 0), BUILD_COMPLEX (0, 0));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (cpow);
+
+ TEST_cc_c (cpow, 1, 0, 0, 0, 1.0, 0.0);
+ TEST_cc_c (cpow, 2, 0, 10, 0, 1024.0, 0.0);
+
+ TEST_cc_c (cpow, M_El, 0, 0, 2 * M_PIl, 1.0, 0.0);
+ TEST_cc_c (cpow, 2, 3, 4, 0, -119.0, -120.0);
+
+ TEST_cc_c (cpow, nan_value, nan_value, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_cc_c (cpow, 0.75L, 1.25L, 0.75L, 1.25L, 0.117506293914473555420279832210420483L, 0.346552747708338676483025352060418001L);
+ TEST_cc_c (cpow, 0.75L, 1.25L, 1.0L, 1.0L, 0.0846958290317209430433805274189191353L, 0.513285749182902449043287190519090481L);
+ TEST_cc_c (cpow, 0.75L, 1.25L, 1.0L, 0.0L, 0.75L, 1.25L);
+ TEST_cc_c (cpow, 0.75L, 1.25L, 0.0L, 1.0L, 0.331825439177608832276067945276730566L, 0.131338600281188544930936345230903032L);
+
+ END (cpow, complex);
+}
+
+
+static void
+cproj_test (void)
+{
+ START (cproj);
+ TEST_c_c (cproj, 0.0, 0.0, 0.0, 0.0);
+ TEST_c_c (cproj, minus_zero, minus_zero, minus_zero, minus_zero);
+ TEST_c_c (cproj, 0.0, minus_zero, 0.0, minus_zero);
+ TEST_c_c (cproj, minus_zero, 0.0, minus_zero, 0.0);
+
+ TEST_c_c (cproj, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (cproj, plus_infty, plus_infty, plus_infty, 0.0);
+ TEST_c_c (cproj, plus_infty, minus_infty, plus_infty, minus_zero);
+ TEST_c_c (cproj, minus_infty, plus_infty, plus_infty, 0.0);
+ TEST_c_c (cproj, minus_infty, minus_infty, plus_infty, minus_zero);
+
+ TEST_c_c (cproj, 1.0, 0.0, 1.0, 0.0);
+ TEST_c_c (cproj, 2.0, 3.0, 0.2857142857142857142857142857142857L, 0.42857142857142857142857142857142855L);
+
+ END (cproj, complex);
+}
+
+
+static void
+creal_test (void)
+{
+ START (creal);
+ TEST_c_f (creal, 0.0, 1.0, 0.0);
+ TEST_c_f (creal, minus_zero, 1.0, minus_zero);
+ TEST_c_f (creal, nan_value, 1.0, nan_value);
+ TEST_c_f (creal, nan_value, nan_value, nan_value);
+ TEST_c_f (creal, plus_infty, 1.0, plus_infty);
+ TEST_c_f (creal, minus_infty, 1.0, minus_infty);
+ TEST_c_f (creal, 2.0, 3.0, 2.0);
+
+ END (creal);
+}
+
+static void
+csin_test (void)
+{
+ errno = 0;
+ FUNC(csin) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (csin);
+
+ TEST_c_c (csin, 0.0, 0.0, 0.0, 0.0);
+ TEST_c_c (csin, minus_zero, 0.0, minus_zero, 0.0);
+ TEST_c_c (csin, 0.0, minus_zero, 0, minus_zero);
+ TEST_c_c (csin, minus_zero, minus_zero, minus_zero, minus_zero);
+
+ TEST_c_c (csin, 0.0, plus_infty, 0.0, plus_infty);
+ TEST_c_c (csin, minus_zero, plus_infty, minus_zero, plus_infty);
+ TEST_c_c (csin, 0.0, minus_infty, 0.0, minus_infty);
+ TEST_c_c (csin, minus_zero, minus_infty, minus_zero, minus_infty);
+
+ TEST_c_c (csin, plus_infty, 0.0, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csin, minus_infty, 0.0, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csin, plus_infty, minus_zero, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csin, minus_infty, minus_zero, nan_value, 0.0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (csin, plus_infty, plus_infty, nan_value, plus_infty, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csin, minus_infty, plus_infty, nan_value, plus_infty, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csin, plus_infty, minus_infty, nan_value, plus_infty, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csin, minus_infty, minus_infty, nan_value, plus_infty, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (csin, plus_infty, 6.75, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (csin, plus_infty, -6.75, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (csin, minus_infty, 6.75, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (csin, minus_infty, -6.75, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (csin, 4.625, plus_infty, minus_infty, minus_infty);
+ TEST_c_c (csin, 4.625, minus_infty, minus_infty, plus_infty);
+ TEST_c_c (csin, -4.625, plus_infty, plus_infty, minus_infty);
+ TEST_c_c (csin, -4.625, minus_infty, plus_infty, plus_infty);
+
+ TEST_c_c (csin, nan_value, 0.0, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csin, nan_value, minus_zero, nan_value, 0.0, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (csin, nan_value, plus_infty, nan_value, plus_infty, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csin, nan_value, minus_infty, nan_value, plus_infty, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (csin, nan_value, 9.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csin, nan_value, -9.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (csin, 0.0, nan_value, 0.0, nan_value);
+ TEST_c_c (csin, minus_zero, nan_value, minus_zero, nan_value);
+
+ TEST_c_c (csin, 10.0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csin, nan_value, -10.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (csin, plus_infty, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csin, minus_infty, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (csin, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (csin, 0.75L, 1.25L, 1.28722291002649188575873510790565441L, 1.17210635989270256101081285116138863L);
+ TEST_c_c (csin, -2, -3, -9.15449914691142957346729954460983256L, 4.16890695996656435075481305885375484L);
+
+ END (csin, complex);
+}
+
+
+static void
+csinh_test (void)
+{
+ errno = 0;
+ FUNC(csinh) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (csinh);
+
+ TEST_c_c (csinh, 0.0, 0.0, 0.0, 0.0);
+ TEST_c_c (csinh, minus_zero, 0.0, minus_zero, 0.0);
+ TEST_c_c (csinh, 0.0, minus_zero, 0.0, minus_zero);
+ TEST_c_c (csinh, minus_zero, minus_zero, minus_zero, minus_zero);
+
+ TEST_c_c (csinh, 0.0, plus_infty, 0.0, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csinh, minus_zero, plus_infty, 0.0, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csinh, 0.0, minus_infty, 0.0, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csinh, minus_zero, minus_infty, 0.0, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (csinh, plus_infty, 0.0, plus_infty, 0.0);
+ TEST_c_c (csinh, minus_infty, 0.0, minus_infty, 0.0);
+ TEST_c_c (csinh, plus_infty, minus_zero, plus_infty, minus_zero);
+ TEST_c_c (csinh, minus_infty, minus_zero, minus_infty, minus_zero);
+
+ TEST_c_c (csinh, plus_infty, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csinh, minus_infty, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csinh, plus_infty, minus_infty, plus_infty, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csinh, minus_infty, minus_infty, plus_infty, nan_value, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (csinh, plus_infty, 4.625, minus_infty, minus_infty);
+ TEST_c_c (csinh, minus_infty, 4.625, plus_infty, minus_infty);
+ TEST_c_c (csinh, plus_infty, -4.625, minus_infty, plus_infty);
+ TEST_c_c (csinh, minus_infty, -4.625, plus_infty, plus_infty);
+
+ TEST_c_c (csinh, 6.75, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (csinh, -6.75, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (csinh, 6.75, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (csinh, -6.75, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (csinh, 0.0, nan_value, 0.0, nan_value, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csinh, minus_zero, nan_value, 0.0, nan_value, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (csinh, plus_infty, nan_value, plus_infty, nan_value, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (csinh, minus_infty, nan_value, plus_infty, nan_value, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (csinh, 9.0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csinh, -9.0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (csinh, nan_value, 0.0, nan_value, 0.0);
+ TEST_c_c (csinh, nan_value, minus_zero, nan_value, minus_zero);
+
+ TEST_c_c (csinh, nan_value, 10.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csinh, nan_value, -10.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (csinh, nan_value, plus_infty, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csinh, nan_value, minus_infty, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (csinh, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (csinh, 0.75L, 1.25L, 0.259294854551162779153349830618433028L, 1.22863452409509552219214606515777594L);
+ TEST_c_c (csinh, -2, -3, 3.59056458998577995201256544779481679L, -0.530921086248519805267040090660676560L);
+
+ END (csinh, complex);
+}
+
+
+static void
+csqrt_test (void)
+{
+ errno = 0;
+ FUNC(csqrt) (BUILD_COMPLEX (-1, 0));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (csqrt);
+
+ TEST_c_c (csqrt, 0, 0, 0.0, 0.0);
+ TEST_c_c (csqrt, 0, minus_zero, 0, minus_zero);
+ TEST_c_c (csqrt, minus_zero, 0, 0.0, 0.0);
+ TEST_c_c (csqrt, minus_zero, minus_zero, 0.0, minus_zero);
+
+ TEST_c_c (csqrt, minus_infty, 0, 0.0, plus_infty);
+ TEST_c_c (csqrt, minus_infty, 6, 0.0, plus_infty);
+ TEST_c_c (csqrt, minus_infty, minus_zero, 0.0, minus_infty);
+ TEST_c_c (csqrt, minus_infty, -6, 0.0, minus_infty);
+
+ TEST_c_c (csqrt, plus_infty, 0, plus_infty, 0.0);
+ TEST_c_c (csqrt, plus_infty, 6, plus_infty, 0.0);
+ TEST_c_c (csqrt, plus_infty, minus_zero, plus_infty, minus_zero);
+ TEST_c_c (csqrt, plus_infty, -6, plus_infty, minus_zero);
+
+ TEST_c_c (csqrt, 0, plus_infty, plus_infty, plus_infty);
+ TEST_c_c (csqrt, 4, plus_infty, plus_infty, plus_infty);
+ TEST_c_c (csqrt, plus_infty, plus_infty, plus_infty, plus_infty);
+ TEST_c_c (csqrt, minus_zero, plus_infty, plus_infty, plus_infty);
+ TEST_c_c (csqrt, -4, plus_infty, plus_infty, plus_infty);
+ TEST_c_c (csqrt, minus_infty, plus_infty, plus_infty, plus_infty);
+ TEST_c_c (csqrt, 0, minus_infty, plus_infty, minus_infty);
+ TEST_c_c (csqrt, 4, minus_infty, plus_infty, minus_infty);
+ TEST_c_c (csqrt, plus_infty, minus_infty, plus_infty, minus_infty);
+ TEST_c_c (csqrt, minus_zero, minus_infty, plus_infty, minus_infty);
+ TEST_c_c (csqrt, -4, minus_infty, plus_infty, minus_infty);
+ TEST_c_c (csqrt, minus_infty, minus_infty, plus_infty, minus_infty);
+
+ TEST_c_c (csqrt, minus_infty, nan_value, nan_value, plus_infty, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (csqrt, plus_infty, nan_value, plus_infty, nan_value);
+
+ TEST_c_c (csqrt, 0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csqrt, 1, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csqrt, minus_zero, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csqrt, -1, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (csqrt, nan_value, 0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csqrt, nan_value, 8, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csqrt, nan_value, minus_zero, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (csqrt, nan_value, -8, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (csqrt, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (csqrt, 16.0, -30.0, 5.0, -3.0);
+ TEST_c_c (csqrt, -1, 0, 0.0, 1.0);
+ TEST_c_c (csqrt, 0, 2, 1.0, 1.0);
+ TEST_c_c (csqrt, 119, 120, 12.0, 5.0);
+ TEST_c_c (csqrt, 0.75L, 1.25L, 1.05065169626078392338656675760808326L, 0.594868882070379067881984030639932657L);
+ TEST_c_c (csqrt, -2, -3, 0.89597747612983812471573375529004348L, -1.6741492280355400404480393008490519L);
+ TEST_c_c (csqrt, -2, 3, 0.89597747612983812471573375529004348L, 1.6741492280355400404480393008490519L);
+ /* Principal square root should be returned (i.e., non-negative real
+ part). */
+ TEST_c_c (csqrt, 0, -1, M_SQRT_2_2, -M_SQRT_2_2);
+
+ END (csqrt, complex);
+}
+
+static void
+ctan_test (void)
+{
+ errno = 0;
+ FUNC(ctan) (BUILD_COMPLEX (0.7L, 1.2L));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (ctan);
+
+ TEST_c_c (ctan, 0, 0, 0.0, 0.0);
+ TEST_c_c (ctan, 0, minus_zero, 0.0, minus_zero);
+ TEST_c_c (ctan, minus_zero, 0, minus_zero, 0.0);
+ TEST_c_c (ctan, minus_zero, minus_zero, minus_zero, minus_zero);
+
+ TEST_c_c (ctan, 0, plus_infty, 0.0, 1.0);
+ TEST_c_c (ctan, 1, plus_infty, 0.0, 1.0);
+ TEST_c_c (ctan, minus_zero, plus_infty, minus_zero, 1.0);
+ TEST_c_c (ctan, -1, plus_infty, minus_zero, 1.0);
+
+ TEST_c_c (ctan, 0, minus_infty, 0.0, -1.0);
+ TEST_c_c (ctan, 1, minus_infty, 0.0, -1.0);
+ TEST_c_c (ctan, minus_zero, minus_infty, minus_zero, -1.0);
+ TEST_c_c (ctan, -1, minus_infty, minus_zero, -1.0);
+
+ TEST_c_c (ctan, plus_infty, 0, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctan, plus_infty, 2, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctan, minus_infty, 0, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctan, minus_infty, 2, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctan, plus_infty, minus_zero, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctan, plus_infty, -2, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctan, minus_infty, minus_zero, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctan, minus_infty, -2, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (ctan, nan_value, plus_infty, 0.0, 1.0, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ctan, nan_value, minus_infty, 0.0, -1.0, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (ctan, 0, nan_value, 0.0, nan_value);
+ TEST_c_c (ctan, minus_zero, nan_value, minus_zero, nan_value);
+
+ TEST_c_c (ctan, 0.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ctan, -4.5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ctan, nan_value, 0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ctan, nan_value, 5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ctan, nan_value, minus_zero, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ctan, nan_value, -0.25, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ctan, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (ctan, 0.75L, 1.25L, 0.160807785916206426725166058173438663L, 0.975363285031235646193581759755216379L);
+ TEST_c_c (ctan, -2, -3, 0.376402564150424829275122113032269084e-2L, -1.00323862735360980144635859782192726L);
+
+ END (ctan, complex);
+}
+
+
+static void
+ctanh_test (void)
+{
+ errno = 0;
+ FUNC(ctanh) (BUILD_COMPLEX (0, 0));
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (ctanh);
+
+ TEST_c_c (ctanh, 0, 0, 0.0, 0.0);
+ TEST_c_c (ctanh, 0, minus_zero, 0.0, minus_zero);
+ TEST_c_c (ctanh, minus_zero, 0, minus_zero, 0.0);
+ TEST_c_c (ctanh, minus_zero, minus_zero, minus_zero, minus_zero);
+
+ TEST_c_c (ctanh, plus_infty, 0, 1.0, 0.0);
+ TEST_c_c (ctanh, plus_infty, 1, 1.0, 0.0);
+ TEST_c_c (ctanh, plus_infty, minus_zero, 1.0, minus_zero);
+ TEST_c_c (ctanh, plus_infty, -1, 1.0, minus_zero);
+ TEST_c_c (ctanh, minus_infty, 0, -1.0, 0.0);
+ TEST_c_c (ctanh, minus_infty, 1, -1.0, 0.0);
+ TEST_c_c (ctanh, minus_infty, minus_zero, -1.0, minus_zero);
+ TEST_c_c (ctanh, minus_infty, -1, -1.0, minus_zero);
+
+ TEST_c_c (ctanh, 0, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctanh, 2, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctanh, 0, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctanh, 2, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctanh, minus_zero, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctanh, -2, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctanh, minus_zero, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_c_c (ctanh, -2, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+
+ TEST_c_c (ctanh, plus_infty, nan_value, 1.0, 0.0, IGNORE_ZERO_INF_SIGN);
+ TEST_c_c (ctanh, minus_infty, nan_value, -1.0, 0.0, IGNORE_ZERO_INF_SIGN);
+
+ TEST_c_c (ctanh, nan_value, 0, nan_value, 0.0);
+ TEST_c_c (ctanh, nan_value, minus_zero, nan_value, minus_zero);
+
+ TEST_c_c (ctanh, nan_value, 0.5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ctanh, nan_value, -4.5, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ctanh, 0, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ctanh, 5, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ctanh, minus_zero, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_c_c (ctanh, -0.25, nan_value, nan_value, nan_value, INVALID_EXCEPTION_OK);
+
+ TEST_c_c (ctanh, nan_value, nan_value, nan_value, nan_value);
+
+ TEST_c_c (ctanh, 0, M_PI_4l, 0.0, 1.0);
+
+ TEST_c_c (ctanh, 0.75L, 1.25L, 1.37260757053378320258048606571226857L, 0.385795952609750664177596760720790220L);
+ TEST_c_c (ctanh, -2, -3, -0.965385879022133124278480269394560686L, 0.988437503832249372031403430350121098e-2L);
+
+ END (ctanh, complex);
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+
+static void
+erf_test (void)
+{
+ errno = 0;
+ FUNC(erf) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (erf);
+
+ TEST_f_f (erf, 0, 0);
+ TEST_f_f (erf, minus_zero, minus_zero);
+ TEST_f_f (erf, plus_infty, 1);
+ TEST_f_f (erf, minus_infty, -1);
+ TEST_f_f (erf, nan_value, nan_value);
+
+ TEST_f_f (erf, 0.125L, 0.140316204801333817393029446521623398L);
+ TEST_f_f (erf, 0.75L, 0.711155633653515131598937834591410777L);
+ TEST_f_f (erf, 1.25L, 0.922900128256458230136523481197281140L);
+ TEST_f_f (erf, 2.0L, 0.995322265018952734162069256367252929L);
+ TEST_f_f (erf, 4.125L, 0.999999994576599200434933994687765914L);
+ TEST_f_f (erf, 27.0L, 1.0L);
+
+ END (erf);
+}
+
+
+static void
+erfc_test (void)
+{
+ errno = 0;
+ FUNC(erfc) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (erfc);
+
+ TEST_f_f (erfc, plus_infty, 0.0);
+ TEST_f_f (erfc, minus_infty, 2.0);
+ TEST_f_f (erfc, 0.0, 1.0);
+ TEST_f_f (erfc, minus_zero, 1.0);
+ TEST_f_f (erfc, nan_value, nan_value);
+
+ TEST_f_f (erfc, 0.125L, 0.859683795198666182606970553478376602L);
+ TEST_f_f (erfc, 0.75L, 0.288844366346484868401062165408589223L);
+ TEST_f_f (erfc, 1.25L, 0.0770998717435417698634765188027188596L);
+ TEST_f_f (erfc, 2.0L, 0.00467773498104726583793074363274707139L);
+ TEST_f_f (erfc, 4.125L, 0.542340079956506600531223408575531062e-8L);
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+# if LDBL_MIN_10_EXP < -319
+ TEST_f_f (erfc, 27.0L, 0.523704892378925568501606768284954709e-318L);
+# endif
+#endif
+
+ END (erfc);
+}
+
+
+static void
+exp_test (void)
+{
+ errno = 0;
+ FUNC(exp) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (exp);
+
+ TEST_f_f (exp, 0, 1);
+ TEST_f_f (exp, minus_zero, 1);
+
+#ifndef TEST_INLINE
+ TEST_f_f (exp, plus_infty, plus_infty);
+ TEST_f_f (exp, minus_infty, 0);
+#endif
+ TEST_f_f (exp, nan_value, nan_value);
+ TEST_f_f (exp, 1, M_El);
+
+ TEST_f_f (exp, 2, M_E2l);
+ TEST_f_f (exp, 3, M_E3l);
+ TEST_f_f (exp, 0.75L, 2.11700001661267466854536981983709561L);
+ TEST_f_f (exp, 50.0L, 5184705528587072464087.45332293348538L);
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (exp, 1000.0L, 0.197007111401704699388887935224332313e435L);
+#endif
+
+ END (exp);
+}
+
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have the exp10 function */
+static void
+exp10_test (void)
+{
+ errno = 0;
+ FUNC(exp10) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (exp10);
+
+ TEST_f_f (exp10, 0, 1);
+ TEST_f_f (exp10, minus_zero, 1);
+
+ TEST_f_f (exp10, plus_infty, plus_infty);
+ TEST_f_f (exp10, minus_infty, 0);
+ TEST_f_f (exp10, nan_value, nan_value);
+ TEST_f_f (exp10, 3, 1000);
+ TEST_f_f (exp10, -1, 0.1L);
+ TEST_f_f (exp10, 1e6, plus_infty);
+ TEST_f_f (exp10, -1e6, 0);
+ TEST_f_f (exp10, 0.75L, 5.62341325190349080394951039776481231L);
+
+ END (exp10);
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+
+static void
+exp2_test (void)
+{
+ errno = 0;
+ FUNC(exp2) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (exp2);
+
+ TEST_f_f (exp2, 0, 1);
+ TEST_f_f (exp2, minus_zero, 1);
+ TEST_f_f (exp2, plus_infty, plus_infty);
+ TEST_f_f (exp2, minus_infty, 0);
+ TEST_f_f (exp2, nan_value, nan_value);
+
+ TEST_f_f (exp2, 10, 1024);
+ TEST_f_f (exp2, -1, 0.5);
+ TEST_f_f (exp2, 1e6, plus_infty);
+ TEST_f_f (exp2, -1e6, 0);
+ TEST_f_f (exp2, 0.75L, 1.68179283050742908606225095246642979L);
+
+ END (exp2);
+}
+
+
+static void
+expm1_test (void)
+{
+ errno = 0;
+ FUNC(expm1) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (expm1);
+
+ TEST_f_f (expm1, 0, 0);
+ TEST_f_f (expm1, minus_zero, minus_zero);
+
+#ifndef TEST_INLINE
+ TEST_f_f (expm1, plus_infty, plus_infty);
+ TEST_f_f (expm1, minus_infty, -1);
+#endif
+ TEST_f_f (expm1, nan_value, nan_value);
+
+ TEST_f_f (expm1, 1, M_El - 1.0);
+ TEST_f_f (expm1, 0.75L, 1.11700001661267466854536981983709561L);
+
+ END (expm1);
+}
+
+
+static void
+fabs_test (void)
+{
+ START (fabs);
+
+ TEST_f_f (fabs, 0, 0);
+ TEST_f_f (fabs, minus_zero, 0);
+
+ TEST_f_f (fabs, plus_infty, plus_infty);
+ TEST_f_f (fabs, minus_infty, plus_infty);
+ TEST_f_f (fabs, nan_value, nan_value);
+
+ TEST_f_f (fabs, 38.0, 38.0);
+ TEST_f_f (fabs, -M_El, M_El);
+
+ END (fabs);
+}
+
+
+static void
+fdim_test (void)
+{
+ START (fdim);
+
+ TEST_ff_f (fdim, 0, 0, 0);
+ TEST_ff_f (fdim, 9, 0, 9);
+ TEST_ff_f (fdim, 0, 9, 0);
+ TEST_ff_f (fdim, -9, 0, 0);
+ TEST_ff_f (fdim, 0, -9, 9);
+
+ TEST_ff_f (fdim, plus_infty, 9, plus_infty);
+ TEST_ff_f (fdim, plus_infty, -9, plus_infty);
+ TEST_ff_f (fdim, minus_infty, 9, 0);
+ TEST_ff_f (fdim, minus_infty, -9, 0);
+ TEST_ff_f (fdim, 9, minus_infty, plus_infty);
+ TEST_ff_f (fdim, -9, minus_infty, plus_infty);
+ TEST_ff_f (fdim, 9, plus_infty, 0);
+ TEST_ff_f (fdim, -9, plus_infty, 0);
+
+ TEST_ff_f (fdim, 0, nan_value, nan_value);
+ TEST_ff_f (fdim, 9, nan_value, nan_value);
+ TEST_ff_f (fdim, -9, nan_value, nan_value);
+ TEST_ff_f (fdim, nan_value, 9, nan_value);
+ TEST_ff_f (fdim, nan_value, -9, nan_value);
+ TEST_ff_f (fdim, plus_infty, nan_value, nan_value);
+ TEST_ff_f (fdim, minus_infty, nan_value, nan_value);
+ TEST_ff_f (fdim, nan_value, plus_infty, nan_value);
+ TEST_ff_f (fdim, nan_value, minus_infty, nan_value);
+ TEST_ff_f (fdim, nan_value, nan_value, nan_value);
+
+ TEST_ff_f (fdim, plus_infty, plus_infty, 0);
+
+ END (fdim);
+}
+
+
+static void
+floor_test (void)
+{
+ START (floor);
+
+ TEST_f_f (floor, 0.0, 0.0);
+ TEST_f_f (floor, minus_zero, minus_zero);
+ TEST_f_f (floor, plus_infty, plus_infty);
+ TEST_f_f (floor, minus_infty, minus_infty);
+ TEST_f_f (floor, nan_value, nan_value);
+
+ TEST_f_f (floor, M_PIl, 3.0);
+ TEST_f_f (floor, -M_PIl, -4.0);
+
+ TEST_f_f (floor, 0.1, 0.0);
+ TEST_f_f (floor, 0.25, 0.0);
+ TEST_f_f (floor, 0.625, 0.0);
+ TEST_f_f (floor, -0.1, -1.0);
+ TEST_f_f (floor, -0.25, -1.0);
+ TEST_f_f (floor, -0.625, -1.0);
+
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (floor, 4503599627370495.5L, 4503599627370495.0L);
+ TEST_f_f (floor, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (floor, 4503599627370496.5L, 4503599627370496.0L);
+ TEST_f_f (floor, 4503599627370496.75L, 4503599627370496.0L);
+ TEST_f_f (floor, 4503599627370497.5L, 4503599627370497.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (floor, 4503599627370494.5000000000001L, 4503599627370494.0L);
+ TEST_f_f (floor, 4503599627370495.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (floor, 4503599627370496.5000000000001L, 4503599627370496.0L);
+# endif
+
+ TEST_f_f (floor, -4503599627370495.5L, -4503599627370496.0L);
+ TEST_f_f (floor, -4503599627370496.25L, -4503599627370497.0L);
+ TEST_f_f (floor, -4503599627370496.5L, -4503599627370497.0L);
+ TEST_f_f (floor, -4503599627370496.75L, -4503599627370497.0L);
+ TEST_f_f (floor, -4503599627370497.5L, -4503599627370498.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (floor, -4503599627370494.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (floor, -4503599627370495.5000000000001L, -4503599627370496.0L);
+ TEST_f_f (floor, -4503599627370496.5000000000001L, -4503599627370497.0L);
+# endif
+
+ TEST_f_f (floor, 9007199254740991.5L, 9007199254740991.0L);
+ TEST_f_f (floor, 9007199254740992.25L, 9007199254740992.0L);
+ TEST_f_f (floor, 9007199254740992.5L, 9007199254740992.0L);
+ TEST_f_f (floor, 9007199254740992.75L, 9007199254740992.0L);
+ TEST_f_f (floor, 9007199254740993.5L, 9007199254740993.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (floor, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (floor, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (floor, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (floor, 9007199254740991.5000000000001L, 9007199254740991.0L);
+ TEST_f_f (floor, 9007199254740992.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (floor, 9007199254740993.5000000000001L, 9007199254740993.0L);
+# endif
+
+ TEST_f_f (floor, -9007199254740991.5L, -9007199254740992.0L);
+ TEST_f_f (floor, -9007199254740992.25L, -9007199254740993.0L);
+ TEST_f_f (floor, -9007199254740992.5L, -9007199254740993.0L);
+ TEST_f_f (floor, -9007199254740992.75L, -9007199254740993.0L);
+ TEST_f_f (floor, -9007199254740993.5L, -9007199254740994.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (floor, -9007199254740991.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (floor, -9007199254740992.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (floor, -9007199254740993.0000000000001L, -9007199254740994.0L);
+ TEST_f_f (floor, -9007199254740991.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (floor, -9007199254740992.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (floor, -9007199254740993.5000000000001L, -9007199254740994.0L);
+# endif
+
+ TEST_f_f (floor, 72057594037927935.5L, 72057594037927935.0L);
+ TEST_f_f (floor, 72057594037927936.25L, 72057594037927936.0L);
+ TEST_f_f (floor, 72057594037927936.5L, 72057594037927936.0L);
+ TEST_f_f (floor, 72057594037927936.75L, 72057594037927936.0L);
+ TEST_f_f (floor, 72057594037927937.5L, 72057594037927937.0L);
+
+ TEST_f_f (floor, -72057594037927935.5L, -72057594037927936.0L);
+ TEST_f_f (floor, -72057594037927936.25L, -72057594037927937.0L);
+ TEST_f_f (floor, -72057594037927936.5L, -72057594037927937.0L);
+ TEST_f_f (floor, -72057594037927936.75L, -72057594037927937.0L);
+ TEST_f_f (floor, -72057594037927937.5L, -72057594037927938.0L);
+
+ TEST_f_f (floor, 10141204801825835211973625643007.5L, 10141204801825835211973625643007.0L);
+ TEST_f_f (floor, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L);
+ TEST_f_f (floor, 10141204801825835211973625643008.5L, 10141204801825835211973625643008.0L);
+ TEST_f_f (floor, 10141204801825835211973625643008.75L, 10141204801825835211973625643008.0L);
+ TEST_f_f (floor, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L);
+#endif
+
+ END (floor);
+}
+
+
+static void
+fma_test (void)
+{
+ START (fma);
+
+ TEST_fff_f (fma, 1.0, 2.0, 3.0, 5.0);
+ TEST_fff_f (fma, nan_value, 2.0, 3.0, nan_value);
+ TEST_fff_f (fma, 1.0, nan_value, 3.0, nan_value);
+ TEST_fff_f (fma, 1.0, 2.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_fff_f (fma, plus_infty, 0.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_fff_f (fma, minus_infty, 0.0, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_fff_f (fma, 0.0, plus_infty, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_fff_f (fma, 0.0, minus_infty, nan_value, nan_value, INVALID_EXCEPTION_OK);
+ TEST_fff_f (fma, plus_infty, 0.0, 1.0, nan_value, INVALID_EXCEPTION);
+ TEST_fff_f (fma, minus_infty, 0.0, 1.0, nan_value, INVALID_EXCEPTION);
+ TEST_fff_f (fma, 0.0, plus_infty, 1.0, nan_value, INVALID_EXCEPTION);
+ TEST_fff_f (fma, 0.0, minus_infty, 1.0, nan_value, INVALID_EXCEPTION);
+
+ TEST_fff_f (fma, plus_infty, plus_infty, minus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_fff_f (fma, minus_infty, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_fff_f (fma, plus_infty, minus_infty, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_fff_f (fma, minus_infty, minus_infty, minus_infty, nan_value, INVALID_EXCEPTION);
+
+ TEST_fff_f (fma, 1.25L, 0.75L, 0.0625L, 1.0L);
+
+ END (fma);
+}
+
+
+static void
+fmax_test (void)
+{
+ START (fmax);
+
+ TEST_ff_f (fmax, 0, 0, 0);
+ TEST_ff_f (fmax, minus_zero, minus_zero, minus_zero);
+ TEST_ff_f (fmax, 9, 0, 9);
+ TEST_ff_f (fmax, 0, 9, 9);
+ TEST_ff_f (fmax, -9, 0, 0);
+ TEST_ff_f (fmax, 0, -9, 0);
+
+ TEST_ff_f (fmax, plus_infty, 9, plus_infty);
+ TEST_ff_f (fmax, 0, plus_infty, plus_infty);
+ TEST_ff_f (fmax, -9, plus_infty, plus_infty);
+ TEST_ff_f (fmax, plus_infty, -9, plus_infty);
+
+ TEST_ff_f (fmax, minus_infty, 9, 9);
+ TEST_ff_f (fmax, minus_infty, -9, -9);
+ TEST_ff_f (fmax, 9, minus_infty, 9);
+ TEST_ff_f (fmax, -9, minus_infty, -9);
+
+ TEST_ff_f (fmax, 0, nan_value, 0);
+ TEST_ff_f (fmax, 9, nan_value, 9);
+ TEST_ff_f (fmax, -9, nan_value, -9);
+ TEST_ff_f (fmax, nan_value, 0, 0);
+ TEST_ff_f (fmax, nan_value, 9, 9);
+ TEST_ff_f (fmax, nan_value, -9, -9);
+ TEST_ff_f (fmax, plus_infty, nan_value, plus_infty);
+ TEST_ff_f (fmax, minus_infty, nan_value, minus_infty);
+ TEST_ff_f (fmax, nan_value, plus_infty, plus_infty);
+ TEST_ff_f (fmax, nan_value, minus_infty, minus_infty);
+ TEST_ff_f (fmax, nan_value, nan_value, nan_value);
+
+ END (fmax);
+}
+
+
+static void
+fmin_test (void)
+{
+ START (fmin);
+
+ TEST_ff_f (fmin, 0, 0, 0);
+ TEST_ff_f (fmin, minus_zero, minus_zero, minus_zero);
+ TEST_ff_f (fmin, 9, 0, 0);
+ TEST_ff_f (fmin, 0, 9, 0);
+ TEST_ff_f (fmin, -9, 0, -9);
+ TEST_ff_f (fmin, 0, -9, -9);
+
+ TEST_ff_f (fmin, plus_infty, 9, 9);
+ TEST_ff_f (fmin, 9, plus_infty, 9);
+ TEST_ff_f (fmin, plus_infty, -9, -9);
+ TEST_ff_f (fmin, -9, plus_infty, -9);
+ TEST_ff_f (fmin, minus_infty, 9, minus_infty);
+ TEST_ff_f (fmin, minus_infty, -9, minus_infty);
+ TEST_ff_f (fmin, 9, minus_infty, minus_infty);
+ TEST_ff_f (fmin, -9, minus_infty, minus_infty);
+
+ TEST_ff_f (fmin, 0, nan_value, 0);
+ TEST_ff_f (fmin, 9, nan_value, 9);
+ TEST_ff_f (fmin, -9, nan_value, -9);
+ TEST_ff_f (fmin, nan_value, 0, 0);
+ TEST_ff_f (fmin, nan_value, 9, 9);
+ TEST_ff_f (fmin, nan_value, -9, -9);
+ TEST_ff_f (fmin, plus_infty, nan_value, plus_infty);
+ TEST_ff_f (fmin, minus_infty, nan_value, minus_infty);
+ TEST_ff_f (fmin, nan_value, plus_infty, plus_infty);
+ TEST_ff_f (fmin, nan_value, minus_infty, minus_infty);
+ TEST_ff_f (fmin, nan_value, nan_value, nan_value);
+
+ END (fmin);
+}
+
+
+static void
+fmod_test (void)
+{
+ errno = 0;
+ FUNC(fmod) (6.5, 2.3L);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (fmod);
+
+ /* fmod (+0, y) == +0 for y != 0. */
+ TEST_ff_f (fmod, 0, 3, 0);
+
+ /* fmod (-0, y) == -0 for y != 0. */
+ TEST_ff_f (fmod, minus_zero, 3, minus_zero);
+
+ /* fmod (+inf, y) == NaN plus invalid exception. */
+ TEST_ff_f (fmod, plus_infty, 3, nan_value, INVALID_EXCEPTION);
+ /* fmod (-inf, y) == NaN plus invalid exception. */
+ TEST_ff_f (fmod, minus_infty, 3, nan_value, INVALID_EXCEPTION);
+ /* fmod (x, +0) == NaN plus invalid exception. */
+ TEST_ff_f (fmod, 3, 0, nan_value, INVALID_EXCEPTION);
+ /* fmod (x, -0) == NaN plus invalid exception. */
+ TEST_ff_f (fmod, 3, minus_zero, nan_value, INVALID_EXCEPTION);
+
+ /* fmod (x, +inf) == x for x not infinite. */
+ TEST_ff_f (fmod, 3.0, plus_infty, 3.0);
+ /* fmod (x, -inf) == x for x not infinite. */
+ TEST_ff_f (fmod, 3.0, minus_infty, 3.0);
+
+ TEST_ff_f (fmod, nan_value, nan_value, nan_value);
+
+ TEST_ff_f (fmod, 6.5, 2.25L, 2.0L);
+ TEST_ff_f (fmod, -6.5, 2.25L, -2.0L);
+ TEST_ff_f (fmod, 6.5, -2.25L, 2.0L);
+ TEST_ff_f (fmod, -6.5, -2.25L, -2.0L);
+
+ END (fmod);
+}
+
+
+static void
+fpclassify_test (void)
+{
+ START (fpclassify);
+
+ TEST_f_i (fpclassify, nan_value, FP_NAN);
+ TEST_f_i (fpclassify, plus_infty, FP_INFINITE);
+ TEST_f_i (fpclassify, minus_infty, FP_INFINITE);
+ TEST_f_i (fpclassify, plus_zero, FP_ZERO);
+ TEST_f_i (fpclassify, minus_zero, FP_ZERO);
+ TEST_f_i (fpclassify, 1000, FP_NORMAL);
+
+ END (fpclassify);
+}
+
+
+/* This is nonapplicable to DFP. DFP should have its own frexp tests. */
+#ifndef __STDC_WANT_DEC_FP__
+static void
+frexp_test (void)
+{
+ int x;
+
+ START (frexp);
+
+ TEST_fI_f1 (frexp, plus_infty, plus_infty, IGNORE);
+ TEST_fI_f1 (frexp, minus_infty, minus_infty, IGNORE);
+ TEST_fI_f1 (frexp, nan_value, nan_value, IGNORE);
+
+ TEST_fI_f1 (frexp, 0.0, 0.0, 0.0);
+ TEST_fI_f1 (frexp, minus_zero, minus_zero, 0.0);
+
+ TEST_fI_f1 (frexp, 12.8L, 0.8L, 4);
+ TEST_fI_f1 (frexp, -27.34L, -0.854375L, 5);
+
+ END (frexp);
+}
+#endif
+
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have this function */
+static void
+gamma_test (void)
+{
+ errno = 0;
+ FUNC(gamma) (1);
+
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+ feclearexcept (FE_ALL_EXCEPT);
+
+ START (gamma);
+
+ TEST_f_f (gamma, plus_infty, plus_infty);
+ TEST_f_f (gamma, 0, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (gamma, -3, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (gamma, minus_infty, plus_infty);
+ TEST_f_f (gamma, nan_value, nan_value);
+
+ TEST_f_f1 (gamma, 1, 0, 1);
+ TEST_f_f1 (gamma, 3, M_LN2l, 1);
+
+ TEST_f_f1 (gamma, 0.5, M_LOG_SQRT_PIl, 1);
+ TEST_f_f1 (gamma, -0.5, M_LOG_2_SQRT_PIl, -1);
+
+ END (gamma);
+}
+#endif
+
+static void
+hypot_test (void)
+{
+ errno = 0;
+ FUNC(hypot) (0.7L, 12.4L);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (hypot);
+
+ TEST_ff_f (hypot, plus_infty, 1, plus_infty, IGNORE_ZERO_INF_SIGN);
+ TEST_ff_f (hypot, minus_infty, 1, plus_infty, IGNORE_ZERO_INF_SIGN);
+
+#ifndef TEST_INLINE
+ TEST_ff_f (hypot, plus_infty, nan_value, plus_infty);
+ TEST_ff_f (hypot, minus_infty, nan_value, plus_infty);
+ TEST_ff_f (hypot, nan_value, plus_infty, plus_infty);
+ TEST_ff_f (hypot, nan_value, minus_infty, plus_infty);
+#endif
+
+ TEST_ff_f (hypot, nan_value, nan_value, nan_value);
+
+ /* hypot (x,y) == hypot (+-x, +-y) */
+ TEST_ff_f (hypot, 0.7L, 12.4L, 12.419742348374220601176836866763271L);
+ TEST_ff_f (hypot, -0.7L, 12.4L, 12.419742348374220601176836866763271L);
+ TEST_ff_f (hypot, 0.7L, -12.4L, 12.419742348374220601176836866763271L);
+ TEST_ff_f (hypot, -0.7L, -12.4L, 12.419742348374220601176836866763271L);
+ TEST_ff_f (hypot, 12.4L, 0.7L, 12.419742348374220601176836866763271L);
+ TEST_ff_f (hypot, -12.4L, 0.7L, 12.419742348374220601176836866763271L);
+ TEST_ff_f (hypot, 12.4L, -0.7L, 12.419742348374220601176836866763271L);
+ TEST_ff_f (hypot, -12.4L, -0.7L, 12.419742348374220601176836866763271L);
+
+ /* hypot (x,0) == fabs (x) */
+ TEST_ff_f (hypot, 0.75L, 0, 0.75L);
+ TEST_ff_f (hypot, -0.75L, 0, 0.75L);
+ TEST_ff_f (hypot, -5.7e7, 0, 5.7e7L);
+
+ TEST_ff_f (hypot, 0.75L, 1.25L, 1.45773797371132511771853821938639577L);
+
+ END (hypot);
+}
+
+
+#ifndef __STDC_WANT_DEC_FP__ /* This is nonapplicable to DFP */
+static void
+ilogb_test (void)
+{
+ START (ilogb);
+
+ TEST_f_i (ilogb, 1, 0);
+ TEST_f_i (ilogb, M_El, 1);
+ TEST_f_i (ilogb, 1024, 10);
+ TEST_f_i (ilogb, -2000, 10);
+
+ /* XXX We have a problem here: the standard does not tell us whether
+ exceptions are allowed/required. ignore them for now. */
+
+ TEST_f_i (ilogb, 0.0, FP_ILOGB0, EXCEPTIONS_OK);
+ TEST_f_i (ilogb, nan_value, FP_ILOGBNAN, EXCEPTIONS_OK);
+ TEST_f_i (ilogb, plus_infty, INT_MAX, EXCEPTIONS_OK);
+ TEST_f_i (ilogb, minus_infty, INT_MAX, EXCEPTIONS_OK);
+
+ END (ilogb);
+}
+#endif
+
+static void
+isfinite_test (void)
+{
+ START (isfinite);
+
+ TEST_f_b (isfinite, 0, 1);
+ TEST_f_b (isfinite, minus_zero, 1);
+ TEST_f_b (isfinite, 10, 1);
+ TEST_f_b (isfinite, plus_infty, 0);
+ TEST_f_b (isfinite, minus_infty, 0);
+ TEST_f_b (isfinite, nan_value, 0);
+
+ END (isfinite);
+}
+
+static void
+isnormal_test (void)
+{
+ START (isnormal);
+
+ TEST_f_b (isnormal, 0, 0);
+ TEST_f_b (isnormal, minus_zero, 0);
+ TEST_f_b (isnormal, 10, 1);
+ TEST_f_b (isnormal, plus_infty, 0);
+ TEST_f_b (isnormal, minus_infty, 0);
+ TEST_f_b (isnormal, nan_value, 0);
+
+ END (isnormal);
+}
+
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have the j* function. */
+static void
+j0_test (void)
+{
+ FLOAT s, c;
+ errno = 0;
+ FUNC (sincos) (0, &s, &c);
+ if (errno == ENOSYS)
+ /* Required function not implemented. */
+ return;
+ FUNC(j0) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (j0);
+
+ /* j0 is the Bessel function of the first kind of order 0 */
+ TEST_f_f (j0, nan_value, nan_value);
+ TEST_f_f (j0, plus_infty, 0);
+ TEST_f_f (j0, -1.0, 0.765197686557966551449717526102663221L);
+ TEST_f_f (j0, 0.0, 1.0);
+ TEST_f_f (j0, 0.125L, 0.996097563041985204620768999453174712L);
+ TEST_f_f (j0, 0.75L, 0.864242275166648623555731103820923211L);
+ TEST_f_f (j0, 1.0, 0.765197686557966551449717526102663221L);
+ TEST_f_f (j0, 1.5, 0.511827671735918128749051744283411720L);
+ TEST_f_f (j0, 2.0, 0.223890779141235668051827454649948626L);
+ TEST_f_f (j0, 8.0, 0.171650807137553906090869407851972001L);
+ TEST_f_f (j0, 10.0, -0.245935764451348335197760862485328754L);
+ TEST_f_f (j0, 4.0, -3.9714980986384737228659076845169804197562E-1L);
+ TEST_f_f (j0, -4.0, -3.9714980986384737228659076845169804197562E-1L);
+
+ END (j0);
+}
+
+
+static void
+j1_test (void)
+{
+ FLOAT s, c;
+ errno = 0;
+ FUNC (sincos) (0, &s, &c);
+ if (errno == ENOSYS)
+ /* Required function not implemented. */
+ return;
+ FUNC(j1) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ /* j1 is the Bessel function of the first kind of order 1 */
+
+ START (j1);
+
+ TEST_f_f (j1, nan_value, nan_value);
+ TEST_f_f (j1, plus_infty, 0);
+
+ TEST_f_f (j1, -1.0, -0.440050585744933515959682203718914913L);
+ TEST_f_f (j1, 0.0, 0.0);
+ TEST_f_f (j1, 0.125L, 0.0623780091344946810942311355879361177L);
+ TEST_f_f (j1, 0.75L, 0.349243602174862192523281016426251335L);
+ TEST_f_f (j1, 1.0, 0.440050585744933515959682203718914913L);
+ TEST_f_f (j1, 1.5, 0.557936507910099641990121213156089400L);
+ TEST_f_f (j1, 2.0, 0.576724807756873387202448242269137087L);
+ TEST_f_f (j1, 8.0, 0.234636346853914624381276651590454612L);
+ TEST_f_f (j1, 10.0, 0.0434727461688614366697487680258592883L);
+
+ END (j1);
+}
+
+static void
+jn_test (void)
+{
+ FLOAT s, c;
+ errno = 0;
+ FUNC (sincos) (0, &s, &c);
+ if (errno == ENOSYS)
+ /* Required function not implemented. */
+ return;
+ FUNC(jn) (1, 1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ /* jn is the Bessel function of the first kind of order n. */
+ START (jn);
+
+ /* jn (0, x) == j0 (x) */
+ TEST_ff_f (jn, 0, nan_value, nan_value);
+ TEST_ff_f (jn, 0, plus_infty, 0);
+ TEST_ff_f (jn, 0, -1.0, 0.765197686557966551449717526102663221L);
+ TEST_ff_f (jn, 0, 0.0, 1.0);
+ TEST_ff_f (jn, 0, 0.125L, 0.996097563041985204620768999453174712L);
+ TEST_ff_f (jn, 0, 0.75L, 0.864242275166648623555731103820923211L);
+ TEST_ff_f (jn, 0, 1.0, 0.765197686557966551449717526102663221L);
+ TEST_ff_f (jn, 0, 1.5, 0.511827671735918128749051744283411720L);
+ TEST_ff_f (jn, 0, 2.0, 0.223890779141235668051827454649948626L);
+ TEST_ff_f (jn, 0, 8.0, 0.171650807137553906090869407851972001L);
+ TEST_ff_f (jn, 0, 10.0, -0.245935764451348335197760862485328754L);
+ TEST_ff_f (jn, 0, 4.0, -3.9714980986384737228659076845169804197562E-1L);
+ TEST_ff_f (jn, 0, -4.0, -3.9714980986384737228659076845169804197562E-1L);
+
+ /* jn (1, x) == j1 (x) */
+ TEST_ff_f (jn, 1, nan_value, nan_value);
+ TEST_ff_f (jn, 1, plus_infty, 0);
+ TEST_ff_f (jn, 1, -1.0, -0.440050585744933515959682203718914913L);
+ TEST_ff_f (jn, 1, 0.0, 0.0);
+ TEST_ff_f (jn, 1, 0.125L, 0.0623780091344946810942311355879361177L);
+ TEST_ff_f (jn, 1, 0.75L, 0.349243602174862192523281016426251335L);
+ TEST_ff_f (jn, 1, 1.0, 0.440050585744933515959682203718914913L);
+ TEST_ff_f (jn, 1, 1.5, 0.557936507910099641990121213156089400L);
+ TEST_ff_f (jn, 1, 2.0, 0.576724807756873387202448242269137087L);
+ TEST_ff_f (jn, 1, 8.0, 0.234636346853914624381276651590454612L);
+ TEST_ff_f (jn, 1, 10.0, 0.0434727461688614366697487680258592883L);
+
+ /* jn (3, x) */
+ TEST_ff_f (jn, 3, nan_value, nan_value);
+ TEST_ff_f (jn, 3, plus_infty, 0);
+
+ TEST_ff_f (jn, 3, -1.0, -0.0195633539826684059189053216217515083L);
+ TEST_ff_f (jn, 3, 0.0, 0.0);
+ TEST_ff_f (jn, 3, 0.125L, 0.406503832554912875023029337653442868e-4L);
+ TEST_ff_f (jn, 3, 0.75L, 0.848438342327410884392755236884386804e-2L);
+ TEST_ff_f (jn, 3, 1.0, 0.0195633539826684059189053216217515083L);
+ TEST_ff_f (jn, 3, 2.0, 0.128943249474402051098793332969239835L);
+ TEST_ff_f (jn, 3, 10.0, 0.0583793793051868123429354784103409563L);
+
+ /* jn (10, x) */
+ TEST_ff_f (jn, 10, nan_value, nan_value);
+ TEST_ff_f (jn, 10, plus_infty, 0);
+
+ TEST_ff_f (jn, 10, -1.0, 0.263061512368745320699785368779050294e-9L);
+ TEST_ff_f (jn, 10, 0.0, 0.0);
+ TEST_ff_f (jn, 10, 0.125L, 0.250543369809369890173993791865771547e-18L);
+ TEST_ff_f (jn, 10, 0.75L, 0.149621713117596814698712483621682835e-10L);
+ TEST_ff_f (jn, 10, 1.0, 0.263061512368745320699785368779050294e-9L);
+ TEST_ff_f (jn, 10, 2.0, 0.251538628271673670963516093751820639e-6L);
+ TEST_ff_f (jn, 10, 10.0, 0.207486106633358857697278723518753428L);
+
+ END (jn);
+}
+
+/* This is nonapplicable to DFP. DFP should have its own ldexp tests. */
+static void
+ldexp_test (void)
+{
+ TEST_ff_f (ldexp, 0, 0, 0);
+ TEST_ff_f (ldexp, minus_zero, 0, minus_zero);
+
+ TEST_ff_f (ldexp, plus_infty, 1, plus_infty);
+ TEST_ff_f (ldexp, minus_infty, 1, minus_infty);
+ TEST_ff_f (ldexp, nan_value, 1, nan_value);
+
+ TEST_ff_f (ldexp, 0.8L, 4, 12.8L);
+ TEST_ff_f (ldexp, -0.854375L, 5, -27.34L);
+
+ /* ldexp (x, 0) == x. */
+ TEST_ff_f (ldexp, 1.0L, 0L, 1.0L);
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+static void
+lgamma_test (void)
+{
+ errno = 0;
+ FUNC(lgamma) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+ feclearexcept (FE_ALL_EXCEPT);
+
+ START (lgamma);
+
+ TEST_f_f (lgamma, plus_infty, plus_infty);
+ TEST_f_f (lgamma, 0, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (lgamma, nan_value, nan_value);
+
+ /* lgamma (x) == +inf plus divide by zero exception for integer x <= 0. */
+ TEST_f_f (lgamma, -3, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (lgamma, minus_infty, plus_infty);
+
+ TEST_f_f1 (lgamma, 1, 0, 1);
+
+ TEST_f_f1 (lgamma, 3, M_LN2l, 1);
+
+ TEST_f_f1 (lgamma, 0.5, M_LOG_SQRT_PIl, 1);
+ TEST_f_f1 (lgamma, -0.5, M_LOG_2_SQRT_PIl, -1);
+ TEST_f_f1 (lgamma, 0.7L, 0.260867246531666514385732417016759578L, 1);
+ TEST_f_f1 (lgamma, 1.2L, -0.853740900033158497197028392998854470e-1L, 1);
+
+ END (lgamma);
+}
+
+
+static void
+lrint_test (void)
+{
+ /* XXX this test is incomplete. We need to have a way to specifiy
+ the rounding method and test the critical cases. So far, only
+ unproblematic numbers are tested. */
+
+ START (lrint);
+
+ TEST_f_l (lrint, 0.0, 0);
+ TEST_f_l (lrint, minus_zero, 0);
+ TEST_f_l (lrint, 0.2L, 0);
+ TEST_f_l (lrint, -0.2L, 0);
+
+ TEST_f_l (lrint, 1.4L, 1);
+ TEST_f_l (lrint, -1.4L, -1);
+
+ TEST_f_l (lrint, 8388600.3L, 8388600);
+ TEST_f_l (lrint, -8388600.3L, -8388600);
+
+ TEST_f_l (lrint, 1071930.0008, 1071930);
+#ifndef TEST_FLOAT
+ TEST_f_l (lrint, 1073741824.01, 1073741824);
+# if LONG_MAX > 281474976710656
+ TEST_f_l (lrint, 281474976710656.025, 281474976710656);
+# endif
+#endif
+
+ END (lrint);
+}
+
+
+static void
+llrint_test (void)
+{
+ /* XXX this test is incomplete. We need to have a way to specifiy
+ the rounding method and test the critical cases. So far, only
+ unproblematic numbers are tested. */
+
+ START (llrint);
+
+ TEST_f_L (llrint, 0.0, 0);
+ TEST_f_L (llrint, minus_zero, 0);
+ TEST_f_L (llrint, 0.2L, 0);
+ TEST_f_L (llrint, -0.2L, 0);
+
+ TEST_f_L (llrint, 1.4L, 1);
+ TEST_f_L (llrint, -1.4L, -1);
+
+ TEST_f_L (llrint, 8388600.3L, 8388600);
+ TEST_f_L (llrint, -8388600.3L, -8388600);
+
+ TEST_f_l (llrint, 1071930.0008, 1071930);
+
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llrint, 2097151.0,2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llrint, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llrint, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llrint, 4503599627370495.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.75L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370497.5L, 4503599627370498LL);
+
+ TEST_f_L (llrint, -4503599627370495.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL);
+#endif
+
+ TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.75L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5L, 9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL);
+#endif
+
+ TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.75L, 72057594037927937LL);
+ TEST_f_L (llrint, 72057594037927937.5L, 72057594037927938LL);
+
+ TEST_f_L (llrint, -72057594037927935.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL);
+ TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+
+ END (llrint);
+}
+
+static void
+llrint_test_tonearest (void)
+{
+ int save_round_mode;
+ START (llrint_tonearest);
+
+ save_round_mode = GETROUND();
+
+ if (!SETROUND (TONEAREST))
+ {
+ TEST_f_L (llrint, 0.0, 0);
+ TEST_f_L (llrint, minus_zero, 0);
+ TEST_f_L (llrint, 0.2L, 0);
+ TEST_f_L (llrint, -0.2L, 0);
+
+ TEST_f_L (llrint, 1.4L, 1);
+ TEST_f_L (llrint, -1.4L, -1);
+
+ TEST_f_L (llrint, 8388600.3L, 8388600);
+ TEST_f_L (llrint, -8388600.3L, -8388600);
+
+ TEST_f_l (llrint, 1071930.0008, 1071930);
+
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llrint, 2097151.0,2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llrint, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llrint, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llrint, 4503599627370495.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.75L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370497.5L, 4503599627370498LL);
+
+ TEST_f_L (llrint, -4503599627370495.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL);
+#endif
+
+ TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.75L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5L, 9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL);
+#endif
+
+ TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.75L, 72057594037927937LL);
+ TEST_f_L (llrint, 72057594037927937.5L, 72057594037927938LL);
+
+ TEST_f_L (llrint, -72057594037927935.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL);
+ TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+ }
+
+ SETROUND (save_round_mode);
+
+ END (llrint_tonearest);
+}
+
+static void
+llrint_test_towardzero (void)
+{
+ int save_round_mode;
+ START (llrint_towardzero);
+
+ save_round_mode = GETROUND();
+
+ if (!SETROUND (TOWARDZERO))
+ {
+ TEST_f_L (llrint, 0.0, 0);
+ TEST_f_L (llrint, minus_zero, 0);
+ TEST_f_L (llrint, 0.2L, 0);
+ TEST_f_L (llrint, -0.2L, 0);
+
+ TEST_f_L (llrint, 1.4L, 1);
+ TEST_f_L (llrint, -1.4L, -1);
+
+ TEST_f_L (llrint, 8388600.3L, 8388600);
+ TEST_f_L (llrint, -8388600.3L, -8388600);
+
+ TEST_f_l (llrint, 1071930.0008, 1071930);
+
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llrint, 2097151.0,2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llrint, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llrint, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llrint, 4503599627370495.5L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.75L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.5L, 4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.5L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.75L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.5L, -4503599627370497LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370494LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370496LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370494LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370496LL);
+#endif
+
+ TEST_f_L (llrint, 9007199254740991.5L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.75L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.5L, 9007199254740993LL);
+
+ TEST_f_L (llrint, -9007199254740991.5L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.75L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.5L, -9007199254740993LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740993LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740993LL);
+#endif
+
+ TEST_f_L (llrint, 72057594037927935.5L, 72057594037927935LL);
+ TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.75L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927937.5L, 72057594037927937LL);
+
+ TEST_f_L (llrint, -72057594037927935.5L, -72057594037927935LL);
+ TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.75L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927937.5L, -72057594037927937LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775805LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775805LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+ }
+
+ SETROUND (save_round_mode);
+
+ END (llrint_towardzero);
+}
+
+static void
+llrint_test_downward (void)
+{
+ int save_round_mode;
+ START (llrint_downward);
+
+ save_round_mode = GETROUND();
+
+ if (!SETROUND (DOWNWARD))
+ {
+ TEST_f_L (llrint, 0.0, 0);
+ TEST_f_L (llrint, minus_zero, 0);
+ TEST_f_L (llrint, 0.2L, 0);
+ TEST_f_L (llrint, -0.2L, -1);
+
+ TEST_f_L (llrint, 1.4L, 1);
+ TEST_f_L (llrint, -1.4L, -2);
+
+ TEST_f_L (llrint, 8388600.3L, 8388600);
+ TEST_f_L (llrint, -8388600.3L, -8388601);
+
+ TEST_f_l (llrint, 1071930.0008, 1071930);
+
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llrint, 2097151.0,2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llrint, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llrint, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llrint, 4503599627370495.5L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.75L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.5L, 4503599627370497LL);
+
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370494LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370496LL);
+
+ TEST_f_L (llrint, -4503599627370495.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.25L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370496.5L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370498LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL);
+
+ TEST_f_L (llrint, 9007199254740991.5L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.75L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.5L, 9007199254740993LL);
+
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740991LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740993LL);
+
+ TEST_f_L (llrint, -9007199254740991.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.25L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740992.5L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740994LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL);
+
+ TEST_f_L (llrint, 72057594037927935.5L, 72057594037927935LL);
+ TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.75L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927937.5L, 72057594037927937LL);
+
+ TEST_f_L (llrint, -72057594037927935.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.25L, -72057594037927937LL);
+ TEST_f_L (llrint, -72057594037927936.5L, -72057594037927937LL);
+ TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL);
+ TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775805LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+ }
+
+ SETROUND (save_round_mode);
+
+ END (llrint_downward);
+}
+
+static void
+llrint_test_upward (void)
+{
+ int save_round_mode;
+ START (llrint_upward);
+
+ save_round_mode = GETROUND();
+
+ if (!SETROUND (UPWARD))
+ {
+ TEST_f_L (llrint, 0.0, 0);
+ TEST_f_L (llrint, minus_zero, 0);
+ TEST_f_L (llrint, 0.2L, 1);
+ TEST_f_L (llrint, -0.2L, 0);
+
+ TEST_f_L (llrint, 1.4L, 2);
+ TEST_f_L (llrint, -1.4L, -1);
+
+ TEST_f_L (llrint, 8388600.3L, 8388601);
+ TEST_f_L (llrint, -8388600.3L, -8388600);
+#ifndef TEST_FLOAT
+ TEST_f_l (llrint, 1071930.0008, 1071931);
+#endif
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llrint, 2097151.0,2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llrint, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llrint, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llrint, 4503599627370495.5L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.25L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370496.5L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370496.75L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370497.5L, 4503599627370498LL);
+
+ TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370498LL);
+ TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL);
+ TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.5L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370496.75L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.5L, -4503599627370497LL);
+
+ TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370494LL);
+ TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370496LL);
+
+ TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.25L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740992.5L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740992.75L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5L, 9007199254740994LL);
+
+ TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740994LL);
+ TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL);
+ TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+ TEST_f_L (llrint, -9007199254740991.5L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740992.75L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.5L, -9007199254740993LL);
+
+ TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740991LL);
+ TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740993LL);
+
+ TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL);
+ TEST_f_L (llrint, 72057594037927936.25L, 72057594037927937LL);
+ TEST_f_L (llrint, 72057594037927936.5L, 72057594037927937LL);
+ TEST_f_L (llrint, 72057594037927936.75L, 72057594037927937LL);
+ TEST_f_L (llrint, 72057594037927937.5L, 72057594037927938LL);
+
+ TEST_f_L (llrint, -72057594037927935.5L, -72057594037927935LL);
+ TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927936.75L, -72057594037927936LL);
+ TEST_f_L (llrint, -72057594037927937.5L, -72057594037927937LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775805LL);
+ TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+ TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775807L);
+ TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775806LL);
+ TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+ }
+
+ SETROUND (save_round_mode);
+
+ END (llrint_upward);
+}
+
+
+static void
+log_test (void)
+{
+ errno = 0;
+ FUNC(log) (1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+ START (log);
+
+ TEST_f_f (log, 0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (log, minus_zero, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+
+ TEST_f_f (log, 1, 0);
+
+ TEST_f_f (log, -1, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (log, plus_infty, plus_infty);
+
+ TEST_f_f (log, M_El, 1);
+ TEST_f_f (log, 1.0 / M_El, -1);
+ TEST_f_f (log, 2, M_LN2l);
+ TEST_f_f (log, 10, M_LN10l);
+ TEST_f_f (log, 0.75L, -0.287682072451780927439219005993827432L);
+
+ END (log);
+}
+
+
+static void
+log10_test (void)
+{
+ errno = 0;
+ FUNC(log10) (1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (log10);
+
+ TEST_f_f (log10, 0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (log10, minus_zero, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+
+ TEST_f_f (log10, 1, 0);
+
+ /* log10 (x) == NaN plus invalid exception if x < 0. */
+ TEST_f_f (log10, -1, nan_value, INVALID_EXCEPTION);
+
+ TEST_f_f (log10, plus_infty, plus_infty);
+ TEST_f_f (log10, nan_value, nan_value);
+
+ TEST_f_f (log10, 0.1L, -1);
+ TEST_f_f (log10, 10.0, 1);
+ TEST_f_f (log10, 100.0, 2);
+ TEST_f_f (log10, 10000.0, 4);
+ TEST_f_f (log10, M_El, M_LOG10El);
+ TEST_f_f (log10, 0.75L, -0.124938736608299953132449886193870744L);
+
+ END (log10);
+}
+
+
+static void
+log1p_test (void)
+{
+ errno = 0;
+ FUNC(log1p) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (log1p);
+
+ TEST_f_f (log1p, 0, 0);
+ TEST_f_f (log1p, minus_zero, minus_zero);
+
+ TEST_f_f (log1p, -1, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (log1p, -2, nan_value, INVALID_EXCEPTION);
+
+ TEST_f_f (log1p, plus_infty, plus_infty);
+ TEST_f_f (log1p, nan_value, nan_value);
+
+ TEST_f_f (log1p, M_El - 1.0, 1);
+
+ TEST_f_f (log1p, -0.25L, -0.287682072451780927439219005993827432L);
+ TEST_f_f (log1p, -0.875, -2.07944154167983592825169636437452970L);
+
+ END (log1p);
+}
+
+
+static void
+log2_test (void)
+{
+ errno = 0;
+ FUNC(log2) (1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (log2);
+
+ TEST_f_f (log2, 0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (log2, minus_zero, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+
+ TEST_f_f (log2, 1, 0);
+
+ TEST_f_f (log2, -1, nan_value, INVALID_EXCEPTION);
+
+ TEST_f_f (log2, plus_infty, plus_infty);
+ TEST_f_f (log2, nan_value, nan_value);
+
+ TEST_f_f (log2, M_El, M_LOG2El);
+ TEST_f_f (log2, 2.0, 1);
+ TEST_f_f (log2, 16.0, 4);
+ TEST_f_f (log2, 256.0, 8);
+ TEST_f_f (log2, 0.75L, -.415037499278843818546261056052183492L);
+
+ END (log2);
+}
+
+
+static void
+logb_test (void)
+{
+ START (logb);
+
+ TEST_f_f (logb, plus_infty, plus_infty);
+ TEST_f_f (logb, minus_infty, plus_infty);
+
+ TEST_f_f (logb, 0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+
+ TEST_f_f (logb, minus_zero, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (logb, nan_value, nan_value);
+
+ TEST_f_f (logb, 1, 0);
+ TEST_f_f (logb, M_El, 1);
+ TEST_f_f (logb, 1024, 10);
+ TEST_f_f (logb, -2000, 10);
+
+ END (logb);
+}
+
+
+static void
+lround_test (void)
+{
+ START (lround);
+
+ TEST_f_l (lround, 0, 0);
+ TEST_f_l (lround, minus_zero, 0);
+ TEST_f_l (lround, 0.2L, 0.0);
+ TEST_f_l (lround, -0.2L, 0);
+ TEST_f_l (lround, 0.5, 1);
+ TEST_f_l (lround, -0.5, -1);
+ TEST_f_l (lround, 0.8L, 1);
+ TEST_f_l (lround, -0.8L, -1);
+ TEST_f_l (lround, 1.5, 2);
+ TEST_f_l (lround, -1.5, -2);
+ TEST_f_l (lround, 22514.5, 22515);
+ TEST_f_l (lround, -22514.5, -22515);
+ TEST_f_l (lround, 1071930.0008, 1071930);
+#ifndef TEST_FLOAT
+ TEST_f_l (lround, 1073741824.01, 1073741824);
+# if LONG_MAX > 281474976710656
+ TEST_f_l (lround, 281474976710656.025, 281474976710656);
+# endif
+ TEST_f_l (lround, 2097152.5, 2097153);
+ TEST_f_l (lround, -2097152.5, -2097153);
+#endif
+ END (lround);
+}
+
+
+static void
+llround_test (void)
+{
+ START (llround);
+
+ TEST_f_L (llround, 0, 0);
+ TEST_f_L (llround, minus_zero, 0);
+ TEST_f_L (llround, 0.2L, 0.0);
+ TEST_f_L (llround, -0.2L, 0);
+ TEST_f_L (llround, 0.5, 1);
+ TEST_f_L (llround, -0.5, -1);
+ TEST_f_L (llround, 0.8L, 1);
+ TEST_f_L (llround, -0.8L, -1);
+ TEST_f_L (llround, 1.5, 2);
+ TEST_f_L (llround, -1.5, -2);
+ TEST_f_L (llround, 22514.5, 22515);
+ TEST_f_L (llround, -22514.5, -22515);
+ TEST_f_l (llround, 1071930.0008, 1071930);
+#ifndef TEST_FLOAT
+ TEST_f_L (llround, 2097152.5, 2097153);
+ TEST_f_L (llround, -2097152.5, -2097153);
+ TEST_f_L (llround, 34359738368.5, 34359738369ll);
+ TEST_f_L (llround, -34359738368.5, -34359738369ll);
+#endif
+
+ /* Test boundary conditions. */
+ /* 0x1FFFFF */
+ TEST_f_L (llround, 2097151.0, 2097151LL);
+ /* 0x800000 */
+ TEST_f_L (llround, 8388608.0, 8388608LL);
+ /* 0x1000000 */
+ TEST_f_L (llround, 16777216.0, 16777216LL);
+ /* 0x20000000000 */
+ TEST_f_L (llround, 2199023255552.0, 2199023255552LL);
+ /* 0x40000000000 */
+ TEST_f_L (llround, 4398046511104.0, 4398046511104LL);
+ /* 0x1000000000000 */
+ TEST_f_L (llround, 281474976710656.0, 281474976710656LL);
+ /* 0x10000000000000 */
+ TEST_f_L (llround, 4503599627370496.0, 4503599627370496LL);
+ /* 0x10000080000000 */
+ TEST_f_L (llround, 4503601774854144.0, 4503601774854144LL);
+ /* 0x20000000000000 */
+ TEST_f_L (llround, 9007199254740992.0, 9007199254740992LL);
+ /* 0x80000000000000 */
+ TEST_f_L (llround, 36028797018963968.0, 36028797018963968LL);
+ /* 0x100000000000000 */
+ TEST_f_L (llround, 72057594037927936.0, 72057594037927936LL);
+
+#ifndef TEST_FLOAT
+ /* 0x100000000 */
+ TEST_f_L (llround, 4294967295.5, 4294967296LL);
+ /* 0x200000000 */
+ TEST_f_L (llround, 8589934591.5, 8589934592LL);
+#endif
+
+#ifdef TEST_LDOUBLE
+ /* The input can only be represented in long double. */
+ TEST_f_L (llround, 4503599627370495.5L, 4503599627370496LL);
+ TEST_f_L (llround, 4503599627370496.25L, 4503599627370496LL);
+ TEST_f_L (llround, 4503599627370496.5L, 4503599627370497LL);
+ TEST_f_L (llround, 4503599627370496.75L, 4503599627370497LL);
+ TEST_f_L (llround, 4503599627370497.5L, 4503599627370498LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llround, 4503599627370495.4999999999999L, 4503599627370495LL);
+ TEST_f_L (llround, 4503599627370496.4999999999999L, 4503599627370496LL);
+ TEST_f_L (llround, 4503599627370497.4999999999999L, 4503599627370497LL);
+ TEST_f_L (llround, 4503599627370494.5000000000001L, 4503599627370495LL);
+ TEST_f_L (llround, 4503599627370495.5000000000001L, 4503599627370496LL);
+ TEST_f_L (llround, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+ TEST_f_L (llround, -4503599627370495.4999999999999L, -4503599627370495LL);
+ TEST_f_L (llround, -4503599627370496.4999999999999L, -4503599627370496LL);
+ TEST_f_L (llround, -4503599627370497.4999999999999L, -4503599627370497LL);
+ TEST_f_L (llround, -4503599627370494.5000000000001L, -4503599627370495LL);
+ TEST_f_L (llround, -4503599627370495.5000000000001L, -4503599627370496LL);
+ TEST_f_L (llround, -4503599627370496.5000000000001L, -4503599627370497LL);
+# endif
+
+ TEST_f_L (llround, -4503599627370495.5L, -4503599627370496LL);
+ TEST_f_L (llround, -4503599627370496.25L, -4503599627370496LL);
+ TEST_f_L (llround, -4503599627370496.5L, -4503599627370497LL);
+ TEST_f_L (llround, -4503599627370496.75L, -4503599627370497LL);
+ TEST_f_L (llround, -4503599627370497.5L, -4503599627370498LL);
+
+ TEST_f_L (llround, 9007199254740991.5L, 9007199254740992LL);
+ TEST_f_L (llround, 9007199254740992.25L, 9007199254740992LL);
+ TEST_f_L (llround, 9007199254740992.5L, 9007199254740993LL);
+ TEST_f_L (llround, 9007199254740992.75L, 9007199254740993LL);
+ TEST_f_L (llround, 9007199254740993.5L, 9007199254740994LL);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_L (llround, 9007199254740991.4999999999999L, 9007199254740991LL);
+ TEST_f_L (llround, 9007199254740992.4999999999999L, 9007199254740992LL);
+ TEST_f_L (llround, 9007199254740993.4999999999999L, 9007199254740993LL);
+ TEST_f_L (llround, 9007199254740991.5000000000001L, 9007199254740992LL);
+ TEST_f_L (llround, 9007199254740992.5000000000001L, 9007199254740993LL);
+ TEST_f_L (llround, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+ TEST_f_L (llround, -9007199254740991.4999999999999L, -9007199254740991LL);
+ TEST_f_L (llround, -9007199254740992.4999999999999L, -9007199254740992LL);
+ TEST_f_L (llround, -9007199254740993.4999999999999L, -9007199254740993LL);
+ TEST_f_L (llround, -9007199254740991.5000000000001L, -9007199254740992LL);
+ TEST_f_L (llround, -9007199254740992.5000000000001L, -9007199254740993LL);
+ TEST_f_L (llround, -9007199254740993.5000000000001L, -9007199254740994LL);
+# endif
+
+ TEST_f_L (llround, -9007199254740991.5L, -9007199254740992LL);
+ TEST_f_L (llround, -9007199254740992.25L, -9007199254740992LL);
+ TEST_f_L (llround, -9007199254740992.5L, -9007199254740993LL);
+ TEST_f_L (llround, -9007199254740992.75L, -9007199254740993LL);
+ TEST_f_L (llround, -9007199254740993.5L, -9007199254740994LL);
+
+ TEST_f_L (llround, 72057594037927935.5L, 72057594037927936LL);
+ TEST_f_L (llround, 72057594037927936.25L, 72057594037927936LL);
+ TEST_f_L (llround, 72057594037927936.5L, 72057594037927937LL);
+ TEST_f_L (llround, 72057594037927936.75L, 72057594037927937LL);
+ TEST_f_L (llround, 72057594037927937.5L, 72057594037927938LL);
+
+ TEST_f_L (llround, -72057594037927935.5L, -72057594037927936LL);
+ TEST_f_L (llround, -72057594037927936.25L, -72057594037927936LL);
+ TEST_f_L (llround, -72057594037927936.5L, -72057594037927937LL);
+ TEST_f_L (llround, -72057594037927936.75L, -72057594037927937LL);
+ TEST_f_L (llround, -72057594037927937.5L, -72057594037927938LL);
+
+ TEST_f_L (llround, 9223372036854775806.25L, 9223372036854775806LL);
+ TEST_f_L (llround, -9223372036854775806.25L, -9223372036854775806LL);
+ TEST_f_L (llround, 9223372036854775806.5L, 9223372036854775807LL);
+ TEST_f_L (llround, -9223372036854775806.5L, -9223372036854775807LL);
+ TEST_f_L (llround, 9223372036854775807.0L, 9223372036854775807LL);
+ TEST_f_L (llround, -9223372036854775807.0L, -9223372036854775807LL);
+#endif
+
+ END (llround);
+}
+
+static void
+modf_test (void)
+{
+ FLOAT x;
+
+ START (modf);
+
+ TEST_fF_f1 (modf, plus_infty, 0, plus_infty);
+ TEST_fF_f1 (modf, minus_infty, minus_zero, minus_infty);
+ TEST_fF_f1 (modf, nan_value, nan_value, nan_value);
+ TEST_fF_f1 (modf, 0, 0, 0);
+ TEST_fF_f1 (modf, 1.5, 0.5, 1);
+ TEST_fF_f1 (modf, 2.5, 0.5, 2);
+ TEST_fF_f1 (modf, -2.5, -0.5, -2);
+ TEST_fF_f1 (modf, 20, 0, 20);
+ TEST_fF_f1 (modf, 21, 0, 21);
+ TEST_fF_f1 (modf, 89.5, 0.5, 89);
+
+ END (modf);
+}
+
+
+static void
+nearbyint_test (void)
+{
+ START (nearbyint);
+
+ TEST_f_f (nearbyint, 0.0, 0.0);
+ TEST_f_f (nearbyint, minus_zero, minus_zero);
+ TEST_f_f (nearbyint, plus_infty, plus_infty);
+ TEST_f_f (nearbyint, minus_infty, minus_infty);
+ TEST_f_f (nearbyint, nan_value, nan_value);
+
+ /* Default rounding mode is round to nearest. */
+ TEST_f_f (nearbyint, 0.5, 0.0);
+ TEST_f_f (nearbyint, 1.5, 2.0);
+ TEST_f_f (nearbyint, -0.5, minus_zero);
+ TEST_f_f (nearbyint, -1.5, -2.0);
+
+ END (nearbyint);
+}
+
+static void
+nextafter_test (void)
+{
+
+ START (nextafter);
+
+ TEST_ff_f (nextafter, 0, 0, 0);
+ TEST_ff_f (nextafter, minus_zero, 0, 0);
+ TEST_ff_f (nextafter, 0, minus_zero, minus_zero);
+ TEST_ff_f (nextafter, minus_zero, minus_zero, minus_zero);
+
+ TEST_ff_f (nextafter, 9, 9, 9);
+ TEST_ff_f (nextafter, -9, -9, -9);
+ TEST_ff_f (nextafter, plus_infty, plus_infty, plus_infty);
+ TEST_ff_f (nextafter, minus_infty, minus_infty, minus_infty);
+
+ TEST_ff_f (nextafter, nan_value, 1.1L, nan_value);
+ TEST_ff_f (nextafter, 1.1L, nan_value, nan_value);
+ TEST_ff_f (nextafter, nan_value, nan_value, nan_value);
+
+ FLOAT fltmax = CHOOSE (LDBL_MAX, DBL_MAX, FLT_MAX,
+ LDBL_MAX, DBL_MAX, FLT_MAX,
+ DEC128_MAX, DEC64_MAX, DEC32_MAX);
+ TEST_ff_f (nextafter, fltmax, plus_infty, plus_infty);
+ TEST_ff_f (nextafter, -fltmax, minus_infty, minus_infty);
+
+#ifdef TEST_LDOUBLE
+ #ifndef __STDC_WANT_DEC_FP__
+ // XXX Enable once gcc is fixed.
+ //TEST_ff_f (nextafter, 0x0.00000040000000000000p-16385L, -0.1L, 0x0.0000003ffffffff00000p-16385L);
+ #endif
+#endif
+
+ /* XXX We need the hexadecimal FP number representation here for further
+ tests. */
+
+ END (nextafter);
+}
+
+
+static void
+nexttoward_test (void)
+{
+ START (nexttoward);
+ TEST_ff_f (nexttoward, 0, 0, 0);
+ TEST_ff_f (nexttoward, minus_zero, 0, 0);
+ TEST_ff_f (nexttoward, 0, minus_zero, minus_zero);
+ TEST_ff_f (nexttoward, minus_zero, minus_zero, minus_zero);
+
+ TEST_ff_f (nexttoward, 9, 9, 9);
+ TEST_ff_f (nexttoward, -9, -9, -9);
+ TEST_ff_f (nexttoward, plus_infty, plus_infty, plus_infty);
+ TEST_ff_f (nexttoward, minus_infty, minus_infty, minus_infty);
+
+ TEST_ff_f (nexttoward, nan_value, 1.1L, nan_value);
+ TEST_ff_f (nexttoward, 1.1L, nan_value, nan_value);
+ TEST_ff_f (nexttoward, nan_value, nan_value, nan_value);
+
+ /* XXX We need the hexadecimal FP number representation here for further
+ tests. */
+
+ END (nexttoward);
+}
+
+
+static void
+pow_test (void)
+{
+
+ errno = 0;
+ FUNC(pow) (0, 0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (pow);
+
+ TEST_ff_f (pow, 0, 0, 1);
+ TEST_ff_f (pow, 0, minus_zero, 1);
+ TEST_ff_f (pow, minus_zero, 0, 1);
+ TEST_ff_f (pow, minus_zero, minus_zero, 1);
+
+ TEST_ff_f (pow, 10, 0, 1);
+ TEST_ff_f (pow, 10, minus_zero, 1);
+ TEST_ff_f (pow, -10, 0, 1);
+ TEST_ff_f (pow, -10, minus_zero, 1);
+
+ TEST_ff_f (pow, nan_value, 0, 1);
+ TEST_ff_f (pow, nan_value, minus_zero, 1);
+
+
+#ifndef TEST_INLINE
+ TEST_ff_f (pow, 1.1L, plus_infty, plus_infty);
+ TEST_ff_f (pow, plus_infty, plus_infty, plus_infty);
+ TEST_ff_f (pow, -1.1L, plus_infty, plus_infty);
+ TEST_ff_f (pow, minus_infty, plus_infty, plus_infty);
+
+ TEST_ff_f (pow, 0.9L, plus_infty, 0);
+ TEST_ff_f (pow, 1e-7L, plus_infty, 0);
+ TEST_ff_f (pow, -0.9L, plus_infty, 0);
+ TEST_ff_f (pow, -1e-7L, plus_infty, 0);
+
+ TEST_ff_f (pow, 1.1L, minus_infty, 0);
+ TEST_ff_f (pow, plus_infty, minus_infty, 0);
+ TEST_ff_f (pow, -1.1L, minus_infty, 0);
+ TEST_ff_f (pow, minus_infty, minus_infty, 0);
+
+ TEST_ff_f (pow, 0.9L, minus_infty, plus_infty);
+ TEST_ff_f (pow, 1e-7L, minus_infty, plus_infty);
+ TEST_ff_f (pow, -0.9L, minus_infty, plus_infty);
+ TEST_ff_f (pow, -1e-7L, minus_infty, plus_infty);
+
+ TEST_ff_f (pow, plus_infty, 1e-7L, plus_infty);
+ TEST_ff_f (pow, plus_infty, 1, plus_infty);
+ TEST_ff_f (pow, plus_infty, 1e7L, plus_infty);
+
+ TEST_ff_f (pow, plus_infty, -1e-7L, 0);
+ TEST_ff_f (pow, plus_infty, -1, 0);
+ TEST_ff_f (pow, plus_infty, -1e7L, 0);
+
+ TEST_ff_f (pow, minus_infty, 1, minus_infty);
+ TEST_ff_f (pow, minus_infty, 11, minus_infty);
+ TEST_ff_f (pow, minus_infty, 1001, minus_infty);
+
+ TEST_ff_f (pow, minus_infty, 2, plus_infty);
+ TEST_ff_f (pow, minus_infty, 12, plus_infty);
+ TEST_ff_f (pow, minus_infty, 1002, plus_infty);
+ TEST_ff_f (pow, minus_infty, 0.1L, plus_infty);
+ TEST_ff_f (pow, minus_infty, 1.1L, plus_infty);
+ TEST_ff_f (pow, minus_infty, 11.1L, plus_infty);
+ TEST_ff_f (pow, minus_infty, 1001.1L, plus_infty);
+
+ TEST_ff_f (pow, minus_infty, -1, minus_zero);
+ TEST_ff_f (pow, minus_infty, -11, minus_zero);
+ TEST_ff_f (pow, minus_infty, -1001, minus_zero);
+
+ TEST_ff_f (pow, minus_infty, -2, 0);
+ TEST_ff_f (pow, minus_infty, -12, 0);
+ TEST_ff_f (pow, minus_infty, -1002, 0);
+ TEST_ff_f (pow, minus_infty, -0.1L, 0);
+ TEST_ff_f (pow, minus_infty, -1.1L, 0);
+ TEST_ff_f (pow, minus_infty, -11.1L, 0);
+ TEST_ff_f (pow, minus_infty, -1001.1L, 0);
+#endif
+
+ TEST_ff_f (pow, nan_value, nan_value, nan_value);
+ TEST_ff_f (pow, 0, nan_value, nan_value);
+ TEST_ff_f (pow, 1, nan_value, 1);
+ TEST_ff_f (pow, -1, nan_value, nan_value);
+ TEST_ff_f (pow, nan_value, 1, nan_value);
+ TEST_ff_f (pow, nan_value, -1, nan_value);
+
+ /* pow (x, NaN) == NaN. */
+ TEST_ff_f (pow, 3.0, nan_value, nan_value);
+
+ TEST_ff_f (pow, 1, plus_infty, 1);
+ TEST_ff_f (pow, -1, plus_infty, 1);
+ TEST_ff_f (pow, 1, minus_infty, 1);
+ TEST_ff_f (pow, -1, minus_infty, 1);
+ TEST_ff_f (pow, 1, 1, 1);
+ TEST_ff_f (pow, 1, -1, 1);
+ TEST_ff_f (pow, 1, 1.25, 1);
+ TEST_ff_f (pow, 1, -1.25, 1);
+
+#ifndef __STDC_WANT_DEC_FP__ /* format 0x*p*DL NOT supported by GCC. */
+ TEST_ff_f (pow, 1, 0x1p62L, 1);
+ TEST_ff_f (pow, 1, 0x1p63L, 1);
+ TEST_ff_f (pow, 1, 0x1p64L, 1);
+ TEST_ff_f (pow, 1, 0x1p72L, 1);
+#endif /* __STDC_WANT_DEC_FP__ */
+
+ /* pow (x, +-0) == 1. */
+ TEST_ff_f (pow, plus_infty, 0, 1);
+ TEST_ff_f (pow, plus_infty, minus_zero, 1);
+ TEST_ff_f (pow, minus_infty, 0, 1);
+ TEST_ff_f (pow, minus_infty, minus_zero, 1);
+ TEST_ff_f (pow, 32.75L, 0, 1);
+ TEST_ff_f (pow, 32.75L, minus_zero, 1);
+ TEST_ff_f (pow, -32.75L, 0, 1);
+ TEST_ff_f (pow, -32.75L, minus_zero, 1);
+
+#ifndef __STDC_WANT_DEC_FP__ /* format 0x*p*DL NOT supported by GCC. */
+ TEST_ff_f (pow, 0x1p72L, 0, 1);
+ TEST_ff_f (pow, 0x1p72L, minus_zero, 1);
+ TEST_ff_f (pow, 0x1p-72L, 0, 1);
+ TEST_ff_f (pow, 0x1p-72L, minus_zero, 1);
+#endif
+
+ TEST_ff_f (pow, -0.1L, 1.1L, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (pow, -0.1L, -1.1L, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (pow, -10.1L, 1.1L, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (pow, -10.1L, -1.1L, nan_value, INVALID_EXCEPTION);
+
+ TEST_ff_f (pow, 0, -1, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_ff_f (pow, 0, -11, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_ff_f (pow, minus_zero, -1, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_ff_f (pow, minus_zero, -11, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+
+ TEST_ff_f (pow, 0, -2, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_ff_f (pow, 0, -11.1L, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_ff_f (pow, minus_zero, -2, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_ff_f (pow, minus_zero, -11.1L, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+
+#ifndef __STDC_WANT_DEC_FP__ /* format 0x*p*DL NOT supported by GCC. */
+ TEST_ff_f (pow, 0x1p72L, 0x1p72L, plus_infty);
+ TEST_ff_f (pow, 10, -0x1p72L, 0);
+#endif
+ TEST_ff_f (pow, max_value, max_value, plus_infty);
+ TEST_ff_f (pow, 10, -max_value, 0);
+
+ TEST_ff_f (pow, 0, 1, 0);
+ TEST_ff_f (pow, 0, 11, 0);
+
+ TEST_ff_f (pow, minus_zero, 1, minus_zero);
+ TEST_ff_f (pow, minus_zero, 11, minus_zero);
+
+
+ TEST_ff_f (pow, 0, 2, 0);
+ TEST_ff_f (pow, 0, 11.1L, 0);
+
+
+ TEST_ff_f (pow, minus_zero, 2, 0);
+ TEST_ff_f (pow, minus_zero, 11.1L, 0);
+ TEST_ff_f (pow, 0, plus_infty, 0);
+ TEST_ff_f (pow, minus_zero, plus_infty, 0);
+
+#ifndef TEST_INLINE
+ /* pow (x, +inf) == +inf for |x| > 1. */
+ TEST_ff_f (pow, 1.5, plus_infty, plus_infty);
+
+ /* pow (x, +inf) == +0 for |x| < 1. */
+ TEST_ff_f (pow, 0.5, plus_infty, 0.0);
+
+ /* pow (x, -inf) == +0 for |x| > 1. */
+ TEST_ff_f (pow, 1.5, minus_infty, 0.0);
+
+ /* pow (x, -inf) == +inf for |x| < 1. */
+ TEST_ff_f (pow, 0.5, minus_infty, plus_infty);
+#endif
+
+ /* pow (+inf, y) == +inf for y > 0. */
+ TEST_ff_f (pow, plus_infty, 2, plus_infty);
+
+ /* pow (+inf, y) == +0 for y < 0. */
+ TEST_ff_f (pow, plus_infty, -1, 0.0);
+
+ /* pow (-inf, y) == -inf for y an odd integer > 0. */
+ TEST_ff_f (pow, minus_infty, 27, minus_infty);
+
+ /* pow (-inf, y) == +inf for y > 0 and not an odd integer. */
+ TEST_ff_f (pow, minus_infty, 28, plus_infty);
+
+ /* pow (-inf, y) == -0 for y an odd integer < 0. */
+ TEST_ff_f (pow, minus_infty, -3, minus_zero);
+ /* pow (-inf, y) == +0 for y < 0 and not an odd integer. */
+ TEST_ff_f (pow, minus_infty, -2.0, 0.0);
+
+ /* pow (+0, y) == +0 for y an odd integer > 0. */
+ TEST_ff_f (pow, 0.0, 27, 0.0);
+
+ /* pow (-0, y) == -0 for y an odd integer > 0. */
+ TEST_ff_f (pow, minus_zero, 27, minus_zero);
+
+ /* pow (+0, y) == +0 for y > 0 and not an odd integer. */
+ TEST_ff_f (pow, 0.0, 4, 0.0);
+
+ /* pow (-0, y) == +0 for y > 0 and not an odd integer. */
+ TEST_ff_f (pow, minus_zero, 4, 0.0);
+
+ TEST_ff_f (pow, 16, 0.25L, 2);
+#ifndef __STDC_WANT_DEC_FP__ /* format 0x*p*DL NOT supported by GCC. */
+ TEST_ff_f (pow, 0x1p64L, 0.125L, 256);
+#endif
+ TEST_ff_f (pow, 2, 4, 16);
+#ifndef __STDC_WANT_DEC_FP__ /* format 0x*p*DL NOT supported by GCC. */
+ TEST_ff_f (pow, 256, 8, 0x1p64L);
+#endif
+
+ TEST_ff_f (pow, 0.75L, 1.25L, 0.697953644326574699205914060237425566L);
+
+#if defined TEST_DOUBLE || defined TEST_LDOUBLE
+ TEST_ff_f (pow, -7.49321e+133, -9.80818e+16, 0);
+#endif
+
+ END (pow);
+}
+
+static void
+remainder_test (void)
+{
+ errno = 0;
+ FUNC(remainder) (1.625, 1.0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (remainder);
+
+ TEST_ff_f (remainder, 1, 0, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (remainder, 1, minus_zero, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (remainder, plus_infty, 1, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (remainder, minus_infty, 1, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (remainder, nan_value, nan_value, nan_value);
+
+ TEST_ff_f (remainder, 1.625, 1.0, -0.375);
+ TEST_ff_f (remainder, -1.625, 1.0, 0.375);
+ TEST_ff_f (remainder, 1.625, -1.0, -0.375);
+ TEST_ff_f (remainder, -1.625, -1.0, 0.375);
+ TEST_ff_f (remainder, 5.0, 2.0, 1.0);
+ TEST_ff_f (remainder, 3.0, 2.0, -1.0);
+
+ END (remainder);
+}
+
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have this functions */
+static void
+remquo_test (void)
+{
+ /* x is needed. */
+ int x;
+
+ errno = 0;
+ FUNC(remquo) (1.625, 1.0, &x);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (remquo);
+
+ TEST_ffI_f1 (remquo, 1, 0, nan_value, IGNORE, INVALID_EXCEPTION);
+ TEST_ffI_f1 (remquo, 1, minus_zero, nan_value, IGNORE, INVALID_EXCEPTION);
+ TEST_ffI_f1 (remquo, plus_infty, 1, nan_value, IGNORE, INVALID_EXCEPTION);
+ TEST_ffI_f1 (remquo, minus_infty, 1, nan_value, IGNORE, INVALID_EXCEPTION);
+ TEST_ffI_f1 (remquo, nan_value, nan_value, nan_value, IGNORE);
+
+ TEST_ffI_f1 (remquo, 1.625, 1.0, -0.375, 2);
+ TEST_ffI_f1 (remquo, -1.625, 1.0, 0.375, -2);
+ TEST_ffI_f1 (remquo, 1.625, -1.0, -0.375, -2);
+ TEST_ffI_f1 (remquo, -1.625, -1.0, 0.375, 2);
+
+ TEST_ffI_f1 (remquo, 5, 2, 1, 2);
+ TEST_ffI_f1 (remquo, 3, 2, -1, 2);
+
+ END (remquo);
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+static void
+rint_test (void)
+{
+ START (rint);
+
+ TEST_f_f (rint, 0.0, 0.0);
+ TEST_f_f (rint, minus_zero, minus_zero);
+ TEST_f_f (rint, plus_infty, plus_infty);
+ TEST_f_f (rint, minus_infty, minus_infty);
+
+ /* Default rounding mode is round to even. */
+ TEST_f_f (rint, 0.5, 0.0);
+ TEST_f_f (rint, 1.5, 2.0);
+ TEST_f_f (rint, 2.5, 2.0);
+ TEST_f_f (rint, 3.5, 4.0);
+ TEST_f_f (rint, 4.5, 4.0);
+ TEST_f_f (rint, -0.5, -0.0);
+ TEST_f_f (rint, -1.5, -2.0);
+ TEST_f_f (rint, -2.5, -2.0);
+ TEST_f_f (rint, -3.5, -4.0);
+ TEST_f_f (rint, -4.5, -4.0);
+ TEST_f_f (rint, 0.1, 0.0);
+ TEST_f_f (rint, 0.25, 0.0);
+ TEST_f_f (rint, 0.625, 1.0);
+ TEST_f_f (rint, -0.1, -0.0);
+ TEST_f_f (rint, -0.25, -0.0);
+ TEST_f_f (rint, -0.625, -1.0);
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
+# endif
+
+ TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
+# endif
+
+ TEST_f_f (rint, 9007199254740991.5L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.25L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.5L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.75L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740993.5L, 9007199254740994.0L);
+
+ TEST_f_f (rint, -9007199254740991.5L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.25L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.5L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.75L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740993.5L, -9007199254740994.0L);
+
+ TEST_f_f (rint, 72057594037927935.5L, 72057594037927936.0L);
+ TEST_f_f (rint, 72057594037927936.25L, 72057594037927936.0L);
+ TEST_f_f (rint, 72057594037927936.5L, 72057594037927936.0L);
+ TEST_f_f (rint, 72057594037927936.75L, 72057594037927937.0L);
+ TEST_f_f (rint, 72057594037927937.5L, 72057594037927938.0L);
+
+ TEST_f_f (rint, -72057594037927935.5L, -72057594037927936.0L);
+ TEST_f_f (rint, -72057594037927936.25L, -72057594037927936.0L);
+ TEST_f_f (rint, -72057594037927936.5L, -72057594037927936.0L);
+ TEST_f_f (rint, -72057594037927936.75L, -72057594037927937.0L);
+ TEST_f_f (rint, -72057594037927937.5L, -72057594037927938.0L);
+
+ TEST_f_f (rint, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L);
+ TEST_f_f (rint, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L);
+ TEST_f_f (rint, 10141204801825835211973625643008.5L, 10141204801825835211973625643008.0L);
+ TEST_f_f (rint, 10141204801825835211973625643008.75L, 10141204801825835211973625643009.0L);
+ TEST_f_f (rint, 10141204801825835211973625643009.5L, 10141204801825835211973625643010.0L);
+#endif
+
+ END (rint);
+}
+
+static void
+rint_test_tonearest (void)
+{
+ int save_round_mode;
+ START (rint_tonearest);
+
+ save_round_mode = GETROUND();
+
+ if (!SETROUND (TONEAREST))
+ {
+ TEST_f_f (rint, 2.0, 2.0);
+ TEST_f_f (rint, 1.5, 2.0);
+ TEST_f_f (rint, 1.0, 1.0);
+ TEST_f_f (rint, 0.5, 0.0);
+ TEST_f_f (rint, 0.0, 0.0);
+ TEST_f_f (rint, minus_zero, minus_zero);
+ TEST_f_f (rint, -0.5, -0.0);
+ TEST_f_f (rint, -1.0, -1.0);
+ TEST_f_f (rint, -1.5, -2.0);
+ TEST_f_f (rint, -2.0, -2.0);
+ TEST_f_f (rint, 0.1, 0.0);
+ TEST_f_f (rint, 0.25, 0.0);
+ TEST_f_f (rint, 0.625, 1.0);
+ TEST_f_f (rint, -0.1, -0.0);
+ TEST_f_f (rint, -0.25, -0.0);
+ TEST_f_f (rint, -0.625, -1.0);
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
+# endif
+ TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
+# endif
+#endif
+ }
+
+ SETROUND (save_round_mode);
+
+ END (rint_tonearest);
+}
+
+static void
+rint_test_towardzero (void)
+{
+ int save_round_mode;
+ START (rint_towardzero);
+
+ save_round_mode = GETROUND();
+
+ if (!SETROUND (TOWARDZERO))
+ {
+ TEST_f_f (rint, 2.0, 2.0);
+ TEST_f_f (rint, 1.5, 1.0);
+ TEST_f_f (rint, 1.0, 1.0);
+ TEST_f_f (rint, 0.5, 0.0);
+ TEST_f_f (rint, 0.0, 0.0);
+ TEST_f_f (rint, minus_zero, minus_zero);
+ TEST_f_f (rint, -0.5, -0.0);
+ TEST_f_f (rint, -1.0, -1.0);
+ TEST_f_f (rint, -1.5, -1.0);
+ TEST_f_f (rint, -2.0, -2.0);
+ TEST_f_f (rint, 0.1, 0.0);
+ TEST_f_f (rint, 0.25, 0.0);
+ TEST_f_f (rint, 0.625, 0.0);
+ TEST_f_f (rint, -0.1, -0.0);
+ TEST_f_f (rint, -0.25, -0.0);
+ TEST_f_f (rint, -0.625, -0.0);
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L);
+# endif
+ TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L);
+# endif
+#endif
+ }
+
+ SETROUND (save_round_mode);
+
+ END (rint_towardzero);
+}
+
+static void
+rint_test_downward (void)
+{
+ int save_round_mode;
+ START (rint_downward);
+
+ save_round_mode = GETROUND();
+
+ if (!SETROUND (DOWNWARD))
+ {
+ TEST_f_f (rint, 2.0, 2.0);
+ TEST_f_f (rint, 1.5, 1.0);
+ TEST_f_f (rint, 1.0, 1.0);
+ TEST_f_f (rint, 0.5, 0.0);
+ TEST_f_f (rint, 0.0, 0.0);
+ TEST_f_f (rint, minus_zero, minus_zero);
+ TEST_f_f (rint, -0.5, -1.0);
+ TEST_f_f (rint, -1.0, -1.0);
+ TEST_f_f (rint, -1.5, -2.0);
+ TEST_f_f (rint, -2.0, -2.0);
+ TEST_f_f (rint, 0.1, 0.0);
+ TEST_f_f (rint, 0.25, 0.0);
+ TEST_f_f (rint, 0.625, 0.0);
+ TEST_f_f (rint, -0.1, -1.0);
+ TEST_f_f (rint, -0.25, -1.0);
+ TEST_f_f (rint, -0.625, -1.0);
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L);
+# endif
+ TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.25L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370496.5L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L);
+ TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740994.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
+# endif
+#endif
+ }
+
+ SETROUND (save_round_mode);
+
+ END (rint_downward);
+}
+
+static void
+rint_test_upward (void)
+{
+ int save_round_mode;
+ START (rint_upward);
+
+ save_round_mode = GETROUND();
+
+ if (!SETROUND (UPWARD))
+ {
+ TEST_f_f (rint, 2.0, 2.0);
+ TEST_f_f (rint, 1.5, 2.0);
+ TEST_f_f (rint, 1.0, 1.0);
+ TEST_f_f (rint, 0.5, 1.0);
+ TEST_f_f (rint, 0.0, 0.0);
+ TEST_f_f (rint, minus_zero, minus_zero);
+ TEST_f_f (rint, -0.5, -0.0);
+ TEST_f_f (rint, -1.0, -1.0);
+ TEST_f_f (rint, -1.5, -1.0);
+ TEST_f_f (rint, -2.0, -2.0);
+ TEST_f_f (rint, 0.1, 1.0);
+ TEST_f_f (rint, 0.25, 1.0);
+ TEST_f_f (rint, 0.625, 1.0);
+ TEST_f_f (rint, -0.1, -0.0);
+ TEST_f_f (rint, -0.25, -0.0);
+ TEST_f_f (rint, -0.625, -0.0);
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.25L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370496.5L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L);
+ TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
+# endif
+ TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L);
+ TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L);
+ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L);
+
+ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740994.0L);
+ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L);
+ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L);
+
+ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L);
+ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L);
+# endif
+#endif
+ }
+
+ SETROUND (save_round_mode);
+
+ END (rint_upward);
+}
+
+static void
+round_test (void)
+{
+ START (round);
+
+ TEST_f_f (round, 0, 0);
+ TEST_f_f (round, minus_zero, minus_zero);
+ TEST_f_f (round, 0.2L, 0.0);
+ TEST_f_f (round, -0.2L, minus_zero);
+ TEST_f_f (round, 0.5, 1.0);
+ TEST_f_f (round, -0.5, -1.0);
+ TEST_f_f (round, 0.8L, 1.0);
+ TEST_f_f (round, -0.8L, -1.0);
+ TEST_f_f (round, 1.5, 2.0);
+ TEST_f_f (round, -1.5, -2.0);
+ TEST_f_f (round, 0.1, 0.0);
+ TEST_f_f (round, 0.25, 0.0);
+ TEST_f_f (round, 0.625, 1.0);
+ TEST_f_f (round, -0.1, -0.0);
+ TEST_f_f (round, -0.25, -0.0);
+ TEST_f_f (round, -0.625, -1.0);
+ TEST_f_f (round, 2097152.5, 2097153);
+ TEST_f_f (round, -2097152.5, -2097153);
+
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (round, 4503599627370495.5L, 4503599627370496.0L);
+ TEST_f_f (round, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (round, 4503599627370496.5L, 4503599627370497.0L);
+ TEST_f_f (round, 4503599627370496.75L, 4503599627370497.0L);
+ TEST_f_f (round, 4503599627370497.5L, 4503599627370498.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (round, 4503599627370494.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (round, 4503599627370495.5000000000001L, 4503599627370496.0L);
+ TEST_f_f (round, 4503599627370496.5000000000001L, 4503599627370497.0L);
+# endif
+
+ TEST_f_f (round, -4503599627370495.5L, -4503599627370496.0L);
+ TEST_f_f (round, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (round, -4503599627370496.5L, -4503599627370497.0L);
+ TEST_f_f (round, -4503599627370496.75L, -4503599627370497.0L);
+ TEST_f_f (round, -4503599627370497.5L, -4503599627370498.0L);
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (round, -4503599627370494.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (round, -4503599627370495.5000000000001L, -4503599627370496.0L);
+ TEST_f_f (round, -4503599627370496.5000000000001L, -4503599627370497.0L);
+# endif
+
+ TEST_f_f (round, 9007199254740991.5L, 9007199254740992.0L);
+ TEST_f_f (round, 9007199254740992.25L, 9007199254740992.0L);
+ TEST_f_f (round, 9007199254740992.5L, 9007199254740993.0L);
+ TEST_f_f (round, 9007199254740992.75L, 9007199254740993.0L);
+ TEST_f_f (round, 9007199254740993.5L, 9007199254740994.0L);
+
+ TEST_f_f (round, -9007199254740991.5L, -9007199254740992.0L);
+ TEST_f_f (round, -9007199254740992.25L, -9007199254740992.0L);
+ TEST_f_f (round, -9007199254740992.5L, -9007199254740993.0L);
+ TEST_f_f (round, -9007199254740992.75L, -9007199254740993.0L);
+ TEST_f_f (round, -9007199254740993.5L, -9007199254740994.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (round, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (round, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (round, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (round, 9007199254740991.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (round, 9007199254740992.5000000000001L, 9007199254740993.0L);
+ TEST_f_f (round, 9007199254740993.5000000000001L, 9007199254740994.0L);
+
+ TEST_f_f (round, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (round, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (round, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (round, -9007199254740991.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (round, -9007199254740992.5000000000001L, -9007199254740993.0L);
+ TEST_f_f (round, -9007199254740993.5000000000001L, -9007199254740994.0L);
+# endif
+
+ TEST_f_f (round, 72057594037927935.5L, 72057594037927936.0L);
+ TEST_f_f (round, 72057594037927936.25L, 72057594037927936.0L);
+ TEST_f_f (round, 72057594037927936.5L, 72057594037927937.0L);
+ TEST_f_f (round, 72057594037927936.75L, 72057594037927937.0L);
+ TEST_f_f (round, 72057594037927937.5L, 72057594037927938.0L);
+
+ TEST_f_f (round, -72057594037927935.5L, -72057594037927936.0L);
+ TEST_f_f (round, -72057594037927936.25L, -72057594037927936.0L);
+ TEST_f_f (round, -72057594037927936.5L, -72057594037927937.0L);
+ TEST_f_f (round, -72057594037927936.75L, -72057594037927937.0L);
+ TEST_f_f (round, -72057594037927937.5L, -72057594037927938.0L);
+
+ TEST_f_f (round, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L);
+ TEST_f_f (round, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L);
+ TEST_f_f (round, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L);
+ TEST_f_f (round, 10141204801825835211973625643008.75L, 10141204801825835211973625643009.0L);
+ TEST_f_f (round, 10141204801825835211973625643009.5L, 10141204801825835211973625643010.0L);
+#endif
+
+ END (round);
+}
+
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have the scalb function. */
+static void
+scalb_test (void)
+{
+
+ START (scalb);
+
+ TEST_ff_f (scalb, 2.0, 0.5, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (scalb, 3.0, -2.5, nan_value, INVALID_EXCEPTION);
+
+ TEST_ff_f (scalb, 0, nan_value, nan_value);
+ TEST_ff_f (scalb, 1, nan_value, nan_value);
+
+ TEST_ff_f (scalb, 1, 0, 1);
+ TEST_ff_f (scalb, -1, 0, -1);
+
+ TEST_ff_f (scalb, 0, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (scalb, minus_zero, plus_infty, nan_value, INVALID_EXCEPTION);
+
+ TEST_ff_f (scalb, 0, 2, 0);
+ TEST_ff_f (scalb, minus_zero, -4, minus_zero);
+ TEST_ff_f (scalb, 0, 0, 0);
+ TEST_ff_f (scalb, minus_zero, 0, minus_zero);
+ TEST_ff_f (scalb, 0, -1, 0);
+ TEST_ff_f (scalb, minus_zero, -10, minus_zero);
+ TEST_ff_f (scalb, 0, minus_infty, 0);
+ TEST_ff_f (scalb, minus_zero, minus_infty, minus_zero);
+
+ TEST_ff_f (scalb, plus_infty, -1, plus_infty);
+ TEST_ff_f (scalb, minus_infty, -10, minus_infty);
+ TEST_ff_f (scalb, plus_infty, 0, plus_infty);
+ TEST_ff_f (scalb, minus_infty, 0, minus_infty);
+ TEST_ff_f (scalb, plus_infty, 2, plus_infty);
+ TEST_ff_f (scalb, minus_infty, 100, minus_infty);
+
+ TEST_ff_f (scalb, 0.1L, minus_infty, 0.0);
+ TEST_ff_f (scalb, -0.1L, minus_infty, minus_zero);
+
+ TEST_ff_f (scalb, 1, plus_infty, plus_infty);
+ TEST_ff_f (scalb, -1, plus_infty, minus_infty);
+ TEST_ff_f (scalb, plus_infty, plus_infty, plus_infty);
+ TEST_ff_f (scalb, minus_infty, plus_infty, minus_infty);
+
+ TEST_ff_f (scalb, plus_infty, minus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_ff_f (scalb, minus_infty, minus_infty, nan_value, INVALID_EXCEPTION);
+
+ TEST_ff_f (scalb, nan_value, 1, nan_value);
+ TEST_ff_f (scalb, 1, nan_value, nan_value);
+ TEST_ff_f (scalb, nan_value, 0, nan_value);
+ TEST_ff_f (scalb, 0, nan_value, nan_value);
+ TEST_ff_f (scalb, nan_value, plus_infty, nan_value);
+ TEST_ff_f (scalb, plus_infty, nan_value, nan_value);
+ TEST_ff_f (scalb, nan_value, nan_value, nan_value);
+
+ TEST_ff_f (scalb, 0.8L, 4, 12.8L);
+ TEST_ff_f (scalb, -0.854375L, 5, -27.34L);
+
+ END (scalb);
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+
+static void
+scalbn_test (void)
+{
+
+ START (scalbn);
+
+ TEST_fi_f (scalbn, 0, 0, 0);
+ TEST_fi_f (scalbn, minus_zero, 0, minus_zero);
+
+ TEST_fi_f (scalbn, plus_infty, 1, plus_infty);
+ TEST_fi_f (scalbn, minus_infty, 1, minus_infty);
+ TEST_fi_f (scalbn, nan_value, 1, nan_value);
+
+ TEST_fi_f (scalbn, 0.8L, 4, 12.8L);
+ TEST_fi_f (scalbn, -0.854375L, 5, -27.34L);
+
+ TEST_fi_f (scalbn, 1, 0L, 1);
+
+ END (scalbn);
+}
+
+
+static void
+scalbln_test (void)
+{
+
+ START (scalbln);
+
+ TEST_fl_f (scalbln, 0, 0, 0);
+ TEST_fl_f (scalbln, minus_zero, 0, minus_zero);
+
+ TEST_fl_f (scalbln, plus_infty, 1, plus_infty);
+ TEST_fl_f (scalbln, minus_infty, 1, minus_infty);
+ TEST_fl_f (scalbln, nan_value, 1, nan_value);
+
+ TEST_fl_f (scalbln, 0.8L, 4, 12.8L);
+ TEST_fl_f (scalbln, -0.854375L, 5, -27.34L);
+
+ TEST_fl_f (scalbln, 1, 0L, 1);
+
+ END (scalbn);
+}
+
+
+static void
+signbit_test (void)
+{
+
+ START (signbit);
+
+ TEST_f_b (signbit, 0, 0);
+ TEST_f_b (signbit, minus_zero, 1);
+ TEST_f_b (signbit, plus_infty, 0);
+ TEST_f_b (signbit, minus_infty, 1);
+
+ /* signbit (x) != 0 for x < 0. */
+ TEST_f_b (signbit, -1, 1);
+ /* signbit (x) == 0 for x >= 0. */
+ TEST_f_b (signbit, 1, 0);
+
+ END (signbit);
+}
+
+
+static void
+sin_test (void)
+{
+ errno = 0;
+ FUNC(sin) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (sin);
+
+ TEST_f_f (sin, 0, 0);
+ TEST_f_f (sin, minus_zero, minus_zero);
+ TEST_f_f (sin, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (sin, minus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (sin, nan_value, nan_value);
+
+ TEST_f_f (sin, M_PI_6l, 0.5);
+ TEST_f_f (sin, -M_PI_6l, -0.5);
+ TEST_f_f (sin, M_PI_2l, 1);
+ TEST_f_f (sin, -M_PI_2l, -1);
+ TEST_f_f (sin, 0.75L, 0.681638760023334166733241952779893935L);
+
+#ifdef TEST_DOUBLE
+ TEST_f_f (sin, 0.80190127184058835, 0.71867942238767868);
+#endif
+
+ END (sin);
+
+}
+
+
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have this function */
+static void
+sincos_test (void)
+{
+ FLOAT sin_res, cos_res;
+
+ errno = 0;
+ FUNC(sincos) (0, &sin_res, &cos_res);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (sincos);
+
+ /* sincos is treated differently because it returns void. */
+ TEST_extra (sincos, 0, 0, 1);
+
+ TEST_extra (sincos, minus_zero, minus_zero, 1);
+ TEST_extra (sincos, plus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_extra (sincos, minus_infty, nan_value, nan_value, INVALID_EXCEPTION);
+ TEST_extra (sincos, nan_value, nan_value, nan_value);
+
+ TEST_extra (sincos, M_PI_2l, 1, 0);
+ TEST_extra (sincos, M_PI_6l, 0.5, 0.86602540378443864676372317075293616L);
+ TEST_extra (sincos, M_PI_6l * 2.0, 0.86602540378443864676372317075293616L, 0.5);
+ TEST_extra (sincos, 0.75L, 0.681638760023334166733241952779893935L, 0.731688868873820886311838753000084544L);
+
+#ifdef TEST_DOUBLE
+ TEST_extra (sincos, 0.80190127184058835, 0.71867942238767868, 0.69534156199418473);
+#endif
+
+ END (sincos);
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+static void
+sinh_test (void)
+{
+ errno = 0;
+ FUNC(sinh) (0.7L);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (sinh);
+ TEST_f_f (sinh, 0, 0);
+ TEST_f_f (sinh, minus_zero, minus_zero);
+
+#ifndef TEST_INLINE
+ TEST_f_f (sinh, plus_infty, plus_infty);
+ TEST_f_f (sinh, minus_infty, minus_infty);
+#endif
+ TEST_f_f (sinh, nan_value, nan_value);
+
+ TEST_f_f (sinh, 0.75L, 0.822316731935829980703661634446913849L);
+#ifndef __STDC_WANT_DEC_FP__ /* format 0x*p*DL NOT supported by GCC. */
+ TEST_f_f (sinh, 0x8p-32L, 1.86264514923095703232705808926175479e-9L);
+#endif
+
+ END (sinh);
+}
+
+static void
+sqrt_test (void)
+{
+ errno = 0;
+ FUNC(sqrt) (1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (sqrt);
+
+ TEST_f_f (sqrt, 0, 0);
+ TEST_f_f (sqrt, nan_value, nan_value);
+ TEST_f_f (sqrt, plus_infty, plus_infty);
+
+ TEST_f_f (sqrt, minus_zero, minus_zero);
+
+ /* sqrt (x) == NaN plus invalid exception for x < 0. */
+ TEST_f_f (sqrt, -1, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (sqrt, minus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (sqrt, nan_value, nan_value);
+
+ TEST_f_f (sqrt, 2209, 47);
+ TEST_f_f (sqrt, 4, 2);
+ TEST_f_f (sqrt, 2, M_SQRT2l);
+ TEST_f_f (sqrt, 0.25, 0.5);
+ TEST_f_f (sqrt, 6642.25, 81.5);
+ TEST_f_f (sqrt, 15190.5625L, 123.25L);
+ TEST_f_f (sqrt, 0.75L, 0.866025403784438646763723170752936183L);
+
+ END (sqrt);
+}
+
+
+static void
+tan_test (void)
+{
+ errno = 0;
+ FUNC(tan) (0);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (tan);
+
+ TEST_f_f (tan, 0, 0);
+ TEST_f_f (tan, minus_zero, minus_zero);
+ TEST_f_f (tan, plus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (tan, minus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (tan, nan_value, nan_value);
+
+ TEST_f_f (tan, M_PI_4l, 1);
+ TEST_f_f (tan, 0.75L, 0.931596459944072461165202756573936428L);
+
+ END (tan);
+}
+
+static void
+tanh_test (void)
+{
+ errno = 0;
+ FUNC(tanh) (0.7L);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ START (tanh);
+
+ TEST_f_f (tanh, 0, 0);
+ TEST_f_f (tanh, minus_zero, minus_zero);
+
+#ifndef TEST_INLINE
+ TEST_f_f (tanh, plus_infty, 1);
+ TEST_f_f (tanh, minus_infty, -1);
+#endif
+ TEST_f_f (tanh, nan_value, nan_value);
+
+ TEST_f_f (tanh, 0.75L, 0.635148952387287319214434357312496495L);
+ TEST_f_f (tanh, -0.75L, -0.635148952387287319214434357312496495L);
+
+ TEST_f_f (tanh, 1.0L, 0.7615941559557648881194582826047935904L);
+ TEST_f_f (tanh, -1.0L, -0.7615941559557648881194582826047935904L);
+
+#ifndef __STDC_WANT_DEC_FP__ /* format 0x*p*DL NOT supported by GCC. */
+ /* 2^-57 */
+ TEST_f_f (tanh, 0x1p-57L, 6.938893903907228377647697925567626953125e-18L);
+#endif
+
+ END (tanh);
+}
+
+static void
+tgamma_test (void)
+{
+ errno = 0;
+ FUNC(tgamma) (1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+ feclearexcept (FE_ALL_EXCEPT);
+
+ START (tgamma);
+
+ TEST_f_f (tgamma, plus_infty, plus_infty);
+ TEST_f_f (tgamma, 0, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ TEST_f_f (tgamma, minus_zero, minus_infty, DIVIDE_BY_ZERO_EXCEPTION);
+ /* tgamma (x) == NaN plus invalid exception for integer x <= 0. */
+ TEST_f_f (tgamma, -2, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (tgamma, minus_infty, nan_value, INVALID_EXCEPTION);
+ TEST_f_f (tgamma, nan_value, nan_value);
+
+ TEST_f_f (tgamma, 0.5, M_SQRT_PIl);
+ TEST_f_f (tgamma, -0.5, -M_2_SQRT_PIl);
+
+ TEST_f_f (tgamma, 1, 1);
+ TEST_f_f (tgamma, 4, 6);
+
+ TEST_f_f (tgamma, 0.7L, 1.29805533264755778568117117915281162L);
+ TEST_f_f (tgamma, 1.2L, 0.918168742399760610640951655185830401L);
+
+ END (tgamma);
+}
+
+
+static void
+trunc_test (void)
+{
+ START (trunc);
+
+ TEST_f_f (trunc, plus_infty, plus_infty);
+ TEST_f_f (trunc, minus_infty, minus_infty);
+ TEST_f_f (trunc, nan_value, nan_value);
+
+ TEST_f_f (trunc, 0, 0);
+ TEST_f_f (trunc, minus_zero, minus_zero);
+ TEST_f_f (trunc, 0.1, 0);
+ TEST_f_f (trunc, 0.25, 0);
+ TEST_f_f (trunc, 0.625, 0);
+ TEST_f_f (trunc, -0.1, minus_zero);
+ TEST_f_f (trunc, -0.25, minus_zero);
+ TEST_f_f (trunc, -0.625, minus_zero);
+ TEST_f_f (trunc, 1, 1);
+ TEST_f_f (trunc, -1, -1);
+ TEST_f_f (trunc, 1.625, 1);
+ TEST_f_f (trunc, -1.625, -1);
+
+ TEST_f_f (trunc, 1048580.625L, 1048580L);
+ TEST_f_f (trunc, -1048580.625L, -1048580L);
+
+ TEST_f_f (trunc, 8388610.125L, 8388610.0L);
+ TEST_f_f (trunc, -8388610.125L, -8388610.0L);
+
+ TEST_f_f (trunc, 4294967296.625L, 4294967296.0L);
+ TEST_f_f (trunc, -4294967296.625L, -4294967296.0L);
+
+#ifdef TEST_LDOUBLE
+ /* The result can only be represented in long double. */
+ TEST_f_f (trunc, 4503599627370495.5L, 4503599627370495.0L);
+ TEST_f_f (trunc, 4503599627370496.25L, 4503599627370496.0L);
+ TEST_f_f (trunc, 4503599627370496.5L, 4503599627370496.0L);
+ TEST_f_f (trunc, 4503599627370496.75L, 4503599627370496.0L);
+ TEST_f_f (trunc, 4503599627370497.5L, 4503599627370497.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (trunc, 4503599627370494.5000000000001L, 4503599627370494.0L);
+ TEST_f_f (trunc, 4503599627370495.5000000000001L, 4503599627370495.0L);
+ TEST_f_f (trunc, 4503599627370496.5000000000001L, 4503599627370496.0L);
+# endif
+
+ TEST_f_f (trunc, -4503599627370495.5L, -4503599627370495.0L);
+ TEST_f_f (trunc, -4503599627370496.25L, -4503599627370496.0L);
+ TEST_f_f (trunc, -4503599627370496.5L, -4503599627370496.0L);
+ TEST_f_f (trunc, -4503599627370496.75L, -4503599627370496.0L);
+ TEST_f_f (trunc, -4503599627370497.5L, -4503599627370497.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (trunc, -4503599627370494.5000000000001L, -4503599627370494.0L);
+ TEST_f_f (trunc, -4503599627370495.5000000000001L, -4503599627370495.0L);
+ TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L);
+# endif
+
+ TEST_f_f (trunc, 9007199254740991.5L, 9007199254740991.0L);
+ TEST_f_f (trunc, 9007199254740992.25L, 9007199254740992.0L);
+ TEST_f_f (trunc, 9007199254740992.5L, 9007199254740992.0L);
+ TEST_f_f (trunc, 9007199254740992.75L, 9007199254740992.0L);
+ TEST_f_f (trunc, 9007199254740993.5L, 9007199254740993.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (trunc, 9007199254740991.0000000000001L, 9007199254740991.0L);
+ TEST_f_f (trunc, 9007199254740992.0000000000001L, 9007199254740992.0L);
+ TEST_f_f (trunc, 9007199254740993.0000000000001L, 9007199254740993.0L);
+ TEST_f_f (trunc, 9007199254740991.5000000000001L, 9007199254740991.0L);
+ TEST_f_f (trunc, 9007199254740992.5000000000001L, 9007199254740992.0L);
+ TEST_f_f (trunc, 9007199254740993.5000000000001L, 9007199254740993.0L);
+# endif
+
+ TEST_f_f (trunc, -9007199254740991.5L, -9007199254740991.0L);
+ TEST_f_f (trunc, -9007199254740992.25L, -9007199254740992.0L);
+ TEST_f_f (trunc, -9007199254740992.5L, -9007199254740992.0L);
+ TEST_f_f (trunc, -9007199254740992.75L, -9007199254740992.0L);
+ TEST_f_f (trunc, -9007199254740993.5L, -9007199254740993.0L);
+
+# if LDBL_MANT_DIG > 100
+ TEST_f_f (trunc, -9007199254740991.0000000000001L, -9007199254740991.0L);
+ TEST_f_f (trunc, -9007199254740992.0000000000001L, -9007199254740992.0L);
+ TEST_f_f (trunc, -9007199254740993.0000000000001L, -9007199254740993.0L);
+ TEST_f_f (trunc, -9007199254740991.5000000000001L, -9007199254740991.0L);
+ TEST_f_f (trunc, -9007199254740992.5000000000001L, -9007199254740992.0L);
+ TEST_f_f (trunc, -9007199254740993.5000000000001L, -9007199254740993.0L);
+# endif
+
+ TEST_f_f (trunc, 72057594037927935.5L, 72057594037927935.0L);
+ TEST_f_f (trunc, 72057594037927936.25L, 72057594037927936.0L);
+ TEST_f_f (trunc, 72057594037927936.5L, 72057594037927936.0L);
+ TEST_f_f (trunc, 72057594037927936.75L, 72057594037927936.0L);
+ TEST_f_f (trunc, 72057594037927937.5L, 72057594037927937.0L);
+
+ TEST_f_f (trunc, -72057594037927935.5L, -72057594037927935.0L);
+ TEST_f_f (trunc, -72057594037927936.25L, -72057594037927936.0L);
+ TEST_f_f (trunc, -72057594037927936.5L, -72057594037927936.0L);
+ TEST_f_f (trunc, -72057594037927936.75L, -72057594037927936.0L);
+ TEST_f_f (trunc, -72057594037927937.5L, -72057594037927937.0L);
+
+ TEST_f_f (trunc, 10141204801825835211973625643007.5L, 10141204801825835211973625643007.0L);
+ TEST_f_f (trunc, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L);
+ TEST_f_f (trunc, 10141204801825835211973625643008.5L, 10141204801825835211973625643008.0L);
+ TEST_f_f (trunc, 10141204801825835211973625643008.75L, 10141204801825835211973625643008.0L);
+ TEST_f_f (trunc, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L);
+#endif
+
+ END (trunc);
+}
+
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have the y functions */
+static void
+y0_test (void)
+{
+ FLOAT s, c;
+ errno = 0;
+ FUNC (sincos) (0, &s, &c);
+ if (errno == ENOSYS)
+ /* Required function not implemented. */
+ return;
+ FUNC(y0) (1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ /* y0 is the Bessel function of the second kind of order 0 */
+ START (y0);
+
+ TEST_f_f (y0, -1.0, minus_infty, INVALID_EXCEPTION);
+ TEST_f_f (y0, 0.0, minus_infty);
+ TEST_f_f (y0, nan_value, nan_value);
+ TEST_f_f (y0, plus_infty, 0);
+
+ TEST_f_f (y0, 0.125L, -1.38968062514384052915582277745018693L);
+ TEST_f_f (y0, 0.75L, -0.137172769385772397522814379396581855L);
+ TEST_f_f (y0, 1.0, 0.0882569642156769579829267660235151628L);
+ TEST_f_f (y0, 1.5, 0.382448923797758843955068554978089862L);
+ TEST_f_f (y0, 2.0, 0.510375672649745119596606592727157873L);
+ TEST_f_f (y0, 8.0, 0.223521489387566220527323400498620359L);
+ TEST_f_f (y0, 10.0, 0.0556711672835993914244598774101900481L);
+
+ END (y0);
+}
+
+
+static void
+y1_test (void)
+{
+ FLOAT s, c;
+ errno = 0;
+ FUNC (sincos) (0, &s, &c);
+ if (errno == ENOSYS)
+ /* Required function not implemented. */
+ return;
+ FUNC(y1) (1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ /* y1 is the Bessel function of the second kind of order 1 */
+ START (y1);
+
+ TEST_f_f (y1, -1.0, minus_infty, INVALID_EXCEPTION);
+ TEST_f_f (y1, 0.0, minus_infty);
+ TEST_f_f (y1, plus_infty, 0);
+ TEST_f_f (y1, nan_value, nan_value);
+
+ TEST_f_f (y1, 0.125L, -5.19993611253477499595928744876579921L);
+ TEST_f_f (y1, 0.75L, -1.03759455076928541973767132140642198L);
+ TEST_f_f (y1, 1.0, -0.781212821300288716547150000047964821L);
+ TEST_f_f (y1, 1.5, -0.412308626973911295952829820633445323L);
+ TEST_f_f (y1, 2.0, -0.107032431540937546888370772277476637L);
+ TEST_f_f (y1, 8.0, -0.158060461731247494255555266187483550L);
+ TEST_f_f (y1, 10.0, 0.249015424206953883923283474663222803L);
+
+ END (y1);
+}
+
+
+static void
+yn_test (void)
+{
+ FLOAT s, c;
+ errno = 0;
+ FUNC (sincos) (0, &s, &c);
+ if (errno == ENOSYS)
+ /* Required function not implemented. */
+ return;
+ FUNC(yn) (1, 1);
+ if (errno == ENOSYS)
+ /* Function not implemented. */
+ return;
+
+ /* yn is the Bessel function of the second kind of order n */
+ START (yn);
+
+ /* yn (0, x) == y0 (x) */
+ TEST_ff_f (yn, 0, -1.0, minus_infty, INVALID_EXCEPTION);
+ TEST_ff_f (yn, 0, 0.0, minus_infty);
+ TEST_ff_f (yn, 0, nan_value, nan_value);
+ TEST_ff_f (yn, 0, plus_infty, 0);
+
+ TEST_ff_f (yn, 0, 0.125L, -1.38968062514384052915582277745018693L);
+ TEST_ff_f (yn, 0, 0.75L, -0.137172769385772397522814379396581855L);
+ TEST_ff_f (yn, 0, 1.0, 0.0882569642156769579829267660235151628L);
+ TEST_ff_f (yn, 0, 1.5, 0.382448923797758843955068554978089862L);
+ TEST_ff_f (yn, 0, 2.0, 0.510375672649745119596606592727157873L);
+ TEST_ff_f (yn, 0, 8.0, 0.223521489387566220527323400498620359L);
+ TEST_ff_f (yn, 0, 10.0, 0.0556711672835993914244598774101900481L);
+
+ /* yn (1, x) == y1 (x) */
+ TEST_ff_f (yn, 1, -1.0, minus_infty, INVALID_EXCEPTION);
+ TEST_ff_f (yn, 1, 0.0, minus_infty);
+ TEST_ff_f (yn, 1, plus_infty, 0);
+ TEST_ff_f (yn, 1, nan_value, nan_value);
+
+ TEST_ff_f (yn, 1, 0.125L, -5.19993611253477499595928744876579921L);
+ TEST_ff_f (yn, 1, 0.75L, -1.03759455076928541973767132140642198L);
+ TEST_ff_f (yn, 1, 1.0, -0.781212821300288716547150000047964821L);
+ TEST_ff_f (yn, 1, 1.5, -0.412308626973911295952829820633445323L);
+ TEST_ff_f (yn, 1, 2.0, -0.107032431540937546888370772277476637L);
+ TEST_ff_f (yn, 1, 8.0, -0.158060461731247494255555266187483550L);
+ TEST_ff_f (yn, 1, 10.0, 0.249015424206953883923283474663222803L);
+
+ /* yn (3, x) */
+ TEST_ff_f (yn, 3, plus_infty, 0);
+ TEST_ff_f (yn, 3, nan_value, nan_value);
+
+ TEST_ff_f (yn, 3, 0.125L, -2612.69757350066712600220955744091741L);
+ TEST_ff_f (yn, 3, 0.75L, -12.9877176234475433186319774484809207L);
+ TEST_ff_f (yn, 3, 1.0, -5.82151760596472884776175706442981440L);
+ TEST_ff_f (yn, 3, 2.0, -1.12778377684042778608158395773179238L);
+ TEST_ff_f (yn, 3, 10.0, -0.251362657183837329779204747654240998L);
+
+ /* yn (10, x) */
+ TEST_ff_f (yn, 10, plus_infty, 0);
+ TEST_ff_f (yn, 10, nan_value, nan_value);
+
+ TEST_ff_f (yn, 10, 0.125L, -127057845771019398.252538486899753195L);
+ TEST_ff_f (yn, 10, 0.75L, -2133501638.90573424452445412893839236L);
+ TEST_ff_f (yn, 10, 1.0, -121618014.278689189288130426667971145L);
+ TEST_ff_f (yn, 10, 2.0, -129184.542208039282635913145923304214L);
+ TEST_ff_f (yn, 10, 10.0, -0.359814152183402722051986577343560609L);
+
+ END (yn);
+
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have this function */
+static void
+significand_test (void)
+{
+ /* significand returns the mantissa of the exponential representation. */
+ START (significand);
+
+ TEST_f_f (significand, 4.0, 1.0);
+ TEST_f_f (significand, 6.0, 1.5);
+ TEST_f_f (significand, 8.0, 1.0);
+
+ END (significand);
+}
+#endif /* __STDC_WANT_DEC_FP__ */
+
+static void
+initialize (void)
+{
+ fpstack_test ("start *init*");
+ plus_zero = 0.0;
+ nan_value = plus_zero / plus_zero; /* Suppress GCC warning */
+
+ minus_zero = FUNC(copysign) (0.0, -1.0);
+ plus_infty = CHOOSE (HUGE_VALL, HUGE_VAL, HUGE_VALF,
+ HUGE_VALL, HUGE_VAL, HUGE_VALF,
+ HUGE_VAL_D128, HUGE_VAL_D64, HUGE_VAL_D32);
+ minus_infty = CHOOSE (-HUGE_VALL, -HUGE_VAL, -HUGE_VALF,
+ -HUGE_VALL, -HUGE_VAL, -HUGE_VALF,
+ -HUGE_VAL_D128, -HUGE_VAL_D64, -HUGE_VAL_D32);
+ max_value = CHOOSE (LDBL_MAX, DBL_MAX, FLT_MAX,
+ LDBL_MAX, DBL_MAX, FLT_MAX,
+ DEC128_MAX, DEC64_MAX, DEC32_MAX);
+ min_value = CHOOSE (LDBL_MIN, DBL_MIN, FLT_MIN,
+ LDBL_MIN, DBL_MIN, FLT_MIN,
+ DEC128_MIN, DEC64_MIN, DEC32_MIN);
+
+ (void) &plus_zero;
+ (void) &nan_value;
+ (void) &minus_zero;
+ (void) &plus_infty;
+ (void) &minus_infty;
+ (void) &max_value;
+ (void) &min_value;
+
+ /* Clear all exceptions. From now on we must not get random exceptions. */
+ feclearexcept (FE_ALL_EXCEPT);
+
+ /* Test to make sure we start correctly. */
+ fpstack_test ("end *init*");
+}
+
+/* Definitions of arguments for argp functions. */
+static const struct argp_option options[] =
+{
+ { "verbose", 'v', "NUMBER", 0, "Level of verbosity (0..3)"},
+ { "ulps-file", 'u', NULL, 0, "Output ulps to file ULPs"},
+ { "no-max-error", 'f', NULL, 0,
+ "Don't output maximal errors of functions"},
+ { "no-points", 'p', NULL, 0,
+ "Don't output results of functions invocations"},
+ { "ignore-max-ulp", 'i', "yes/no", 0,
+ "Ignore given maximal errors"},
+ { NULL, 0, NULL, 0, NULL }
+};
+
+/* Short description of program. */
+static const char doc[] = "Math test suite: " TEST_MSG ;
+
+/* Prototype for option handler. */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions. */
+static struct argp argp =
+{
+ options, parse_opt, NULL, doc,
+};
+
+
+/* Handle program arguments. */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ switch (key)
+ {
+ case 'f':
+ output_max_error = 0;
+ break;
+ case 'i':
+ if (strcmp (arg, "yes") == 0)
+ ignore_max_ulp = 1;
+ else if (strcmp (arg, "no") == 0)
+ ignore_max_ulp = 0;
+ break;
+ case 'p':
+ output_points = 0;
+ break;
+ case 'u':
+ output_ulps = 1;
+ break;
+ case 'v':
+ if (optarg)
+ verbose = (unsigned int) strtoul (optarg, NULL, 0);
+ else
+ verbose = 3;
+ break;
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+#if 0
+/* function to check our ulp calculation. */
+void
+check_ulp (void)
+{
+ int i;
+
+ FLOAT u, diff, ulp;
+ /* This gives one ulp. */
+ u = FUNC(nextafter) (10, 20);
+ check_equal (10.0, u, 1, &diff, &ulp);
+ printf ("One ulp: % .4" PRINTF_NEXPR "\n", ulp);
+
+ /* This gives one more ulp. */
+ u = FUNC(nextafter) (u, 20);
+ check_equal (10.0, u, 2, &diff, &ulp);
+ printf ("two ulp: % .4" PRINTF_NEXPR "\n", ulp);
+
+ /* And now calculate 100 ulp. */
+ for (i = 2; i < 100; i++)
+ u = FUNC(nextafter) (u, 20);
+ check_equal (10.0, u, 100, &diff, &ulp);
+ printf ("100 ulp: % .4" PRINTF_NEXPR "\n", ulp);
+}
+#endif
+
+int
+main (int argc, char **argv)
+{
+
+ int remaining;
+
+ verbose = 1;
+ output_ulps = 0;
+ output_max_error = 1;
+ output_points = 1;
+ /* XXX set to 0 for releases. */
+ ignore_max_ulp = 0;
+
+ /* Parse and process arguments. */
+ argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+ if (remaining != argc)
+ {
+ fprintf (stderr, "wrong number of arguments");
+ argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
+ exit (EXIT_FAILURE);
+ }
+
+ if (output_ulps)
+ {
+ ulps_file = fopen ("ULPs", "a");
+ if (ulps_file == NULL)
+ {
+ perror ("can't open file `ULPs' for writing: ");
+ exit (1);
+ }
+ }
+
+
+ initialize ();
+ printf (TEST_MSG);
+
+#if 0
+ check_ulp ();
+#endif
+
+ /* Keep the tests a wee bit ordered (according to ISO C99). */
+ /* Classification macros: */
+ fpclassify_test ();
+ isfinite_test ();
+ isnormal_test ();
+ signbit_test ();
+
+ /* Trigonometric functions: */
+ acos_test ();
+ asin_test ();
+ atan_test ();
+ atan2_test ();
+ cos_test ();
+ sin_test ();
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have the sincos function */
+ sincos_test ();
+#endif
+ tan_test ();
+
+ /* Hyperbolic functions: */
+ acosh_test ();
+ asinh_test ();
+ atanh_test ();
+ cosh_test ();
+ sinh_test ();
+ tanh_test ();
+
+ /* Exponential and logarithmic functions: */
+ exp_test ();
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have this function */
+ exp10_test ();
+#endif
+ exp2_test ();
+ expm1_test ();
+/* This is nonapplicable to DFP. DFP should have its own frexp tests. */
+#ifndef __STDC_WANT_DEC_FP__
+ frexp_test ();
+ ldexp_test ();
+#endif
+ log_test ();
+ log10_test ();
+ log1p_test ();
+ log2_test ();
+ logb_test ();
+ modf_test ();
+#ifndef __STDC_WANT_DEC_FP__ /* This is nonapplicable to DFP */
+ ilogb_test ();
+#endif
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have this function */
+ scalb_test ();
+#endif
+ scalbn_test ();
+ scalbln_test ();
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have this function */
+ significand_test ();
+#endif /* __STDC_WANT_DEC_FP__ */
+
+ /* Power and absolute value functions: */
+#ifndef __STDC_WANT_DEC_FP__
+ cbrt_test ();
+#endif
+ fabs_test ();
+ hypot_test ();
+ pow_test ();
+ sqrt_test ();
+
+ /* Error and gamma functions: */
+ erf_test ();
+ erfc_test ();
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have this function */
+ gamma_test ();
+#endif
+ lgamma_test ();
+ tgamma_test ();
+
+ /* Nearest integer functions: */
+ ceil_test ();
+ floor_test ();
+ nearbyint_test ();
+ rint_test ();
+ rint_test_tonearest ();
+ rint_test_towardzero ();
+ rint_test_downward ();
+ rint_test_upward ();
+ lrint_test ();
+ llrint_test ();
+ llrint_test_tonearest ();
+ llrint_test_towardzero ();
+ llrint_test_downward ();
+ llrint_test_upward ();
+ round_test ();
+ lround_test ();
+ llround_test ();
+ trunc_test ();
+
+ /* Remainder functions: */
+ fmod_test ();
+ remainder_test ();
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have this function. */
+ remquo_test ();
+#endif
+
+ /* Manipulation functions: */
+ copysign_test ();
+ nextafter_test ();
+ nexttoward_test ();
+
+ /* maximum, minimum and positive difference functions */
+ fdim_test ();
+ fmax_test ();
+ fmin_test ();
+
+ /* Multiply and add: */
+ fma_test ();
+
+#ifndef __STDC_WANT_DEC_FP__
+ /* Complex functions: */
+ cabs_test ();
+ cacos_test ();
+ cacosh_test ();
+ carg_test ();
+ casin_test ();
+ casinh_test ();
+ catan_test ();
+ catanh_test ();
+ ccos_test ();
+ ccosh_test ();
+ cexp_test ();
+ cimag_test ();
+ clog10_test ();
+ clog_test ();
+ conj_test ();
+ cpow_test ();
+ cproj_test ();
+ creal_test ();
+ csin_test ();
+ csinh_test ();
+ csqrt_test ();
+ ctan_test ();
+ ctanh_test ();
+#endif /* __STDC_WANT_DEC_FP__ */
+
+#ifndef __STDC_WANT_DEC_FP__ /* DFP doesn't have the bessel functions */
+ /* Bessel functions: */
+ j0_test ();
+ j1_test ();
+ jn_test ();
+ y0_test ();
+ y1_test ();
+ yn_test ();
+#endif /* __STDC_WANT_DEC_FP__ */
+
+ if (output_ulps)
+ fclose (ulps_file);
+
+ printf ("\nTest suite completed:\n");
+ printf (" %d test cases plus %d tests for exception flags executed.\n",
+ noTests, noExcTests);
+ if (noXFails)
+ printf (" %d expected failures occurred.\n", noXFails);
+ if (noXPasses)
+ printf (" %d unexpected passes occurred.\n", noXPasses);
+ if (noErrors)
+ {
+ printf (" %d errors occurred.\n", noErrors);
+ return 1;
+ }
+ printf (" All tests passed successfully.\n");
+
+ return 0;
+}
+
+/*
+ * Local Variables:
+ * mode:c
+ * End:
+ */
diff --git a/libc/dfp/mapround.c b/libc/dfp/mapround.c
new file mode 100644
index 000000000..8835fcd61
--- /dev/null
+++ b/libc/dfp/mapround.c
@@ -0,0 +1,81 @@
+/* Get the Decimal Float rounding mode mapped to the decNumber rounding mode
+ enumeration values.
+
+ Copyright (C) 2006 IBM Corporation.
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#include <fenv.h>
+#include <dfpfenv_private.h>
+#include <mapround.h>
+#include <decContext.h>
+
+int __dn_getround(void)
+{
+ /* Only match on supported rounding modes. Power6[x] hardware supports the
+ * greatest number of rounding modes. The decNumber library supports
+ * one fewer than Power6[x] hardware. */
+
+ /* C Rounding Mode: Hardware Description
+ * DecNumber description
+ *
+ * FE_DEC_TONEAREST: 000 Round to nearest, ties to even.
+ * DEC_ROUND_HALF_EVEN
+ *
+ * FE_DEC_TOWARDZERO: 001 Round toward zero.
+ * DEC_ROUND_DOWN
+ *
+ * FE_DEC_UPWARD: 010 Round toward +Infinity
+ * DEC_ROUND_CEILING
+ *
+ * FE_DEC_DOWNWARD: 011 Round toward -Infinity
+ * DEC_ROUND_FLOOR
+ *
+ * FE_DEC_TONEARESTFROMZERO: 100 Round to nearest, ties away from zero
+ * DEC_ROUND_HALF_UP
+ *
+ * 5: 101 Round to nearest, ties toward zero
+ * DEC_ROUND_HALF_DOWN
+ *
+ * 6: 110 Round away from zero
+ * DEC_ROUND_UP
+ *
+ * 7: 111 Round for prepare for shorter precision
+ * Not supported by decNumber. */
+
+ switch(__fe_dec_getround())
+ {
+ case FE_DEC_TONEAREST:
+ return DEC_ROUND_HALF_EVEN;
+ case FE_DEC_TOWARDZERO:
+ return DEC_ROUND_DOWN;
+ case FE_DEC_UPWARD:
+ return DEC_ROUND_CEILING;
+ case FE_DEC_DOWNWARD:
+ return DEC_ROUND_FLOOR;
+ case FE_DEC_TONEARESTFROMZERO:
+ return DEC_ROUND_HALF_UP;
+ case 5:
+ return DEC_ROUND_HALF_DOWN;
+ case 6:
+ return DEC_ROUND_UP;
+ case 7:
+ default:
+ return DEC_ROUND_HALF_EVEN;
+ }
+}
diff --git a/libc/dfp/mapround.h b/libc/dfp/mapround.h
new file mode 100644
index 000000000..ac4e0e783
--- /dev/null
+++ b/libc/dfp/mapround.h
@@ -0,0 +1,29 @@
+/* Prototype for getting the decimal rounding mode mapped to the decNumber
+ rounding mode enumeration values.
+
+ Copyright (C) 2006 IBM Corporation.
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _MAPROUND_
+#define _MAPROUND_
+
+/* Get the rounding mode mapped to the decNumber rounding modes. */
+extern int __dn_getround(void);
+
+#endif /* _MAPROUND_ */
diff --git a/libc/dfp/sysdeps/dfp/Subdirs b/libc/dfp/sysdeps/dfp/Subdirs
new file mode 100644
index 000000000..3d687b0d6
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/Subdirs
@@ -0,0 +1 @@
+dfp
diff --git a/libc/dfp/sysdeps/dfp/Versions b/libc/dfp/sysdeps/dfp/Versions
new file mode 100644
index 000000000..1c6b288cc
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/Versions
@@ -0,0 +1,6 @@
+libc {
+ GLIBC_2.5 {
+ # functions used in other libraries
+ __printf_dfp;
+ };
+}
diff --git a/libc/dfp/sysdeps/dfp/configure.in b/libc/dfp/sysdeps/dfp/configure.in
new file mode 100644
index 000000000..b9f6a0028
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/configure.in
@@ -0,0 +1,14 @@
+GLIBC_PROVIDES
+
+dnl does the compiler support decimal float
+AC_CACHE_CHECK(for decimal-float-support in compiler,
+ libc_cv_cc_with_decimal_float, [
+ if ${CC-cc} -v 2>&1 >/dev/null | grep -q " --enable-decimal-float "; then
+ libc_cv_cc_with_decimal_float=yes
+ else
+ libc_cv_cc_with_decimal_float=no
+ fi ])
+AC_SUBST(libc_cv_cc_with_decimal_float)
+if test $libc_cv_cc_with_decimal_float = no; then
+ AC_MSG_ERROR([The dfp add-on requires a compiler with --enable-decimal-float configured.])
+fi
diff --git a/libc/dfp/sysdeps/dfp/decroundtls.c b/libc/dfp/sysdeps/dfp/decroundtls.c
new file mode 100644
index 000000000..8d5562f93
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/decroundtls.c
@@ -0,0 +1,32 @@
+/* Decimal Float Rounding Mode accessor function definition and TLS variable.
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#include <tls.h>
+#include <fenv.h>
+#include <decroundtls.h>
+
+__thread int __dec_round_mode attribute_tls_model_ie = FE_DEC_TONEAREST;
+
+int *__decrm_location (void)
+{
+ return &__dec_round_mode;
+}
+libc_hidden_def (__decrm_location)
diff --git a/libc/dfp/sysdeps/dfp/decroundtls.h b/libc/dfp/sysdeps/dfp/decroundtls.h
new file mode 100644
index 000000000..7a29d87e6
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/decroundtls.h
@@ -0,0 +1,33 @@
+/* Decimal Float Rounding Mode accessor function prototype
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECROUNDTLS_
+#define _DECROUNDTLS_
+
+#include <features.h>
+__BEGIN_DECLS
+
+extern int * __decrm_location (void);
+libc_hidden_proto (__decrm_location)
+
+__END_DECLS
+
+#endif /* _DECROUNDTLS_ */
diff --git a/libc/dfp/sysdeps/dfp/dfpwchar.h b/libc/dfp/sysdeps/dfp/dfpwchar.h
new file mode 100644
index 000000000..863a4fc9f
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/dfpwchar.h
@@ -0,0 +1,35 @@
+/* Wide character string-to-decimal conversion function prototypes
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DFPWCHAR_H
+#define _DFPWCHAR_H 1
+
+extern _Decimal32 __wcstod32_internal (const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int group);
+extern _Decimal64 __wcstod64_internal (const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int group);
+extern _Decimal128 __wcstod128_internal (const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int group);
+
+libc_hidden_proto (__wcstod32_internal)
+libc_hidden_proto (__wcstod64_internal)
+libc_hidden_proto (__wcstod128_internal)
+
+#endif /* _DFPWCHAR_H */
+
diff --git a/libc/dfp/sysdeps/dfp/fe_decround.c b/libc/dfp/sysdeps/dfp/fe_decround.c
new file mode 100644
index 000000000..d294f770a
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/fe_decround.c
@@ -0,0 +1,71 @@
+/* Decimal Float fe_dec_getround and fe_dec_setround definitions.
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#include <decroundtls.h>
+#include <dfpfenv_private.h>
+
+int __fe_dec_setround(int __rounding_direction)
+{
+
+ /* Only match on supported rounding modes. The decNum library supports
+ * additional ones that aren't valid C rounding modes. We also allow rounding
+ * modes to be set covertly for the three additional hardware rounding modes
+ * supported by Power6[x] that aren't in the DFP Draft Technical Report. */
+
+ /* C Rounding Mode: Hardware Description
+ * DecNumber description
+ *
+ * FE_DEC_TONEAREST: 000 Round to nearest, ties to even.
+ * DEC_ROUND_HALF_EVEN
+ *
+ * FE_DEC_TOWARDZERO: 001 Round toward zero.
+ * DEC_ROUND_DOWN
+ *
+ * FE_DEC_UPWARD: 010 Round toward +Infinity
+ * DEC_ROUND_CEILING
+ *
+ * FE_DEC_DOWNWARD: 011 Round toward -Infinity
+ * DEC_ROUND_FLOOR
+ *
+ * FE_DEC_TONEARESTFROMZERO: 100 Round to nearest, ties away from zero
+ * DEC_ROUND_HALF_UP
+ *
+ * 5: 101 Round to nearest, ties toward zero
+ * DEC_ROUND_HALF_DOWN
+ *
+ * 6: 110 Round away from zero
+ * DEC_ROUND_UP
+ *
+ * 7: 111 Round for prepare for shorter precision
+ * Not supported by decNumber. */
+ if (__rounding_direction > 7)
+ return 1;
+ *__decrm_location() = __rounding_direction;
+ return 0;
+}
+strong_alias(__fe_dec_setround, fe_dec_setround)
+
+int __fe_dec_getround(void)
+{
+ return *__decrm_location();
+}
+strong_alias(__fe_dec_getround, fe_dec_getround)
+
diff --git a/libc/dfp/sysdeps/dfp/math/bits/mathcalls.h b/libc/dfp/sysdeps/dfp/math/bits/mathcalls.h
new file mode 100644
index 000000000..b787695de
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/math/bits/mathcalls.h
@@ -0,0 +1,367 @@
+/* Prototype declarations for math functions; helper file for <math.h>.
+ Copyright (C) 1996-2002, 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* NOTE: Because of the special way this file is used by <math.h>, this
+ file must NOT be protected from multiple inclusion as header files
+ usually are.
+
+ This file provides prototype declarations for the math functions.
+ Most functions are declared using the macro:
+
+ __MATHCALL (NAME,[_r], (ARGS...));
+
+ This means there is a function `NAME' returning `double' and a function
+ `NAMEf' returning `float'. Each place `_Mdouble_' appears in the
+ prototype, that is actually `double' in the prototype for `NAME' and
+ `float' in the prototype for `NAMEf'. Reentrant variant functions are
+ called `NAME_r' and `NAMEf_r'.
+
+ Functions returning other types like `int' are declared using the macro:
+
+ __MATHDECL (TYPE, NAME,[_r], (ARGS...));
+
+ This is just like __MATHCALL but for a function returning `TYPE'
+ instead of `_Mdouble_'. In all of these cases, there is still
+ both a `NAME' and a `NAMEf' that takes `float' arguments.
+
+ Note that there must be no whitespace before the argument passed for
+ NAME, to make token pasting work with -traditional. */
+
+#ifndef _MATH_H
+# error "Never include <bits/mathcalls.h> directly; include <math.h> instead."
+#endif
+
+
+/* Trigonometric functions. */
+
+_Mdouble_BEGIN_NAMESPACE
+/* Arc cosine of X. */
+__MATHCALL (acos,, (_Mdouble_ __x));
+/* Arc sine of X. */
+__MATHCALL (asin,, (_Mdouble_ __x));
+/* Arc tangent of X. */
+__MATHCALL (atan,, (_Mdouble_ __x));
+/* Arc tangent of Y/X. */
+__MATHCALL (atan2,, (_Mdouble_ __y, _Mdouble_ __x));
+
+/* Cosine of X. */
+__MATHCALL (cos,, (_Mdouble_ __x));
+/* Sine of X. */
+__MATHCALL (sin,, (_Mdouble_ __x));
+/* Tangent of X. */
+__MATHCALL (tan,, (_Mdouble_ __x));
+
+/* Hyperbolic functions. */
+
+/* Hyperbolic cosine of X. */
+__MATHCALL (cosh,, (_Mdouble_ __x));
+/* Hyperbolic sine of X. */
+__MATHCALL (sinh,, (_Mdouble_ __x));
+/* Hyperbolic tangent of X. */
+__MATHCALL (tanh,, (_Mdouble_ __x));
+_Mdouble_END_NAMESPACE
+
+#ifdef __USE_GNU
+/* Cosine and sine of X. */
+__MATHDECL (void,sincos,,
+ (_Mdouble_ __x, _Mdouble_ *__sinx, _Mdouble_ *__cosx));
+#endif
+
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Hyperbolic arc cosine of X. */
+__MATHCALL (acosh,, (_Mdouble_ __x));
+/* Hyperbolic arc sine of X. */
+__MATHCALL (asinh,, (_Mdouble_ __x));
+/* Hyperbolic arc tangent of X. */
+__MATHCALL (atanh,, (_Mdouble_ __x));
+__END_NAMESPACE_C99
+#endif
+
+/* Exponential and logarithmic functions. */
+
+_Mdouble_BEGIN_NAMESPACE
+/* Exponential function of X. */
+__MATHCALL (exp,, (_Mdouble_ __x));
+
+/* Break VALUE into a normalized fraction and an integral power of 2. */
+__MATHCALL (frexp,, (_Mdouble_ __x, int *__exponent));
+
+/* X times (two to the EXP power). */
+__MATHCALL (ldexp,, (_Mdouble_ __x, int __exponent));
+
+/* Natural logarithm of X. */
+__MATHCALL (log,, (_Mdouble_ __x));
+
+/* Base-ten logarithm of X. */
+__MATHCALL (log10,, (_Mdouble_ __x));
+
+/* Break VALUE into integral and fractional parts. */
+__MATHCALL (modf,, (_Mdouble_ __x, _Mdouble_ *__iptr));
+_Mdouble_END_NAMESPACE
+
+#ifdef __USE_GNU
+/* A function missing in all standards: compute exponent to base ten. */
+__MATHCALL (exp10,, (_Mdouble_ __x));
+/* Another name occasionally used. */
+__MATHCALL (pow10,, (_Mdouble_ __x));
+#endif
+
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Return exp(X) - 1. */
+__MATHCALL (expm1,, (_Mdouble_ __x));
+
+/* Return log(1 + X). */
+__MATHCALL (log1p,, (_Mdouble_ __x));
+
+/* Return the base 2 signed integral exponent of X. */
+__MATHCALL (logb,, (_Mdouble_ __x));
+__END_NAMESPACE_C99
+#endif
+
+#ifdef __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Compute base-2 exponential of X. */
+__MATHCALL (exp2,, (_Mdouble_ __x));
+
+/* Compute base-2 logarithm of X. */
+__MATHCALL (log2,, (_Mdouble_ __x));
+__END_NAMESPACE_C99
+#endif
+
+
+/* Power functions. */
+
+_Mdouble_BEGIN_NAMESPACE
+/* Return X to the Y power. */
+__MATHCALL (pow,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Return the square root of X. */
+__MATHCALL (sqrt,, (_Mdouble_ __x));
+_Mdouble_END_NAMESPACE
+
+#if defined __USE_MISC || defined __USE_XOPEN || defined __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Return `sqrt(X*X + Y*Y)'. */
+__MATHCALL (hypot,, (_Mdouble_ __x, _Mdouble_ __y));
+__END_NAMESPACE_C99
+#endif
+
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Return the cube root of X. */
+__MATHCALL (cbrt,, (_Mdouble_ __x));
+__END_NAMESPACE_C99
+#endif
+
+
+/* Nearest integer, absolute value, and remainder functions. */
+
+_Mdouble_BEGIN_NAMESPACE
+/* Smallest integral value not less than X. */
+__MATHCALLX (ceil,, (_Mdouble_ __x), (__const__));
+
+/* Absolute value of X. */
+__MATHCALLX (fabs,, (_Mdouble_ __x), (__const__));
+
+/* Largest integer not greater than X. */
+__MATHCALLX (floor,, (_Mdouble_ __x), (__const__));
+
+/* Floating-point modulo remainder of X/Y. */
+__MATHCALL (fmod,, (_Mdouble_ __x, _Mdouble_ __y));
+
+
+/* Return 0 if VALUE is finite or NaN, +1 if it
+ is +Infinity, -1 if it is -Infinity. */
+__MATHDECL_1 (int,__isinf,, (_Mdouble_ __value)) __attribute__ ((__const__));
+
+/* Return nonzero if VALUE is finite and not NaN. */
+__MATHDECL_1 (int,__finite,, (_Mdouble_ __value)) __attribute__ ((__const__));
+_Mdouble_END_NAMESPACE
+
+#ifdef __USE_MISC
+/* Return 0 if VALUE is finite or NaN, +1 if it
+ is +Infinity, -1 if it is -Infinity. */
+__MATHDECL_1 (int,isinf,, (_Mdouble_ __value)) __attribute__ ((__const__));
+
+/* Return nonzero if VALUE is finite and not NaN. */
+__MATHDECL_1 (int,finite,, (_Mdouble_ __value)) __attribute__ ((__const__));
+
+/* Return the remainder of X/Y. */
+__MATHCALL (drem,, (_Mdouble_ __x, _Mdouble_ __y));
+
+
+/* Return the fractional part of X after dividing out `ilogb (X)'. */
+__MATHCALL (significand,, (_Mdouble_ __x));
+#endif /* Use misc. */
+
+#if defined __USE_MISC || defined __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Return X with its signed changed to Y's. */
+__MATHCALLX (copysign,, (_Mdouble_ __x, _Mdouble_ __y), (__const__));
+__END_NAMESPACE_C99
+#endif
+
+#ifdef __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Return representation of NaN for double type. */
+__MATHCALLX (nan,, (__const char *__tagb), (__const__));
+__END_NAMESPACE_C99
+#endif
+
+
+/* Return nonzero if VALUE is not a number. */
+__MATHDECL_1 (int,__isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
+
+#if defined __USE_MISC || defined __USE_XOPEN
+/* Return nonzero if VALUE is not a number. */
+__MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
+
+/* Bessel functions. */
+__MATHCALL (j0,, (_Mdouble_));
+__MATHCALL (j1,, (_Mdouble_));
+__MATHCALL (jn,, (int, _Mdouble_));
+__MATHCALL (y0,, (_Mdouble_));
+__MATHCALL (y1,, (_Mdouble_));
+__MATHCALL (yn,, (int, _Mdouble_));
+#endif
+
+
+#if defined __USE_MISC || defined __USE_XOPEN || defined __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Error and gamma functions. */
+__MATHCALL (erf,, (_Mdouble_));
+__MATHCALL (erfc,, (_Mdouble_));
+__MATHCALL (lgamma,, (_Mdouble_));
+__END_NAMESPACE_C99
+#endif
+
+#ifdef __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* True gamma function. */
+__MATHCALL (tgamma,, (_Mdouble_));
+__END_NAMESPACE_C99
+#endif
+
+#if defined __USE_MISC || defined __USE_XOPEN
+/* Obsolete alias for `lgamma'. */
+__MATHCALL (gamma,, (_Mdouble_));
+#endif
+
+#ifdef __USE_MISC
+/* Reentrant version of lgamma. This function uses the global variable
+ `signgam'. The reentrant version instead takes a pointer and stores
+ the value through it. */
+__MATHCALL (lgamma,_r, (_Mdouble_, int *__signgamp));
+#endif
+
+
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Return the integer nearest X in the direction of the
+ prevailing rounding mode. */
+__MATHCALL (rint,, (_Mdouble_ __x));
+
+/* Return X + epsilon if X < Y, X - epsilon if X > Y. */
+__MATHCALLX (nextafter,, (_Mdouble_ __x, _Mdouble_ __y), (__const__));
+# if defined __STDC_WANT_DEC_FP__ && __USE_DEC_FP_NEXTTOWARD__
+__MATHCALLX (nexttoward,, (_Mdouble_ __x, _Decimal128 __y), (__const__));
+# elif defined __USE_ISOC99 && !defined __LDBL_COMPAT
+__MATHCALLX (nexttoward,, (_Mdouble_ __x, long double __y), (__const__));
+# endif
+
+/* Return the remainder of integer divison X / Y with infinite precision. */
+__MATHCALL (remainder,, (_Mdouble_ __x, _Mdouble_ __y));
+
+# if defined __USE_MISC || defined __USE_ISOC99
+/* Return X times (2 to the Nth power). */
+__MATHCALL (scalbn,, (_Mdouble_ __x, int __n));
+# endif
+
+/* Return the binary exponent of X, which must be nonzero. */
+__MATHDECL (int,ilogb,, (_Mdouble_ __x));
+#endif
+
+#ifdef __USE_ISOC99
+/* Return X times (2 to the Nth power). */
+__MATHCALL (scalbln,, (_Mdouble_ __x, long int __n));
+
+/* Round X to integral value in floating-point format using current
+ rounding direction, but do not raise inexact exception. */
+__MATHCALL (nearbyint,, (_Mdouble_ __x));
+
+/* Round X to nearest integral value, rounding halfway cases away from
+ zero. */
+__MATHCALLX (round,, (_Mdouble_ __x), (__const__));
+
+/* Round X to the integral value in floating-point format nearest but
+ not larger in magnitude. */
+__MATHCALLX (trunc,, (_Mdouble_ __x), (__const__));
+
+/* Compute remainder of X and Y and put in *QUO a value with sign of x/y
+ and magnitude congruent `mod 2^n' to the magnitude of the integral
+ quotient x/y, with n >= 3. */
+__MATHCALL (remquo,, (_Mdouble_ __x, _Mdouble_ __y, int *__quo));
+
+
+/* Conversion functions. */
+
+/* Round X to nearest integral value according to current rounding
+ direction. */
+__MATHDECL (long int,lrint,, (_Mdouble_ __x));
+__MATHDECL (long long int,llrint,, (_Mdouble_ __x));
+
+/* Round X to nearest integral value, rounding halfway cases away from
+ zero. */
+__MATHDECL (long int,lround,, (_Mdouble_ __x));
+__MATHDECL (long long int,llround,, (_Mdouble_ __x));
+
+
+/* Return positive difference between X and Y. */
+__MATHCALL (fdim,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Return maximum numeric value from X and Y. */
+__MATHCALL (fmax,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Return minimum numeric value from X and Y. */
+__MATHCALL (fmin,, (_Mdouble_ __x, _Mdouble_ __y));
+
+
+/* Classify given number. */
+__MATHDECL_1 (int, __fpclassify,, (_Mdouble_ __value))
+ __attribute__ ((__const__));
+
+/* Test for negative number. */
+__MATHDECL_1 (int, __signbit,, (_Mdouble_ __value))
+ __attribute__ ((__const__));
+
+
+/* Multiply-add function computed as a ternary operation. */
+__MATHCALL (fma,, (_Mdouble_ __x, _Mdouble_ __y, _Mdouble_ __z));
+#endif /* Use ISO C99. */
+
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+__END_NAMESPACE_C99
+#endif
+
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
+/* Return X times (2 to the Nth power). */
+__MATHCALL (scalb,, (_Mdouble_ __x, _Mdouble_ __n));
+#endif
diff --git a/libc/dfp/sysdeps/dfp/math/fenv.h b/libc/dfp/sysdeps/dfp/math/fenv.h
new file mode 100644
index 000000000..5e48ea4a5
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/math/fenv.h
@@ -0,0 +1,140 @@
+/* Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * ISO C99 7.6: Floating-point environment <fenv.h>
+ */
+
+#ifndef _FENV_H
+#define _FENV_H 1
+
+#include <features.h>
+
+/* Get the architecture dependend definitions. The following definitions
+ are expected to be done:
+
+ fenv_t type for object representing an entire floating-point
+ environment
+
+ FE_DFL_ENV macro of type pointer to fenv_t to be used as the argument
+ to functions taking an argument of type fenv_t; in this
+ case the default environment will be used
+
+ fexcept_t type for object representing the floating-point exception
+ flags including status associated with the flags
+
+ The following macros are defined iff the implementation supports this
+ kind of exception.
+ FE_INEXACT inexact result
+ FE_DIVBYZERO division by zero
+ FE_UNDERFLOW result not representable due to underflow
+ FE_OVERFLOW result not representable due to overflow
+ FE_INVALID invalid operation
+
+ FE_ALL_EXCEPT bitwise OR of all supported exceptions
+
+ The next macros are defined iff the appropriate rounding mode is
+ supported by the implementation.
+ FE_TONEAREST round to nearest
+ FE_UPWARD round toward +Inf
+ FE_DOWNWARD round toward -Inf
+ FE_TOWARDZERO round toward 0
+*/
+#include <bits/fenv.h>
+
+#ifdef __STDC_WANT_DEC_FP__
+# include <bits/dfpfenv.h>
+#endif
+
+__BEGIN_DECLS
+
+/* Floating-point exception handling. */
+
+/* Clear the supported exceptions represented by EXCEPTS. */
+extern int feclearexcept (int __excepts) __THROW;
+
+/* Store implementation-defined representation of the exception flags
+ indicated by EXCEPTS in the object pointed to by FLAGP. */
+extern int fegetexceptflag (fexcept_t *__flagp, int __excepts) __THROW;
+
+/* Raise the supported exceptions represented by EXCEPTS. */
+extern int feraiseexcept (int __excepts) __THROW;
+
+/* Set complete status for exceptions indicated by EXCEPTS according to
+ the representation in the object pointed to by FLAGP. */
+extern int fesetexceptflag (__const fexcept_t *__flagp, int __excepts) __THROW;
+
+/* Determine which of subset of the exceptions specified by EXCEPTS are
+ currently set. */
+extern int fetestexcept (int __excepts) __THROW;
+
+
+/* Rounding control. */
+
+/* Get current rounding direction. */
+extern int fegetround (void) __THROW;
+
+/* Establish the rounding direction represented by ROUND. */
+extern int fesetround (int __rounding_direction) __THROW;
+
+
+/* Floating-point environment. */
+
+/* Store the current floating-point environment in the object pointed
+ to by ENVP. */
+extern int fegetenv (fenv_t *__envp) __THROW;
+
+/* Save the current environment in the object pointed to by ENVP, clear
+ exception flags and install a non-stop mode (if available) for all
+ exceptions. */
+extern int feholdexcept (fenv_t *__envp) __THROW;
+
+/* Establish the floating-point environment represented by the object
+ pointed to by ENVP. */
+extern int fesetenv (__const fenv_t *__envp) __THROW;
+
+/* Save current exceptions in temporary storage, install environment
+ represented by object pointed to by ENVP and raise exceptions
+ according to saved exceptions. */
+extern int feupdateenv (__const fenv_t *__envp) __THROW;
+
+
+/* Include optimization. */
+#ifdef __OPTIMIZE__
+# include <bits/fenvinline.h>
+#endif
+
+#ifdef __USE_GNU
+
+/* Enable individual exceptions. Will not enable more exceptions than
+ EXCEPTS specifies. Returns the previous enabled exceptions if all
+ exceptions are successfully set, otherwise returns -1. */
+extern int feenableexcept (int __excepts) __THROW;
+
+/* Disable individual exceptions. Will not disable more exceptions than
+ EXCEPTS specifies. Returns the previous enabled exceptions if all
+ exceptions are successfully disabled, otherwise returns -1. */
+extern int fedisableexcept (int __excepts) __THROW;
+
+/* Return enabled exceptions. */
+extern int fegetexcept (void) __THROW;
+#endif
+
+__END_DECLS
+
+#endif /* fenv.h */
diff --git a/libc/dfp/sysdeps/dfp/math/math.h b/libc/dfp/sysdeps/dfp/math/math.h
new file mode 100644
index 000000000..d6d3651b3
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/math/math.h
@@ -0,0 +1,645 @@
+/* Declarations for math functions.
+ Copyright (C) 1991-1993, 1995-1999, 2001, 2002, 2004, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * ISO C99 Standard: 7.12 Mathematics <math.h>
+ */
+
+#ifndef _MATH_H
+#define _MATH_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Get machine-dependent HUGE_VAL value (returned on overflow).
+ On all IEEE754 machines, this is +Infinity. */
+#include <bits/huge_val.h>
+#ifdef __USE_ISOC99
+# include <bits/huge_valf.h>
+# include <bits/huge_vall.h>
+
+/* Get machine-dependent INFINITY value. */
+# include <bits/inf.h>
+
+/* Get machine-dependent NAN value (returned for some domain errors). */
+# include <bits/nan.h>
+#endif /* __USE_ISOC99 */
+
+/* Get general and ISO C99 specific information. */
+#include <bits/mathdef.h>
+
+/* The file <bits/mathcalls.h> contains the prototypes for all the
+ actual math functions. These macros are used for those prototypes,
+ so we can easily declare each function as both `name' and `__name',
+ and can declare the float versions `namef' and `__namef'. */
+
+#define __MATHCALL(function,suffix, args) \
+ __MATHDECL (_Mdouble_,function,suffix, args)
+#define __MATHDECL(type, function,suffix, args) \
+ __MATHDECL_1(type, function,suffix, args); \
+ __MATHDECL_1(type, __CONCAT(__,function),suffix, args)
+#define __MATHCALLX(function,suffix, args, attrib) \
+ __MATHDECLX (_Mdouble_,function,suffix, args, attrib)
+#define __MATHDECLX(type, function,suffix, args, attrib) \
+ __MATHDECL_1(type, function,suffix, args) __attribute__ (attrib); \
+ __MATHDECL_1(type, __CONCAT(__,function),suffix, args) __attribute__ (attrib)
+#define __MATHDECL_1(type, function,suffix, args) \
+ extern type __MATH_PRECNAME(function,suffix) args __THROW
+
+#ifdef __USE_DEC_FP_NEXTTOWARD__
+#undef __USE_DEC_FP_NEXTTOWARD__
+#endif
+
+#define _Mdouble_ double
+#define __MATH_PRECNAME(name,r) __CONCAT(name,r)
+# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_STD
+# define _Mdouble_END_NAMESPACE __END_NAMESPACE_STD
+#include <bits/mathcalls.h>
+#undef _Mdouble_
+#undef _Mdouble_BEGIN_NAMESPACE
+#undef _Mdouble_END_NAMESPACE
+#undef __MATH_PRECNAME
+
+/* Decimal-Floating point support is outlined in ISO proposed C-specification
+ WG14 N1176 and IEEE 754r. */
+#ifdef __STDC_WANT_DEC_FP__
+#define DEC_INFINITY __builtin_infd32()
+#define DEC_NAN (0.0DF * DEC_INFINITY)
+# define HUGE_VAL_D64 __builtin_infd64()
+/*# define DEC_INFINITY (9999999.E96DF + 1.E96df)
+#define DEC_NAN (0.0DF * DEC_INFINITY)
+# define HUGE_VAL_D64 (9.999999999999999E384DD + 1.E384dd) */
+# define HUGE_VAL_D32 HUGE_VAL_D64
+# define HUGE_VAL_D128 HUGE_VAL_D64
+
+/* this causes the nexttoward mathcall to get a _Decimal128 second parameter
+ * rather than a long double one. */
+#define __USE_DEC_FP_NEXTTOWARD__ 1
+
+#define __dfp_compatible(X) ((_Decimal128)(__typeof__(X))1.E-50DL == 1.E-50DL)
+
+/* For _Decimal32 */
+# ifndef _M_Decimal32_
+# define _M_Decimal32_ _Decimal32
+# endif
+# define _Mdouble_ _M_Decimal32_
+# ifdef __STDC__
+# define __MATH_PRECNAME(name,r) name##d32##r
+# else
+# define __MATH_PRECNAME(name,r) name/**/d32/**/r
+# endif
+# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99
+# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99
+# include <bits/mathcalls.h>
+# include <bits/dfpcalls.h>
+# undef _Mdouble_
+# undef _Mdouble_BEGIN_NAMESPACE
+# undef _Mdouble_END_NAMESPACE
+# undef __MATH_PRECNAME
+
+/* For _Decimal64 */
+# ifndef _M_Decimal64_
+# define _M_Decimal64_ _Decimal64
+# endif
+# define _Mdouble_ _M_Decimal64_
+# ifdef __STDC__
+# define __MATH_PRECNAME(name,r) name##d64##r
+# else
+# define __MATH_PRECNAME(name,r) name/**/d64/**/r
+# endif
+# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99
+# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99
+# include <bits/mathcalls.h>
+# include <bits/dfpcalls.h>
+# undef _Mdouble_
+# undef _Mdouble_BEGIN_NAMESPACE
+# undef _Mdouble_END_NAMESPACE
+# undef __MATH_PRECNAME
+
+/* For _Decimal128 */
+# ifndef _M_Decimal128_
+# define _M_Decimal128_ _Decimal128
+# endif
+# define _Mdouble_ _M_Decimal128_
+# ifdef __STDC__
+# define __MATH_PRECNAME(name,r) name##d128##r
+# else
+# define __MATH_PRECNAME(name,r) name/**/d128/**/r
+# endif
+# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99
+# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99
+# include <bits/mathcalls.h>
+# include <bits/dfpcalls.h>
+# undef _Mdouble_
+# undef _Mdouble_BEGIN_NAMESPACE
+# undef _Mdouble_END_NAMESPACE
+# undef __MATH_PRECNAME
+
+#endif /* __STDC_WANT_DEC_FP__ */
+
+#ifdef __USE_DEC_FP_NEXTTOWARD__
+#undef __USE_DEC_FP_NEXTTOWARD__
+#endif
+
+#if defined __USE_MISC || defined __USE_ISOC99
+
+
+/* Include the file of declarations again, this time using `float'
+ instead of `double' and appending f to each function name. */
+
+# ifndef _Mfloat_
+# define _Mfloat_ float
+# endif
+# define _Mdouble_ _Mfloat_
+# ifdef __STDC__
+# define __MATH_PRECNAME(name,r) name##f##r
+# else
+# define __MATH_PRECNAME(name,r) name/**/f/**/r
+# endif
+# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99
+# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99
+# include <bits/mathcalls.h>
+# undef _Mdouble_
+# undef _Mdouble_BEGIN_NAMESPACE
+# undef _Mdouble_END_NAMESPACE
+# undef __MATH_PRECNAME
+
+# if (__STDC__ - 0 || __GNUC__ - 0) \
+ && (!defined __NO_LONG_DOUBLE_MATH || defined __LDBL_COMPAT)
+# ifdef __LDBL_COMPAT
+
+# ifdef __USE_ISOC99
+extern float __nldbl_nexttowardf (float __x, long double __y)
+ __THROW __attribute__ ((__const__));
+# ifdef __REDIRECT_NTH
+extern float __REDIRECT_NTH (nexttowardf, (float __x, long double __y),
+ __nldbl_nexttowardf)
+ __attribute__ ((__const__));
+extern double __REDIRECT_NTH (nexttoward, (double __x, long double __y),
+ nextafter) __attribute__ ((__const__));
+extern long double __REDIRECT_NTH (nexttowardl,
+ (long double __x, long double __y),
+ nextafter) __attribute__ ((__const__));
+# endif
+# endif
+
+/* Include the file of declarations again, this time using `long double'
+ instead of `double' and appending l to each function name. */
+
+# undef __MATHDECL_1
+# define __MATHDECL_2(type, function,suffix, args, alias) \
+ extern type __REDIRECT_NTH(__MATH_PRECNAME(function,suffix), \
+ args, alias)
+# define __MATHDECL_1(type, function,suffix, args) \
+ __MATHDECL_2(type, function,suffix, args, __CONCAT(function,suffix))
+# endif
+
+# ifndef _Mlong_double_
+# define _Mlong_double_ long double
+# endif
+# define _Mdouble_ _Mlong_double_
+# ifdef __STDC__
+# define __MATH_PRECNAME(name,r) name##l##r
+# else
+# define __MATH_PRECNAME(name,r) name/**/l/**/r
+# endif
+# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_C99
+# define _Mdouble_END_NAMESPACE __END_NAMESPACE_C99
+# include <bits/mathcalls.h>
+# undef _Mdouble_
+# undef _Mdouble_BEGIN_NAMESPACE
+# undef _Mdouble_END_NAMESPACE
+# undef __MATH_PRECNAME
+
+# endif /* __STDC__ || __GNUC__ */
+
+#endif /* Use misc or ISO C99. */
+#undef __MATHDECL_1
+#undef __MATHDECL
+#undef __MATHCALL
+
+
+#if defined __USE_MISC || defined __USE_XOPEN
+/* This variable is used by `gamma' and `lgamma'. */
+extern int signgam;
+#endif
+
+
+/* ISO C99 defines some generic macros which work on any data type. */
+#ifdef __USE_ISOC99
+
+/* Get the architecture specific values describing the floating-point
+ evaluation. The following symbols will get defined:
+
+ float_t floating-point type at least as wide as `float' used
+ to evaluate `float' expressions
+ double_t floating-point type at least as wide as `double' used
+ to evaluate `double' expressions
+
+ FLT_EVAL_METHOD
+ Defined to
+ 0 if `float_t' is `float' and `double_t' is `double'
+ 1 if `float_t' and `double_t' are `double'
+ 2 if `float_t' and `double_t' are `long double'
+ else `float_t' and `double_t' are unspecified
+
+ INFINITY representation of the infinity value of type `float'
+
+ FP_FAST_FMA
+ FP_FAST_FMAF
+ FP_FAST_FMAL
+ If defined it indicates that the `fma' function
+ generally executes about as fast as a multiply and an add.
+ This macro is defined only iff the `fma' function is
+ implemented directly with a hardware multiply-add instructions.
+
+ FP_ILOGB0 Expands to a value returned by `ilogb (0.0)'.
+ FP_ILOGBNAN Expands to a value returned by `ilogb (NAN)'.
+
+ DECIMAL_DIG Number of decimal digits supported by conversion between
+ decimal and all internal floating-point formats.
+
+*/
+
+/* All decimal and binary floating-point numbers can be put in one of these
+ categories. */
+enum
+ {
+ FP_NAN,
+# define FP_NAN FP_NAN
+ FP_INFINITE,
+# define FP_INFINITE FP_INFINITE
+ FP_ZERO,
+# define FP_ZERO FP_ZERO
+ FP_SUBNORMAL,
+# define FP_SUBNORMAL FP_SUBNORMAL
+ FP_NORMAL
+# define FP_NORMAL FP_NORMAL
+ };
+
+/* Return number of classification appropriate for X. */
+# ifdef __NO_LONG_DOUBLE_MATH
+# define ____fpclassify(x) \
+ (sizeof (x) == sizeof (float) ? __fpclassifyf (x) : __fpclassify (x))
+# else
+# define ____fpclassify(x) \
+ (sizeof (x) == sizeof (float) \
+ ? __fpclassifyf (x) \
+ : sizeof (x) == sizeof (double) \
+ ? __fpclassify (x) : __fpclassifyl (x))
+# endif
+
+# ifdef __STDC_WANT_DEC_FP__
+# define fpclassify(x) \
+ ( \
+ (!__dfp_compatible(x)? (____fpclassify(x)) : \
+ (sizeof (x) == sizeof (_Decimal128)? __fpclassifyd128(x): \
+ (sizeof (x) == sizeof (_Decimal64)? __fpclassifyd64(x): \
+ __fpclassifyd32(x) \
+ ) \
+ ) \
+ ) \
+ )
+# else
+# define fpclassify(x) ____fpclassify(x)
+# endif
+
+/* Return nonzero value if sign of X is negative. */
+# ifdef __NO_LONG_DOUBLE_MATH
+# define ____signbit(x) \
+ (sizeof (x) == sizeof (float) ? __signbitf (x) : __signbit (x))
+# else
+# define ____signbit(x) \
+ (sizeof (x) == sizeof (float) \
+ ? __signbitf (x) \
+ : sizeof (x) == sizeof (double) \
+ ? __signbit (x) : __signbitl (x))
+# endif
+
+# ifdef __STDC_WANT_DEC_FP__
+# define signbit(x) \
+ ( \
+ (!__dfp_compatible(x)? (____signbit(x)) : \
+ (sizeof (x) == sizeof (_Decimal128)? __signbitd128(x): \
+ (sizeof (x) == sizeof (_Decimal64)? __signbitd64(x): \
+ __signbitd32(x) \
+ ) \
+ ) \
+ ) \
+ )
+# else
+# define signbit(x) ____signbit(x)
+# endif
+
+/* Return nonzero value if X is not +-Inf or NaN. */
+# ifdef __NO_LONG_DOUBLE_MATH
+# define ____isfinite(x) \
+ (sizeof (x) == sizeof (float) ? __finitef (x) : __finite (x))
+# else
+# define ____isfinite(x) \
+ (sizeof (x) == sizeof (float) \
+ ? __finitef (x) \
+ : sizeof (x) == sizeof (double) \
+ ? __finite (x) : __finitel (x))
+# endif
+
+# ifdef __STDC_WANT_DEC_FP__
+# define isfinite(x) \
+ ( \
+ (!__dfp_compatible(x)? (____isfinite(x)) : \
+ (sizeof (x) == sizeof (_Decimal128)? __finited128(x): \
+ (sizeof (x) == sizeof (_Decimal64)? __finited64(x): \
+ __finited32(x) \
+ ) \
+ ) \
+ ) \
+ )
+# else
+# define isfinite(x) ____isfinite(x)
+# endif
+
+/* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */
+# define isnormal(x) (fpclassify (x) == FP_NORMAL)
+
+/* Return nonzero value if X is a NaN. We could use `fpclassify' but
+ we already have this functions `__isnan' and it is faster. */
+# ifdef __NO_LONG_DOUBLE_MATH
+# define ____isnan(x) \
+ (sizeof (x) == sizeof (float) ? __isnanf (x) : __isnan (x))
+# else
+# define ____isnan(x) \
+ (sizeof (x) == sizeof (float) \
+ ? __isnanf (x) \
+ : sizeof (x) == sizeof (double) \
+ ? __isnan (x) : __isnanl (x))
+# endif
+
+# ifdef __STDC_WANT_DEC_FP__
+# define isnan(x) \
+ (!__dfp_compatible(x) \
+ ? (____isnan(x)) \
+ : (sizeof (x) == sizeof (_Decimal128) \
+ ? __isnand128(x) \
+ : (sizeof (x) == sizeof (_Decimal64) \
+ ? __isnand64(x) \
+ : __isnand32(x))) \
+ )
+# else
+# define isnan(x) ____isnan(x)
+# endif
+
+/* Return nonzero value is X is positive or negative infinity. */
+# ifdef __NO_LONG_DOUBLE_MATH
+# define _____isinf(x) \
+ (sizeof (x) == sizeof (float) ? __isinff (x) : __isinf (x))
+# else
+# define ____isinf(x) \
+ (sizeof (x) == sizeof (float) \
+ ? __isinff (x) \
+ : sizeof (x) == sizeof (double) \
+ ? __isinf (x) : __isinfl (x))
+# endif
+
+# ifdef __STDC_WANT_DEC_FP__
+# define isinf(x) \
+ ( \
+ (!__dfp_compatible(x)? (____isinf(x)) : \
+ (sizeof (x) == sizeof (_Decimal128)? __isinfd128(x): \
+ (sizeof (x) == sizeof (_Decimal64)? __isinfd64(x): \
+ __isinfd32(x) \
+ ) \
+ ) \
+ ) \
+ )
+# else
+# define isinf(x) ____isinf(x)
+# endif
+
+/* Bitmasks for the math_errhandling macro. */
+# define MATH_ERRNO 1 /* errno set by math functions. */
+# define MATH_ERREXCEPT 2 /* Exceptions raised by math functions. */
+
+#endif /* Use ISO C99. */
+
+#ifdef __USE_MISC
+/* Support for various different standard error handling behaviors. */
+typedef enum
+{
+ _IEEE_ = -1, /* According to IEEE 754/IEEE 854. */
+ _SVID_, /* According to System V, release 4. */
+ _XOPEN_, /* Nowadays also Unix98. */
+ _POSIX_,
+ _ISOC_ /* Actually this is ISO C99. */
+} _LIB_VERSION_TYPE;
+
+/* This variable can be changed at run-time to any of the values above to
+ affect floating point error handling behavior (it may also be necessary
+ to change the hardware FPU exception settings). */
+extern _LIB_VERSION_TYPE _LIB_VERSION;
+#endif
+
+
+#ifdef __USE_SVID
+/* In SVID error handling, `matherr' is called with this description
+ of the exceptional condition.
+
+ We have a problem when using C++ since `exception' is a reserved
+ name in C++. */
+# ifdef __cplusplus
+struct __exception
+# else
+struct exception
+# endif
+ {
+ int type;
+ char *name;
+ double arg1;
+ double arg2;
+ double retval;
+ };
+
+# ifdef __cplusplus
+extern int matherr (struct __exception *__exc) throw ();
+# else
+extern int matherr (struct exception *__exc);
+# endif
+
+# define X_TLOSS 1.41484755040568800000e+16
+
+/* Types of exceptions in the `type' field. */
+# define DOMAIN 1
+# define SING 2
+# define OVERFLOW 3
+# define UNDERFLOW 4
+# define TLOSS 5
+# define PLOSS 6
+
+/* SVID mode specifies returning this large value instead of infinity. */
+# define HUGE 3.40282347e+38F
+
+#else /* !SVID */
+
+# ifdef __USE_XOPEN
+/* X/Open wants another strange constant. */
+# define MAXFLOAT 3.40282347e+38F
+# endif
+
+#endif /* SVID */
+
+
+/* Some useful constants. */
+#if defined __USE_BSD || defined __USE_XOPEN
+# define M_E 2.7182818284590452354 /* e */
+# define M_LOG2E 1.4426950408889634074 /* log_2 e */
+# define M_LOG10E 0.43429448190325182765 /* log_10 e */
+# define M_LN2 0.69314718055994530942 /* log_e 2 */
+# define M_LN10 2.30258509299404568402 /* log_e 10 */
+# define M_PI 3.14159265358979323846 /* pi */
+# define M_PI_2 1.57079632679489661923 /* pi/2 */
+# define M_PI_4 0.78539816339744830962 /* pi/4 */
+# define M_1_PI 0.31830988618379067154 /* 1/pi */
+# define M_2_PI 0.63661977236758134308 /* 2/pi */
+# define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
+# define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+# define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+#endif
+
+/* The above constants are not adequate for computation using `long double's.
+ Therefore we provide as an extension constants with similar names as a
+ GNU extension. Provide enough digits for the 128-bit IEEE quad. */
+#ifdef __USE_GNU
+# define M_El 2.7182818284590452353602874713526625L /* e */
+# define M_LOG2El 1.4426950408889634073599246810018921L /* log_2 e */
+# define M_LOG10El 0.4342944819032518276511289189166051L /* log_10 e */
+# define M_LN2l 0.6931471805599453094172321214581766L /* log_e 2 */
+# define M_LN10l 2.3025850929940456840179914546843642L /* log_e 10 */
+# define M_PIl 3.1415926535897932384626433832795029L /* pi */
+# define M_PI_2l 1.5707963267948966192313216916397514L /* pi/2 */
+# define M_PI_4l 0.7853981633974483096156608458198757L /* pi/4 */
+# define M_1_PIl 0.3183098861837906715377675267450287L /* 1/pi */
+# define M_2_PIl 0.6366197723675813430755350534900574L /* 2/pi */
+# define M_2_SQRTPIl 1.1283791670955125738961589031215452L /* 2/sqrt(pi) */
+# define M_SQRT2l 1.4142135623730950488016887242096981L /* sqrt(2) */
+# define M_SQRT1_2l 0.7071067811865475244008443621048490L /* 1/sqrt(2) */
+#endif
+
+/* Some useful constants for DFP support (with the DL specifier). Proper
+ * truncation to DD and DF will be handled by libdfp. */
+#ifdef __STDC_WANT_DEC_FP__
+# define M_Edl 2.7182818284590452353602874713526625DL /* e */
+# define M_LOG2Edl 1.4426950408889634073599246810018921DL /* log_2 e */
+# define M_LOG10Edl 0.4342944819032518276511289189166051DL /* log_10 e */
+# define M_LN2dl 0.6931471805599453094172321214581766DL /* log_e 2 */
+# define M_LN10dl 2.3025850929940456840179914546843642DL /* log_e 10 */
+# define M_PIdl 3.1415926535897932384626433832795029DL /* pi */
+# define M_PI_2dl 1.5707963267948966192313216916397514DL /* pi/2 */
+# define M_PI_4dl 0.7853981633974483096156608458198757DL /* pi/4 */
+# define M_1_PIdl 0.3183098861837906715377675267450287DL /* 1/pi */
+# define M_2_PIdl 0.6366197723675813430755350534900574DL /* 2/pi */
+# define M_2_SQRTPIdl 1.1283791670955125738961589031215452DL /* 2/sqrt(pi) */
+# define M_SQRT2dl 1.4142135623730950488016887242096981DL /* sqrt(2) */
+# define M_SQRT1_2dl 0.7071067811865475244008443621048490DL /* 1/sqrt(2) */
+#endif /* __STDC_WANT_DEC_FP__ */
+
+/* When compiling in strict ISO C compatible mode we must not use the
+ inline functions since they, among other things, do not set the
+ `errno' variable correctly. */
+#if defined __STRICT_ANSI__ && !defined __NO_MATH_INLINES
+# define __NO_MATH_INLINES 1
+#endif
+
+#if defined __USE_ISOC99 && __GNUC_PREREQ(2,97)
+/* ISO C99 defines some macros to compare number while taking care for
+ unordered numbers. Many FPUs provide special instructions to support
+ these operations. Generic support in GCC for these as builtins went
+ in before 3.0.0, but not all cpus added their patterns. We define
+ versions that use the builtins here, and <bits/mathinline.h> will
+ undef/redefine as appropriate for the specific GCC version in use. */
+# define isgreater(x, y) __builtin_isgreater(x, y)
+# define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
+# define isless(x, y) __builtin_isless(x, y)
+# define islessequal(x, y) __builtin_islessequal(x, y)
+# define islessgreater(x, y) __builtin_islessgreater(x, y)
+# define isunordered(u, v) __builtin_isunordered(u, v)
+#endif
+
+/* Get machine-dependent inline versions (if there are any). */
+#ifdef __USE_EXTERN_INLINES
+# include <bits/mathinline.h>
+#endif
+
+#ifdef __USE_ISOC99
+/* If we've still got undefined comparison macros, provide defaults. */
+
+/* Return nonzero value if X is greater than Y. */
+# ifndef isgreater
+# define isgreater(x, y) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ !isunordered (__x, __y) && __x > __y; }))
+# endif
+
+/* Return nonzero value if X is greater than or equal to Y. */
+# ifndef isgreaterequal
+# define isgreaterequal(x, y) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ !isunordered (__x, __y) && __x >= __y; }))
+# endif
+
+/* Return nonzero value if X is less than Y. */
+# ifndef isless
+# define isless(x, y) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ !isunordered (__x, __y) && __x < __y; }))
+# endif
+
+/* Return nonzero value if X is less than or equal to Y. */
+# ifndef islessequal
+# define islessequal(x, y) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ !isunordered (__x, __y) && __x <= __y; }))
+# endif
+
+/* Return nonzero value if either X is less than Y or Y is less than X. */
+# ifndef islessgreater
+# define islessgreater(x, y) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ !isunordered (__x, __y) && (__x < __y || __y < __x); }))
+# endif
+
+/* Return nonzero value if arguments are unordered. */
+# ifndef isunordered
+# define isunordered(u, v) \
+ (__extension__ \
+ ({ __typeof__(u) __u = (u); __typeof__(v) __v = (v); \
+ fpclassify (__u) == FP_NAN || fpclassify (__v) == FP_NAN; }))
+# endif
+
+#endif
+
+__END_DECLS
+
+
+#endif /* math.h */
diff --git a/libc/dfp/sysdeps/dfp/printf_dfp.c b/libc/dfp/sysdeps/dfp/printf_dfp.c
new file mode 100644
index 000000000..669dd0813
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/printf_dfp.c
@@ -0,0 +1,120 @@
+/* Function definition to convert DFP values to strings
+
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ Contributed by IBM Corporation.
+ Based on GLIBC stdio-common/printf_fp.c by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "printf_dfp.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <libioP.h>
+
+#include <fmt_dfp.h>
+
+/* This defines make it possible to use the same code for GNU C library and
+ the GNU I/O library. */
+#define PUT(f, s, n) _IO_sputn (f, s, n)
+/* We use this file GNU C library and GNU I/O library. So make
+ names equal. */
+#undef putc
+#define putc(c, f) (wide \
+ ? (int)_IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f))
+#define size_t _IO_size_t
+#define FILE _IO_FILE
+
+/* Macros for doing the actual output. */
+
+#define outchar(ch) \
+ do \
+ { \
+ register const int outc = (ch); \
+ if (putc (outc, fp) == EOF) \
+ { \
+ if (buffer_malloced) \
+ free (wbuffer); \
+ return -1; \
+ } \
+ ++done; \
+ } while (0)
+
+#define PRINT(ptr, wptr, len) \
+ do \
+ { \
+ register size_t outlen = (len); \
+ if (len > 20) \
+ { \
+ if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen) \
+ { \
+ if (buffer_malloced) \
+ free (wbuffer); \
+ return -1; \
+ } \
+ ptr += outlen; \
+ done += outlen; \
+ } \
+ else \
+ { \
+ if (wide) \
+ while (outlen-- > 0) \
+ outchar (*wptr++); \
+ else \
+ while (outlen-- > 0) \
+ outchar (*ptr++); \
+ } \
+ } while (0)
+
+#define DECIMAL_PRINTF_BUF_SIZE 65 /* ((DECIMAL128_PMAX + 14) * 2) + 1 */
+/* TODO: add wide character support */
+
+int
+__printf_dfp (FILE *fp,
+ const struct printf_info *info,
+ const void *const *args)
+{
+ char str[DECIMAL_PRINTF_BUF_SIZE];
+ const char *str_ptr = str;
+
+ int wide = info->wide;
+ wchar_t *wbuffer = NULL;
+ int buffer_malloced = 0; /* PRINT macro uses this. */
+ /* Counter for number of written characters. */
+ int done = 0;
+ int len = 0;
+
+ if (info->is_short) /* %H */
+ {
+ __fmt_d32 (info, args, str, DECIMAL_PRINTF_BUF_SIZE);
+ }
+ else if (info->is_long_double) /* %DD */
+ {
+ __fmt_d128 (info, args, str, DECIMAL_PRINTF_BUF_SIZE);
+ }
+ else /* %D */
+ {
+ __fmt_d64 (info, args, str, DECIMAL_PRINTF_BUF_SIZE);
+ }
+ len=strlen(str);
+ PRINT(str_ptr, wbuffer, len);
+
+ return 0;
+}
+libc_hidden_def (__printf_dfp)
diff --git a/libc/dfp/sysdeps/dfp/printf_dfp.h b/libc/dfp/sysdeps/dfp/printf_dfp.h
new file mode 100644
index 000000000..bd682a89a
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/printf_dfp.h
@@ -0,0 +1,35 @@
+/* Function prototypes to convert DFP values to strings
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _PRINTF_DFP_H
+
+#define _PRINTF_DFP_H 1
+#include <printf.h>
+/* Internal interfaces for formatting DFP. */
+extern int __printf_dfphex (FILE *, const struct printf_info *,
+ const void *const *);
+extern int __printf_dfp (FILE *, const struct printf_info *,
+ const void *const *);
+libc_hidden_proto (__printf_dfp)
+
+#endif
+
diff --git a/libc/dfp/sysdeps/dfp/printf_dfphex.c b/libc/dfp/sysdeps/dfp/printf_dfphex.c
new file mode 100644
index 000000000..56ee8c9a7
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/printf_dfphex.c
@@ -0,0 +1,37 @@
+/* Function body to print DFP values in hex
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+/* The gmp headers need some configuration frobs. */
+/* #define HAVE_ALLOCA 1 */
+
+#include "printf_dfp.h"
+#include <unistd.h>
+
+int
+__printf_dfphex (FILE *fp,
+ const struct printf_info *info,
+ const void *const *args)
+{
+ write (1, "in __printf_dfphex\n", 19);
+ return 0;
+}
+/* libc_hidden_def (__printf_dfphex) */
diff --git a/libc/dfp/sysdeps/dfp/stdio-common/printf-parse.h b/libc/dfp/sysdeps/dfp/stdio-common/printf-parse.h
new file mode 100644
index 000000000..372969578
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdio-common/printf-parse.h
@@ -0,0 +1,109 @@
+/* Internal header for parsing printf format strings.
+ Copyright (C) 1995-1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of th GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <printf.h>
+#include <stdint.h>
+#include <stddef.h>
+
+struct printf_spec
+ {
+ /* Information parsed from the format spec. */
+ struct printf_info info;
+
+ /* Pointers into the format string for the end of this format
+ spec and the next (or to the end of the string if no more). */
+ const UCHAR_T *end_of_fmt, *next_fmt;
+
+ /* Position of arguments for precision and width, or -1 if `info' has
+ the constant value. */
+ int prec_arg, width_arg;
+
+ int data_arg; /* Position of data argument. */
+ int data_arg_type; /* Type of first argument. */
+ /* Number of arguments consumed by this format specifier. */
+ size_t ndata_args;
+ };
+
+/* The various kinds of arguments that can be passed to printf. */
+union printf_arg
+ {
+ wchar_t pa_wchar;
+ int pa_int;
+ long int pa_long_int;
+ long long int pa_long_long_int;
+ unsigned int pa_u_int;
+ unsigned long int pa_u_long_int;
+ unsigned long long int pa_u_long_long_int;
+ double pa_double;
+ long double pa_long_double;
+ const char *pa_string;
+ const wchar_t *pa_wstring;
+ void *pa_pointer;
+ _Decimal128 pa_decimal128;
+ _Decimal64 pa_decimal64;
+ _Decimal32 pa_decimal32;
+ };
+
+
+#ifndef DONT_NEED_READ_INT
+/* Read a simple integer from a string and update the string pointer.
+ It is assumed that the first character is a digit. */
+static unsigned int
+read_int (const UCHAR_T * *pstr)
+{
+ unsigned int retval = **pstr - L_('0');
+
+ while (ISDIGIT (*++(*pstr)))
+ {
+ retval *= 10;
+ retval += **pstr - L_('0');
+ }
+
+ return retval;
+}
+#endif
+
+
+/* These are defined in reg-printf.c. */
+extern printf_arginfo_function **__printf_arginfo_table attribute_hidden;
+extern printf_function **__printf_function_table attribute_hidden;
+
+
+/* Find the next spec in FORMAT, or the end of the string. Returns
+ a pointer into FORMAT, to a '%' or a '\0'. */
+extern const unsigned char *__find_specmb (const UCHAR_T *format,
+ mbstate_t *ps) attribute_hidden;
+
+extern const unsigned int *__find_specwc (const UCHAR_T *format)
+ attribute_hidden;
+
+
+/* FORMAT must point to a '%' at the beginning of a spec. Fills in *SPEC
+ with the parsed details. POSN is the number of arguments already
+ consumed. At most MAXTYPES - POSN types are filled in TYPES. Return
+ the number of args consumed by this spec; *MAX_REF_ARG is updated so it
+ remains the highest argument index used. */
+extern size_t __parse_one_specmb (const unsigned char *format, size_t posn,
+ struct printf_spec *spec,
+ size_t *max_ref_arg, mbstate_t *ps)
+ attribute_hidden;
+
+extern size_t __parse_one_specwc (const unsigned int *format, size_t posn,
+ struct printf_spec *spec,
+ size_t *max_ref_arg) attribute_hidden;
diff --git a/libc/dfp/sysdeps/dfp/stdio-common/printf.h b/libc/dfp/sysdeps/dfp/stdio-common/printf.h
new file mode 100644
index 000000000..6c4a66cd9
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdio-common/printf.h
@@ -0,0 +1,149 @@
+/* Copyright (C) 1991-1993,1995-1999,2000,2001,2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _PRINTF_H
+
+#define _PRINTF_H 1
+#include <features.h>
+
+__BEGIN_DECLS
+
+#define __need_FILE
+#include <stdio.h>
+#define __need_size_t
+#define __need_wchar_t
+#include <stddef.h>
+
+
+struct printf_info
+{
+ int prec; /* Precision. */
+ int width; /* Width. */
+ wchar_t spec; /* Format letter. */
+ unsigned int is_long_double:1;/* L flag. */
+ unsigned int is_short:1; /* h flag. */
+ unsigned int is_long:1; /* l flag. */
+ unsigned int alt:1; /* # flag. */
+ unsigned int space:1; /* Space flag. */
+ unsigned int left:1; /* - flag. */
+ unsigned int showsign:1; /* + flag. */
+ unsigned int group:1; /* ' flag. */
+ unsigned int extra:1; /* For special use. */
+ unsigned int is_char:1; /* hh flag. */
+ unsigned int wide:1; /* Nonzero for wide character streams. */
+ unsigned int i18n:1; /* I flag. */
+ unsigned int is_decimal:1; /* H/D/DD flags. */
+ wchar_t pad; /* Padding character. */
+};
+
+
+/* Type of a printf specifier-handler function.
+ STREAM is the FILE on which to write output.
+ INFO gives information about the format specification.
+ ARGS is a vector of pointers to the argument data;
+ the number of pointers will be the number returned
+ by the associated arginfo function for the same INFO.
+
+ The function should return the number of characters written,
+ or -1 for errors. */
+
+typedef int printf_function (FILE *__stream,
+ __const struct printf_info *__info,
+ __const void *__const *__args);
+
+/* Type of a printf specifier-arginfo function.
+ INFO gives information about the format specification.
+ N, ARGTYPES, and return value are as for parse_printf_format. */
+
+typedef int printf_arginfo_function (__const struct printf_info *__info,
+ size_t __n, int *__argtypes);
+
+
+/* Register FUNC to be called to format SPEC specifiers; ARGINFO must be
+ specified to determine how many arguments a SPEC conversion requires and
+ what their types are. */
+
+extern int register_printf_function (int __spec, printf_function __func,
+ printf_arginfo_function __arginfo);
+
+
+/* Parse FMT, and fill in N elements of ARGTYPES with the
+ types needed for the conversions FMT specifies. Returns
+ the number of arguments required by FMT.
+
+ The ARGINFO function registered with a user-defined format is passed a
+ `struct printf_info' describing the format spec being parsed. A width
+ or precision of INT_MIN means a `*' was used to indicate that the
+ width/precision will come from an arg. The function should fill in the
+ array it is passed with the types of the arguments it wants, and return
+ the number of arguments it wants. */
+
+extern size_t parse_printf_format (__const char *__restrict __fmt, size_t __n,
+ int *__restrict __argtypes) __THROW;
+
+
+/* Codes returned by `parse_printf_format' for basic types.
+
+ These values cover all the standard format specifications.
+ Users can add new values after PA_LAST for their own types. */
+
+enum
+{ /* C type: */
+ PA_INT, /* int */
+ PA_CHAR, /* int, cast to char */
+ PA_WCHAR, /* wide char */
+ PA_STRING, /* const char *, a '\0'-terminated string */
+ PA_WSTRING, /* const wchar_t *, wide character string */
+ PA_POINTER, /* void * */
+ PA_FLOAT, /* float */
+ PA_DOUBLE, /* double */
+ PA_DECIMAL, /* _Decimal* types */
+ PA_LAST
+};
+
+/* Flag bits that can be set in a type returned by `parse_printf_format'. */
+#define PA_FLAG_MASK 0xff00
+#define PA_FLAG_LONG_LONG (1 << 8)
+#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
+#define PA_FLAG_LONG (1 << 9)
+#define PA_FLAG_SHORT (1 << 10)
+#define PA_FLAG_PTR (1 << 11)
+
+/* Function which can be registered as `printf'-handlers. */
+
+/* Print floating point value using using abbreviations for the orders
+ of magnitude used for numbers ('k' for kilo, 'm' for mega etc). If
+ the format specifier is a uppercase character powers of 1000 are
+ used. Otherwise powers of 1024. */
+extern int printf_size (FILE *__restrict __fp,
+ __const struct printf_info *__info,
+ __const void *__const *__restrict __args) __THROW;
+
+/* This is the appropriate argument information function for `printf_size'. */
+extern int printf_size_info (__const struct printf_info *__restrict
+ __info, size_t __n, int *__restrict __argtypes)
+ __THROW;
+
+#ifdef __LDBL_COMPAT
+# include <bits/printf-ldbl.h>
+#endif
+
+__END_DECLS
+
+#endif /* printf.h */
diff --git a/libc/dfp/sysdeps/dfp/stdio-common/vfprintf.c b/libc/dfp/sysdeps/dfp/stdio-common/vfprintf.c
new file mode 100644
index 000000000..7b6541c13
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdio-common/vfprintf.c
@@ -0,0 +1,2307 @@
+/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <ctype.h>
+#include <limits.h>
+#include <printf.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <wchar.h>
+#include <bits/libc-lock.h>
+#include <sys/param.h>
+#include "_itoa.h"
+#include <locale/localeinfo.h>
+#include <stdio.h>
+#include <printf_dfp.h>
+
+/* This code is shared between the standard stdio implementation found
+ in GNU C library and the libio implementation originally found in
+ GNU libg++.
+
+ Beside this it is also shared between the normal and wide character
+ implementation as defined in ISO/IEC 9899:1990/Amendment 1:1995. */
+
+
+#include <libioP.h>
+#define FILE _IO_FILE
+#undef va_list
+#define va_list _IO_va_list
+#undef BUFSIZ
+#define BUFSIZ _IO_BUFSIZ
+#define ARGCHECK(S, Format) \
+ do \
+ { \
+ /* Check file argument for consistence. */ \
+ CHECK_FILE (S, -1); \
+ if (S->_flags & _IO_NO_WRITES) \
+ { \
+ __set_errno (EBADF); \
+ return -1; \
+ } \
+ if (Format == NULL) \
+ { \
+ MAYBE_SET_EINVAL; \
+ return -1; \
+ } \
+ } while (0)
+#define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED)
+
+#ifndef COMPILE_WPRINTF
+# define vfprintf _IO_vfprintf_internal
+# define CHAR_T char
+# define UCHAR_T unsigned char
+# define INT_T int
+# define L_(Str) Str
+# define ISDIGIT(Ch) ((unsigned int) ((Ch) - '0') < 10)
+# define STR_LEN(Str) strlen (Str)
+
+# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
+# define PAD(Padchar) \
+ if (width > 0) \
+ done += INTUSE(_IO_padn) (s, (Padchar), width)
+# define PUTC(C, F) _IO_putc_unlocked (C, F)
+# define ORIENT if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\
+ return -1
+#else
+# define vfprintf _IO_vfwprintf
+# define CHAR_T wchar_t
+/* This is a hack!!! There should be a type uwchar_t. */
+# define UCHAR_T unsigned int /* uwchar_t */
+# define INT_T wint_t
+# define L_(Str) L##Str
+# define ISDIGIT(Ch) ((unsigned int) ((Ch) - L'0') < 10)
+# define STR_LEN(Str) __wcslen (Str)
+
+# include "_itowa.h"
+
+# define PUT(F, S, N) _IO_sputn ((F), (S), (N))
+# define PAD(Padchar) \
+ if (width > 0) \
+ done += _IO_wpadn (s, (Padchar), width)
+# define PUTC(C, F) _IO_putwc_unlocked (C, F)
+# define ORIENT if (_IO_fwide (s, 1) != 1) return -1
+
+# define _itoa(Val, Buf, Base, Case) _itowa (Val, Buf, Base, Case)
+# define _itoa_word(Val, Buf, Base, Case) _itowa_word (Val, Buf, Base, Case)
+# undef EOF
+# define EOF WEOF
+#endif
+
+#include "_i18n_number.h"
+
+/* Include the shared code for parsing the format string. */
+/*#include "printf-parse.h" */
+#include <printf-parse.h>
+
+
+#define outchar(Ch) \
+ do \
+ { \
+ register const INT_T outc = (Ch); \
+ if (PUTC (outc, s) == EOF) \
+ { \
+ done = -1; \
+ goto all_done; \
+ } \
+ else \
+ ++done; \
+ } \
+ while (0)
+
+#define outstring(String, Len) \
+ do \
+ { \
+ if ((size_t) PUT (s, (String), (Len)) != (size_t) (Len)) \
+ { \
+ done = -1; \
+ goto all_done; \
+ } \
+ done += (Len); \
+ } \
+ while (0)
+
+/* For handling long_double and longlong we use the same flag. If
+ `long' and `long long' are effectively the same type define it to
+ zero. */
+#if LONG_MAX == LONG_LONG_MAX
+# define is_longlong 0
+#else
+# define is_longlong is_long_double
+#endif
+
+/* If `long' and `int' is effectively the same type we don't have to
+ handle `long separately. */
+#if INT_MAX == LONG_MAX
+# define is_long_num 0
+#else
+# define is_long_num is_long
+#endif
+
+
+/* Global variables. */
+static const CHAR_T null[] = L_("(null)");
+
+
+/* Helper function to provide temporary buffering for unbuffered streams. */
+static int buffered_vfprintf (FILE *stream, const CHAR_T *fmt, va_list)
+ __THROW __attribute__ ((noinline)) internal_function;
+
+/* Handle unknown format specifier. */
+static int printf_unknown (FILE *, const struct printf_info *,
+ const void *const *) __THROW;
+
+/* Group digits of number string. */
+#ifdef COMPILE_WPRINTF
+static CHAR_T *group_number (CHAR_T *, CHAR_T *, const char *, wchar_t)
+ __THROW internal_function;
+#else
+static CHAR_T *group_number (CHAR_T *, CHAR_T *, const char *, const char *)
+ __THROW internal_function;
+#endif
+
+
+/* The function itself. */
+int
+vfprintf (FILE *s, const CHAR_T *format, va_list ap)
+{
+ /* The character used as thousands separator. */
+#ifdef COMPILE_WPRINTF
+ wchar_t thousands_sep = L'\0';
+#else
+ const char *thousands_sep = NULL;
+#endif
+
+ /* The string describing the size of groups of digits. */
+ const char *grouping;
+
+ /* Place to accumulate the result. */
+ int done;
+
+ /* Current character in format string. */
+ const UCHAR_T *f;
+
+ /* End of leading constant string. */
+ const UCHAR_T *lead_str_end;
+
+ /* Points to next format specifier. */
+ const UCHAR_T *end_of_spec;
+
+ /* Buffer intermediate results. */
+ CHAR_T work_buffer[1000];
+ CHAR_T *workstart = NULL;
+ CHAR_T *workend;
+
+ /* State for restartable multibyte character handling functions. */
+#ifndef COMPILE_WPRINTF
+ mbstate_t mbstate;
+#endif
+
+ /* We have to save the original argument pointer. */
+ va_list ap_save;
+
+ /* Count number of specifiers we already processed. */
+ int nspecs_done;
+
+ /* For the %m format we may need the current `errno' value. */
+ int save_errno = errno;
+
+ /* 1 if format is in read-only memory, -1 if it is in writable memory,
+ 0 if unknown. */
+ int readonly_format = 0;
+
+ /* This table maps a character into a number representing a
+ class. In each step there is a destination label for each
+ class. */
+ static const int jump_table[] =
+ {
+ /* ' ' */ 1, 0, 0, /* '#' */ 4,
+ 0, /* '%' */ 14, 0, /* '\''*/ 6,
+ 0, 0, /* '*' */ 7, /* '+' */ 2,
+ 0, /* '-' */ 3, /* '.' */ 9, 0,
+ /* '0' */ 5, /* '1' */ 8, /* '2' */ 8, /* '3' */ 8,
+ /* '4' */ 8, /* '5' */ 8, /* '6' */ 8, /* '7' */ 8,
+ /* '8' */ 8, /* '9' */ 8, 0, 0,
+ 0, 0, 0, 0,
+ 0, /* 'A' */ 26, 0, /* 'C' */ 25,
+ /* 'D' */ 31, /* 'E' */ 19, /* F */ 19, /* 'G' */ 19,
+ /* 'H' */ 30, /* 'I' */ 29, 0, 0,
+ /* 'L' */ 12, 0, 0, 0,
+ 0, 0, 0, /* 'S' */ 21,
+ 0, 0, 0, 0,
+ /* 'X' */ 18, 0, /* 'Z' */ 13, 0,
+ 0, 0, 0, 0,
+ 0, /* 'a' */ 26, 0, /* 'c' */ 20,
+ /* 'd' */ 15, /* 'e' */ 19, /* 'f' */ 19, /* 'g' */ 19,
+ /* 'h' */ 10, /* 'i' */ 15, /* 'j' */ 28, 0,
+ /* 'l' */ 11, /* 'm' */ 24, /* 'n' */ 23, /* 'o' */ 17,
+ /* 'p' */ 22, /* 'q' */ 12, 0, /* 's' */ 21,
+ /* 't' */ 27, /* 'u' */ 16, 0, 0,
+ /* 'x' */ 18, 0, /* 'z' */ 13
+ };
+
+#define NOT_IN_JUMP_RANGE(Ch) ((Ch) < L_(' ') || (Ch) > L_('z'))
+#define CHAR_CLASS(Ch) (jump_table[(INT_T) (Ch) - L_(' ')])
+#ifdef SHARED
+ /* 'int' is enough and it saves some space on 64 bit systems. */
+# define JUMP_TABLE_TYPE const int
+# define JUMP(ChExpr, table) \
+ do \
+ { \
+ int offset; \
+ void *__unbounded ptr; \
+ spec = (ChExpr); \
+ offset = NOT_IN_JUMP_RANGE (spec) ? REF (form_unknown) \
+ : table[CHAR_CLASS (spec)]; \
+ ptr = &&do_form_unknown + offset; \
+ goto *ptr; \
+ } \
+ while (0)
+#else
+# define JUMP_TABLE_TYPE const void *const
+# define JUMP(ChExpr, table) \
+ do \
+ { \
+ const void *__unbounded ptr; \
+ spec = (ChExpr); \
+ ptr = NOT_IN_JUMP_RANGE (spec) ? REF (form_unknown) \
+ : table[CHAR_CLASS (spec)]; \
+ goto *ptr; \
+ } \
+ while (0)
+#endif
+
+#define STEP0_3_TABLE \
+ /* Step 0: at the beginning. */ \
+ static JUMP_TABLE_TYPE step0_jumps[32] = \
+ { \
+ REF (form_unknown), \
+ REF (flag_space), /* for ' ' */ \
+ REF (flag_plus), /* for '+' */ \
+ REF (flag_minus), /* for '-' */ \
+ REF (flag_hash), /* for '<hash>' */ \
+ REF (flag_zero), /* for '0' */ \
+ REF (flag_quote), /* for '\'' */ \
+ REF (width_asterics), /* for '*' */ \
+ REF (width), /* for '1'...'9' */ \
+ REF (precision), /* for '.' */ \
+ REF (mod_half), /* for 'h' */ \
+ REF (mod_long), /* for 'l' */ \
+ REF (mod_longlong), /* for 'L', 'q' */ \
+ REF (mod_size_t), /* for 'z', 'Z' */ \
+ REF (form_percent), /* for '%' */ \
+ REF (form_integer), /* for 'd', 'i' */ \
+ REF (form_unsigned), /* for 'u' */ \
+ REF (form_octal), /* for 'o' */ \
+ REF (form_hexa), /* for 'X', 'x' */ \
+ REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \
+ REF (form_character), /* for 'c' */ \
+ REF (form_string), /* for 's', 'S' */ \
+ REF (form_pointer), /* for 'p' */ \
+ REF (form_number), /* for 'n' */ \
+ REF (form_strerror), /* for 'm' */ \
+ REF (form_wcharacter), /* for 'C' */ \
+ REF (form_floathex), /* for 'A', 'a' */ \
+ REF (mod_ptrdiff_t), /* for 't' */ \
+ REF (mod_intmax_t), /* for 'j' */ \
+ REF (flag_i18n), /* for 'I' */ \
+ REF (mod_decimal_half), /* for 'H' */ \
+ REF (mod_decimal), /* for 'D' */ \
+ }; \
+ /* Step 1: after processing width. */ \
+ static JUMP_TABLE_TYPE step1_jumps[32] = \
+ { \
+ REF (form_unknown), \
+ REF (form_unknown), /* for ' ' */ \
+ REF (form_unknown), /* for '+' */ \
+ REF (form_unknown), /* for '-' */ \
+ REF (form_unknown), /* for '<hash>' */ \
+ REF (form_unknown), /* for '0' */ \
+ REF (form_unknown), /* for '\'' */ \
+ REF (form_unknown), /* for '*' */ \
+ REF (form_unknown), /* for '1'...'9' */ \
+ REF (precision), /* for '.' */ \
+ REF (mod_half), /* for 'h' */ \
+ REF (mod_long), /* for 'l' */ \
+ REF (mod_longlong), /* for 'L', 'q' */ \
+ REF (mod_size_t), /* for 'z', 'Z' */ \
+ REF (form_percent), /* for '%' */ \
+ REF (form_integer), /* for 'd', 'i' */ \
+ REF (form_unsigned), /* for 'u' */ \
+ REF (form_octal), /* for 'o' */ \
+ REF (form_hexa), /* for 'X', 'x' */ \
+ REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \
+ REF (form_character), /* for 'c' */ \
+ REF (form_string), /* for 's', 'S' */ \
+ REF (form_pointer), /* for 'p' */ \
+ REF (form_number), /* for 'n' */ \
+ REF (form_strerror), /* for 'm' */ \
+ REF (form_wcharacter), /* for 'C' */ \
+ REF (form_floathex), /* for 'A', 'a' */ \
+ REF (mod_ptrdiff_t), /* for 't' */ \
+ REF (mod_intmax_t), /* for 'j' */ \
+ REF (form_unknown), /* for 'I' */ \
+ REF (mod_decimal_half), /* for 'H' */ \
+ REF (mod_decimal) /* for 'D' */ \
+ }; \
+ /* Step 2: after processing precision. */ \
+ static JUMP_TABLE_TYPE step2_jumps[32] = \
+ { \
+ REF (form_unknown), \
+ REF (form_unknown), /* for ' ' */ \
+ REF (form_unknown), /* for '+' */ \
+ REF (form_unknown), /* for '-' */ \
+ REF (form_unknown), /* for '<hash>' */ \
+ REF (form_unknown), /* for '0' */ \
+ REF (form_unknown), /* for '\'' */ \
+ REF (form_unknown), /* for '*' */ \
+ REF (form_unknown), /* for '1'...'9' */ \
+ REF (form_unknown), /* for '.' */ \
+ REF (mod_half), /* for 'h' */ \
+ REF (mod_long), /* for 'l' */ \
+ REF (mod_longlong), /* for 'L', 'q' */ \
+ REF (mod_size_t), /* for 'z', 'Z' */ \
+ REF (form_percent), /* for '%' */ \
+ REF (form_integer), /* for 'd', 'i' */ \
+ REF (form_unsigned), /* for 'u' */ \
+ REF (form_octal), /* for 'o' */ \
+ REF (form_hexa), /* for 'X', 'x' */ \
+ REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \
+ REF (form_character), /* for 'c' */ \
+ REF (form_string), /* for 's', 'S' */ \
+ REF (form_pointer), /* for 'p' */ \
+ REF (form_number), /* for 'n' */ \
+ REF (form_strerror), /* for 'm' */ \
+ REF (form_wcharacter), /* for 'C' */ \
+ REF (form_floathex), /* for 'A', 'a' */ \
+ REF (mod_ptrdiff_t), /* for 't' */ \
+ REF (mod_intmax_t), /* for 'j' */ \
+ REF (form_unknown), /* for 'I' */ \
+ REF (mod_decimal_half), /* for 'H' */ \
+ REF (mod_decimal) /* for 'D' */ \
+ }; \
+ /* Step 3a: after processing first 'h' modifier. */ \
+ static JUMP_TABLE_TYPE step3a_jumps[32] = \
+ { \
+ REF (form_unknown), \
+ REF (form_unknown), /* for ' ' */ \
+ REF (form_unknown), /* for '+' */ \
+ REF (form_unknown), /* for '-' */ \
+ REF (form_unknown), /* for '<hash>' */ \
+ REF (form_unknown), /* for '0' */ \
+ REF (form_unknown), /* for '\'' */ \
+ REF (form_unknown), /* for '*' */ \
+ REF (form_unknown), /* for '1'...'9' */ \
+ REF (form_unknown), /* for '.' */ \
+ REF (mod_halfhalf), /* for 'h' */ \
+ REF (form_unknown), /* for 'l' */ \
+ REF (form_unknown), /* for 'L', 'q' */ \
+ REF (form_unknown), /* for 'z', 'Z' */ \
+ REF (form_percent), /* for '%' */ \
+ REF (form_integer), /* for 'd', 'i' */ \
+ REF (form_unsigned), /* for 'u' */ \
+ REF (form_octal), /* for 'o' */ \
+ REF (form_hexa), /* for 'X', 'x' */ \
+ REF (form_unknown), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \
+ REF (form_unknown), /* for 'c' */ \
+ REF (form_unknown), /* for 's', 'S' */ \
+ REF (form_unknown), /* for 'p' */ \
+ REF (form_number), /* for 'n' */ \
+ REF (form_unknown), /* for 'm' */ \
+ REF (form_unknown), /* for 'C' */ \
+ REF (form_unknown), /* for 'A', 'a' */ \
+ REF (form_unknown), /* for 't' */ \
+ REF (form_unknown), /* for 'j' */ \
+ REF (form_unknown), /* for 'I' */ \
+ REF (form_unknown), /* for 'H' */ \
+ REF (form_unknown) /* for 'D' */ \
+ }; \
+ /* Step 3b: after processing first 'l' modifier. */ \
+ static JUMP_TABLE_TYPE step3b_jumps[32] = \
+ { \
+ REF (form_unknown), \
+ REF (form_unknown), /* for ' ' */ \
+ REF (form_unknown), /* for '+' */ \
+ REF (form_unknown), /* for '-' */ \
+ REF (form_unknown), /* for '<hash>' */ \
+ REF (form_unknown), /* for '0' */ \
+ REF (form_unknown), /* for '\'' */ \
+ REF (form_unknown), /* for '*' */ \
+ REF (form_unknown), /* for '1'...'9' */ \
+ REF (form_unknown), /* for '.' */ \
+ REF (form_unknown), /* for 'h' */ \
+ REF (mod_longlong), /* for 'l' */ \
+ REF (form_unknown), /* for 'L', 'q' */ \
+ REF (form_unknown), /* for 'z', 'Z' */ \
+ REF (form_percent), /* for '%' */ \
+ REF (form_integer), /* for 'd', 'i' */ \
+ REF (form_unsigned), /* for 'u' */ \
+ REF (form_octal), /* for 'o' */ \
+ REF (form_hexa), /* for 'X', 'x' */ \
+ REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \
+ REF (form_character), /* for 'c' */ \
+ REF (form_string), /* for 's', 'S' */ \
+ REF (form_pointer), /* for 'p' */ \
+ REF (form_number), /* for 'n' */ \
+ REF (form_strerror), /* for 'm' */ \
+ REF (form_wcharacter), /* for 'C' */ \
+ REF (form_floathex), /* for 'A', 'a' */ \
+ REF (form_unknown), /* for 't' */ \
+ REF (form_unknown), /* for 'j' */ \
+ REF (form_unknown), /* for 'I' */ \
+ REF (form_unknown), /* for 'H' */ \
+ REF (form_unknown) /* for 'D' */ \
+ }; \
+ /* Some format codes should not be allowed for decimal-float. */ \
+ /* Step 3c: after processing first 'D' modifier. */ \
+ static JUMP_TABLE_TYPE step3c_jumps[32] = \
+ { \
+ REF (form_unknown), \
+ REF (form_unknown), /* for ' ' */ \
+ REF (form_unknown), /* for '+' */ \
+ REF (form_unknown), /* for '-' */ \
+ REF (form_unknown), /* for '<hash>' */ \
+ REF (form_unknown), /* for '0' */ \
+ REF (form_unknown), /* for '\'' */ \
+ REF (form_unknown), /* for '*' */ \
+ REF (form_unknown), /* for '1'...'9' */ \
+ REF (form_unknown), /* for '.' */ \
+ REF (form_unknown), /* for 'h' */ \
+ REF (form_unknown), /* for 'l' */ \
+ REF (form_unknown), /* for 'L', 'q' */ \
+ REF (form_unknown), /* for 'z', 'Z' */ \
+ REF (form_percent), /* for '%' */ \
+ REF (form_integer), /* for 'd', 'i' */ \
+ REF (form_unsigned), /* for 'u' */ \
+ REF (form_octal), /* for 'o' */ \
+ REF (form_hexa), /* for 'X', 'x' */ \
+ REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \
+ REF (form_character), /* for 'c' */ \
+ REF (form_string), /* for 's', 'S' */ \
+ REF (form_pointer), /* for 'p' */ \
+ REF (form_number), /* for 'n' */ \
+ REF (form_strerror), /* for 'm' */ \
+ REF (form_wcharacter), /* for 'C' */ \
+ REF (form_floathex), /* for 'A', 'a' */ \
+ REF (form_unknown), /* for 't' */ \
+ REF (form_unknown), /* for 'j' */ \
+ REF (form_unknown), /* for 'I' */ \
+ REF (form_unknown), /* for 'H' */ \
+ REF (mod_decimal_long) /* for 'D' */ \
+ };
+
+
+#define STEP4_TABLE \
+ /* Step 4: processing format specifier. */ \
+ static JUMP_TABLE_TYPE step4_jumps[32] = \
+ { \
+ REF (form_unknown), \
+ REF (form_unknown), /* for ' ' */ \
+ REF (form_unknown), /* for '+' */ \
+ REF (form_unknown), /* for '-' */ \
+ REF (form_unknown), /* for '<hash>' */ \
+ REF (form_unknown), /* for '0' */ \
+ REF (form_unknown), /* for '\'' */ \
+ REF (form_unknown), /* for '*' */ \
+ REF (form_unknown), /* for '1'...'9' */ \
+ REF (form_unknown), /* for '.' */ \
+ REF (form_unknown), /* for 'h' */ \
+ REF (form_unknown), /* for 'l' */ \
+ REF (form_unknown), /* for 'L', 'q' */ \
+ REF (form_unknown), /* for 'z', 'Z' */ \
+ REF (form_percent), /* for '%' */ \
+ REF (form_integer), /* for 'd', 'i' */ \
+ REF (form_unsigned), /* for 'u' */ \
+ REF (form_octal), /* for 'o' */ \
+ REF (form_hexa), /* for 'X', 'x' */ \
+ REF (form_float), /* for 'E', 'e', 'F', 'f', 'G', 'g' */ \
+ REF (form_character), /* for 'c' */ \
+ REF (form_string), /* for 's', 'S' */ \
+ REF (form_pointer), /* for 'p' */ \
+ REF (form_number), /* for 'n' */ \
+ REF (form_strerror), /* for 'm' */ \
+ REF (form_wcharacter), /* for 'C' */ \
+ REF (form_floathex), /* for 'A', 'a' */ \
+ REF (form_unknown), /* for 't' */ \
+ REF (form_unknown), /* for 'j' */ \
+ REF (form_unknown), /* for 'I' */ \
+ REF (form_unknown), /* for 'H' */ \
+ REF (form_unknown) /* for 'D' */ \
+ }; \
+
+
+#define process_arg(fspec) \
+ /* Start real work. We know about all flags and modifiers and \
+ now process the wanted format specifier. */ \
+ LABEL (form_percent): \
+ /* Write a literal "%". */ \
+ outchar (L_('%')); \
+ break; \
+ \
+ LABEL (form_integer): \
+ /* Signed decimal integer. */ \
+ base = 10; \
+ \
+ if (is_longlong) \
+ { \
+ long long int signed_number; \
+ \
+ if (fspec == NULL) \
+ signed_number = va_arg (ap, long long int); \
+ else \
+ signed_number = args_value[fspec->data_arg].pa_long_long_int; \
+ \
+ is_negative = signed_number < 0; \
+ number.longlong = is_negative ? (- signed_number) : signed_number; \
+ \
+ goto LABEL (longlong_number); \
+ } \
+ else \
+ { \
+ long int signed_number; \
+ \
+ if (fspec == NULL) \
+ { \
+ if (is_long_num) \
+ signed_number = va_arg (ap, long int); \
+ else if (is_char) \
+ signed_number = (signed char) va_arg (ap, unsigned int); \
+ else if (!is_short) \
+ signed_number = va_arg (ap, int); \
+ else \
+ signed_number = (short int) va_arg (ap, unsigned int); \
+ } \
+ else \
+ if (is_long_num) \
+ signed_number = args_value[fspec->data_arg].pa_long_int; \
+ else if (is_char) \
+ signed_number = (signed char) \
+ args_value[fspec->data_arg].pa_u_int; \
+ else if (!is_short) \
+ signed_number = args_value[fspec->data_arg].pa_int; \
+ else \
+ signed_number = (short int) \
+ args_value[fspec->data_arg].pa_u_int; \
+ \
+ is_negative = signed_number < 0; \
+ number.word = is_negative ? (- signed_number) : signed_number; \
+ \
+ goto LABEL (number); \
+ } \
+ /* NOTREACHED */ \
+ \
+ LABEL (form_unsigned): \
+ /* Unsigned decimal integer. */ \
+ base = 10; \
+ goto LABEL (unsigned_number); \
+ /* NOTREACHED */ \
+ \
+ LABEL (form_octal): \
+ /* Unsigned octal integer. */ \
+ base = 8; \
+ goto LABEL (unsigned_number); \
+ /* NOTREACHED */ \
+ \
+ LABEL (form_hexa): \
+ /* Unsigned hexadecimal integer. */ \
+ base = 16; \
+ \
+ LABEL (unsigned_number): /* Unsigned number of base BASE. */ \
+ \
+ /* ISO specifies the `+' and ` ' flags only for signed \
+ conversions. */ \
+ is_negative = 0; \
+ showsign = 0; \
+ space = 0; \
+ \
+ if (is_longlong) \
+ { \
+ if (fspec == NULL) \
+ number.longlong = va_arg (ap, unsigned long long int); \
+ else \
+ number.longlong = args_value[fspec->data_arg].pa_u_long_long_int; \
+ \
+ LABEL (longlong_number): \
+ if (prec < 0) \
+ /* Supply a default precision if none was given. */ \
+ prec = 1; \
+ else \
+ /* We have to take care for the '0' flag. If a precision \
+ is given it must be ignored. */ \
+ pad = L_(' '); \
+ \
+ /* If the precision is 0 and the number is 0 nothing has to \
+ be written for the number, except for the 'o' format in \
+ alternate form. */ \
+ if (prec == 0 && number.longlong == 0) \
+ { \
+ string = workend; \
+ if (base == 8 && alt) \
+ *--string = L_('0'); \
+ } \
+ else \
+ { \
+ /* Put the number in WORK. */ \
+ string = _itoa (number.longlong, workend, base, \
+ spec == L_('X')); \
+ if (group && grouping) \
+ string = group_number (string, workend, grouping, \
+ thousands_sep); \
+ \
+ if (use_outdigits && base == 10) \
+ string = _i18n_number_rewrite (string, workend); \
+ } \
+ /* Simplify further test for num != 0. */ \
+ number.word = number.longlong != 0; \
+ } \
+ else \
+ { \
+ if (fspec == NULL) \
+ { \
+ if (is_long_num) \
+ number.word = va_arg (ap, unsigned long int); \
+ else if (is_char) \
+ number.word = (unsigned char) va_arg (ap, unsigned int); \
+ else if (!is_short) \
+ number.word = va_arg (ap, unsigned int); \
+ else \
+ number.word = (unsigned short int) va_arg (ap, unsigned int); \
+ } \
+ else \
+ if (is_long_num) \
+ number.word = args_value[fspec->data_arg].pa_u_long_int; \
+ else if (is_char) \
+ number.word = (unsigned char) \
+ args_value[fspec->data_arg].pa_u_int; \
+ else if (!is_short) \
+ number.word = args_value[fspec->data_arg].pa_u_int; \
+ else \
+ number.word = (unsigned short int) \
+ args_value[fspec->data_arg].pa_u_int; \
+ \
+ LABEL (number): \
+ if (prec < 0) \
+ /* Supply a default precision if none was given. */ \
+ prec = 1; \
+ else \
+ /* We have to take care for the '0' flag. If a precision \
+ is given it must be ignored. */ \
+ pad = L_(' '); \
+ \
+ /* If the precision is 0 and the number is 0 nothing has to \
+ be written for the number, except for the 'o' format in \
+ alternate form. */ \
+ if (prec == 0 && number.word == 0) \
+ { \
+ string = workend; \
+ if (base == 8 && alt) \
+ *--string = L_('0'); \
+ } \
+ else \
+ { \
+ /* Put the number in WORK. */ \
+ string = _itoa_word (number.word, workend, base, \
+ spec == L_('X')); \
+ if (group && grouping) \
+ string = group_number (string, workend, grouping, \
+ thousands_sep); \
+ \
+ if (use_outdigits && base == 10) \
+ string = _i18n_number_rewrite (string, workend); \
+ } \
+ } \
+ \
+ if (prec <= workend - string && number.word != 0 && alt && base == 8) \
+ /* Add octal marker. */ \
+ *--string = L_('0'); \
+ \
+ prec = MAX (0, prec - (workend - string)); \
+ \
+ if (!left) \
+ { \
+ width -= workend - string + prec; \
+ \
+ if (number.word != 0 && alt && base == 16) \
+ /* Account for 0X hex marker. */ \
+ width -= 2; \
+ \
+ if (is_negative || showsign || space) \
+ --width; \
+ \
+ if (pad == L_(' ')) \
+ { \
+ PAD (L_(' ')); \
+ width = 0; \
+ } \
+ \
+ if (is_negative) \
+ outchar (L_('-')); \
+ else if (showsign) \
+ outchar (L_('+')); \
+ else if (space) \
+ outchar (L_(' ')); \
+ \
+ if (number.word != 0 && alt && base == 16) \
+ { \
+ outchar (L_('0')); \
+ outchar (spec); \
+ } \
+ \
+ width += prec; \
+ PAD (L_('0')); \
+ \
+ outstring (string, workend - string); \
+ \
+ break; \
+ } \
+ else \
+ { \
+ if (is_negative) \
+ { \
+ outchar (L_('-')); \
+ --width; \
+ } \
+ else if (showsign) \
+ { \
+ outchar (L_('+')); \
+ --width; \
+ } \
+ else if (space) \
+ { \
+ outchar (L_(' ')); \
+ --width; \
+ } \
+ \
+ if (number.word != 0 && alt && base == 16) \
+ { \
+ outchar (L_('0')); \
+ outchar (spec); \
+ width -= 2; \
+ } \
+ \
+ width -= workend - string + prec; \
+ \
+ if (prec > 0) \
+ { \
+ int temp = width; \
+ width = prec; \
+ PAD (L_('0'));; \
+ width = temp; \
+ } \
+ \
+ outstring (string, workend - string); \
+ \
+ PAD (L_(' ')); \
+ break; \
+ } \
+ \
+ LABEL (form_float): \
+ { \
+ /* Floating-point number. This is handled by printf_fp.c */ \
+ /* or printf_dfp.c */ \
+ const void *ptr; \
+ int function_done; \
+ \
+ if (fspec == NULL) \
+ { \
+ if (__ldbl_is_dbl) \
+ is_long_double = 0; \
+ \
+ struct printf_info info = { .prec = prec, \
+ .width = width, \
+ .spec = spec, \
+ .is_long_double = is_long_double, \
+ .is_short = is_short, \
+ .is_long = is_long, \
+ .alt = alt, \
+ .space = space, \
+ .left = left, \
+ .showsign = showsign, \
+ .group = group, \
+ .pad = pad, \
+ .extra = 0, \
+ .i18n = use_outdigits, \
+ .is_decimal = is_decimal, \
+ .wide = sizeof (CHAR_T) != 1 }; \
+ \
+ if (is_long_double && !is_decimal) \
+ the_arg.pa_long_double = va_arg (ap, long double); \
+ else if (is_long_double && is_decimal) \
+ the_arg.pa_decimal128 = va_arg (ap, _Decimal128); \
+ else if (is_short && is_decimal) \
+ /* The specification indicates that _Decimal32 should */ \
+ /* NOT be promoted to _Decimal64 for DFP types. */ \
+ the_arg.pa_decimal32 = va_arg (ap, _Decimal32); \
+ else if (is_decimal && !is_long_double && !is_short) \
+ the_arg.pa_decimal64 = va_arg (ap, _Decimal64); \
+ else \
+ the_arg.pa_double = va_arg (ap, double); \
+ ptr = (const void *) &the_arg; \
+ \
+ if (is_decimal) \
+ function_done = __printf_dfp (s, &info, &ptr); \
+ else \
+ function_done = __printf_fp (s, &info, &ptr); \
+ } \
+ else \
+ { \
+ ptr = (const void *) &args_value[fspec->data_arg]; \
+ if (__ldbl_is_dbl) \
+ { \
+ fspec->data_arg_type = PA_DOUBLE; \
+ fspec->info.is_long_double = 0; \
+ } \
+ \
+ if (is_decimal) \
+ /* FIXME: The above flags are not being set for dfp */ \
+ function_done = __printf_dfp (s, &fspec->info, &ptr); \
+ else \
+ function_done = __printf_fp (s, &fspec->info, &ptr); \
+ } \
+ \
+ if (function_done < 0) \
+ { \
+ /* Error in print handler. */ \
+ done = -1; \
+ goto all_done; \
+ } \
+ \
+ done += function_done; \
+ } \
+ break; \
+ \
+ LABEL (form_floathex): \
+ { \
+ /* Floating point number printed as hexadecimal number. */ \
+ const void *ptr; \
+ int function_done; \
+ \
+ if (fspec == NULL) \
+ { \
+ if (__ldbl_is_dbl) \
+ is_long_double = 0; \
+ \
+ struct printf_info info = { .prec = prec, \
+ .width = width, \
+ .spec = spec, \
+ .is_long_double = is_long_double, \
+ .is_short = is_short, \
+ .is_long = is_long, \
+ .alt = alt, \
+ .space = space, \
+ .left = left, \
+ .showsign = showsign, \
+ .group = group, \
+ .pad = pad, \
+ .extra = 0, \
+ .is_decimal = is_decimal, \
+ .wide = sizeof (CHAR_T) != 1 }; \
+ \
+ if (is_long_double && !is_decimal) \
+ the_arg.pa_long_double = va_arg (ap, long double); \
+ else if (is_long_double && is_decimal) \
+ the_arg.pa_decimal128 = va_arg (ap, _Decimal128); \
+ else if (is_short && is_decimal) \
+ the_arg.pa_decimal32 = va_arg (ap, _Decimal32); \
+ else if (is_decimal && !is_long_double && !is_short) \
+ the_arg.pa_decimal64 = va_arg (ap, _Decimal64); \
+ else \
+ the_arg.pa_double = va_arg (ap, double); \
+ ptr = (const void *) &the_arg; \
+ \
+ if (is_decimal) \
+ function_done = __printf_dfphex (s, &info, &ptr); \
+ else \
+ function_done = __printf_fphex (s, &info, &ptr); \
+ } \
+ else \
+ { \
+ ptr = (const void *) &args_value[fspec->data_arg]; \
+ if (__ldbl_is_dbl) \
+ fspec->info.is_long_double = 0; \
+ \
+ /* FIX ME */ \
+ if (is_decimal) \
+ function_done = __printf_dfphex (s, &fspec->info, &ptr); \
+ else \
+ function_done = __printf_fphex (s, &fspec->info, &ptr); \
+ } \
+ \
+ if (function_done < 0) \
+ { \
+ /* Error in print handler. */ \
+ done = -1; \
+ goto all_done; \
+ } \
+ \
+ done += function_done; \
+ } \
+ break; \
+ \
+ LABEL (form_pointer): \
+ /* Generic pointer. */ \
+ { \
+ const void *ptr; \
+ if (fspec == NULL) \
+ ptr = va_arg (ap, void *); \
+ else \
+ ptr = args_value[fspec->data_arg].pa_pointer; \
+ if (ptr != NULL) \
+ { \
+ /* If the pointer is not NULL, write it as a %#x spec. */ \
+ base = 16; \
+ number.word = (unsigned long int) ptr; \
+ is_negative = 0; \
+ alt = 1; \
+ group = 0; \
+ spec = L_('x'); \
+ goto LABEL (number); \
+ } \
+ else \
+ { \
+ /* Write "(nil)" for a nil pointer. */ \
+ string = (CHAR_T *) L_("(nil)"); \
+ /* Make sure the full string "(nil)" is printed. */ \
+ if (prec < 5) \
+ prec = 5; \
+ is_long = 0; /* This is no wide-char string. */ \
+ goto LABEL (print_string); \
+ } \
+ } \
+ /* NOTREACHED */ \
+ \
+ LABEL (form_number): \
+ if (s->_flags2 & _IO_FLAGS2_FORTIFY) \
+ { \
+ if (! readonly_format) \
+ { \
+ extern int __readonly_area (const void *, size_t) \
+ attribute_hidden; \
+ readonly_format \
+ = __readonly_area (format, ((STR_LEN (format) + 1) \
+ * sizeof (CHAR_T))); \
+ } \
+ if (readonly_format < 0) \
+ __libc_fatal ("*** %n in writable segment detected ***\n"); \
+ } \
+ /* Answer the count of characters written. */ \
+ if (fspec == NULL) \
+ { \
+ if (is_longlong) \
+ *(long long int *) va_arg (ap, void *) = done; \
+ else if (is_long_num) \
+ *(long int *) va_arg (ap, void *) = done; \
+ else if (is_char) \
+ *(char *) va_arg (ap, void *) = done; \
+ else if (!is_short) \
+ *(int *) va_arg (ap, void *) = done; \
+ else \
+ *(short int *) va_arg (ap, void *) = done; \
+ } \
+ else \
+ if (is_longlong) \
+ *(long long int *) args_value[fspec->data_arg].pa_pointer = done; \
+ else if (is_long_num) \
+ *(long int *) args_value[fspec->data_arg].pa_pointer = done; \
+ else if (is_char) \
+ *(char *) args_value[fspec->data_arg].pa_pointer = done; \
+ else if (!is_short) \
+ *(int *) args_value[fspec->data_arg].pa_pointer = done; \
+ else \
+ *(short int *) args_value[fspec->data_arg].pa_pointer = done; \
+ break; \
+ \
+ LABEL (form_strerror): \
+ /* Print description of error ERRNO. */ \
+ string = \
+ (CHAR_T *) __strerror_r (save_errno, (char *) work_buffer, \
+ sizeof work_buffer); \
+ is_long = 0; /* This is no wide-char string. */ \
+ goto LABEL (print_string)
+
+#ifdef COMPILE_WPRINTF
+# define process_string_arg(fspec) \
+ LABEL (form_character): \
+ /* Character. */ \
+ if (is_long) \
+ goto LABEL (form_wcharacter); \
+ --width; /* Account for the character itself. */ \
+ if (!left) \
+ PAD (L' '); \
+ if (fspec == NULL) \
+ outchar (__btowc ((unsigned char) va_arg (ap, int))); /* Promoted. */ \
+ else \
+ outchar (__btowc ((unsigned char) \
+ args_value[fspec->data_arg].pa_int)); \
+ if (left) \
+ PAD (L' '); \
+ break; \
+ \
+ LABEL (form_wcharacter): \
+ { \
+ /* Wide character. */ \
+ --width; \
+ if (!left) \
+ PAD (L' '); \
+ if (fspec == NULL) \
+ outchar (va_arg (ap, wchar_t)); \
+ else \
+ outchar (args_value[fspec->data_arg].pa_wchar); \
+ if (left) \
+ PAD (L' '); \
+ } \
+ break; \
+ \
+ LABEL (form_string): \
+ { \
+ size_t len; \
+ int string_malloced; \
+ \
+ /* The string argument could in fact be `char *' or `wchar_t *'. \
+ But this should not make a difference here. */ \
+ if (fspec == NULL) \
+ string = (CHAR_T *) va_arg (ap, const wchar_t *); \
+ else \
+ string = (CHAR_T *) args_value[fspec->data_arg].pa_wstring; \
+ \
+ /* Entry point for printing other strings. */ \
+ LABEL (print_string): \
+ \
+ string_malloced = 0; \
+ if (string == NULL) \
+ { \
+ /* Write "(null)" if there's space. */ \
+ if (prec == -1 \
+ || prec >= (int) (sizeof (null) / sizeof (null[0])) - 1) \
+ { \
+ string = (CHAR_T *) null; \
+ len = (sizeof (null) / sizeof (null[0])) - 1; \
+ } \
+ else \
+ { \
+ string = (CHAR_T *) L""; \
+ len = 0; \
+ } \
+ } \
+ else if (!is_long && spec != L_('S')) \
+ { \
+ /* This is complicated. We have to transform the multibyte \
+ string into a wide character string. */ \
+ const char *mbs = (const char *) string; \
+ mbstate_t mbstate; \
+ \
+ len = prec != -1 ? (size_t) prec : strlen (mbs); \
+ \
+ /* Allocate dynamically an array which definitely is long \
+ enough for the wide character version. */ \
+ if (__libc_use_alloca (len * sizeof (wchar_t))) \
+ string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \
+ else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t))) \
+ == NULL) \
+ { \
+ done = -1; \
+ goto all_done; \
+ } \
+ else \
+ string_malloced = 1; \
+ \
+ memset (&mbstate, '\0', sizeof (mbstate_t)); \
+ len = __mbsrtowcs (string, &mbs, len, &mbstate); \
+ if (len == (size_t) -1) \
+ { \
+ /* Illegal multibyte character. */ \
+ done = -1; \
+ goto all_done; \
+ } \
+ } \
+ else \
+ { \
+ if (prec != -1) \
+ /* Search for the end of the string, but don't search past \
+ the length specified by the precision. */ \
+ len = __wcsnlen (string, prec); \
+ else \
+ len = __wcslen (string); \
+ } \
+ \
+ if ((width -= len) < 0) \
+ { \
+ outstring (string, len); \
+ break; \
+ } \
+ \
+ if (!left) \
+ PAD (L' '); \
+ outstring (string, len); \
+ if (left) \
+ PAD (L' '); \
+ if (__builtin_expect (string_malloced, 0)) \
+ free (string); \
+ } \
+ break;
+#else
+# define process_string_arg(fspec) \
+ LABEL (form_character): \
+ /* Character. */ \
+ if (is_long) \
+ goto LABEL (form_wcharacter); \
+ --width; /* Account for the character itself. */ \
+ if (!left) \
+ PAD (' '); \
+ if (fspec == NULL) \
+ outchar ((unsigned char) va_arg (ap, int)); /* Promoted. */ \
+ else \
+ outchar ((unsigned char) args_value[fspec->data_arg].pa_int); \
+ if (left) \
+ PAD (' '); \
+ break; \
+ \
+ LABEL (form_wcharacter): \
+ { \
+ /* Wide character. */ \
+ char buf[MB_CUR_MAX]; \
+ mbstate_t mbstate; \
+ size_t len; \
+ \
+ memset (&mbstate, '\0', sizeof (mbstate_t)); \
+ len = __wcrtomb (buf, (fspec == NULL ? va_arg (ap, wchar_t) \
+ : args_value[fspec->data_arg].pa_wchar), \
+ &mbstate); \
+ if (len == (size_t) -1) \
+ { \
+ /* Something went wron gduring the conversion. Bail out. */ \
+ done = -1; \
+ goto all_done; \
+ } \
+ width -= len; \
+ if (!left) \
+ PAD (' '); \
+ outstring (buf, len); \
+ if (left) \
+ PAD (' '); \
+ } \
+ break; \
+ \
+ LABEL (form_string): \
+ { \
+ size_t len; \
+ int string_malloced; \
+ \
+ /* The string argument could in fact be `char *' or `wchar_t *'. \
+ But this should not make a difference here. */ \
+ if (fspec == NULL) \
+ string = (char *) va_arg (ap, const char *); \
+ else \
+ string = (char *) args_value[fspec->data_arg].pa_string; \
+ \
+ /* Entry point for printing other strings. */ \
+ LABEL (print_string): \
+ \
+ string_malloced = 0; \
+ if (string == NULL) \
+ { \
+ /* Write "(null)" if there's space. */ \
+ if (prec == -1 || prec >= (int) sizeof (null) - 1) \
+ { \
+ string = (char *) null; \
+ len = sizeof (null) - 1; \
+ } \
+ else \
+ { \
+ string = (char *) ""; \
+ len = 0; \
+ } \
+ } \
+ else if (!is_long && spec != L_('S')) \
+ { \
+ if (prec != -1) \
+ { \
+ /* Search for the end of the string, but don't search past \
+ the length (in bytes) specified by the precision. Also \
+ don't use incomplete characters. */ \
+ if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX) == 1) \
+ len = __strnlen (string, prec); \
+ else \
+ { \
+ /* In case we have a multibyte character set the \
+ situation is more compilcated. We must not copy \
+ bytes at the end which form an incomplete character. */\
+ wchar_t ignore[prec]; \
+ const char *str2 = string; \
+ mbstate_t ps; \
+ \
+ memset (&ps, '\0', sizeof (ps)); \
+ if (__mbsnrtowcs (ignore, &str2, prec, prec, &ps) \
+ == (size_t) -1) \
+ { \
+ done = -1; \
+ goto all_done; \
+ } \
+ if (str2 == NULL) \
+ len = strlen (string); \
+ else \
+ len = str2 - string - (ps.__count & 7); \
+ } \
+ } \
+ else \
+ len = strlen (string); \
+ } \
+ else \
+ { \
+ const wchar_t *s2 = (const wchar_t *) string; \
+ mbstate_t mbstate; \
+ \
+ memset (&mbstate, '\0', sizeof (mbstate_t)); \
+ \
+ if (prec >= 0) \
+ { \
+ /* The string `s2' might not be NUL terminated. */ \
+ if (__libc_use_alloca (prec)) \
+ string = (char *) alloca (prec); \
+ else if ((string = (char *) malloc (prec)) == NULL) \
+ { \
+ done = -1; \
+ goto all_done; \
+ } \
+ else \
+ string_malloced = 1; \
+ len = __wcsrtombs (string, &s2, prec, &mbstate); \
+ } \
+ else \
+ { \
+ len = __wcsrtombs (NULL, &s2, 0, &mbstate); \
+ if (len != (size_t) -1) \
+ { \
+ assert (__mbsinit (&mbstate)); \
+ s2 = (const wchar_t *) string; \
+ if (__libc_use_alloca (len + 1)) \
+ string = (char *) alloca (len + 1); \
+ else if ((string = (char *) malloc (len + 1)) == NULL) \
+ { \
+ done = -1; \
+ goto all_done; \
+ } \
+ else \
+ string_malloced = 1; \
+ (void) __wcsrtombs (string, &s2, len + 1, &mbstate); \
+ } \
+ } \
+ \
+ if (len == (size_t) -1) \
+ { \
+ /* Illegal wide-character string. */ \
+ done = -1; \
+ goto all_done; \
+ } \
+ } \
+ \
+ if ((width -= len) < 0) \
+ { \
+ outstring (string, len); \
+ break; \
+ } \
+ \
+ if (!left) \
+ PAD (' '); \
+ outstring (string, len); \
+ if (left) \
+ PAD (' '); \
+ if (__builtin_expect (string_malloced, 0)) \
+ free (string); \
+ } \
+ break;
+#endif
+
+ /* Orient the stream. */
+#ifdef ORIENT
+ ORIENT;
+#endif
+
+ /* Sanity check of arguments. */
+ ARGCHECK (s, format);
+
+#ifdef ORIENT
+ /* Check for correct orientation. */
+ if (_IO_vtable_offset (s) == 0 &&
+ _IO_fwide (s, sizeof (CHAR_T) == 1 ? -1 : 1)
+ != (sizeof (CHAR_T) == 1 ? -1 : 1))
+ /* The stream is already oriented otherwise. */
+ return EOF;
+#endif
+
+ if (UNBUFFERED_P (s))
+ /* Use a helper function which will allocate a local temporary buffer
+ for the stream and then call us again. */
+ return buffered_vfprintf (s, format, ap);
+
+ /* Initialize local variables. */
+ done = 0;
+ grouping = (const char *) -1;
+#ifdef __va_copy
+ /* This macro will be available soon in gcc's <stdarg.h>. We need it
+ since on some systems `va_list' is not an integral type. */
+ __va_copy (ap_save, ap);
+#else
+ ap_save = ap;
+#endif
+ nspecs_done = 0;
+
+#ifdef COMPILE_WPRINTF
+ /* Find the first format specifier. */
+ f = lead_str_end = __find_specwc ((const UCHAR_T *) format);
+#else
+ /* Put state for processing format string in initial state. */
+ memset (&mbstate, '\0', sizeof (mbstate_t));
+
+ /* Find the first format specifier. */
+ f = lead_str_end = __find_specmb (format, &mbstate);
+#endif
+
+ /* Lock stream. */
+ _IO_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, s);
+ _IO_flockfile (s);
+
+ /* Write the literal text before the first format. */
+ outstring ((const UCHAR_T *) format,
+ lead_str_end - (const UCHAR_T *) format);
+
+ /* If we only have to print a simple string, return now. */
+ if (*f == L_('\0'))
+ goto all_done;
+
+ /* Process whole format string. */
+ do
+ {
+#ifdef SHARED
+# define REF(Name) &&do_##Name - &&do_form_unknown
+#else
+# define REF(Name) &&do_##Name
+#endif
+#define LABEL(Name) do_##Name
+ STEP0_3_TABLE;
+ STEP4_TABLE;
+
+ union printf_arg *args_value; /* This is not used here but ... */
+ int is_negative; /* Flag for negative number. */
+ union
+ {
+ unsigned long long int longlong;
+ unsigned long int word;
+ } number;
+ int base;
+ union printf_arg the_arg;
+ CHAR_T *string; /* Pointer to argument string. */
+ int alt = 0; /* Alternate format. */
+ int space = 0; /* Use space prefix if no sign is needed. */
+ int left = 0; /* Left-justify output. */
+ int showsign = 0; /* Always begin with plus or minus sign. */
+ int group = 0; /* Print numbers according grouping rules. */
+ int is_long_double = 0; /* Argument is long double/ long long int. */
+ int is_short = 0; /* Argument is short int. */
+ int is_long = 0; /* Argument is long int. */
+ int is_char = 0; /* Argument is promoted (unsigned) char. */
+ int is_decimal = 0; /* Argument is decimal floating point. */
+ int width = 0; /* Width of output; 0 means none specified. */
+ int prec = -1; /* Precision of output; -1 means none specified. */
+ /* This flag is set by the 'I' modifier and selects the use of the
+ `outdigits' as determined by the current locale. */
+ int use_outdigits = 0;
+ UCHAR_T pad = L_(' ');/* Padding character. */
+ CHAR_T spec;
+
+ workstart = NULL;
+ workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
+
+ /* Get current character in format string. */
+ JUMP (*++f, step0_jumps);
+
+ /* ' ' flag. */
+ LABEL (flag_space):
+ space = 1;
+ JUMP (*++f, step0_jumps);
+
+ /* '+' flag. */
+ LABEL (flag_plus):
+ showsign = 1;
+ JUMP (*++f, step0_jumps);
+
+ /* The '-' flag. */
+ LABEL (flag_minus):
+ left = 1;
+ pad = L_(' ');
+ JUMP (*++f, step0_jumps);
+
+ /* The '#' flag. */
+ LABEL (flag_hash):
+ alt = 1;
+ JUMP (*++f, step0_jumps);
+
+ /* The '0' flag. */
+ LABEL (flag_zero):
+ if (!left)
+ pad = L_('0');
+ JUMP (*++f, step0_jumps);
+
+ /* The '\'' flag. */
+ LABEL (flag_quote):
+ group = 1;
+
+ if (grouping == (const char *) -1)
+ {
+#ifdef COMPILE_WPRINTF
+ thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
+ _NL_NUMERIC_THOUSANDS_SEP_WC);
+#else
+ thousands_sep = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+#endif
+
+ grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
+ if (*grouping == '\0' || *grouping == CHAR_MAX
+#ifdef COMPILE_WPRINTF
+ || thousands_sep == L'\0'
+#else
+ || *thousands_sep == '\0'
+#endif
+ )
+ grouping = NULL;
+ }
+ JUMP (*++f, step0_jumps);
+
+ LABEL (flag_i18n):
+ use_outdigits = 1;
+ JUMP (*++f, step0_jumps);
+
+ /* Get width from argument. */
+ LABEL (width_asterics):
+ {
+ const UCHAR_T *tmp; /* Temporary value. */
+
+ tmp = ++f;
+ if (ISDIGIT (*tmp) && read_int (&tmp) && *tmp == L_('$'))
+ /* The width comes from a positional parameter. */
+ goto do_positional;
+
+ width = va_arg (ap, int);
+
+ /* Negative width means left justified. */
+ if (width < 0)
+ {
+ width = -width;
+ pad = L_(' ');
+ left = 1;
+ }
+
+ if (width + 32 >= (int) (sizeof (work_buffer)
+ / sizeof (work_buffer[0])))
+ {
+ /* We have to use a special buffer. The "32" is just a safe
+ bet for all the output which is not counted in the width. */
+ if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T)))
+ workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T))
+ + (width + 32));
+ else
+ {
+ workstart = (CHAR_T *) malloc ((width + 32) * sizeof (CHAR_T));
+ if (workstart == NULL)
+ {
+ done = -1;
+ goto all_done;
+ }
+ workend = workstart + (width + 32);
+ }
+ }
+ }
+ JUMP (*f, step1_jumps);
+
+ /* Given width in format string. */
+ LABEL (width):
+ width = read_int (&f);
+
+ if (width + 32 >= (int) (sizeof (work_buffer) / sizeof (work_buffer[0])))
+ {
+ /* We have to use a special buffer. The "32" is just a safe
+ bet for all the output which is not counted in the width. */
+ if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T)))
+ workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T))
+ + (width + 32));
+ else
+ {
+ workstart = (CHAR_T *) malloc ((width + 32) * sizeof (CHAR_T));
+ if (workstart == NULL)
+ {
+ done = -1;
+ goto all_done;
+ }
+ workend = workstart + (width + 32);
+ }
+ }
+ if (*f == L_('$'))
+ /* Oh, oh. The argument comes from a positional parameter. */
+ goto do_positional;
+ JUMP (*f, step1_jumps);
+
+ LABEL (precision):
+ ++f;
+ if (*f == L_('*'))
+ {
+ const UCHAR_T *tmp; /* Temporary value. */
+
+ tmp = ++f;
+ if (ISDIGIT (*tmp) && read_int (&tmp) > 0 && *tmp == L_('$'))
+ /* The precision comes from a positional parameter. */
+ goto do_positional;
+
+ prec = va_arg (ap, int);
+
+ /* If the precision is negative the precision is omitted. */
+ if (prec < 0)
+ prec = -1;
+ }
+ else if (ISDIGIT (*f))
+ prec = read_int (&f);
+ else
+ prec = 0;
+ if (prec > width
+ && prec + 32 > (int)(sizeof (work_buffer) / sizeof (work_buffer[0])))
+ {
+ if (__libc_use_alloca ((prec + 32) * sizeof (CHAR_T)))
+ workend = ((CHAR_T *) alloca ((prec + 32) * sizeof (CHAR_T)))
+ + (prec + 32);
+ else
+ {
+ workstart = (CHAR_T *) malloc ((prec + 32) * sizeof (CHAR_T));
+ if (workstart == NULL)
+ {
+ done = -1;
+ goto all_done;
+ }
+ workend = workstart + (prec + 32);
+ }
+ }
+ JUMP (*f, step2_jumps);
+
+ /* Process 'h' modifier. There might another 'h' following. */
+ LABEL (mod_half):
+ is_short = 1;
+ JUMP (*++f, step3a_jumps);
+
+ /* Process 'hh' modifier. */
+ LABEL (mod_halfhalf):
+ is_short = 0;
+ is_char = 1;
+ JUMP (*++f, step4_jumps);
+
+ /* Process 'l' modifier. There might another 'l' following. */
+ LABEL (mod_long):
+ is_long = 1;
+ JUMP (*++f, step3b_jumps);
+
+ /* Process 'L', 'q', or 'll' modifier. No other modifier is
+ allowed to follow. */
+ LABEL (mod_longlong):
+ is_long_double = 1;
+ is_long = 1;
+ JUMP (*++f, step4_jumps);
+
+ LABEL (mod_size_t):
+ is_long_double = sizeof (size_t) > sizeof (unsigned long int);
+ is_long = sizeof (size_t) > sizeof (unsigned int);
+ JUMP (*++f, step4_jumps);
+
+ LABEL (mod_ptrdiff_t):
+ is_long_double = sizeof (ptrdiff_t) > sizeof (unsigned long int);
+ is_long = sizeof (ptrdiff_t) > sizeof (unsigned int);
+ JUMP (*++f, step4_jumps);
+
+ LABEL (mod_intmax_t):
+ is_long_double = sizeof (intmax_t) > sizeof (unsigned long int);
+ is_long = sizeof (intmax_t) > sizeof (unsigned int);
+ JUMP (*++f, step4_jumps);
+
+ /* Process 'H' modifier. No other modifier is allowed to follow. */
+ LABEL (mod_decimal_half):
+ is_decimal = 1;
+ is_short = 1;
+ JUMP (*++f, step4_jumps);
+
+ /* Process 'D' modifier. There might be another 'D' following. */
+ LABEL (mod_decimal):
+ is_decimal = 1;
+ is_short = 0;
+ is_long = 0;
+ JUMP (*++f, step3c_jumps);
+
+ /* Process 'DD' modifier. */
+ LABEL (mod_decimal_long):
+ /* is_decimal = 0; */
+ is_decimal = 1;
+ is_long_double = 1;
+ JUMP (*++f, step4_jumps);
+
+ /* The previous step3c_jumps or step4_jumps will jump directly
+ * to the LABELs defined in the process_arg macro. */
+
+ /* Process current format. */
+ while (1)
+ {
+ process_arg (((struct printf_spec *) NULL));
+ process_string_arg (((struct printf_spec *) NULL));
+
+ LABEL (form_unknown):
+ if (spec == L_('\0'))
+ {
+ /* The format string ended before the specifier is complete. */
+ done = -1;
+ goto all_done;
+ }
+
+ /* If we are in the fast loop force entering the complicated
+ one. */
+ goto do_positional;
+ }
+
+ /* The format is correctly handled. */
+ ++nspecs_done;
+
+ if (__builtin_expect (workstart != NULL, 0))
+ free (workstart);
+ workstart = NULL;
+
+ /* Look for next format specifier. */
+#ifdef COMPILE_WPRINTF
+ f = __find_specwc ((end_of_spec = ++f));
+#else
+ f = __find_specmb ((end_of_spec = ++f), &mbstate);
+#endif
+
+ /* Write the following constant string. */
+ outstring (end_of_spec, f - end_of_spec);
+ }
+ while (*f != L_('\0'));
+
+ /* Unlock stream and return. */
+ goto all_done;
+
+ /* Here starts the more complex loop to handle positional parameters. */
+do_positional:
+ {
+ /* Array with information about the needed arguments. This has to
+ be dynamically extensible. */
+ size_t nspecs = 0;
+ size_t nspecs_max = 32; /* A more or less arbitrary start value. */
+ struct printf_spec *specs
+ = alloca (nspecs_max * sizeof (struct printf_spec));
+
+ /* The number of arguments the format string requests. This will
+ determine the size of the array needed to store the argument
+ attributes. */
+ size_t nargs = 0;
+ int *args_type;
+ union printf_arg *args_value = NULL;
+
+ /* Positional parameters refer to arguments directly. This could
+ also determine the maximum number of arguments. Track the
+ maximum number. */
+ size_t max_ref_arg = 0;
+
+ /* Just a counter. */
+ size_t cnt;
+
+
+ if (grouping == (const char *) -1)
+ {
+#ifdef COMPILE_WPRINTF
+ thousands_sep = _NL_CURRENT_WORD (LC_NUMERIC,
+ _NL_NUMERIC_THOUSANDS_SEP_WC);
+#else
+ thousands_sep = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+#endif
+
+ grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
+ if (*grouping == '\0' || *grouping == CHAR_MAX)
+ grouping = NULL;
+ }
+
+ for (f = lead_str_end; *f != L_('\0'); f = specs[nspecs++].next_fmt)
+ {
+ if (nspecs >= nspecs_max)
+ {
+ /* Extend the array of format specifiers. */
+ struct printf_spec *old = specs;
+
+ nspecs_max *= 2;
+ specs = alloca (nspecs_max * sizeof (struct printf_spec));
+
+ if (specs == &old[nspecs])
+ /* Stack grows up, OLD was the last thing allocated;
+ extend it. */
+ nspecs_max += nspecs_max / 2;
+ else
+ {
+ /* Copy the old array's elements to the new space. */
+ memcpy (specs, old, nspecs * sizeof (struct printf_spec));
+ if (old == &specs[nspecs])
+ /* Stack grows down, OLD was just below the new
+ SPECS. We can use that space when the new space
+ runs out. */
+ nspecs_max += nspecs_max / 2;
+ }
+ }
+
+ /* Parse the format specifier. */
+#ifdef COMPILE_WPRINTF
+ nargs += __parse_one_specwc (f, nargs, &specs[nspecs], &max_ref_arg);
+#else
+ nargs += __parse_one_specmb (f, nargs, &specs[nspecs], &max_ref_arg,
+ &mbstate);
+#endif
+ }
+
+ /* Determine the number of arguments the format string consumes. */
+ nargs = MAX (nargs, max_ref_arg);
+
+ /* Allocate memory for the argument descriptions. */
+ args_type = alloca (nargs * sizeof (int));
+ memset (args_type, s->_flags2 & _IO_FLAGS2_FORTIFY ? '\xff' : '\0',
+ nargs * sizeof (int));
+ args_value = alloca (nargs * sizeof (union printf_arg));
+
+ /* XXX Could do sanity check here: If any element in ARGS_TYPE is
+ still zero after this loop, format is invalid. For now we
+ simply use 0 as the value. */
+
+ /* Fill in the types of all the arguments. */
+ for (cnt = 0; cnt < nspecs; ++cnt)
+ {
+ /* If the width is determined by an argument this is an int. */
+ if (specs[cnt].width_arg != -1)
+ args_type[specs[cnt].width_arg] = PA_INT;
+
+ /* If the precision is determined by an argument this is an int. */
+ if (specs[cnt].prec_arg != -1)
+ args_type[specs[cnt].prec_arg] = PA_INT;
+
+ switch (specs[cnt].ndata_args)
+ {
+ case 0: /* No arguments. */
+ break;
+ case 1: /* One argument; we already have the type. */
+ args_type[specs[cnt].data_arg] = specs[cnt].data_arg_type;
+ break;
+ default:
+ /* We have more than one argument for this format spec.
+ We must call the arginfo function again to determine
+ all the types. */
+ (void) (*__printf_arginfo_table[specs[cnt].info.spec])
+ (&specs[cnt].info,
+ specs[cnt].ndata_args, &args_type[specs[cnt].data_arg]);
+ break;
+ }
+ }
+
+ /* Now we know all the types and the order. Fill in the argument
+ values. */
+ for (cnt = 0; cnt < nargs; ++cnt)
+ switch (args_type[cnt])
+ {
+#define T(tag, mem, type) \
+ case tag: \
+ args_value[cnt].mem = va_arg (ap_save, type); \
+ break
+
+ T (PA_CHAR, pa_int, int); /* Promoted. */
+ T (PA_WCHAR, pa_wchar, wint_t);
+ T (PA_INT|PA_FLAG_SHORT, pa_int, int); /* Promoted. */
+ T (PA_INT, pa_int, int);
+ T (PA_INT|PA_FLAG_LONG, pa_long_int, long int);
+ T (PA_INT|PA_FLAG_LONG_LONG, pa_long_long_int, long long int);
+ T (PA_FLOAT, pa_double, double); /* Promoted. */
+ T (PA_DOUBLE, pa_double, double);
+ T (PA_DECIMAL, pa_decimal32, _Decimal32);
+ T (PA_DECIMAL|PA_FLAG_SHORT, pa_decimal64, _Decimal64);
+ T (PA_DECIMAL|PA_FLAG_LONG_DOUBLE, pa_decimal128, _Decimal128);
+ case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:
+ if (__ldbl_is_dbl)
+ {
+ args_value[cnt].pa_double = va_arg (ap_save, double);
+ args_type[cnt] &= ~PA_FLAG_LONG_DOUBLE;
+ }
+ else
+ args_value[cnt].pa_long_double = va_arg (ap_save, long double);
+ break;
+ T (PA_STRING, pa_string, const char *);
+ T (PA_WSTRING, pa_wstring, const wchar_t *);
+ T (PA_POINTER, pa_pointer, void *);
+#undef T
+ default:
+ if ((args_type[cnt] & PA_FLAG_PTR) != 0)
+ args_value[cnt].pa_pointer = va_arg (ap_save, void *);
+ else
+ args_value[cnt].pa_long_double = 0.0;
+ break;
+ case -1:
+ /* Error case. Not all parameters appear in N$ format
+ strings. We have no way to determine their type. */
+ assert (s->_flags2 & _IO_FLAGS2_FORTIFY);
+ __libc_fatal ("*** invalid %N$ use detected ***\n");
+ }
+
+ /* Now walk through all format specifiers and process them. */
+ for (; (size_t) nspecs_done < nspecs; ++nspecs_done)
+ {
+#undef REF
+#ifdef SHARED
+# define REF(Name) &&do2_##Name - &&do_form_unknown
+#else
+# define REF(Name) &&do2_##Name
+#endif
+#undef LABEL
+#define LABEL(Name) do2_##Name
+ STEP4_TABLE;
+
+ int is_negative;
+ union
+ {
+ unsigned long long int longlong;
+ unsigned long int word;
+ } number;
+ int base;
+ union printf_arg the_arg;
+ CHAR_T *string; /* Pointer to argument string. */
+
+ /* Fill variables from values in struct. */
+ int alt = specs[nspecs_done].info.alt;
+ int space = specs[nspecs_done].info.space;
+ int left = specs[nspecs_done].info.left;
+ int showsign = specs[nspecs_done].info.showsign;
+ int group = specs[nspecs_done].info.group;
+ int is_long_double = specs[nspecs_done].info.is_long_double;
+ int is_short = specs[nspecs_done].info.is_short;
+ int is_char = specs[nspecs_done].info.is_char;
+ int is_long = specs[nspecs_done].info.is_long;
+ int width = specs[nspecs_done].info.width;
+ int prec = specs[nspecs_done].info.prec;
+ int use_outdigits = specs[nspecs_done].info.i18n;
+ int is_decimal = specs[nspecs_done].info.is_decimal;
+ char pad = specs[nspecs_done].info.pad;
+ CHAR_T spec = specs[nspecs_done].info.spec;
+ CHAR_T *workstart = NULL;
+
+ /* Fill in last information. */
+ if (specs[nspecs_done].width_arg != -1)
+ {
+ /* Extract the field width from an argument. */
+ specs[nspecs_done].info.width =
+ args_value[specs[nspecs_done].width_arg].pa_int;
+
+ if (specs[nspecs_done].info.width < 0)
+ /* If the width value is negative left justification is
+ selected and the value is taken as being positive. */
+ {
+ specs[nspecs_done].info.width *= -1;
+ left = specs[nspecs_done].info.left = 1;
+ }
+ width = specs[nspecs_done].info.width;
+ }
+
+ if (specs[nspecs_done].prec_arg != -1)
+ {
+ /* Extract the precision from an argument. */
+ specs[nspecs_done].info.prec =
+ args_value[specs[nspecs_done].prec_arg].pa_int;
+
+ if (specs[nspecs_done].info.prec < 0)
+ /* If the precision is negative the precision is
+ omitted. */
+ specs[nspecs_done].info.prec = -1;
+
+ prec = specs[nspecs_done].info.prec;
+ }
+
+ /* Maybe the buffer is too small. */
+ if (MAX (prec, width) + 32 > (int) (sizeof (work_buffer)
+ / sizeof (CHAR_T)))
+ {
+ if (__libc_use_alloca ((MAX (prec, width) + 32)
+ * sizeof (CHAR_T)))
+ workend = ((CHAR_T *) alloca ((MAX (prec, width) + 32)
+ * sizeof (CHAR_T))
+ + (MAX (prec, width) + 32));
+ else
+ {
+ workstart = (CHAR_T *) malloc ((MAX (prec, width) + 32)
+ * sizeof (CHAR_T));
+ workend = workstart + (MAX (prec, width) + 32);
+ }
+ }
+
+ /* Process format specifiers. */
+ while (1)
+ {
+ JUMP (spec, step4_jumps);
+
+ process_arg ((&specs[nspecs_done]));
+ process_string_arg ((&specs[nspecs_done]));
+
+ LABEL (form_unknown):
+ {
+ extern printf_function **__printf_function_table;
+ int function_done;
+ printf_function *function;
+ unsigned int i;
+ const void **ptr;
+
+ function =
+ (__printf_function_table == NULL ? NULL :
+ __printf_function_table[specs[nspecs_done].info.spec]);
+
+ if (function == NULL)
+ function = &printf_unknown;
+
+ ptr = alloca (specs[nspecs_done].ndata_args
+ * sizeof (const void *));
+
+ /* Fill in an array of pointers to the argument values. */
+ for (i = 0; i < specs[nspecs_done].ndata_args; ++i)
+ ptr[i] = &args_value[specs[nspecs_done].data_arg + i];
+
+ /* Call the function. */
+ function_done = (*function) (s, &specs[nspecs_done].info, ptr);
+
+ /* If an error occurred we don't have information about #
+ of chars. */
+ if (function_done < 0)
+ {
+ done = -1;
+ goto all_done;
+ }
+
+ done += function_done;
+ }
+ break;
+ }
+
+ if (__builtin_expect (workstart != NULL, 0))
+ free (workstart);
+ workstart = NULL;
+
+ /* Write the following constant string. */
+ outstring (specs[nspecs_done].end_of_fmt,
+ specs[nspecs_done].next_fmt
+ - specs[nspecs_done].end_of_fmt);
+ }
+ }
+
+all_done:
+ if (__builtin_expect (workstart != NULL, 0))
+ free (workstart);
+ /* Unlock the stream. */
+ _IO_funlockfile (s);
+ _IO_cleanup_region_end (0);
+
+ return done;
+}
+
+/* Handle an unknown format specifier. This prints out a canonicalized
+ representation of the format spec itself. */
+static int
+printf_unknown (FILE *s, const struct printf_info *info,
+ const void *const *args)
+
+{
+ int done = 0;
+ CHAR_T work_buffer[MAX (info->width, info->spec) + 32];
+ CHAR_T *const workend
+ = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
+ register CHAR_T *w;
+
+ outchar (L_('%'));
+
+ if (info->alt)
+ outchar (L_('#'));
+ if (info->group)
+ outchar (L_('\''));
+ if (info->showsign)
+ outchar (L_('+'));
+ else if (info->space)
+ outchar (L_(' '));
+ if (info->left)
+ outchar (L_('-'));
+ if (info->pad == L_('0'))
+ outchar (L_('0'));
+ if (info->i18n)
+ outchar (L_('I'));
+
+ if (info->width != 0)
+ {
+ w = _itoa_word (info->width, workend, 10, 0);
+ while (w < workend)
+ outchar (*w++);
+ }
+
+ if (info->prec != -1)
+ {
+ outchar (L_('.'));
+ w = _itoa_word (info->prec, workend, 10, 0);
+ while (w < workend)
+ outchar (*w++);
+ }
+
+ if (info->spec != L_('\0'))
+ outchar (info->spec);
+
+ all_done:
+ return done;
+}
+
+/* Group the digits according to the grouping rules of the current locale.
+ The interpretation of GROUPING is as in `struct lconv' from <locale.h>. */
+static CHAR_T *
+internal_function
+group_number (CHAR_T *w, CHAR_T *rear_ptr, const char *grouping,
+#ifdef COMPILE_WPRINTF
+ wchar_t thousands_sep
+#else
+ const char *thousands_sep
+#endif
+ )
+{
+ int len;
+ CHAR_T *src, *s;
+#ifndef COMPILE_WPRINTF
+ int tlen = strlen (thousands_sep);
+#endif
+
+ /* We treat all negative values like CHAR_MAX. */
+
+ if (*grouping == CHAR_MAX || *grouping <= 0)
+ /* No grouping should be done. */
+ return w;
+
+ len = *grouping++;
+
+ /* Copy existing string so that nothing gets overwritten. */
+ src = (CHAR_T *) alloca ((rear_ptr - w) * sizeof (CHAR_T));
+ s = (CHAR_T *) __mempcpy (src, w,
+ (rear_ptr - w) * sizeof (CHAR_T));
+ w = rear_ptr;
+
+ /* Process all characters in the string. */
+ while (s > src)
+ {
+ *--w = *--s;
+
+ if (--len == 0 && s > src)
+ {
+ /* A new group begins. */
+#ifdef COMPILE_WPRINTF
+ *--w = thousands_sep;
+#else
+ int cnt = tlen;
+ do
+ *--w = thousands_sep[--cnt];
+ while (cnt > 0);
+#endif
+
+ if (*grouping == CHAR_MAX
+#if CHAR_MIN < 0
+ || *grouping < 0
+#endif
+ )
+ {
+ /* No further grouping to be done.
+ Copy the rest of the number. */
+ do
+ *--w = *--s;
+ while (s > src);
+ break;
+ }
+ else if (*grouping != '\0')
+ /* The previous grouping repeats ad infinitum. */
+ len = *grouping++;
+ else
+ len = grouping[-1];
+ }
+ }
+ return w;
+}
+
+/* Helper "class" for `fprintf to unbuffered': creates a temporary buffer. */
+struct helper_file
+ {
+ struct _IO_FILE_plus _f;
+#ifdef COMPILE_WPRINTF
+ struct _IO_wide_data _wide_data;
+#endif
+ _IO_FILE *_put_stream;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+#endif
+ };
+
+static int
+_IO_helper_overflow (_IO_FILE *s, int c)
+{
+ _IO_FILE *target = ((struct helper_file*) s)->_put_stream;
+#ifdef COMPILE_WPRINTF
+ int used = s->_wide_data->_IO_write_ptr - s->_wide_data->_IO_write_base;
+ if (used)
+ {
+ _IO_size_t written = _IO_sputn (target, s->_wide_data->_IO_write_base,
+ used);
+ s->_wide_data->_IO_write_ptr -= written;
+ }
+#else
+ int used = s->_IO_write_ptr - s->_IO_write_base;
+ if (used)
+ {
+ _IO_size_t written = _IO_sputn (target, s->_IO_write_base, used);
+ s->_IO_write_ptr -= written;
+ }
+#endif
+ return PUTC (c, s);
+}
+
+#ifdef COMPILE_WPRINTF
+static const struct _IO_jump_t _IO_helper_jumps =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT (finish, INTUSE(_IO_wdefault_finish)),
+ JUMP_INIT (overflow, _IO_helper_overflow),
+ JUMP_INIT (underflow, _IO_default_underflow),
+ JUMP_INIT (uflow, INTUSE(_IO_default_uflow)),
+ JUMP_INIT (pbackfail, (_IO_pbackfail_t) INTUSE(_IO_wdefault_pbackfail)),
+ JUMP_INIT (xsputn, INTUSE(_IO_wdefault_xsputn)),
+ JUMP_INIT (xsgetn, INTUSE(_IO_wdefault_xsgetn)),
+ JUMP_INIT (seekoff, _IO_default_seekoff),
+ JUMP_INIT (seekpos, _IO_default_seekpos),
+ JUMP_INIT (setbuf, _IO_default_setbuf),
+ JUMP_INIT (sync, _IO_default_sync),
+ JUMP_INIT (doallocate, INTUSE(_IO_wdefault_doallocate)),
+ JUMP_INIT (read, _IO_default_read),
+ JUMP_INIT (write, _IO_default_write),
+ JUMP_INIT (seek, _IO_default_seek),
+ JUMP_INIT (close, _IO_default_close),
+ JUMP_INIT (stat, _IO_default_stat)
+};
+#else
+static const struct _IO_jump_t _IO_helper_jumps =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT (finish, INTUSE(_IO_default_finish)),
+ JUMP_INIT (overflow, _IO_helper_overflow),
+ JUMP_INIT (underflow, _IO_default_underflow),
+ JUMP_INIT (uflow, INTUSE(_IO_default_uflow)),
+ JUMP_INIT (pbackfail, INTUSE(_IO_default_pbackfail)),
+ JUMP_INIT (xsputn, INTUSE(_IO_default_xsputn)),
+ JUMP_INIT (xsgetn, INTUSE(_IO_default_xsgetn)),
+ JUMP_INIT (seekoff, _IO_default_seekoff),
+ JUMP_INIT (seekpos, _IO_default_seekpos),
+ JUMP_INIT (setbuf, _IO_default_setbuf),
+ JUMP_INIT (sync, _IO_default_sync),
+ JUMP_INIT (doallocate, INTUSE(_IO_default_doallocate)),
+ JUMP_INIT (read, _IO_default_read),
+ JUMP_INIT (write, _IO_default_write),
+ JUMP_INIT (seek, _IO_default_seek),
+ JUMP_INIT (close, _IO_default_close),
+ JUMP_INIT (stat, _IO_default_stat)
+};
+#endif
+
+static int
+internal_function
+buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format,
+ _IO_va_list args)
+{
+ CHAR_T buf[_IO_BUFSIZ];
+ struct helper_file helper;
+ register _IO_FILE *hp = (_IO_FILE *) &helper._f;
+ int result, to_flush;
+
+ /* Orient the stream. */
+#ifdef ORIENT
+ ORIENT;
+#endif
+
+ /* Initialize helper. */
+ helper._put_stream = s;
+#ifdef COMPILE_WPRINTF
+ hp->_wide_data = &helper._wide_data;
+ _IO_wsetp (hp, buf, buf + sizeof buf / sizeof (CHAR_T));
+ hp->_mode = 1;
+#else
+ _IO_setp (hp, buf, buf + sizeof buf);
+ hp->_mode = -1;
+#endif
+ hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS|_IO_USER_LOCK;
+#if _IO_JUMPS_OFFSET
+ hp->_vtable_offset = 0;
+#endif
+#ifdef _IO_MTSAFE_IO
+ hp->_lock = NULL;
+#endif
+ hp->_flags2 = s->_flags2;
+ _IO_JUMPS (&helper._f) = (struct _IO_jump_t *) &_IO_helper_jumps;
+
+ /* Now print to helper instead. */
+#ifndef COMPILE_WPRINTF
+ result = INTUSE(_IO_vfprintf) (hp, format, args);
+#else
+ result = vfprintf (hp, format, args);
+#endif
+
+ /* Lock stream. */
+ __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, s);
+ _IO_flockfile (s);
+
+ /* Now flush anything from the helper to the S. */
+#ifdef COMPILE_WPRINTF
+ if ((to_flush = (hp->_wide_data->_IO_write_ptr
+ - hp->_wide_data->_IO_write_base)) > 0)
+ {
+ if ((int) _IO_sputn (s, hp->_wide_data->_IO_write_base, to_flush)
+ != to_flush)
+ result = -1;
+ }
+#else
+ if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0)
+ {
+ if ((int) _IO_sputn (s, hp->_IO_write_base, to_flush) != to_flush)
+ result = -1;
+ }
+#endif
+
+ /* Unlock the stream. */
+ _IO_funlockfile (s);
+ __libc_cleanup_region_end (0);
+
+ return result;
+}
+
+#undef vfprintf
+#ifdef COMPILE_WPRINTF
+strong_alias (_IO_vfwprintf, __vfwprintf);
+ldbl_weak_alias (_IO_vfwprintf, vfwprintf);
+#else
+ldbl_strong_alias (_IO_vfprintf_internal, vfprintf);
+ldbl_hidden_def (_IO_vfprintf_internal, vfprintf)
+ldbl_strong_alias (_IO_vfprintf_internal, _IO_vfprintf);
+#endif
diff --git a/libc/dfp/sysdeps/dfp/stdio-common/vfscanf.c b/libc/dfp/sysdeps/dfp/stdio-common/vfscanf.c
new file mode 100644
index 000000000..b17c6fb44
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdio-common/vfscanf.c
@@ -0,0 +1,2524 @@
+/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <dfpstdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <bits/libc-lock.h>
+#include <locale/localeinfo.h>
+
+#ifdef __GNUC__
+# define HAVE_LONGLONG
+# define LONGLONG long long
+#else
+# define LONGLONG long
+#endif
+
+/* Determine whether we have to handle `long long' at all. */
+#if LONG_MAX == LONG_LONG_MAX
+# define need_longlong 0
+#else
+# define need_longlong 1
+#endif
+
+/* Determine whether we have to handle `long'. */
+#if INT_MAX == LONG_MAX
+# define need_long 0
+#else
+# define need_long 1
+#endif
+
+/* Those are flags in the conversion format. */
+#define LONG 0x001 /* l: long or double */
+#define LONGDBL 0x002 /* L: long long or long double */
+#define SHORT 0x004 /* h: short */
+#define SUPPRESS 0x008 /* *: suppress assignment */
+#define POINTER 0x010 /* weird %p pointer (`fake hex') */
+#define NOSKIP 0x020 /* do not skip blanks */
+#define WIDTH 0x040 /* width was given */
+#define GROUP 0x080 /* ': group numbers */
+#define MALLOC 0x100 /* a: malloc strings */
+#define CHAR 0x200 /* hh: char */
+#define I18N 0x400 /* I: use locale's digits */
+#define DECIMAL 0x800 /* H/D/DD: decimal float */
+
+
+#include <locale/localeinfo.h>
+#include <libioP.h>
+#include <libio.h>
+
+#undef va_list
+#define va_list _IO_va_list
+
+#ifdef COMPILE_WSCANF
+# define ungetc(c, s) ((void) (c == WEOF \
+ || (--read_in, \
+ INTUSE(_IO_sputbackwc) (s, c))))
+# define ungetc_not_eof(c, s) ((void) (--read_in, \
+ INTUSE(_IO_sputbackwc) (s, c)))
+# define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
+ : ((c = _IO_getwc_unlocked (s)), \
+ (void) (c != WEOF \
+ ? ++read_in \
+ : (size_t) (inchar_errno = errno)), c))
+
+# define MEMCPY(d, s, n) __wmemcpy (d, s, n)
+# define ISSPACE(Ch) iswspace (Ch)
+# define ISDIGIT(Ch) iswdigit (Ch)
+# define ISXDIGIT(Ch) iswxdigit (Ch)
+# define TOLOWER(Ch) towlower (Ch)
+# define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF
+# define __strtoll_internal __wcstoll_internal
+# define __strtoull_internal __wcstoull_internal
+# define __strtol_internal __wcstol_internal
+# define __strtoul_internal __wcstoul_internal
+# define __strtold_internal __wcstold_internal
+# define __strtod_internal __wcstod_internal
+# define __strtof_internal __wcstof_internal
+
+# define L_(Str) L##Str
+# define CHAR_T wchar_t
+# define UCHAR_T unsigned int
+# define WINT_T wint_t
+# undef EOF
+# define EOF WEOF
+#else
+# define ungetc(c, s) ((void) ((int) c == EOF \
+ || (--read_in, \
+ INTUSE(_IO_sputbackc) (s, (unsigned char) c))))
+# define ungetc_not_eof(c, s) ((void) (--read_in, \
+ INTUSE(_IO_sputbackc) (s, (unsigned char) c)))
+# define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
+ : ((c = _IO_getc_unlocked (s)), \
+ (void) (c != EOF \
+ ? ++read_in \
+ : (size_t) (inchar_errno = errno)), c))
+# define MEMCPY(d, s, n) memcpy (d, s, n)
+# define ISSPACE(Ch) __isspace_l (Ch, loc)
+# define ISDIGIT(Ch) __isdigit_l (Ch, loc)
+# define ISXDIGIT(Ch) __isxdigit_l (Ch, loc)
+# define TOLOWER(Ch) __tolower_l ((unsigned char) (Ch), loc)
+# define ORIENT if (_IO_vtable_offset (s) == 0 \
+ && _IO_fwide (s, -1) != -1) \
+ return EOF
+
+# define L_(Str) Str
+# define CHAR_T char
+# define UCHAR_T unsigned char
+# define WINT_T int
+#endif
+
+#define encode_error() do { \
+ errval = 4; \
+ __set_errno (EILSEQ); \
+ goto errout; \
+ } while (0)
+#define conv_error() do { \
+ errval = 2; \
+ goto errout; \
+ } while (0)
+#define input_error() do { \
+ errval = 1; \
+ if (done == 0) done = EOF; \
+ goto errout; \
+ } while (0)
+#define ARGCHECK(s, format) \
+ do \
+ { \
+ /* Check file argument for consistence. */ \
+ CHECK_FILE (s, EOF); \
+ if (s->_flags & _IO_NO_READS) \
+ { \
+ __set_errno (EBADF); \
+ return EOF; \
+ } \
+ else if (format == NULL) \
+ { \
+ MAYBE_SET_EINVAL; \
+ return EOF; \
+ } \
+ } while (0)
+#define LOCK_STREAM(S) \
+ __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \
+ _IO_flockfile (S)
+#define UNLOCK_STREAM(S) \
+ _IO_funlockfile (S); \
+ __libc_cleanup_region_end (0)
+
+
+/* Read formatted input from S according to the format string
+ FORMAT, using the argument list in ARG.
+ Return the number of assignments made, or -1 for an input error. */
+#ifdef COMPILE_WSCANF
+int
+_IO_vfwscanf (_IO_FILE *s, const wchar_t *format, _IO_va_list argptr,
+ int *errp)
+#else
+int
+_IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
+ int *errp)
+#endif
+{
+ va_list arg;
+ register const CHAR_T *f = format;
+ register UCHAR_T fc; /* Current character of the format. */
+ register WINT_T done = 0; /* Assignments done. */
+ register size_t read_in = 0; /* Chars read in. */
+ register WINT_T c = 0; /* Last char read. */
+ register int width; /* Maximum field width. */
+ register int flags; /* Modifiers for current format element. */
+ int errval = 0;
+#ifndef COMPILE_WSCANF
+ __locale_t loc = _NL_CURRENT_LOCALE;
+ struct locale_data *const curctype = loc->__locales[LC_CTYPE];
+#endif
+
+ /* Errno of last failed inchar call. */
+ int inchar_errno = 0;
+ /* Status for reading F-P nums. */
+ char got_dot, got_e, negative;
+ /* If a [...] is a [^...]. */
+ CHAR_T not_in;
+#define exp_char not_in
+ /* Base for integral numbers. */
+ int base;
+ /* Signedness for integral numbers. */
+ int number_signed;
+#define is_hexa number_signed
+ /* Decimal point character. */
+#ifdef COMPILE_WSCANF
+ wint_t decimal;
+#else
+ const char *decimal;
+#endif
+ /* The thousands character of the current locale. */
+#ifdef COMPILE_WSCANF
+ wint_t thousands;
+#else
+ const char *thousands;
+#endif
+ /* State for the conversions. */
+ mbstate_t state;
+ /* Integral holding variables. */
+ union
+ {
+ long long int q;
+ unsigned long long int uq;
+ long int l;
+ unsigned long int ul;
+ } num;
+ /* Character-buffer pointer. */
+ char *str = NULL;
+ wchar_t *wstr = NULL;
+ char **strptr = NULL;
+ ssize_t strsize = 0;
+ /* We must not react on white spaces immediately because they can
+ possibly be matched even if in the input stream no character is
+ available anymore. */
+ int skip_space = 0;
+ /* Nonzero if we are reading a pointer. */
+ int read_pointer;
+ /* Workspace. */
+ CHAR_T *tw; /* Temporary pointer. */
+ CHAR_T *wp = NULL; /* Workspace. */
+ size_t wpmax = 0; /* Maximal size of workspace. */
+ size_t wpsize; /* Currently used bytes in workspace. */
+#define ADDW(Ch) \
+ do \
+ { \
+ if (wpsize == wpmax) \
+ { \
+ CHAR_T *old = wp; \
+ wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \
+ wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \
+ if (old != NULL) \
+ MEMCPY (wp, old, wpsize); \
+ } \
+ wp[wpsize++] = (Ch); \
+ } \
+ while (0)
+
+#ifdef __va_copy
+ __va_copy (arg, argptr);
+#else
+ arg = (va_list) argptr;
+#endif
+
+#ifdef ORIENT
+ ORIENT;
+#endif
+
+ ARGCHECK (s, format);
+
+ {
+#ifndef COMPILE_WSCANF
+ struct locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
+#endif
+
+ /* Figure out the decimal point character. */
+#ifdef COMPILE_WSCANF
+ decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
+#else
+ decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
+#endif
+ /* Figure out the thousands separator character. */
+#ifdef COMPILE_WSCANF
+ thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
+#else
+ thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
+ if (*thousands == '\0')
+ thousands = NULL;
+#endif
+ }
+
+ /* Lock the stream. */
+ LOCK_STREAM (s);
+
+
+#ifndef COMPILE_WSCANF
+ /* From now on we use `state' to convert the format string. */
+ memset (&state, '\0', sizeof (state));
+#endif
+
+ /* Run through the format string. */
+ while (*f != '\0')
+ {
+ unsigned int argpos;
+ /* Extract the next argument, which is of type TYPE.
+ For a %N$... spec, this is the Nth argument from the beginning;
+ otherwise it is the next argument after the state now in ARG. */
+#ifdef __va_copy
+# define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
+ ({ unsigned int pos = argpos; \
+ va_list arg; \
+ __va_copy (arg, argptr); \
+ while (--pos > 0) \
+ (void) va_arg (arg, void *); \
+ va_arg (arg, type); \
+ }))
+#else
+# if 0
+ /* XXX Possible optimization. */
+# define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
+ ({ va_list arg = (va_list) argptr; \
+ arg = (va_list) ((char *) arg \
+ + (argpos - 1) \
+ * __va_rounded_size (void *)); \
+ va_arg (arg, type); \
+ }))
+# else
+# define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
+ ({ unsigned int pos = argpos; \
+ va_list arg = (va_list) argptr; \
+ while (--pos > 0) \
+ (void) va_arg (arg, void *); \
+ va_arg (arg, type); \
+ }))
+# endif
+#endif
+
+#ifndef COMPILE_WSCANF
+ if (!isascii ((unsigned char) *f))
+ {
+ /* Non-ASCII, may be a multibyte. */
+ int len = __mbrlen (f, strlen (f), &state);
+ if (len > 0)
+ {
+ do
+ {
+ c = inchar ();
+ if (__builtin_expect (c == EOF, 0))
+ input_error ();
+ else if (c != (unsigned char) *f++)
+ {
+ ungetc_not_eof (c, s);
+ conv_error ();
+ }
+ }
+ while (--len > 0);
+ continue;
+ }
+ }
+#endif
+
+ fc = *f++;
+ if (fc != '%')
+ {
+ /* Remember to skip spaces. */
+ if (ISSPACE (fc))
+ {
+ skip_space = 1;
+ continue;
+ }
+
+ /* Read a character. */
+ c = inchar ();
+
+ /* Characters other than format specs must just match. */
+ if (__builtin_expect (c == EOF, 0))
+ input_error ();
+
+ /* We saw white space char as the last character in the format
+ string. Now it's time to skip all leading white space. */
+ if (skip_space)
+ {
+ while (ISSPACE (c))
+ if (__builtin_expect (inchar () == EOF, 0))
+ input_error ();
+ skip_space = 0;
+ }
+
+ if (__builtin_expect (c != fc, 0))
+ {
+ ungetc (c, s);
+ conv_error ();
+ }
+
+ continue;
+ }
+
+ /* This is the start of the conversion string. */
+ flags = 0;
+
+ /* Not yet decided whether we read a pointer or not. */
+ read_pointer = 0;
+
+ /* Initialize state of modifiers. */
+ argpos = 0;
+
+ /* Prepare temporary buffer. */
+ wpsize = 0;
+
+ /* Check for a positional parameter specification. */
+ if (ISDIGIT ((UCHAR_T) *f))
+ {
+ argpos = (UCHAR_T) *f++ - L_('0');
+ while (ISDIGIT ((UCHAR_T) *f))
+ argpos = argpos * 10 + ((UCHAR_T) *f++ - L_('0'));
+ if (*f == L_('$'))
+ ++f;
+ else
+ {
+ /* Oops; that was actually the field width. */
+ width = argpos;
+ flags |= WIDTH;
+ argpos = 0;
+ goto got_width;
+ }
+ }
+
+ /* Check for the assignment-suppressing, the number grouping flag,
+ and the signal to use the locale's digit representation. */
+ while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
+ switch (*f++)
+ {
+ case L_('*'):
+ flags |= SUPPRESS;
+ break;
+ case L_('\''):
+ flags |= GROUP;
+ break;
+ case L_('I'):
+ flags |= I18N;
+ break;
+ }
+
+ /* We have seen width. */
+ if (ISDIGIT ((UCHAR_T) *f))
+ flags |= WIDTH;
+
+ /* Find the maximum field width. */
+ width = 0;
+ while (ISDIGIT ((UCHAR_T) *f))
+ {
+ width *= 10;
+ width += (UCHAR_T) *f++ - L_('0');
+ }
+ got_width:
+ if (width == 0)
+ width = -1;
+
+ /* Check for type modifiers. */
+ switch (*f++)
+ {
+ case L_('h'):
+ /* ints are short ints or chars. */
+ if (*f == L_('h'))
+ {
+ ++f;
+ flags |= CHAR;
+ }
+ else
+ flags |= SHORT;
+ break;
+ case L_('l'):
+ if (*f == L_('l'))
+ {
+ /* A double `l' is equivalent to an `L'. */
+ ++f;
+ flags |= LONGDBL | LONG;
+ }
+ else
+ /* ints are long ints. */
+ flags |= LONG;
+ break;
+ case L_('q'):
+ case L_('L'):
+ /* doubles are long doubles, and ints are long long ints. */
+ flags |= LONGDBL | LONG;
+ break;
+ case L_('a'):
+ /* The `a' is used as a flag only if followed by `s', `S' or
+ `['. */
+ if (*f != L_('s') && *f != L_('S') && *f != L_('['))
+ {
+ --f;
+ break;
+ }
+ /* String conversions (%s, %[) take a `char **'
+ arg and fill it in with a malloc'd pointer. */
+ flags |= MALLOC;
+ break;
+ case L_('z'):
+ if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
+ flags |= LONGDBL;
+ else if (sizeof (size_t) > sizeof (unsigned int))
+ flags |= LONG;
+ break;
+ case L_('j'):
+ if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
+ flags |= LONGDBL;
+ else if (sizeof (uintmax_t) > sizeof (unsigned int))
+ flags |= LONG;
+ break;
+ case L_('t'):
+ if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
+ flags |= LONGDBL;
+ else if (sizeof (ptrdiff_t) > sizeof (int))
+ flags |= LONG;
+ break;
+ default:
+ /* Not a recognized modifier. Backup. */
+ --f;
+ break;
+ }
+
+ /* End of the format string? */
+ if (__builtin_expect (*f == L_('\0'), 0))
+ conv_error ();
+
+ /* Find the conversion specifier. */
+ fc = *f++;
+ if (skip_space || (fc != L_('[') && fc != L_('c')
+ && fc != L_('C') && fc != L_('n')))
+ {
+ /* Eat whitespace. */
+ int save_errno = errno;
+ errno = 0;
+ do
+ if (__builtin_expect (inchar () == EOF && errno == EINTR, 0))
+ input_error ();
+ while (ISSPACE (c));
+ errno = save_errno;
+ ungetc (c, s);
+ skip_space = 0;
+ }
+
+found_decimal:
+ switch (fc)
+ {
+ case L_('%'): /* Must match a literal '%'. */
+ c = inchar ();
+ if (__builtin_expect (c == EOF, 0))
+ input_error ();
+ if (__builtin_expect (c != fc, 0))
+ {
+ ungetc_not_eof (c, s);
+ conv_error ();
+ }
+ break;
+
+ case L_('n'): /* Answer number of assignments done. */
+ /* Corrigendum 1 to ISO C 1990 describes the allowed flags
+ with the 'n' conversion specifier. */
+ if (!(flags & SUPPRESS))
+ {
+ /* Don't count the read-ahead. */
+ if (need_longlong && (flags & LONGDBL))
+ *ARG (long long int *) = read_in;
+ else if (need_long && (flags & LONG))
+ *ARG (long int *) = read_in;
+ else if (flags & SHORT)
+ *ARG (short int *) = read_in;
+ else if (!(flags & CHAR))
+ *ARG (int *) = read_in;
+ else
+ *ARG (char *) = read_in;
+
+#ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
+ /* We have a severe problem here. The ISO C standard
+ contradicts itself in explaining the effect of the %n
+ format in `scanf'. While in ISO C:1990 and the ISO C
+ Amendement 1:1995 the result is described as
+
+ Execution of a %n directive does not effect the
+ assignment count returned at the completion of
+ execution of the f(w)scanf function.
+
+ in ISO C Corrigendum 1:1994 the following was added:
+
+ Subclause 7.9.6.2
+ Add the following fourth example:
+ In:
+ #include <stdio.h>
+ int d1, d2, n1, n2, i;
+ i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
+ the value 123 is assigned to d1 and the value3 to n1.
+ Because %n can never get an input failure the value
+ of 3 is also assigned to n2. The value of d2 is not
+ affected. The value 3 is assigned to i.
+
+ We go for now with the historically correct code from ISO C,
+ i.e., we don't count the %n assignments. When it ever
+ should proof to be wrong just remove the #ifdef above. */
+ ++done;
+#endif
+ }
+ break;
+
+ case L_('c'): /* Match characters. */
+ if ((flags & LONG) == 0)
+ {
+ if (!(flags & SUPPRESS))
+ {
+ str = ARG (char *);
+ if (str == NULL)
+ conv_error ();
+ }
+
+ c = inchar ();
+ if (__builtin_expect (c == EOF, 0))
+ input_error ();
+
+ if (width == -1)
+ width = 1;
+
+#ifdef COMPILE_WSCANF
+ /* We have to convert the wide character(s) into multibyte
+ characters and store the result. */
+ memset (&state, '\0', sizeof (state));
+
+ do
+ {
+ size_t n;
+
+ n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
+ if (__builtin_expect (n == (size_t) -1, 0))
+ /* No valid wide character. */
+ input_error ();
+
+ /* Increment the output pointer. Even if we don't
+ write anything. */
+ str += n;
+ }
+ while (--width > 0 && inchar () != EOF);
+#else
+ if (!(flags & SUPPRESS))
+ {
+ do
+ *str++ = c;
+ while (--width > 0 && inchar () != EOF);
+ }
+ else
+ while (--width > 0 && inchar () != EOF);
+#endif
+
+ if (!(flags & SUPPRESS))
+ ++done;
+
+ break;
+ }
+ /* FALLTHROUGH */
+ case L_('C'):
+ if (!(flags & SUPPRESS))
+ {
+ wstr = ARG (wchar_t *);
+ if (wstr == NULL)
+ conv_error ();
+ }
+
+ c = inchar ();
+ if (__builtin_expect (c == EOF, 0))
+ input_error ();
+
+#ifdef COMPILE_WSCANF
+ /* Just store the incoming wide characters. */
+ if (!(flags & SUPPRESS))
+ {
+ do
+ *wstr++ = c;
+ while (--width > 0 && inchar () != EOF);
+ }
+ else
+ while (--width > 0 && inchar () != EOF);
+#else
+ {
+ /* We have to convert the multibyte input sequence to wide
+ characters. */
+ char buf[1];
+ mbstate_t cstate;
+
+ memset (&cstate, '\0', sizeof (cstate));
+
+ do
+ {
+ /* This is what we present the mbrtowc function first. */
+ buf[0] = c;
+
+ while (1)
+ {
+ size_t n;
+
+ n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
+ buf, 1, &cstate);
+
+ if (n == (size_t) -2)
+ {
+ /* Possibly correct character, just not enough
+ input. */
+ if (__builtin_expect (inchar () == EOF, 0))
+ encode_error ();
+
+ buf[0] = c;
+ continue;
+ }
+
+ if (__builtin_expect (n != 1, 0))
+ encode_error ();
+
+ /* We have a match. */
+ break;
+ }
+
+ /* Advance the result pointer. */
+ ++wstr;
+ }
+ while (--width > 0 && inchar () != EOF);
+ }
+#endif
+
+ if (!(flags & SUPPRESS))
+ ++done;
+
+ break;
+
+ case L_('s'): /* Read a string. */
+ if (!(flags & LONG))
+ {
+#define STRING_ARG(Str, Type) \
+ do if (!(flags & SUPPRESS)) \
+ { \
+ if (flags & MALLOC) \
+ { \
+ /* The string is to be stored in a malloc'd buffer. */ \
+ strptr = ARG (char **); \
+ if (strptr == NULL) \
+ conv_error (); \
+ /* Allocate an initial buffer. */ \
+ strsize = 100; \
+ *strptr = (char *) malloc (strsize * sizeof (Type)); \
+ Str = (Type *) *strptr; \
+ } \
+ else \
+ Str = ARG (Type *); \
+ if (Str == NULL) \
+ conv_error (); \
+ } while (0)
+ STRING_ARG (str, char);
+
+ c = inchar ();
+ if (__builtin_expect (c == EOF, 0))
+ input_error ();
+
+#ifdef COMPILE_WSCANF
+ memset (&state, '\0', sizeof (state));
+#endif
+
+ do
+ {
+ if (ISSPACE (c))
+ {
+ ungetc_not_eof (c, s);
+ break;
+ }
+
+#ifdef COMPILE_WSCANF
+ /* This is quite complicated. We have to convert the
+ wide characters into multibyte characters and then
+ store them. */
+ {
+ size_t n;
+
+ if (!(flags & SUPPRESS) && (flags & MALLOC)
+ && str + MB_CUR_MAX >= *strptr + strsize)
+ {
+ /* We have to enlarge the buffer if the `a' flag
+ was given. */
+ size_t strleng = str - *strptr;
+ char *newstr;
+
+ newstr = (char *) realloc (*strptr, strsize * 2);
+ if (newstr == NULL)
+ {
+ /* Can't allocate that much. Last-ditch
+ effort. */
+ newstr = (char *) realloc (*strptr,
+ strleng + MB_CUR_MAX);
+ if (newstr == NULL)
+ {
+ /* We lose. Oh well. Terminate the
+ string and stop converting,
+ so at least we don't skip any input. */
+ ((char *) (*strptr))[strleng] = '\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = newstr;
+ str = newstr + strleng;
+ strsize = strleng + MB_CUR_MAX;
+ }
+ }
+ else
+ {
+ *strptr = newstr;
+ str = newstr + strleng;
+ strsize *= 2;
+ }
+ }
+
+ n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
+ &state);
+ if (__builtin_expect (n == (size_t) -1, 0))
+ encode_error ();
+
+ assert (n <= MB_CUR_MAX);
+ str += n;
+ }
+#else
+ /* This is easy. */
+ if (!(flags & SUPPRESS))
+ {
+ *str++ = c;
+ if ((flags & MALLOC)
+ && (char *) str == *strptr + strsize)
+ {
+ /* Enlarge the buffer. */
+ str = (char *) realloc (*strptr, 2 * strsize);
+ if (str == NULL)
+ {
+ /* Can't allocate that much. Last-ditch
+ effort. */
+ str = (char *) realloc (*strptr, strsize + 1);
+ if (str == NULL)
+ {
+ /* We lose. Oh well. Terminate the
+ string and stop converting,
+ so at least we don't skip any input. */
+ ((char *) (*strptr))[strsize - 1] = '\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = (char *) str;
+ str += strsize;
+ ++strsize;
+ }
+ }
+ else
+ {
+ *strptr = (char *) str;
+ str += strsize;
+ strsize *= 2;
+ }
+ }
+ }
+#endif
+ }
+ while ((width <= 0 || --width > 0) && inchar () != EOF);
+
+ if (!(flags & SUPPRESS))
+ {
+#ifdef COMPILE_WSCANF
+ /* We have to emit the code to get into the initial
+ state. */
+ char buf[MB_LEN_MAX];
+ size_t n = __wcrtomb (buf, L'\0', &state);
+ if (n > 0 && (flags & MALLOC)
+ && str + n >= *strptr + strsize)
+ {
+ /* Enlarge the buffer. */
+ size_t strleng = str - *strptr;
+ char *newstr;
+
+ newstr = (char *) realloc (*strptr, strleng + n + 1);
+ if (newstr == NULL)
+ {
+ /* We lose. Oh well. Terminate the string
+ and stop converting, so at least we don't
+ skip any input. */
+ ((char *) (*strptr))[strleng] = '\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = newstr;
+ str = newstr + strleng;
+ strsize = strleng + n + 1;
+ }
+ }
+
+ str = __mempcpy (str, buf, n);
+#endif
+ *str++ = '\0';
+
+ if ((flags & MALLOC) && str - *strptr != strsize)
+ {
+ char *cp = (char *) realloc (*strptr, str - *strptr);
+ if (cp != NULL)
+ *strptr = cp;
+ }
+
+ ++done;
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case L_('S'):
+ {
+#ifndef COMPILE_WSCANF
+ mbstate_t cstate;
+#endif
+
+ /* Wide character string. */
+ STRING_ARG (wstr, wchar_t);
+
+ c = inchar ();
+ if (__builtin_expect (c == EOF, 0))
+ input_error ();
+
+#ifndef COMPILE_WSCANF
+ memset (&cstate, '\0', sizeof (cstate));
+#endif
+
+ do
+ {
+ if (ISSPACE (c))
+ {
+ ungetc_not_eof (c, s);
+ break;
+ }
+
+#ifdef COMPILE_WSCANF
+ /* This is easy. */
+ if (!(flags & SUPPRESS))
+ {
+ *wstr++ = c;
+ if ((flags & MALLOC)
+ && wstr == (wchar_t *) *strptr + strsize)
+ {
+ /* Enlarge the buffer. */
+ wstr = (wchar_t *) realloc (*strptr,
+ (2 * strsize)
+ * sizeof (wchar_t));
+ if (wstr == NULL)
+ {
+ /* Can't allocate that much. Last-ditch
+ effort. */
+ wstr = (wchar_t *) realloc (*strptr,
+ (strsize + 1)
+ * sizeof (wchar_t));
+ if (wstr == NULL)
+ {
+ /* We lose. Oh well. Terminate the string
+ and stop converting, so at least we don't
+ skip any input. */
+ ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = (char *) wstr;
+ wstr += strsize;
+ ++strsize;
+ }
+ }
+ else
+ {
+ *strptr = (char *) wstr;
+ wstr += strsize;
+ strsize *= 2;
+ }
+ }
+ }
+#else
+ {
+ char buf[1];
+
+ buf[0] = c;
+
+ while (1)
+ {
+ size_t n;
+
+ n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
+ buf, 1, &cstate);
+
+ if (n == (size_t) -2)
+ {
+ /* Possibly correct character, just not enough
+ input. */
+ if (__builtin_expect (inchar () == EOF, 0))
+ encode_error ();
+
+ buf[0] = c;
+ continue;
+ }
+
+ if (__builtin_expect (n != 1, 0))
+ encode_error ();
+
+ /* We have a match. */
+ ++wstr;
+ break;
+ }
+
+ if (!(flags & SUPPRESS) && (flags & MALLOC)
+ && wstr == (wchar_t *) *strptr + strsize)
+ {
+ /* Enlarge the buffer. */
+ wstr = (wchar_t *) realloc (*strptr,
+ (2 * strsize
+ * sizeof (wchar_t)));
+ if (wstr == NULL)
+ {
+ /* Can't allocate that much. Last-ditch effort. */
+ wstr = (wchar_t *) realloc (*strptr,
+ ((strsize + 1)
+ * sizeof (wchar_t)));
+ if (wstr == NULL)
+ {
+ /* We lose. Oh well. Terminate the
+ string and stop converting, so at
+ least we don't skip any input. */
+ ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = (char *) wstr;
+ wstr += strsize;
+ ++strsize;
+ }
+ }
+ else
+ {
+ *strptr = (char *) wstr;
+ wstr += strsize;
+ strsize *= 2;
+ }
+ }
+ }
+#endif
+ }
+ while ((width <= 0 || --width > 0) && inchar () != EOF);
+
+ if (!(flags & SUPPRESS))
+ {
+ *wstr++ = L'\0';
+
+ if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
+ {
+ wchar_t *cp = (wchar_t *) realloc (*strptr,
+ ((wstr
+ - (wchar_t *) *strptr)
+ * sizeof(wchar_t)));
+ if (cp != NULL)
+ *strptr = (char *) cp;
+ }
+
+ ++done;
+ }
+ }
+ break;
+
+ case L_('x'): /* Hexadecimal integer. */
+ case L_('X'): /* Ditto. */
+ base = 16;
+ number_signed = 0;
+ goto number;
+
+ case L_('o'): /* Octal integer. */
+ base = 8;
+ number_signed = 0;
+ goto number;
+
+ case L_('u'): /* Unsigned decimal integer. */
+ base = 10;
+ number_signed = 0;
+ goto number;
+
+ case L_('d'): /* Signed decimal integer. */
+ base = 10;
+ number_signed = 1;
+ goto number;
+
+ case L_('i'): /* Generic number. */
+ base = 0;
+ number_signed = 1;
+
+ number:
+ c = inchar ();
+ if (__builtin_expect (c == EOF, 0))
+ input_error ();
+
+ /* Check for a sign. */
+ if (c == L_('-') || c == L_('+'))
+ {
+ ADDW (c);
+ if (width > 0)
+ --width;
+ c = inchar ();
+ }
+
+ /* Look for a leading indication of base. */
+ if (width != 0 && c == L_('0'))
+ {
+ if (width > 0)
+ --width;
+
+ ADDW (c);
+ c = inchar ();
+
+ if (width != 0 && TOLOWER (c) == L_('x'))
+ {
+ if (base == 0)
+ base = 16;
+ if (base == 16)
+ {
+ if (width > 0)
+ --width;
+ c = inchar ();
+ }
+ }
+ else if (base == 0)
+ base = 8;
+ }
+
+ if (base == 0)
+ base = 10;
+
+ if (base == 10 && __builtin_expect ((flags & I18N) != 0, 0))
+ {
+ int from_level;
+ int to_level;
+ int level;
+#ifdef COMPILE_WSCANF
+ const wchar_t *wcdigits[10];
+ const wchar_t *wcdigits_extended[10];
+#else
+ const char *mbdigits[10];
+ const char *mbdigits_extended[10];
+#endif
+ /* "to_inpunct" is a map from ASCII digits to their
+ equivalent in locale. This is defined for locales
+ which use an extra digits set. */
+ wctrans_t map = __wctrans ("to_inpunct");
+ int n;
+
+ from_level = 0;
+#ifdef COMPILE_WSCANF
+ to_level = _NL_CURRENT_WORD (LC_CTYPE,
+ _NL_CTYPE_INDIGITS_WC_LEN) - 1;
+#else
+ to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
+#endif
+
+ /* Get the alternative digit forms if there are any. */
+ if (__builtin_expect (map != NULL, 0))
+ {
+ /* Adding new level for extra digits set in locale file. */
+ ++to_level;
+
+ for (n = 0; n < 10; ++n)
+ {
+#ifdef COMPILE_WSCANF
+ wcdigits[n] = (const wchar_t *)
+ _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
+
+ wchar_t *wc_extended = (wchar_t *)
+ alloca ((to_level + 2) * sizeof (wchar_t));
+ __wmemcpy (wc_extended, wcdigits[n], to_level);
+ wc_extended[to_level] = __towctrans (L'0' + n, map);
+ wc_extended[to_level + 1] = '\0';
+ wcdigits_extended[n] = wc_extended;
+#else
+ mbdigits[n]
+ = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
+
+ /* Get the equivalent wide char in map. */
+ wint_t extra_wcdigit = __towctrans (L'0' + n, map);
+
+ /* Convert it to multibyte representation. */
+ mbstate_t state;
+ memset (&state, '\0', sizeof (state));
+
+ char extra_mbdigit[MB_LEN_MAX];
+ size_t mblen
+ = __wcrtomb (extra_mbdigit, extra_wcdigit, &state);
+
+ if (mblen == (size_t) -1)
+ {
+ /* Ignore this new level. */
+ map = NULL;
+ break;
+ }
+
+ /* Calculate the length of mbdigits[n]. */
+ const char *last_char = mbdigits[n];
+ for (level = 0; level < to_level; ++level)
+ last_char = strchr (last_char, '\0') + 1;
+
+ size_t mbdigits_len = last_char - mbdigits[n];
+
+ /* Allocate memory for extended multibyte digit. */
+ char *mb_extended;
+ mb_extended = (char *) alloca (mbdigits_len + mblen + 1);
+
+ /* And get the mbdigits + extra_digit string. */
+ *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n],
+ mbdigits_len),
+ extra_mbdigit, mblen) = '\0';
+ mbdigits_extended[n] = mb_extended;
+#endif
+ }
+ }
+
+ /* Read the number into workspace. */
+ while (c != EOF && width != 0)
+ {
+ /* In this round we get the pointer to the digit strings
+ and also perform the first round of comparisons. */
+ for (n = 0; n < 10; ++n)
+ {
+ /* Get the string for the digits with value N. */
+#ifdef COMPILE_WSCANF
+ if (__builtin_expect (map != NULL, 0))
+ wcdigits[n] = wcdigits_extended[n];
+ else
+ wcdigits[n] = (const wchar_t *)
+ _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
+ wcdigits[n] += from_level;
+
+ if (c == (wint_t) *wcdigits[n])
+ {
+ to_level = from_level;
+ break;
+ }
+
+ /* Advance the pointer to the next string. */
+ ++wcdigits[n];
+#else
+ const char *cmpp;
+ int avail = width > 0 ? width : INT_MAX;
+
+ if (__builtin_expect (map != NULL, 0))
+ mbdigits[n] = mbdigits_extended[n];
+ else
+ mbdigits[n]
+ = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
+
+ for (level = 0; level < from_level; level++)
+ mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
+
+ cmpp = mbdigits[n];
+ while ((unsigned char) *cmpp == c && avail > 0)
+ {
+ if (*++cmpp == '\0')
+ break;
+ else
+ {
+ if ((c = inchar ()) == EOF)
+ break;
+ --avail;
+ }
+ }
+
+ if (*cmpp == '\0')
+ {
+ if (width > 0)
+ width = avail;
+ to_level = from_level;
+ break;
+ }
+
+ /* We are pushing all read characters back. */
+ if (cmpp > mbdigits[n])
+ {
+ ungetc (c, s);
+ while (--cmpp > mbdigits[n])
+ ungetc_not_eof ((unsigned char) *cmpp, s);
+ c = (unsigned char) *cmpp;
+ }
+
+ /* Advance the pointer to the next string. */
+ mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
+#endif
+ }
+
+ if (n == 10)
+ {
+ /* Have not yet found the digit. */
+ for (level = from_level + 1; level <= to_level; ++level)
+ {
+ /* Search all ten digits of this level. */
+ for (n = 0; n < 10; ++n)
+ {
+#ifdef COMPILE_WSCANF
+ if (c == (wint_t) *wcdigits[n])
+ break;
+
+ /* Advance the pointer to the next string. */
+ ++wcdigits[n];
+#else
+ const char *cmpp;
+ int avail = width > 0 ? width : INT_MAX;
+
+ cmpp = mbdigits[n];
+ while ((unsigned char) *cmpp == c && avail > 0)
+ {
+ if (*++cmpp == '\0')
+ break;
+ else
+ {
+ if ((c = inchar ()) == EOF)
+ break;
+ --avail;
+ }
+ }
+
+ if (*cmpp == '\0')
+ {
+ if (width > 0)
+ width = avail;
+ break;
+ }
+
+ /* We are pushing all read characters back. */
+ if (cmpp > mbdigits[n])
+ {
+ ungetc (c, s);
+ while (--cmpp > mbdigits[n])
+ ungetc_not_eof ((unsigned char) *cmpp, s);
+ c = (unsigned char) *cmpp;
+ }
+
+ /* Advance the pointer to the next string. */
+ mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
+#endif
+ }
+
+ if (n < 10)
+ {
+ /* Found it. */
+ from_level = level;
+ to_level = level;
+ break;
+ }
+ }
+ }
+
+ if (n < 10)
+ c = L_('0') + n;
+ else if ((flags & GROUP)
+#ifdef COMPILE_WSCANF
+ && thousands != L'\0'
+#else
+ && thousands != NULL
+#endif
+ )
+ {
+ /* Try matching against the thousands separator. */
+#ifdef COMPILE_WSCANF
+ if (c != thousands)
+ break;
+#else
+ const char *cmpp = thousands;
+ int avail = width > 0 ? width : INT_MAX;
+
+ while ((unsigned char) *cmpp == c && avail > 0)
+ {
+ ADDW (c);
+ if (*++cmpp == '\0')
+ break;
+ else
+ {
+ if ((c = inchar ()) == EOF)
+ break;
+ --avail;
+ }
+ }
+
+ if (*cmpp != '\0')
+ {
+ /* We are pushing all read characters back. */
+ if (cmpp > thousands)
+ {
+ wpsize -= cmpp - thousands;
+ ungetc (c, s);
+ while (--cmpp > thousands)
+ ungetc_not_eof ((unsigned char) *cmpp, s);
+ c = (unsigned char) *cmpp;
+ }
+ break;
+ }
+
+ if (width > 0)
+ width = avail;
+
+ /* The last thousands character will be added back by
+ the ADDW below. */
+ --wpsize;
+#endif
+ }
+ else
+ break;
+
+ ADDW (c);
+ if (width > 0)
+ --width;
+
+ c = inchar ();
+ }
+ }
+ else
+ /* Read the number into workspace. */
+ while (c != EOF && width != 0)
+ {
+ if (base == 16)
+ {
+ if (!ISXDIGIT (c))
+ break;
+ }
+ else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base)
+ {
+ if (base == 10 && (flags & GROUP)
+#ifdef COMPILE_WSCANF
+ && thousands != L'\0'
+#else
+ && thousands != NULL
+#endif
+ )
+ {
+ /* Try matching against the thousands separator. */
+#ifdef COMPILE_WSCANF
+ if (c != thousands)
+ break;
+#else
+ const char *cmpp = thousands;
+ int avail = width > 0 ? width : INT_MAX;
+
+ while ((unsigned char) *cmpp == c && avail > 0)
+ {
+ ADDW (c);
+ if (*++cmpp == '\0')
+ break;
+ else
+ {
+ if ((c = inchar ()) == EOF)
+ break;
+ --avail;
+ }
+ }
+
+ if (*cmpp != '\0')
+ {
+ /* We are pushing all read characters back. */
+ if (cmpp > thousands)
+ {
+ wpsize -= cmpp - thousands;
+ ungetc (c, s);
+ while (--cmpp > thousands)
+ ungetc_not_eof ((unsigned char) *cmpp, s);
+ c = (unsigned char) *cmpp;
+ }
+ break;
+ }
+
+ if (width > 0)
+ width = avail;
+
+ /* The last thousands character will be added back by
+ the ADDW below. */
+ --wpsize;
+#endif
+ }
+ else
+ break;
+ }
+ ADDW (c);
+ if (width > 0)
+ --width;
+
+ c = inchar ();
+ }
+
+ if (wpsize == 0
+ || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
+ {
+ /* There was no number. If we are supposed to read a pointer
+ we must recognize "(nil)" as well. */
+ if (__builtin_expect (wpsize == 0
+ && read_pointer
+ && (width < 0 || width >= 0)
+ && c == '('
+ && TOLOWER (inchar ()) == L_('n')
+ && TOLOWER (inchar ()) == L_('i')
+ && TOLOWER (inchar ()) == L_('l')
+ && inchar () == L_(')'), 1))
+ /* We must produce the value of a NULL pointer. A single
+ '0' digit is enough. */
+ ADDW (L_('0'));
+ else
+ {
+ /* The last read character is not part of the number
+ anymore. */
+ ungetc (c, s);
+
+ conv_error ();
+ }
+ }
+ else
+ /* The just read character is not part of the number anymore. */
+ ungetc (c, s);
+
+ /* Convert the number. */
+ ADDW (L_('\0'));
+ if (need_longlong && (flags & LONGDBL))
+ {
+ if (number_signed)
+ num.q = __strtoll_internal (wp, &tw, base, flags & GROUP);
+ else
+ num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP);
+ }
+ else
+ {
+ if (number_signed)
+ num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
+ else
+ num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
+ }
+ if (__builtin_expect (wp == tw, 0))
+ conv_error ();
+
+ if (!(flags & SUPPRESS))
+ {
+ if (! number_signed)
+ {
+ if (need_longlong && (flags & LONGDBL))
+ *ARG (unsigned LONGLONG int *) = num.uq;
+ else if (need_long && (flags & LONG))
+ *ARG (unsigned long int *) = num.ul;
+ else if (flags & SHORT)
+ *ARG (unsigned short int *)
+ = (unsigned short int) num.ul;
+ else if (!(flags & CHAR))
+ *ARG (unsigned int *) = (unsigned int) num.ul;
+ else
+ *ARG (unsigned char *) = (unsigned char) num.ul;
+ }
+ else
+ {
+ if (need_longlong && (flags & LONGDBL))
+ *ARG (LONGLONG int *) = num.q;
+ else if (need_long && (flags & LONG))
+ *ARG (long int *) = num.l;
+ else if (flags & SHORT)
+ *ARG (short int *) = (short int) num.l;
+ else if (!(flags & CHAR))
+ *ARG (int *) = (int) num.l;
+ else
+ *ARG (signed char *) = (signed char) num.ul;
+ }
+ ++done;
+ }
+ break;
+
+ case L_('H'): /* _Decimal32 */
+ base = 10;
+ number_signed = 1;
+ flags |= DECIMAL | SHORT;
+ fc = *f++;
+ /* Pick up trailing float modifier. */
+ goto found_decimal;
+
+ case L_('D'): /* _Decimal64 */
+ flags |= DECIMAL;
+ base = 10;
+ number_signed = 1;
+ char tfc;
+ tfc = *f++;
+ if (tfc == L_('D')) /* _Decimal128 */
+ flags |= LONGDBL;
+ else
+ --f; /* Only one 'D'. Back it up. It is not %DD. */
+ fc = *f++;
+ /* Pick up trailing float modifier. */
+ goto found_decimal;
+
+ case L_('e'): /* Floating-point numbers. */
+ case L_('E'):
+ case L_('f'):
+ case L_('F'):
+ case L_('g'):
+ case L_('G'):
+ case L_('a'):
+ case L_('A'):
+ c = inchar ();
+ if (__builtin_expect (c == EOF, 0))
+ input_error ();
+
+ got_dot = got_e = 0;
+
+ /* Check for a sign. */
+ if (c == L_('-') || c == L_('+'))
+ {
+ negative = c == L_('-');
+ if (__builtin_expect (width == 0 || inchar () == EOF, 0))
+ /* EOF is only an input error before we read any chars. */
+ conv_error ();
+ if (! ISDIGIT (c) && TOLOWER (c) != L_('i')
+ && TOLOWER (c) != L_('n'))
+ {
+#ifdef COMPILE_WSCANF
+ if (__builtin_expect (c != decimal, 0))
+ {
+ /* This is no valid number. */
+ ungetc (c, s);
+ conv_error ();
+ }
+#else
+ /* Match against the decimal point. At this point
+ we are taking advantage of the fact that we can
+ push more than one character back. This is
+ (almost) never necessary since the decimal point
+ string hopefully never contains more than one
+ byte. */
+ const char *cmpp = decimal;
+ int avail = width > 0 ? width : INT_MAX;
+
+ while ((unsigned char) *cmpp == c && avail-- > 0)
+ if (*++cmpp == '\0')
+ break;
+ else
+ {
+ if (inchar () == EOF)
+ break;
+ }
+
+ if (__builtin_expect (*cmpp != '\0', 0))
+ {
+ /* This is no valid number. */
+ while (1)
+ {
+ ungetc (c, s);
+ if (cmpp == decimal)
+ break;
+ c = (unsigned char) *--cmpp;
+ }
+
+ conv_error ();
+ }
+ else
+ {
+ /* Add all the characters. */
+ for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
+ ADDW ((unsigned char) *cmpp);
+ if (width > 0)
+ width = avail;
+ got_dot = 1;
+
+ c = inchar ();
+ }
+ if (width > 0)
+ width = avail;
+#endif
+ }
+ if (width > 0)
+ --width;
+ }
+ else
+ negative = 0;
+
+ /* Take care for the special arguments "nan" and "inf". */
+ if (TOLOWER (c) == L_('n'))
+ {
+ /* Maybe "nan". */
+ ADDW (c);
+ if (__builtin_expect (width == 0
+ || inchar () == EOF
+ || TOLOWER (c) != L_('a'), 0))
+ conv_error ();
+ if (width > 0)
+ --width;
+ ADDW (c);
+ if (__builtin_expect (width == 0
+ || inchar () == EOF
+ || TOLOWER (c) != L_('n'), 0))
+ conv_error ();
+ if (width > 0)
+ --width;
+ ADDW (c);
+ /* It is "nan". */
+ goto scan_float;
+ }
+ else if (TOLOWER (c) == L_('i'))
+ {
+ /* Maybe "inf" or "infinity". */
+ ADDW (c);
+ if (__builtin_expect (width == 0
+ || inchar () == EOF
+ || TOLOWER (c) != L_('n'), 0))
+ conv_error ();
+ if (width > 0)
+ --width;
+ ADDW (c);
+ if (__builtin_expect (width == 0
+ || inchar () == EOF
+ || TOLOWER (c) != L_('f'), 0))
+ conv_error ();
+ if (width > 0)
+ --width;
+ ADDW (c);
+ /* It is as least "inf". */
+ if (width != 0 && inchar () != EOF)
+ {
+ if (TOLOWER (c) == L_('i'))
+ {
+ if (width > 0)
+ --width;
+ /* Now we have to read the rest as well. */
+ ADDW (c);
+ if (__builtin_expect (width == 0
+ || inchar () == EOF
+ || TOLOWER (c) != L_('n'), 0))
+ conv_error ();
+ if (width > 0)
+ --width;
+ ADDW (c);
+ if (__builtin_expect (width == 0
+ || inchar () == EOF
+ || TOLOWER (c) != L_('i'), 0))
+ conv_error ();
+ if (width > 0)
+ --width;
+ ADDW (c);
+ if (__builtin_expect (width == 0
+ || inchar () == EOF
+ || TOLOWER (c) != L_('t'), 0))
+ conv_error ();
+ if (width > 0)
+ --width;
+ ADDW (c);
+ if (__builtin_expect (width == 0
+ || inchar () == EOF
+ || TOLOWER (c) != L_('y'), 0))
+ conv_error ();
+ if (width > 0)
+ --width;
+ ADDW (c);
+ }
+ else
+ /* Never mind. */
+ ungetc (c, s);
+ }
+ goto scan_float;
+ }
+
+ is_hexa = 0;
+ exp_char = L_('e');
+ if (width != 0 && c == L_('0'))
+ {
+ ADDW (c);
+ c = inchar ();
+ if (width > 0)
+ --width;
+ if (width != 0 && TOLOWER (c) == L_('x'))
+ {
+ /* It is a number in hexadecimal format. */
+ ADDW (c);
+
+ is_hexa = 1;
+ exp_char = L_('p');
+
+ /* Grouping is not allowed. */
+ flags &= ~GROUP;
+ c = inchar ();
+ if (width > 0)
+ --width;
+ }
+ }
+
+ do
+ {
+ if (ISDIGIT (c))
+ ADDW (c);
+ else if (!got_e && is_hexa && ISXDIGIT (c))
+ ADDW (c);
+ else if (got_e && wp[wpsize - 1] == exp_char
+ && (c == L_('-') || c == L_('+')))
+ ADDW (c);
+ else if (wpsize > 0 && !got_e
+ && (CHAR_T) TOLOWER (c) == exp_char)
+ {
+ ADDW (exp_char);
+ got_e = got_dot = 1;
+ }
+ else
+ {
+#ifdef COMPILE_WSCANF
+ if (! got_dot && c == decimal)
+ {
+ ADDW (c);
+ got_dot = 1;
+ }
+ else if ((flags & GROUP) != 0 && thousands != L'\0'
+ && ! got_dot && c == thousands)
+ ADDW (c);
+ else
+ {
+ /* The last read character is not part of the number
+ anymore. */
+ ungetc (c, s);
+ break;
+ }
+#else
+ const char *cmpp = decimal;
+ int avail = width > 0 ? width : INT_MAX;
+
+ if (! got_dot)
+ {
+ while ((unsigned char) *cmpp == c && avail > 0)
+ if (*++cmpp == '\0')
+ break;
+ else
+ {
+ if (inchar () == EOF)
+ break;
+ --avail;
+ }
+ }
+
+ if (*cmpp == '\0')
+ {
+ /* Add all the characters. */
+ for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
+ ADDW ((unsigned char) *cmpp);
+ if (width > 0)
+ width = avail;
+ got_dot = 1;
+ }
+ else
+ {
+ /* Figure out whether it is a thousands separator.
+ There is one problem: we possibly read more than
+ one character. We cannot push them back but since
+ we know that parts of the `decimal' string matched,
+ we can compare against it. */
+ const char *cmp2p = thousands;
+
+ if ((flags & GROUP) != 0 && thousands != NULL
+ && ! got_dot)
+ {
+ while (cmp2p - thousands < cmpp - decimal
+ && *cmp2p == decimal[cmp2p - thousands])
+ ++cmp2p;
+ if (cmp2p - thousands == cmpp - decimal)
+ {
+ while ((unsigned char) *cmp2p == c && avail > 0)
+ if (*++cmp2p == '\0')
+ break;
+ else
+ {
+ if (inchar () == EOF)
+ break;
+ --avail;
+ }
+ }
+ }
+
+ if (cmp2p != NULL && *cmp2p == '\0')
+ {
+ /* Add all the characters. */
+ for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
+ ADDW ((unsigned char) *cmpp);
+ if (width > 0)
+ width = avail;
+ }
+ else
+ {
+ /* The last read character is not part of the number
+ anymore. */
+ ungetc (c, s);
+ break;
+ }
+ }
+#endif
+ }
+ if (width > 0)
+ --width;
+ }
+ while (width != 0 && inchar () != EOF);
+
+ /* Have we read any character? If we try to read a number
+ in hexadecimal notation and we have read only the `0x'
+ prefix or no exponent this is an error. */
+ if (__builtin_expect (wpsize == 0
+ || (is_hexa && (wpsize == 2 || ! got_e)), 0))
+ conv_error ();
+
+ scan_float:
+ /* Convert the number. */
+ ADDW (L_('\0'));
+ if((flags & DECIMAL) && (flags & SHORT))
+ {
+ _Decimal32 d = __strtod32_internal(wp, &tw, flags & GROUP);
+ if (!(flags & SUPPRESS) && tw != wp)
+ /* va_arg is currently busted in libgcc for _Decimal32 so this
+ * will segfault */
+ *ARG (_Decimal32 *) = negative ? -d : d;
+ }
+ else if((flags & DECIMAL) && (flags & LONGDBL))
+ {
+ _Decimal128 d = __strtod128_internal(wp, &tw, flags & GROUP);
+ if (!(flags & SUPPRESS) && tw != wp)
+ *ARG (_Decimal128 *) = negative ? -d : d;
+ }
+ else if (flags & DECIMAL)
+ {
+ _Decimal64 d = __strtod64_internal(wp, &tw, flags & GROUP);
+ if (!(flags & SUPPRESS) && tw != wp)
+ *ARG (_Decimal64 *) = negative ? -d : d;
+ }
+ else if ((flags & LONGDBL) && !__ldbl_is_dbl)
+ {
+ long double d = __strtold_internal (wp, &tw, flags & GROUP);
+ if (!(flags & SUPPRESS) && tw != wp)
+ *ARG (long double *) = negative ? -d : d;
+ }
+ else if (flags & (LONG | LONGDBL))
+ {
+ double d = __strtod_internal (wp, &tw, flags & GROUP);
+ if (!(flags & SUPPRESS) && tw != wp)
+ *ARG (double *) = negative ? -d : d;
+ }
+ else
+ {
+ float d = __strtof_internal (wp, &tw, flags & GROUP);
+ if (!(flags & SUPPRESS) && tw != wp)
+ *ARG (float *) = negative ? -d : d;
+ }
+
+ if (__builtin_expect (tw == wp, 0))
+ conv_error ();
+
+ if (!(flags & SUPPRESS))
+ ++done;
+ break;
+
+ case L_('['): /* Character class. */
+ if (flags & LONG)
+ STRING_ARG (wstr, wchar_t);
+ else
+ STRING_ARG (str, char);
+
+ if (*f == L_('^'))
+ {
+ ++f;
+ not_in = 1;
+ }
+ else
+ not_in = 0;
+
+ if (width < 0)
+ /* There is no width given so there is also no limit on the
+ number of characters we read. Therefore we set width to
+ a very high value to make the algorithm easier. */
+ width = INT_MAX;
+
+#ifdef COMPILE_WSCANF
+ /* Find the beginning and the end of the scanlist. We are not
+ creating a lookup table since it would have to be too large.
+ Instead we search each time through the string. This is not
+ a constant lookup time but who uses this feature deserves to
+ be punished. */
+ tw = (wchar_t *) f; /* Marks the beginning. */
+
+ if (*f == L']')
+ ++f;
+
+ while ((fc = *f++) != L'\0' && fc != L']');
+
+ if (__builtin_expect (fc == L'\0', 0))
+ conv_error ();
+ wp = (wchar_t *) f - 1;
+#else
+ /* Fill WP with byte flags indexed by character.
+ We will use this flag map for matching input characters. */
+ if (wpmax < UCHAR_MAX + 1)
+ {
+ wpmax = UCHAR_MAX + 1;
+ wp = (char *) alloca (wpmax);
+ }
+ memset (wp, '\0', UCHAR_MAX + 1);
+
+ fc = *f;
+ if (fc == ']' || fc == '-')
+ {
+ /* If ] or - appears before any char in the set, it is not
+ the terminator or separator, but the first char in the
+ set. */
+ wp[fc] = 1;
+ ++f;
+ }
+
+ while ((fc = *f++) != '\0' && fc != ']')
+ if (fc == '-' && *f != '\0' && *f != ']'
+ && (unsigned char) f[-2] <= (unsigned char) *f)
+ {
+ /* Add all characters from the one before the '-'
+ up to (but not including) the next format char. */
+ for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
+ wp[fc] = 1;
+ }
+ else
+ /* Add the character to the flag map. */
+ wp[fc] = 1;
+
+ if (__builtin_expect (fc == '\0', 0))
+ conv_error();
+#endif
+
+ if (flags & LONG)
+ {
+ size_t now = read_in;
+#ifdef COMPILE_WSCANF
+ if (__builtin_expect (inchar () == WEOF, 0))
+ input_error ();
+
+ do
+ {
+ wchar_t *runp;
+
+ /* Test whether it's in the scanlist. */
+ runp = tw;
+ while (runp < wp)
+ {
+ if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp
+ && runp != tw
+ && (unsigned int) runp[-1] <= (unsigned int) runp[1])
+ {
+ /* Match against all characters in between the
+ first and last character of the sequence. */
+ wchar_t wc;
+
+ for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
+ if ((wint_t) wc == c)
+ break;
+
+ if (wc <= runp[1] && !not_in)
+ break;
+ if (wc <= runp[1] && not_in)
+ {
+ /* The current character is not in the
+ scanset. */
+ ungetc (c, s);
+ goto out;
+ }
+
+ runp += 2;
+ }
+ else
+ {
+ if ((wint_t) *runp == c && !not_in)
+ break;
+ if ((wint_t) *runp == c && not_in)
+ {
+ ungetc (c, s);
+ goto out;
+ }
+
+ ++runp;
+ }
+ }
+
+ if (runp == wp && !not_in)
+ {
+ ungetc (c, s);
+ goto out;
+ }
+
+ if (!(flags & SUPPRESS))
+ {
+ *wstr++ = c;
+
+ if ((flags & MALLOC)
+ && wstr == (wchar_t *) *strptr + strsize)
+ {
+ /* Enlarge the buffer. */
+ wstr = (wchar_t *) realloc (*strptr,
+ (2 * strsize)
+ * sizeof (wchar_t));
+ if (wstr == NULL)
+ {
+ /* Can't allocate that much. Last-ditch
+ effort. */
+ wstr = (wchar_t *)
+ realloc (*strptr, (strsize + 1)
+ * sizeof (wchar_t));
+ if (wstr == NULL)
+ {
+ /* We lose. Oh well. Terminate the string
+ and stop converting, so at least we don't
+ skip any input. */
+ ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = (char *) wstr;
+ wstr += strsize;
+ ++strsize;
+ }
+ }
+ else
+ {
+ *strptr = (char *) wstr;
+ wstr += strsize;
+ strsize *= 2;
+ }
+ }
+ }
+ }
+ while (--width > 0 && inchar () != WEOF);
+ out:
+#else
+ char buf[MB_LEN_MAX];
+ size_t cnt = 0;
+ mbstate_t cstate;
+
+ if (__builtin_expect (inchar () == EOF, 0))
+ input_error ();
+
+ memset (&cstate, '\0', sizeof (cstate));
+
+ do
+ {
+ if (wp[c] == not_in)
+ {
+ ungetc_not_eof (c, s);
+ break;
+ }
+
+ /* This is easy. */
+ if (!(flags & SUPPRESS))
+ {
+ size_t n;
+
+ /* Convert it into a wide character. */
+ buf[0] = c;
+ n = __mbrtowc (wstr, buf, 1, &cstate);
+
+ if (n == (size_t) -2)
+ {
+ /* Possibly correct character, just not enough
+ input. */
+ ++cnt;
+ assert (cnt < MB_CUR_MAX);
+ continue;
+ }
+ cnt = 0;
+
+ ++wstr;
+ if ((flags & MALLOC)
+ && wstr == (wchar_t *) *strptr + strsize)
+ {
+ /* Enlarge the buffer. */
+ wstr = (wchar_t *) realloc (*strptr,
+ (2 * strsize
+ * sizeof (wchar_t)));
+ if (wstr == NULL)
+ {
+ /* Can't allocate that much. Last-ditch
+ effort. */
+ wstr = (wchar_t *)
+ realloc (*strptr, ((strsize + 1)
+ * sizeof (wchar_t)));
+ if (wstr == NULL)
+ {
+ /* We lose. Oh well. Terminate the
+ string and stop converting,
+ so at least we don't skip any input. */
+ ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = (char *) wstr;
+ wstr += strsize;
+ ++strsize;
+ }
+ }
+ else
+ {
+ *strptr = (char *) wstr;
+ wstr += strsize;
+ strsize *= 2;
+ }
+ }
+ }
+
+ if (--width <= 0)
+ break;
+ }
+ while (inchar () != EOF);
+
+ if (__builtin_expect (cnt != 0, 0))
+ /* We stopped in the middle of recognizing another
+ character. That's a problem. */
+ encode_error ();
+#endif
+
+ if (__builtin_expect (now == read_in, 0))
+ /* We haven't succesfully read any character. */
+ conv_error ();
+
+ if (!(flags & SUPPRESS))
+ {
+ *wstr++ = L'\0';
+
+ if ((flags & MALLOC)
+ && wstr - (wchar_t *) *strptr != strsize)
+ {
+ wchar_t *cp = (wchar_t *)
+ realloc (*strptr, ((wstr - (wchar_t *) *strptr)
+ * sizeof(wchar_t)));
+ if (cp != NULL)
+ *strptr = (char *) cp;
+ }
+
+ ++done;
+ }
+ }
+ else
+ {
+ size_t now = read_in;
+
+ if (__builtin_expect (inchar () == EOF, 0))
+ input_error ();
+
+#ifdef COMPILE_WSCANF
+
+ memset (&state, '\0', sizeof (state));
+
+ do
+ {
+ wchar_t *runp;
+ size_t n;
+
+ /* Test whether it's in the scanlist. */
+ runp = tw;
+ while (runp < wp)
+ {
+ if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp
+ && runp != tw
+ && (unsigned int) runp[-1] <= (unsigned int) runp[1])
+ {
+ /* Match against all characters in between the
+ first and last character of the sequence. */
+ wchar_t wc;
+
+ for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
+ if ((wint_t) wc == c)
+ break;
+
+ if (wc <= runp[1] && !not_in)
+ break;
+ if (wc <= runp[1] && not_in)
+ {
+ /* The current character is not in the
+ scanset. */
+ ungetc (c, s);
+ goto out2;
+ }
+
+ runp += 2;
+ }
+ else
+ {
+ if ((wint_t) *runp == c && !not_in)
+ break;
+ if ((wint_t) *runp == c && not_in)
+ {
+ ungetc (c, s);
+ goto out2;
+ }
+
+ ++runp;
+ }
+ }
+
+ if (runp == wp && !not_in)
+ {
+ ungetc (c, s);
+ goto out2;
+ }
+
+ if (!(flags & SUPPRESS))
+ {
+ if ((flags & MALLOC)
+ && str + MB_CUR_MAX >= *strptr + strsize)
+ {
+ /* Enlarge the buffer. */
+ size_t strleng = str - *strptr;
+ char *newstr;
+
+ newstr = (char *) realloc (*strptr, 2 * strsize);
+ if (newstr == NULL)
+ {
+ /* Can't allocate that much. Last-ditch
+ effort. */
+ newstr = (char *) realloc (*strptr,
+ strleng + MB_CUR_MAX);
+ if (newstr == NULL)
+ {
+ /* We lose. Oh well. Terminate the string
+ and stop converting, so at least we don't
+ skip any input. */
+ ((char *) (*strptr))[strleng] = '\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = newstr;
+ str = newstr + strleng;
+ strsize = strleng + MB_CUR_MAX;
+ }
+ }
+ else
+ {
+ *strptr = newstr;
+ str = newstr + strleng;
+ strsize *= 2;
+ }
+ }
+ }
+
+ n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
+ if (__builtin_expect (n == (size_t) -1, 0))
+ encode_error ();
+
+ assert (n <= MB_CUR_MAX);
+ str += n;
+ }
+ while (--width > 0 && inchar () != WEOF);
+ out2:
+#else
+ do
+ {
+ if (wp[c] == not_in)
+ {
+ ungetc_not_eof (c, s);
+ break;
+ }
+
+ /* This is easy. */
+ if (!(flags & SUPPRESS))
+ {
+ *str++ = c;
+ if ((flags & MALLOC)
+ && (char *) str == *strptr + strsize)
+ {
+ /* Enlarge the buffer. */
+ size_t newsize = 2 * strsize;
+
+ allocagain:
+ str = (char *) realloc (*strptr, newsize);
+ if (str == NULL)
+ {
+ /* Can't allocate that much. Last-ditch
+ effort. */
+ if (newsize > strsize + 1)
+ {
+ newsize = strsize + 1;
+ goto allocagain;
+ }
+ /* We lose. Oh well. Terminate the
+ string and stop converting,
+ so at least we don't skip any input. */
+ ((char *) (*strptr))[strsize - 1] = '\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = (char *) str;
+ str += strsize;
+ strsize = newsize;
+ }
+ }
+ }
+ }
+ while (--width > 0 && inchar () != EOF);
+#endif
+
+ if (__builtin_expect (now == read_in, 0))
+ /* We haven't succesfully read any character. */
+ conv_error ();
+
+ if (!(flags & SUPPRESS))
+ {
+#ifdef COMPILE_WSCANF
+ /* We have to emit the code to get into the initial
+ state. */
+ char buf[MB_LEN_MAX];
+ size_t n = __wcrtomb (buf, L'\0', &state);
+ if (n > 0 && (flags & MALLOC)
+ && str + n >= *strptr + strsize)
+ {
+ /* Enlarge the buffer. */
+ size_t strleng = str - *strptr;
+ char *newstr;
+
+ newstr = (char *) realloc (*strptr, strleng + n + 1);
+ if (newstr == NULL)
+ {
+ /* We lose. Oh well. Terminate the string
+ and stop converting, so at least we don't
+ skip any input. */
+ ((char *) (*strptr))[strleng] = '\0';
+ ++done;
+ conv_error ();
+ }
+ else
+ {
+ *strptr = newstr;
+ str = newstr + strleng;
+ strsize = strleng + n + 1;
+ }
+ }
+
+ str = __mempcpy (str, buf, n);
+#endif
+ *str++ = '\0';
+
+ if ((flags & MALLOC) && str - *strptr != strsize)
+ {
+ char *cp = (char *) realloc (*strptr, str - *strptr);
+ if (cp != NULL)
+ *strptr = cp;
+ }
+
+ ++done;
+ }
+ }
+ break;
+
+ case L_('p'): /* Generic pointer. */
+ base = 16;
+ /* A PTR must be the same size as a `long int'. */
+ flags &= ~(SHORT|LONGDBL);
+ if (need_long)
+ flags |= LONG;
+ number_signed = 0;
+ read_pointer = 1;
+ goto number;
+
+ default:
+ /* If this is an unknown format character punt. */
+ conv_error ();
+ }
+ }
+
+ /* The last thing we saw int the format string was a white space.
+ Consume the last white spaces. */
+ if (skip_space)
+ {
+ do
+ c = inchar ();
+ while (ISSPACE (c));
+ ungetc (c, s);
+ }
+
+ errout:
+ /* Unlock stream. */
+ UNLOCK_STREAM (s);
+
+ if (errp != NULL)
+ *errp |= errval;
+
+ return done;
+}
+
+#ifdef COMPILE_WSCANF
+int
+__vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
+{
+ return _IO_vfwscanf (s, format, argptr, NULL);
+}
+ldbl_weak_alias (__vfwscanf, vfwscanf)
+#else
+int
+___vfscanf (FILE *s, const char *format, va_list argptr)
+{
+ return _IO_vfscanf_internal (s, format, argptr, NULL);
+}
+ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf)
+ldbl_strong_alias (___vfscanf, __vfscanf)
+ldbl_hidden_def (___vfscanf, __vfscanf)
+ldbl_weak_alias (___vfscanf, vfscanf)
+#endif
diff --git a/libc/dfp/sysdeps/dfp/stdlib/dfpstdlib.h b/libc/dfp/sysdeps/dfp/stdlib/dfpstdlib.h
new file mode 100644
index 000000000..7330e5051
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdlib/dfpstdlib.h
@@ -0,0 +1,35 @@
+/* Internal function prototypes for string-to-decimal conversions
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DFPSTDLIB_H
+#define _DFPSTDLIB_H 1
+
+#include <features.h>
+
+extern _Decimal32 __strtod32_internal (const char * __restrict nptr, char ** __restrict endptr, int group);
+extern _Decimal64 __strtod64_internal (const char * __restrict nptr, char ** __restrict endptr, int group);
+extern _Decimal128 __strtod128_internal (const char * __restrict nptr, char ** __restrict endptr, int group);
+
+libc_hidden_proto (__strtod32_internal)
+libc_hidden_proto (__strtod64_internal)
+libc_hidden_proto (__strtod128_internal)
+
+#endif /* _DFPSTDLIB_H */
diff --git a/libc/dfp/sysdeps/dfp/stdlib/stdlib.h b/libc/dfp/sysdeps/dfp/stdlib/stdlib.h
new file mode 100644
index 000000000..85552cffc
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdlib/stdlib.h
@@ -0,0 +1,1000 @@
+/* Copyright (C) 1991-2003,2004,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * ISO C99 Standard: 7.20 General utilities <stdlib.h>
+ */
+
+#ifndef _STDLIB_H
+
+#include <features.h>
+
+/* Get size_t, wchar_t and NULL from <stddef.h>. */
+#define __need_size_t
+#ifndef __need_malloc_and_calloc
+# define __need_wchar_t
+# define __need_NULL
+#endif
+#include <stddef.h>
+
+__BEGIN_DECLS
+
+#ifndef __need_malloc_and_calloc
+#define _STDLIB_H 1
+
+#if defined __USE_XOPEN && !defined _SYS_WAIT_H
+/* XPG requires a few symbols from <sys/wait.h> being defined. */
+# include <bits/waitflags.h>
+# include <bits/waitstatus.h>
+
+# ifdef __USE_BSD
+
+/* Lots of hair to allow traditional BSD use of `union wait'
+ as well as POSIX.1 use of `int' for the status word. */
+
+# if defined __GNUC__ && !defined __cplusplus
+# define __WAIT_INT(status) \
+ (__extension__ ({ union { __typeof(status) __in; int __i; } __u; \
+ __u.__in = (status); __u.__i; }))
+# else
+# define __WAIT_INT(status) (*(int *) &(status))
+# endif
+
+/* This is the type of the argument to `wait'. The funky union
+ causes redeclarations with ether `int *' or `union wait *' to be
+ allowed without complaint. __WAIT_STATUS_DEFN is the type used in
+ the actual function definitions. */
+
+# if !defined __GNUC__ || __GNUC__ < 2 || defined __cplusplus
+# define __WAIT_STATUS void *
+# define __WAIT_STATUS_DEFN void *
+# else
+/* This works in GCC 2.6.1 and later. */
+typedef union
+ {
+ union wait *__uptr;
+ int *__iptr;
+ } __WAIT_STATUS __attribute__ ((__transparent_union__));
+# define __WAIT_STATUS_DEFN int *
+# endif
+
+# else /* Don't use BSD. */
+
+# define __WAIT_INT(status) (status)
+# define __WAIT_STATUS int *
+# define __WAIT_STATUS_DEFN int *
+
+# endif /* Use BSD. */
+
+/* Define the macros <sys/wait.h> also would define this way. */
+# define WEXITSTATUS(status) __WEXITSTATUS(__WAIT_INT(status))
+# define WTERMSIG(status) __WTERMSIG(__WAIT_INT(status))
+# define WSTOPSIG(status) __WSTOPSIG(__WAIT_INT(status))
+# define WIFEXITED(status) __WIFEXITED(__WAIT_INT(status))
+# define WIFSIGNALED(status) __WIFSIGNALED(__WAIT_INT(status))
+# define WIFSTOPPED(status) __WIFSTOPPED(__WAIT_INT(status))
+# ifdef __WIFCONTINUED
+# define WIFCONTINUED(status) __WIFCONTINUED(__WAIT_INT(status))
+# endif
+#endif /* X/Open and <sys/wait.h> not included. */
+
+__BEGIN_NAMESPACE_STD
+/* Returned by `div'. */
+typedef struct
+ {
+ int quot; /* Quotient. */
+ int rem; /* Remainder. */
+ } div_t;
+
+/* Returned by `ldiv'. */
+#ifndef __ldiv_t_defined
+typedef struct
+ {
+ long int quot; /* Quotient. */
+ long int rem; /* Remainder. */
+ } ldiv_t;
+# define __ldiv_t_defined 1
+#endif
+__END_NAMESPACE_STD
+
+#if defined __USE_ISOC99 && !defined __lldiv_t_defined
+__BEGIN_NAMESPACE_C99
+/* Returned by `lldiv'. */
+__extension__ typedef struct
+ {
+ long long int quot; /* Quotient. */
+ long long int rem; /* Remainder. */
+ } lldiv_t;
+# define __lldiv_t_defined 1
+__END_NAMESPACE_C99
+#endif
+
+
+/* The largest number rand will return (same as INT_MAX). */
+#define RAND_MAX 2147483647
+
+
+/* We define these the same for all machines.
+ Changes from this to the outside world should be done in `_exit'. */
+#define EXIT_FAILURE 1 /* Failing exit status. */
+#define EXIT_SUCCESS 0 /* Successful exit status. */
+
+
+/* Maximum length of a multibyte character in the current locale. */
+#define MB_CUR_MAX (__ctype_get_mb_cur_max ())
+extern size_t __ctype_get_mb_cur_max (void) __THROW __wur;
+
+
+__BEGIN_NAMESPACE_STD
+/* Convert a string to a floating-point number. */
+extern double atof (__const char *__nptr)
+ __THROW __attribute_pure__ __nonnull ((1)) __wur;
+/* Convert a string to an integer. */
+extern int atoi (__const char *__nptr)
+ __THROW __attribute_pure__ __nonnull ((1)) __wur;
+/* Convert a string to a long integer. */
+extern long int atol (__const char *__nptr)
+ __THROW __attribute_pure__ __nonnull ((1)) __wur;
+__END_NAMESPACE_STD
+
+#if defined __USE_ISOC99 || (defined __GLIBC_HAVE_LONG_LONG && defined __USE_MISC)
+__BEGIN_NAMESPACE_C99
+/* Convert a string to a long long integer. */
+__extension__ extern long long int atoll (__const char *__nptr)
+ __THROW __attribute_pure__ __nonnull ((1)) __wur;
+__END_NAMESPACE_C99
+#endif
+
+__BEGIN_NAMESPACE_STD
+/* Convert a string to a floating-point number. */
+extern double strtod (__const char *__restrict __nptr,
+ char **__restrict __endptr)
+ __THROW __nonnull ((1)) __wur;
+__END_NAMESPACE_STD
+
+#ifdef __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Likewise for `float' and `long double' sizes of floating-point numbers. */
+extern float strtof (__const char *__restrict __nptr,
+ char **__restrict __endptr) __THROW __nonnull ((1)) __wur;
+
+extern long double strtold (__const char *__restrict __nptr,
+ char **__restrict __endptr)
+ __THROW __nonnull ((1)) __wur;
+__END_NAMESPACE_C99
+#endif
+
+__BEGIN_NAMESPACE_STD
+/* Convert a string to a long integer. */
+extern long int strtol (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __base)
+ __THROW __nonnull ((1)) __wur;
+/* Convert a string to an unsigned long integer. */
+extern unsigned long int strtoul (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __base)
+ __THROW __nonnull ((1)) __wur;
+__END_NAMESPACE_STD
+
+#if defined __GLIBC_HAVE_LONG_LONG && defined __USE_BSD
+/* Convert a string to a quadword integer. */
+__extension__
+extern long long int strtoq (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __base)
+ __THROW __nonnull ((1)) __wur;
+/* Convert a string to an unsigned quadword integer. */
+__extension__
+extern unsigned long long int strtouq (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __base)
+ __THROW __nonnull ((1)) __wur;
+#endif /* GCC and use BSD. */
+
+#if defined __USE_ISOC99 || (defined __GLIBC_HAVE_LONG_LONG && defined __USE_MISC)
+__BEGIN_NAMESPACE_C99
+/* Convert a string to a quadword integer. */
+__extension__
+extern long long int strtoll (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __base)
+ __THROW __nonnull ((1)) __wur;
+/* Convert a string to an unsigned quadword integer. */
+__extension__
+extern unsigned long long int strtoull (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __base)
+ __THROW __nonnull ((1)) __wur;
+__END_NAMESPACE_C99
+#endif /* ISO C99 or GCC and use MISC. */
+
+#ifdef __STDC_WANT_DEC_FP__
+__BEGIN_NAMESPACE_STD
+/* Convert a string to a _Decimal32 number. */
+extern _Decimal32 strtod32 (__const char *__restrict __nptr,
+ char **__restrict __endptr)
+ __THROW __nonnull ((1)) __wur;
+/* Convert a string to a _Decimal64 number. */
+
+extern _Decimal64 strtod64 (__const char *__restrict __nptr,
+ char **__restrict __endptr)
+ __THROW __nonnull ((1)) __wur;
+
+/* Convert a string to a _Decimal128 number. */
+extern _Decimal128 strtod128 (__const char *__restrict __nptr,
+ char **__restrict __endptr)
+ __THROW __nonnull ((1)) __wur;
+__END_NAMESPACE_STD
+#endif
+
+
+
+#ifdef __USE_GNU
+/* The concept of one static locale per category is not very well
+ thought out. Many applications will need to process its data using
+ information from several different locales. Another application is
+ the implementation of the internationalization handling in the
+ upcoming ISO C++ standard library. To support this another set of
+ the functions using locale data exist which have an additional
+ argument.
+
+ Attention: all these functions are *not* standardized in any form.
+ This is a proof-of-concept implementation. */
+
+/* Structure for reentrant locale using functions. This is an
+ (almost) opaque type for the user level programs. */
+# include <xlocale.h>
+
+/* Special versions of the functions above which take the locale to
+ use as an additional parameter. */
+extern long int strtol_l (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __base,
+ __locale_t __loc) __THROW __nonnull ((1, 4)) __wur;
+
+extern unsigned long int strtoul_l (__const char *__restrict __nptr,
+ char **__restrict __endptr,
+ int __base, __locale_t __loc)
+ __THROW __nonnull ((1, 4)) __wur;
+
+__extension__
+extern long long int strtoll_l (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __base,
+ __locale_t __loc)
+ __THROW __nonnull ((1, 4)) __wur;
+
+__extension__
+extern unsigned long long int strtoull_l (__const char *__restrict __nptr,
+ char **__restrict __endptr,
+ int __base, __locale_t __loc)
+ __THROW __nonnull ((1, 4)) __wur;
+
+extern double strtod_l (__const char *__restrict __nptr,
+ char **__restrict __endptr, __locale_t __loc)
+ __THROW __nonnull ((1, 3)) __wur;
+
+extern float strtof_l (__const char *__restrict __nptr,
+ char **__restrict __endptr, __locale_t __loc)
+ __THROW __nonnull ((1, 3)) __wur;
+
+extern long double strtold_l (__const char *__restrict __nptr,
+ char **__restrict __endptr,
+ __locale_t __loc)
+ __THROW __nonnull ((1, 3)) __wur;
+#endif /* GNU */
+
+
+/* The internal entry points for `strtoX' take an extra flag argument
+ saying whether or not to parse locale-dependent number grouping. */
+
+extern double __strtod_internal (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __group)
+ __THROW __nonnull ((1)) __wur;
+extern float __strtof_internal (__const char *__restrict __nptr,
+ char **__restrict __endptr, int __group)
+ __THROW __nonnull ((1)) __wur;
+extern long double __strtold_internal (__const char *__restrict __nptr,
+ char **__restrict __endptr,
+ int __group)
+ __THROW __nonnull ((1)) __wur;
+#ifndef __strtol_internal_defined
+extern long int __strtol_internal (__const char *__restrict __nptr,
+ char **__restrict __endptr,
+ int __base, int __group)
+ __THROW __nonnull ((1)) __wur;
+# define __strtol_internal_defined 1
+#endif
+#ifndef __strtoul_internal_defined
+extern unsigned long int __strtoul_internal (__const char *__restrict __nptr,
+ char **__restrict __endptr,
+ int __base, int __group)
+ __THROW __nonnull ((1)) __wur;
+# define __strtoul_internal_defined 1
+#endif
+#if defined __GNUC__ || defined __USE_ISOC99
+# ifndef __strtoll_internal_defined
+__extension__
+extern long long int __strtoll_internal (__const char *__restrict __nptr,
+ char **__restrict __endptr,
+ int __base, int __group)
+ __THROW __nonnull ((1)) __wur;
+# define __strtoll_internal_defined 1
+# endif
+# ifndef __strtoull_internal_defined
+__extension__
+extern unsigned long long int __strtoull_internal (__const char *
+ __restrict __nptr,
+ char **__restrict __endptr,
+ int __base, int __group)
+ __THROW __nonnull ((1)) __wur;
+# define __strtoull_internal_defined 1
+# endif
+#endif /* GCC */
+
+#ifdef __USE_EXTERN_INLINES
+/* Define inline functions which call the internal entry points. */
+
+__BEGIN_NAMESPACE_STD
+extern __inline double
+__NTH (strtod (__const char *__restrict __nptr, char **__restrict __endptr))
+{
+ return __strtod_internal (__nptr, __endptr, 0);
+}
+extern __inline long int
+__NTH (strtol (__const char *__restrict __nptr, char **__restrict __endptr,
+ int __base))
+{
+ return __strtol_internal (__nptr, __endptr, __base, 0);
+}
+extern __inline unsigned long int
+__NTH (strtoul (__const char *__restrict __nptr, char **__restrict __endptr,
+ int __base))
+{
+ return __strtoul_internal (__nptr, __endptr, __base, 0);
+}
+__END_NAMESPACE_STD
+
+# ifdef __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+extern __inline float
+__NTH (strtof (__const char *__restrict __nptr, char **__restrict __endptr))
+{
+ return __strtof_internal (__nptr, __endptr, 0);
+}
+# ifndef __LDBL_COMPAT
+extern __inline long double
+__NTH (strtold (__const char *__restrict __nptr, char **__restrict __endptr))
+{
+ return __strtold_internal (__nptr, __endptr, 0);
+}
+# endif
+__END_NAMESPACE_C99
+# endif
+
+# ifdef __USE_BSD
+__extension__ extern __inline long long int
+__NTH (strtoq (__const char *__restrict __nptr, char **__restrict __endptr,
+ int __base))
+{
+ return __strtoll_internal (__nptr, __endptr, __base, 0);
+}
+__extension__ extern __inline unsigned long long int
+__NTH (strtouq (__const char *__restrict __nptr, char **__restrict __endptr,
+ int __base))
+{
+ return __strtoull_internal (__nptr, __endptr, __base, 0);
+}
+# endif
+
+# if defined __USE_MISC || defined __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+__extension__ extern __inline long long int
+__NTH (strtoll (__const char *__restrict __nptr, char **__restrict __endptr,
+ int __base))
+{
+ return __strtoll_internal (__nptr, __endptr, __base, 0);
+}
+__extension__ extern __inline unsigned long long int
+__NTH (strtoull (__const char * __restrict __nptr, char **__restrict __endptr,
+ int __base))
+{
+ return __strtoull_internal (__nptr, __endptr, __base, 0);
+}
+__END_NAMESPACE_C99
+# endif
+
+__BEGIN_NAMESPACE_STD
+extern __inline double
+__NTH (atof (__const char *__nptr))
+{
+ return strtod (__nptr, (char **) NULL);
+}
+extern __inline int
+__NTH (atoi (__const char *__nptr))
+{
+ return (int) strtol (__nptr, (char **) NULL, 10);
+}
+extern __inline long int
+__NTH (atol (__const char *__nptr))
+{
+ return strtol (__nptr, (char **) NULL, 10);
+}
+__END_NAMESPACE_STD
+
+# if defined __USE_MISC || defined __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+__extension__ extern __inline long long int
+__NTH (atoll (__const char *__nptr))
+{
+ return strtoll (__nptr, (char **) NULL, 10);
+}
+__END_NAMESPACE_C99
+# endif
+#endif /* Optimizing and Inlining. */
+
+
+#if defined __USE_SVID || defined __USE_XOPEN_EXTENDED
+/* Convert N to base 64 using the digits "./0-9A-Za-z", least-significant
+ digit first. Returns a pointer to static storage overwritten by the
+ next call. */
+extern char *l64a (long int __n) __THROW __wur;
+
+/* Read a number from a string S in base 64 as above. */
+extern long int a64l (__const char *__s)
+ __THROW __attribute_pure__ __nonnull ((1)) __wur;
+
+#endif /* Use SVID || extended X/Open. */
+
+#if defined __USE_SVID || defined __USE_XOPEN_EXTENDED || defined __USE_BSD
+# include <sys/types.h> /* we need int32_t... */
+
+/* These are the functions that actually do things. The `random', `srandom',
+ `initstate' and `setstate' functions are those from BSD Unices.
+ The `rand' and `srand' functions are required by the ANSI standard.
+ We provide both interfaces to the same random number generator. */
+/* Return a random long integer between 0 and RAND_MAX inclusive. */
+extern long int random (void) __THROW;
+
+/* Seed the random number generator with the given number. */
+extern void srandom (unsigned int __seed) __THROW;
+
+/* Initialize the random number generator to use state buffer STATEBUF,
+ of length STATELEN, and seed it with SEED. Optimal lengths are 8, 16,
+ 32, 64, 128 and 256, the bigger the better; values less than 8 will
+ cause an error and values greater than 256 will be rounded down. */
+extern char *initstate (unsigned int __seed, char *__statebuf,
+ size_t __statelen) __THROW __nonnull ((2));
+
+/* Switch the random number generator to state buffer STATEBUF,
+ which should have been previously initialized by `initstate'. */
+extern char *setstate (char *__statebuf) __THROW __nonnull ((1));
+
+
+# ifdef __USE_MISC
+/* Reentrant versions of the `random' family of functions.
+ These functions all use the following data structure to contain
+ state, rather than global state variables. */
+
+struct random_data
+ {
+ int32_t *fptr; /* Front pointer. */
+ int32_t *rptr; /* Rear pointer. */
+ int32_t *state; /* Array of state values. */
+ int rand_type; /* Type of random number generator. */
+ int rand_deg; /* Degree of random number generator. */
+ int rand_sep; /* Distance between front and rear. */
+ int32_t *end_ptr; /* Pointer behind state table. */
+ };
+
+extern int random_r (struct random_data *__restrict __buf,
+ int32_t *__restrict __result) __THROW __nonnull ((1, 2));
+
+extern int srandom_r (unsigned int __seed, struct random_data *__buf)
+ __THROW __nonnull ((2));
+
+extern int initstate_r (unsigned int __seed, char *__restrict __statebuf,
+ size_t __statelen,
+ struct random_data *__restrict __buf)
+ __THROW __nonnull ((2, 4));
+
+extern int setstate_r (char *__restrict __statebuf,
+ struct random_data *__restrict __buf)
+ __THROW __nonnull ((1, 2));
+# endif /* Use misc. */
+#endif /* Use SVID || extended X/Open || BSD. */
+
+
+__BEGIN_NAMESPACE_STD
+/* Return a random integer between 0 and RAND_MAX inclusive. */
+extern int rand (void) __THROW;
+/* Seed the random number generator with the given number. */
+extern void srand (unsigned int __seed) __THROW;
+__END_NAMESPACE_STD
+
+#ifdef __USE_POSIX
+/* Reentrant interface according to POSIX.1. */
+extern int rand_r (unsigned int *__seed) __THROW;
+#endif
+
+
+#if defined __USE_SVID || defined __USE_XOPEN
+/* System V style 48-bit random number generator functions. */
+
+/* Return non-negative, double-precision floating-point value in [0.0,1.0). */
+extern double drand48 (void) __THROW;
+extern double erand48 (unsigned short int __xsubi[3]) __THROW __nonnull ((1));
+
+/* Return non-negative, long integer in [0,2^31). */
+extern long int lrand48 (void) __THROW;
+extern long int nrand48 (unsigned short int __xsubi[3])
+ __THROW __nonnull ((1));
+
+/* Return signed, long integers in [-2^31,2^31). */
+extern long int mrand48 (void) __THROW;
+extern long int jrand48 (unsigned short int __xsubi[3])
+ __THROW __nonnull ((1));
+
+/* Seed random number generator. */
+extern void srand48 (long int __seedval) __THROW;
+extern unsigned short int *seed48 (unsigned short int __seed16v[3])
+ __THROW __nonnull ((1));
+extern void lcong48 (unsigned short int __param[7]) __THROW __nonnull ((1));
+
+# ifdef __USE_MISC
+/* Data structure for communication with thread safe versions. This
+ type is to be regarded as opaque. It's only exported because users
+ have to allocate objects of this type. */
+struct drand48_data
+ {
+ unsigned short int __x[3]; /* Current state. */
+ unsigned short int __old_x[3]; /* Old state. */
+ unsigned short int __c; /* Additive const. in congruential formula. */
+ unsigned short int __init; /* Flag for initializing. */
+ unsigned long long int __a; /* Factor in congruential formula. */
+ };
+
+/* Return non-negative, double-precision floating-point value in [0.0,1.0). */
+extern int drand48_r (struct drand48_data *__restrict __buffer,
+ double *__restrict __result) __THROW __nonnull ((1, 2));
+extern int erand48_r (unsigned short int __xsubi[3],
+ struct drand48_data *__restrict __buffer,
+ double *__restrict __result) __THROW __nonnull ((1, 2));
+
+/* Return non-negative, long integer in [0,2^31). */
+extern int lrand48_r (struct drand48_data *__restrict __buffer,
+ long int *__restrict __result)
+ __THROW __nonnull ((1, 2));
+extern int nrand48_r (unsigned short int __xsubi[3],
+ struct drand48_data *__restrict __buffer,
+ long int *__restrict __result)
+ __THROW __nonnull ((1, 2));
+
+/* Return signed, long integers in [-2^31,2^31). */
+extern int mrand48_r (struct drand48_data *__restrict __buffer,
+ long int *__restrict __result)
+ __THROW __nonnull ((1, 2));
+extern int jrand48_r (unsigned short int __xsubi[3],
+ struct drand48_data *__restrict __buffer,
+ long int *__restrict __result)
+ __THROW __nonnull ((1, 2));
+
+/* Seed random number generator. */
+extern int srand48_r (long int __seedval, struct drand48_data *__buffer)
+ __THROW __nonnull ((2));
+
+extern int seed48_r (unsigned short int __seed16v[3],
+ struct drand48_data *__buffer) __THROW __nonnull ((1, 2));
+
+extern int lcong48_r (unsigned short int __param[7],
+ struct drand48_data *__buffer)
+ __THROW __nonnull ((1, 2));
+# endif /* Use misc. */
+#endif /* Use SVID or X/Open. */
+
+#endif /* don't just need malloc and calloc */
+
+#ifndef __malloc_and_calloc_defined
+# define __malloc_and_calloc_defined
+__BEGIN_NAMESPACE_STD
+/* Allocate SIZE bytes of memory. */
+extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur;
+/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
+extern void *calloc (size_t __nmemb, size_t __size)
+ __THROW __attribute_malloc__ __wur;
+__END_NAMESPACE_STD
+#endif
+
+#ifndef __need_malloc_and_calloc
+__BEGIN_NAMESPACE_STD
+/* Re-allocate the previously allocated block
+ in PTR, making the new block SIZE bytes long. */
+extern void *realloc (void *__ptr, size_t __size)
+ __THROW __attribute_malloc__ __attribute_warn_unused_result__;
+/* Free a block allocated by `malloc', `realloc' or `calloc'. */
+extern void free (void *__ptr) __THROW;
+__END_NAMESPACE_STD
+
+#ifdef __USE_MISC
+/* Free a block. An alias for `free'. (Sun Unices). */
+extern void cfree (void *__ptr) __THROW;
+#endif /* Use misc. */
+
+#if defined __USE_GNU || defined __USE_BSD || defined __USE_MISC
+# include <alloca.h>
+#endif /* Use GNU, BSD, or misc. */
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Allocate SIZE bytes on a page boundary. The storage cannot be freed. */
+extern void *valloc (size_t __size) __THROW __attribute_malloc__ __wur;
+#endif
+
+#ifdef __USE_XOPEN2K
+/* Allocate memory of SIZE bytes with an alignment of ALIGNMENT. */
+extern int posix_memalign (void **__memptr, size_t __alignment, size_t __size)
+ __THROW __nonnull ((1)) __wur;
+#endif
+
+__BEGIN_NAMESPACE_STD
+/* Abort execution and generate a core-dump. */
+extern void abort (void) __THROW __attribute__ ((__noreturn__));
+
+
+/* Register a function to be called when `exit' is called. */
+extern int atexit (void (*__func) (void)) __THROW __nonnull ((1));
+__END_NAMESPACE_STD
+
+#ifdef __USE_MISC
+/* Register a function to be called with the status
+ given to `exit' and the given argument. */
+extern int on_exit (void (*__func) (int __status, void *__arg), void *__arg)
+ __THROW __nonnull ((1));
+#endif
+
+__BEGIN_NAMESPACE_STD
+/* Call all functions registered with `atexit' and `on_exit',
+ in the reverse of the order in which they were registered
+ perform stdio cleanup, and terminate program execution with STATUS. */
+extern void exit (int __status) __THROW __attribute__ ((__noreturn__));
+__END_NAMESPACE_STD
+
+#ifdef __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+/* Terminate the program with STATUS without calling any of the
+ functions registered with `atexit' or `on_exit'. */
+extern void _Exit (int __status) __THROW __attribute__ ((__noreturn__));
+__END_NAMESPACE_C99
+#endif
+
+
+__BEGIN_NAMESPACE_STD
+/* Return the value of envariable NAME, or NULL if it doesn't exist. */
+extern char *getenv (__const char *__name) __THROW __nonnull ((1)) __wur;
+__END_NAMESPACE_STD
+
+/* This function is similar to the above but returns NULL if the
+ programs is running with SUID or SGID enabled. */
+extern char *__secure_getenv (__const char *__name)
+ __THROW __nonnull ((1)) __wur;
+
+#if defined __USE_SVID || defined __USE_XOPEN
+/* The SVID says this is in <stdio.h>, but this seems a better place. */
+/* Put STRING, which is of the form "NAME=VALUE", in the environment.
+ If there is no `=', remove NAME from the environment. */
+extern int putenv (char *__string) __THROW __nonnull ((1));
+#endif
+
+#if defined __USE_BSD || defined __USE_XOPEN2K
+/* Set NAME to VALUE in the environment.
+ If REPLACE is nonzero, overwrite an existing value. */
+extern int setenv (__const char *__name, __const char *__value, int __replace)
+ __THROW __nonnull ((2));
+
+/* Remove the variable NAME from the environment. */
+extern int unsetenv (__const char *__name) __THROW;
+#endif
+
+#ifdef __USE_MISC
+/* The `clearenv' was planned to be added to POSIX.1 but probably
+ never made it. Nevertheless the POSIX.9 standard (POSIX bindings
+ for Fortran 77) requires this function. */
+extern int clearenv (void) __THROW;
+#endif
+
+
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
+/* Generate a unique temporary file name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the file name unique.
+ Returns TEMPLATE, or a null pointer if it cannot get a unique file name. */
+extern char *mktemp (char *__template) __THROW __nonnull ((1)) __wur;
+
+/* Generate a unique temporary file name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+ Returns a file descriptor open on the file for reading and writing,
+ or -1 if it cannot create a uniquely-named file.
+
+ This function is a possible cancellation points and therefore not
+ marked with __THROW. */
+# ifndef __USE_FILE_OFFSET64
+extern int mkstemp (char *__template) __nonnull ((1)) __wur;
+# else
+# ifdef __REDIRECT
+extern int __REDIRECT (mkstemp, (char *__template), mkstemp64)
+ __nonnull ((1)) __wur;
+# else
+# define mkstemp mkstemp64
+# endif
+# endif
+# ifdef __USE_LARGEFILE64
+extern int mkstemp64 (char *__template) __nonnull ((1)) __wur;
+# endif
+#endif
+
+#ifdef __USE_BSD
+/* Create a unique temporary directory from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the directory name unique.
+ Returns TEMPLATE, or a null pointer if it cannot get a unique name.
+ The directory is created mode 700. */
+extern char *mkdtemp (char *__template) __THROW __nonnull ((1)) __wur;
+#endif
+
+
+__BEGIN_NAMESPACE_STD
+/* Execute the given line as a shell command.
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int system (__const char *__command) __wur;
+__END_NAMESPACE_STD
+
+
+#ifdef __USE_GNU
+/* Return a malloc'd string containing the canonical absolute name of the
+ named file. The last file name component need not exist, and may be a
+ symlink to a nonexistent file. */
+extern char *canonicalize_file_name (__const char *__name)
+ __THROW __nonnull ((1)) __wur;
+#endif
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Return the canonical absolute name of file NAME. The last file name
+ component need not exist, and may be a symlink to a nonexistent file.
+ If RESOLVED is null, the result is malloc'd; otherwise, if the canonical
+ name is PATH_MAX chars or more, returns null with `errno' set to
+ ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, returns the
+ name in RESOLVED. */
+extern char *realpath (__const char *__restrict __name,
+ char *__restrict __resolved) __THROW __wur;
+#endif
+
+
+/* Shorthand for type of comparison functions. */
+#ifndef __COMPAR_FN_T
+# define __COMPAR_FN_T
+typedef int (*__compar_fn_t) (__const void *, __const void *);
+
+# ifdef __USE_GNU
+typedef __compar_fn_t comparison_fn_t;
+# endif
+#endif
+
+__BEGIN_NAMESPACE_STD
+/* Do a binary search for KEY in BASE, which consists of NMEMB elements
+ of SIZE bytes each, using COMPAR to perform the comparisons. */
+extern void *bsearch (__const void *__key, __const void *__base,
+ size_t __nmemb, size_t __size, __compar_fn_t __compar)
+ __nonnull ((1, 2, 5)) __wur;
+
+/* Sort NMEMB elements of BASE, of SIZE bytes each,
+ using COMPAR to perform the comparisons. */
+extern void qsort (void *__base, size_t __nmemb, size_t __size,
+ __compar_fn_t __compar) __nonnull ((1, 4));
+
+
+/* Return the absolute value of X. */
+extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;
+extern long int labs (long int __x) __THROW __attribute__ ((__const__)) __wur;
+__END_NAMESPACE_STD
+
+#ifdef __USE_ISOC99
+__extension__ extern long long int llabs (long long int __x)
+ __THROW __attribute__ ((__const__)) __wur;
+#endif
+
+
+__BEGIN_NAMESPACE_STD
+/* Return the `div_t', `ldiv_t' or `lldiv_t' representation
+ of the value of NUMER over DENOM. */
+/* GCC may have built-ins for these someday. */
+extern div_t div (int __numer, int __denom)
+ __THROW __attribute__ ((__const__)) __wur;
+extern ldiv_t ldiv (long int __numer, long int __denom)
+ __THROW __attribute__ ((__const__)) __wur;
+__END_NAMESPACE_STD
+
+#ifdef __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+__extension__ extern lldiv_t lldiv (long long int __numer,
+ long long int __denom)
+ __THROW __attribute__ ((__const__)) __wur;
+__END_NAMESPACE_C99
+#endif
+
+
+#if defined __USE_SVID || defined __USE_XOPEN_EXTENDED
+/* Convert floating point numbers to strings. The returned values are
+ valid only until another call to the same function. */
+
+/* Convert VALUE to a string with NDIGIT digits and return a pointer to
+ this. Set *DECPT with the position of the decimal character and *SIGN
+ with the sign of the number. */
+extern char *ecvt (double __value, int __ndigit, int *__restrict __decpt,
+ int *__restrict __sign) __THROW __nonnull ((3, 4)) __wur;
+
+/* Convert VALUE to a string rounded to NDIGIT decimal digits. Set *DECPT
+ with the position of the decimal character and *SIGN with the sign of
+ the number. */
+extern char *fcvt (double __value, int __ndigit, int *__restrict __decpt,
+ int *__restrict __sign) __THROW __nonnull ((3, 4)) __wur;
+
+/* If possible convert VALUE to a string with NDIGIT significant digits.
+ Otherwise use exponential representation. The resulting string will
+ be written to BUF. */
+extern char *gcvt (double __value, int __ndigit, char *__buf)
+ __THROW __nonnull ((3)) __wur;
+
+
+# ifdef __USE_MISC
+/* Long double versions of above functions. */
+extern char *qecvt (long double __value, int __ndigit,
+ int *__restrict __decpt, int *__restrict __sign)
+ __THROW __nonnull ((3, 4)) __wur;
+extern char *qfcvt (long double __value, int __ndigit,
+ int *__restrict __decpt, int *__restrict __sign)
+ __THROW __nonnull ((3, 4)) __wur;
+extern char *qgcvt (long double __value, int __ndigit, char *__buf)
+ __THROW __nonnull ((3)) __wur;
+
+
+/* Reentrant version of the functions above which provide their own
+ buffers. */
+extern int ecvt_r (double __value, int __ndigit, int *__restrict __decpt,
+ int *__restrict __sign, char *__restrict __buf,
+ size_t __len) __THROW __nonnull ((3, 4, 5));
+extern int fcvt_r (double __value, int __ndigit, int *__restrict __decpt,
+ int *__restrict __sign, char *__restrict __buf,
+ size_t __len) __THROW __nonnull ((3, 4, 5));
+
+extern int qecvt_r (long double __value, int __ndigit,
+ int *__restrict __decpt, int *__restrict __sign,
+ char *__restrict __buf, size_t __len)
+ __THROW __nonnull ((3, 4, 5));
+extern int qfcvt_r (long double __value, int __ndigit,
+ int *__restrict __decpt, int *__restrict __sign,
+ char *__restrict __buf, size_t __len)
+ __THROW __nonnull ((3, 4, 5));
+# endif /* misc */
+#endif /* use MISC || use X/Open Unix */
+
+
+__BEGIN_NAMESPACE_STD
+/* Return the length of the multibyte character
+ in S, which is no longer than N. */
+extern int mblen (__const char *__s, size_t __n) __THROW __wur;
+/* Return the length of the given multibyte character,
+ putting its `wchar_t' representation in *PWC. */
+extern int mbtowc (wchar_t *__restrict __pwc,
+ __const char *__restrict __s, size_t __n) __THROW __wur;
+/* Put the multibyte character represented
+ by WCHAR in S, returning its length. */
+extern int wctomb (char *__s, wchar_t __wchar) __THROW __wur;
+
+
+/* Convert a multibyte string to a wide char string. */
+extern size_t mbstowcs (wchar_t *__restrict __pwcs,
+ __const char *__restrict __s, size_t __n) __THROW;
+/* Convert a wide char string to multibyte string. */
+extern size_t wcstombs (char *__restrict __s,
+ __const wchar_t *__restrict __pwcs, size_t __n)
+ __THROW;
+__END_NAMESPACE_STD
+
+
+#ifdef __USE_SVID
+/* Determine whether the string value of RESPONSE matches the affirmation
+ or negative response expression as specified by the LC_MESSAGES category
+ in the program's current locale. Returns 1 if affirmative, 0 if
+ negative, and -1 if not matching. */
+extern int rpmatch (__const char *__response) __THROW __nonnull ((1)) __wur;
+#endif
+
+
+#ifdef __USE_XOPEN_EXTENDED
+/* Parse comma separated suboption from *OPTIONP and match against
+ strings in TOKENS. If found return index and set *VALUEP to
+ optional value introduced by an equal sign. If the suboption is
+ not part of TOKENS return in *VALUEP beginning of unknown
+ suboption. On exit *OPTIONP is set to the beginning of the next
+ token or at the terminating NUL character. */
+extern int getsubopt (char **__restrict __optionp,
+ char *__const *__restrict __tokens,
+ char **__restrict __valuep)
+ __THROW __nonnull ((1, 2, 3)) __wur;
+#endif
+
+
+#ifdef __USE_XOPEN
+/* Setup DES tables according KEY. */
+extern void setkey (__const char *__key) __THROW __nonnull ((1));
+#endif
+
+
+/* X/Open pseudo terminal handling. */
+
+#ifdef __USE_XOPEN2K
+/* Return a master pseudo-terminal handle. */
+extern int posix_openpt (int __oflag) __wur;
+#endif
+
+#ifdef __USE_XOPEN
+/* The next four functions all take a master pseudo-tty fd and
+ perform an operation on the associated slave: */
+
+/* Chown the slave to the calling user. */
+extern int grantpt (int __fd) __THROW;
+
+/* Release an internal lock so the slave can be opened.
+ Call after grantpt(). */
+extern int unlockpt (int __fd) __THROW;
+
+/* Return the pathname of the pseudo terminal slave assoicated with
+ the master FD is open on, or NULL on errors.
+ The returned storage is good until the next call to this function. */
+extern char *ptsname (int __fd) __THROW __wur;
+#endif
+
+#ifdef __USE_GNU
+/* Store at most BUFLEN characters of the pathname of the slave pseudo
+ terminal associated with the master FD is open on in BUF.
+ Return 0 on success, otherwise an error number. */
+extern int ptsname_r (int __fd, char *__buf, size_t __buflen)
+ __THROW __nonnull ((2));
+
+/* Open a master pseudo terminal and return its file descriptor. */
+extern int getpt (void);
+#endif
+
+#ifdef __USE_BSD
+/* Put the 1 minute, 5 minute and 15 minute load averages into the first
+ NELEM elements of LOADAVG. Return the number written (never more than
+ three, but may be less than NELEM), or -1 if an error occurred. */
+extern int getloadavg (double __loadavg[], int __nelem)
+ __THROW __nonnull ((1));
+#endif
+
+
+/* Define some macros helping to catch buffer overflows. */
+#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+# include <bits/stdlib.h>
+#endif
+#ifdef __LDBL_COMPAT
+# include <bits/stdlib-ldbl.h>
+#endif
+
+#endif /* don't just need malloc and calloc */
+#undef __need_malloc_and_calloc
+
+__END_DECLS
+
+#endif /* stdlib.h */
diff --git a/libc/dfp/sysdeps/dfp/stdlib/strtod128.c b/libc/dfp/sysdeps/dfp/stdlib/strtod128.c
new file mode 100644
index 000000000..7b73684f7
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdlib/strtod128.c
@@ -0,0 +1,31 @@
+/* Convert string representing a number to Decimal Float value, using given locale.
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef FLOAT
+#define FLOAT _Decimal128
+#define FLOAT_HUGE_VAL DEC_INFINITY
+#define FLT DEC128
+#define FLOAT_SIZE 128
+#define FLOAT_ZERO 0.0DL
+#define SET_MANTISSA(x,y)
+#endif
+
+#include "strtod32.c"
diff --git a/libc/dfp/sysdeps/dfp/stdlib/strtod32.c b/libc/dfp/sysdeps/dfp/stdlib/strtod32.c
new file mode 100644
index 000000000..f01b11915
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdlib/strtod32.c
@@ -0,0 +1,754 @@
+/* Convert string representing a number to Decimal Float value, using given locale.
+ Copyright (C) 1997,1998,2002,2004-2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ Contributed by IBM Corporation.
+ Adapted primarily from stdlib/strtod_l.c by Ulrich Drepper <drepper@cygnus.com>
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * TODO: SET_MANTISSA macro for preserving NaN info (or parse as mantissa)
+ * TODO: Check that hexadecimal input is done properly... particularly hex
+ * exponants
+ */
+#include <stdio.h>
+#include <xlocale.h>
+#include <ctype.h>
+#include <errno.h>
+#include "../locale/localeinfo.h"
+#include <locale.h>
+#include <string.h>
+
+#include <math.h>
+#include <float.h>
+
+#ifndef FLOAT
+# define FLOAT _Decimal32
+# define FLOAT_HUGE_VAL HUGE_VAL_D32
+# define FLOAT_SIZE 32
+# define FLT DEC32
+# define FLOAT_ZERO 0.0DF
+# define SET_MANTISSA(x,y)
+#endif
+
+/* We use this code for the extended locale handling where the
+ function gets as an additional argument the locale which has to be
+ used. To access the values we have to redefine the _NL_CURRENT and
+ _NL_CURRENT_WORD macros. */
+#undef _NL_CURRENT
+#define _NL_CURRENT(category, item) \
+ (current->values[_NL_ITEM_INDEX (item)].string)
+#undef _NL_CURRENT_WORD
+#define _NL_CURRENT_WORD(category, item) \
+ ((uint32_t) current->values[_NL_ITEM_INDEX (item)].word)
+
+#if defined _LIBC || defined HAVE_WCHAR_H
+# include <wchar.h>
+# include <dfpwchar.h> /* wcstod* internal interfaces */
+#endif
+
+#ifdef USE_WIDE_CHAR
+extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, wchar_t **,
+ int, int, __locale_t);
+# include <wctype.h>
+# define STRTO_PREFIX wcsto
+# define STRING_TYPE wchar_t
+# define CHAR_TYPE wint_t
+# define L_(Ch) L##Ch
+# define ISSPACE(Ch) __iswspace_l ((Ch), loc)
+# define ISDIGIT(Ch) __iswdigit_l ((Ch), loc)
+# define ISXDIGIT(Ch) __iswxdigit_l ((Ch), loc)
+# define TOLOWER(Ch) __towlower_l ((Ch), loc)
+# define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr)
+# define STRNCASECMP(S1, S2, N) \
+ __wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
+# define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc)
+#else
+# include <dfpstdlib.h> /* strtod* internal interfaces. */
+# define STRTO_PREFIX strto
+# define STRING_TYPE char
+# define CHAR_TYPE char
+# define L_(Ch) Ch
+# define ISSPACE(Ch) __isspace_l ((Ch), loc)
+# define ISDIGIT(Ch) __isdigit_l ((Ch), loc)
+# define ISXDIGIT(Ch) __isxdigit_l ((Ch), loc)
+# define TOLOWER(Ch) __tolower_l ((Ch), loc)
+# define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr)
+# define STRNCASECMP(S1, S2, N) \
+ __strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
+# define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc)
+#endif
+
+/* Constants we need from float.h; select the set for the FLOAT precision. */
+#define MANT_DIG PASTE(FLT,_MANT_DIG)
+#define DIG PASTE(FLT,_DIG)
+//#define MAX_EXP PASTE(FLT,_MAX_EXP)
+//#define MIN_EXP PASTE(FLT,_MIN_EXP)
+#define MAX_10_EXP PASTE(FLT,_MAX_EXP)
+#define MIN_10_EXP PASTE(FLT,_MIN_EXP)
+#define FUNCTION_NAME PASTE(PASTE(STRTO_PREFIX,d),FLOAT_SIZE)
+#define __FUNCTION_NAME PASTE(__,FUNCTION_NAME)
+#define FUNCTION_INTERNAL PASTE(__FUNCTION_NAME,_internal)
+#define FUNCTION_L_INTERNAL PASTE(__FUNCTION_NAME,_l_internal)
+
+/* Extra macros required to get FLT expanded before the pasting. */
+#define PASTE(a,b) PASTE1(a,b)
+#define PASTE1(a,b) a##b
+
+
+#define RETURN(val,end) \
+ do { if (endptr != NULL) *endptr = (STRING_TYPE *) (end); \
+ return val; } while (0)
+
+#define NDEBUG 1
+#include <assert.h>
+
+#include "stdlib/grouping.h"
+
+/* This is of the form __strtod32_l_internal() */
+FLOAT
+FUNCTION_L_INTERNAL (const STRING_TYPE * nptr, STRING_TYPE ** endptr,
+ int group, locale_t loc)
+{
+ FLOAT d32 = FLOAT_ZERO;
+
+ int negative; /* The sign of the number. */
+ int exponent; /* Exponent of the number. */
+
+ /* Numbers starting `0X' or `0x' have to be processed with base 16. */
+ int base = 10;
+
+ /* Number of bits currently in result value. */
+ int bits;
+
+ /* Running pointer after the last character processed in the string. */
+ const STRING_TYPE *cp, *tp;
+ /* Start of significant part of the number. */
+ const STRING_TYPE *startp, *start_of_digits;
+ /* Points at the character following the integer and fractional digits. */
+ const STRING_TYPE *expp;
+ /* Total number of digit and number of digits in integer part. */
+ int dig_no, int_no, lead_zero;
+ /* Contains the last character read. */
+ CHAR_TYPE c;
+
+/* We should get wint_t from <stddef.h>, but not all GCC versions define it
+ there. So define it ourselves if it remains undefined. */
+#ifndef _WINT_T
+ typedef unsigned int wint_t;
+#endif
+ /* The radix character of the current locale. */
+#ifdef USE_WIDE_CHAR
+ wchar_t decimal;
+#else
+ const char *decimal;
+ size_t decimal_len;
+#endif
+ /* The thousands character of the current locale. */
+#ifdef USE_WIDE_CHAR
+ wchar_t thousands = L'\0';
+#else
+ const char *thousands = NULL;
+ /* Used in several places. */
+ int cnt;
+#endif
+ /* The numeric grouping specification of the current locale,
+ in the format described in <locale.h>. */
+ const char *grouping;
+
+ struct locale_data *current = loc->__locales[LC_NUMERIC];
+
+ if (group)
+ {
+ grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
+ if (*grouping <= 0 || *grouping == CHAR_MAX)
+ grouping = NULL;
+ else
+ {
+ /* Figure out the thousands separator character. */
+#ifdef USE_WIDE_CHAR
+ thousands = _NL_CURRENT_WORD (LC_NUMERIC,
+ _NL_NUMERIC_THOUSANDS_SEP_WC);
+ if (thousands == L'\0')
+ grouping = NULL;
+#else
+ thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+ if (*thousands == '\0')
+ {
+ thousands = NULL;
+ grouping = NULL;
+ }
+#endif
+ }
+ }
+ else
+ grouping = NULL;
+
+ /* Find the locale's decimal point character. */
+#ifdef USE_WIDE_CHAR
+ decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
+ assert (decimal != L'\0');
+# define decimal_len 1
+#else
+ decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+ decimal_len = strlen (decimal);
+ assert (decimal_len > 0);
+#endif
+
+ /* Prepare number representation. */
+ exponent = 0;
+ negative = 0;
+ bits = 0;
+
+ /* Parse string to get maximal legal prefix. We need the number of
+ characters of the integer part, the fractional part and the exponent. */
+ cp = nptr - 1;
+ /* Ignore leading white space. */
+ do
+ c = *++cp;
+ while (ISSPACE (c));
+
+ /* Get sign of the result. */
+ if (c == L_('-'))
+ {
+ negative = 1;
+ c = *++cp;
+ }
+ else if (c == L_('+'))
+ c = *++cp;
+
+ /* Return 0.0 if no legal string is found.
+ No character is used even if a sign was found. */
+#ifdef USE_WIDE_CHAR
+ if (c == (wint_t) decimal
+ && (wint_t) cp[1] >= L'0' && (wint_t) cp[1] <= L'9')
+ {
+ /* We accept it. This funny construct is here only to indent
+ the code directly. */
+ }
+#else
+ for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
+ if (cp[cnt] != decimal[cnt])
+ break;
+ if (decimal[cnt] == '\0' && cp[cnt] >= '0' && cp[cnt] <= '9')
+ {
+ /* We accept it. This funny construct is here only to indent
+ the code directly. */
+ }
+#endif
+ else if (c < L_('0') || c > L_('9'))
+ {
+ /* Check for `INF' or `INFINITY'. */
+ if (TOLOWER_C (c) == L_('i') && STRNCASECMP (cp, L_("inf"), 3) == 0)
+ {
+ /* Return +/- infinity. */
+ if (endptr != NULL)
+ *endptr = (STRING_TYPE *)
+ (cp + (STRNCASECMP (cp + 3, L_("inity"), 5) == 0
+ ? 8 : 3));
+
+ return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
+ }
+
+ if (TOLOWER_C (c) == L_('n') && STRNCASECMP (cp, L_("nan"), 3) == 0)
+ {
+ /* Return NaN. */
+ FLOAT retval = DEC_NAN;
+
+ cp += 3;
+
+ /* Match `(n-char-sequence-digit)'. */
+ if (*cp == L_('('))
+ {
+ startp = cp;
+ do
+ ++cp;
+ while ((*cp >= L_('0') && *cp <= L_('9'))
+ || (TOLOWER (*cp) >= L_('a') && TOLOWER (*cp) <= L_('z'))
+ || *cp == L_('_'));
+
+ if (*cp != L_(')'))
+ /* The closing brace is missing. Only match the NAN
+ part. */
+ cp = startp;
+ else
+ {
+ /* This is a system-dependent way to specify the
+ bitmask used for the NaN. We expect it to be
+ a number which is put in the mantissa of the
+ number. */
+ STRING_TYPE *endp;
+ unsigned long long int mant;
+
+ mant = STRTOULL (startp + 1, &endp, 0);
+ if (endp == cp)
+ SET_MANTISSA (retval, mant);
+ }
+ }
+
+ if (endptr != NULL)
+ *endptr = (STRING_TYPE *) cp;
+
+ return retval;
+ }
+
+ /* It is really a text we do not recognize. */
+ RETURN (0.0, nptr);
+ }
+
+ /* First look whether we are faced with a hexadecimal number. */
+ if (c == L_('0') && TOLOWER (cp[1]) == L_('x'))
+ {
+ /* Okay, it is a hexa-decimal number. Remember this and skip
+ the characters. BTW: hexadecimal numbers must not be
+ grouped. */
+ base = 16;
+ cp += 2;
+ c = *cp;
+ grouping = NULL;
+ }
+
+ /* Record the start of the digits, in case we will check their grouping. */
+ start_of_digits = startp = cp;
+
+ /* Ignore leading zeroes. This helps us to avoid useless computations. */
+#ifdef USE_WIDE_CHAR
+ while (c == L'0' || ((wint_t) thousands != L'\0' && c == (wint_t) thousands))
+ c = *++cp;
+#else
+ if (thousands == NULL)
+ while (c == '0')
+ c = *++cp;
+ else
+ {
+ /* We also have the multibyte thousands string. */
+ while (1)
+ {
+ if (c != '0')
+ {
+ for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
+ if (c != thousands[cnt])
+ break;
+ if (thousands[cnt] != '\0')
+ break;
+ }
+ c = *++cp;
+ }
+ }
+#endif
+
+ /* If no other digit but a '0' is found the result is 0.0.
+ Return current read pointer. */
+ if ((c < L_('0') || c > L_('9'))
+ && (base == 16 && (c < (CHAR_TYPE) TOLOWER (L_('a'))
+ || c > (CHAR_TYPE) TOLOWER (L_('f'))))
+#ifdef USE_WIDE_CHAR
+ && c != (wint_t) decimal
+#else
+ && ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
+ if (decimal[cnt] != cp[cnt])
+ break;
+ decimal[cnt] != '\0'; })
+#endif
+ && (base == 16 && (cp == start_of_digits
+ || (CHAR_TYPE) TOLOWER (c) != L_('p')))
+ && (base != 16 && (CHAR_TYPE) TOLOWER (c) != L_('e')))
+ {
+#ifdef USE_WIDE_CHAR
+ tp = __correctly_grouped_prefixwc (start_of_digits, cp, thousands,
+ grouping);
+#else
+ tp = __correctly_grouped_prefixmb (start_of_digits, cp, thousands,
+ grouping);
+#endif
+ /* If TP is at the start of the digits, there was no correctly
+ grouped prefix of the string; so no number found. */
+ RETURN (FLOAT_ZERO, tp == start_of_digits ? (base == 16 ? cp - 1 : nptr) : tp);
+ }
+
+ /* Remember first significant digit and read following characters until the
+ decimal point, exponent character or any non-FP number character. */
+ startp = cp;
+ dig_no = 0;
+ while (1)
+ {
+ if ((c >= L_('0') && c <= L_('9'))
+ || (base == 16 && (wint_t) TOLOWER (c) >= L_('a')
+ && (wint_t) TOLOWER (c) <= L_('f')))
+ ++dig_no;
+ else
+ {
+#ifdef USE_WIDE_CHAR
+ if ((wint_t) thousands == L'\0' || c != (wint_t) thousands)
+ /* Not a digit or separator: end of the integer part. */
+ break;
+#else
+ if (thousands == NULL)
+ break;
+ else
+ {
+ for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
+ if (thousands[cnt] != cp[cnt])
+ break;
+ if (thousands[cnt] != '\0')
+ break;
+ }
+#endif
+ }
+ c = *++cp;
+ }
+
+ if (grouping && dig_no > 0)
+ {
+ /* Check the grouping of the digits. */
+#ifdef USE_WIDE_CHAR
+ tp = __correctly_grouped_prefixwc (start_of_digits, cp, thousands,
+ grouping);
+#else
+ tp = __correctly_grouped_prefixmb (start_of_digits, cp, thousands,
+ grouping);
+#endif
+ if (cp != tp)
+ {
+ /* Less than the entire string was correctly grouped. */
+
+ if (tp == start_of_digits)
+ /* No valid group of numbers at all: no valid number. */
+ RETURN (FLOAT_ZERO, nptr);
+
+ if (tp < startp)
+ /* The number is validly grouped, but consists
+ only of zeroes. The whole value is zero. */
+ RETURN (FLOAT_ZERO, tp);
+
+ /* Recompute DIG_NO so we won't read more digits than
+ are properly grouped. */
+ cp = tp;
+ dig_no = 0;
+ for (tp = startp; tp < cp; ++tp)
+ if (*tp >= L_('0') && *tp <= L_('9'))
+ ++dig_no;
+
+ int_no = dig_no;
+ lead_zero = 0;
+
+ goto number_parsed;
+ }
+ }
+
+ /* We have the number digits in the integer part. Whether these are all or
+ any is really a fractional digit will be decided later. */
+ int_no = dig_no;
+ lead_zero = int_no == 0 ? -1 : 0;
+
+ /* Read the fractional digits. A special case are the 'american style'
+ numbers like `16.' i.e. with decimal but without trailing digits. */
+ if (
+#ifdef USE_WIDE_CHAR
+ c == (wint_t) decimal
+#else
+ ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
+ if (decimal[cnt] != cp[cnt])
+ break;
+ decimal[cnt] == '\0'; })
+#endif
+ )
+ {
+ cp += decimal_len;
+ c = *cp;
+ while ((c >= L_('0') && c <= L_('9')) ||
+ (base == 16 && TOLOWER (c) >= L_('a') && TOLOWER (c) <= L_('f')))
+ {
+ if (c != L_('0') && lead_zero == -1)
+ lead_zero = dig_no - int_no;
+ ++dig_no;
+ c = *++cp;
+ }
+ }
+
+ /* Remember start of exponent (if any). */
+ expp = cp;
+
+ /* Read exponent. */
+ if ((base == 16 && TOLOWER (c) == L_('p'))
+ || (base != 16 && TOLOWER (c) == L_('e')))
+ {
+ int exp_negative = 0;
+
+ c = *++cp;
+ if (c == L_('-'))
+ {
+ exp_negative = 1;
+ c = *++cp;
+ }
+ else if (c == L_('+'))
+ c = *++cp;
+
+ if (c >= L_('0') && c <= L_('9'))
+ {
+ int exp_limit;
+
+ /* Get the exponent limit. */
+#if 0
+ if (base == 16)
+ exp_limit = (exp_negative ?
+ -MIN_EXP + MANT_DIG + 4 * int_no :
+ MAX_EXP - 4 * int_no + lead_zero);
+ else
+#endif
+ exp_limit = (exp_negative ?
+ -MIN_10_EXP + MANT_DIG + int_no :
+ MAX_10_EXP - int_no + lead_zero);
+
+ do
+ {
+ exponent *= 10;
+
+ if (exponent > exp_limit)
+ /* The exponent is too large/small to represent a valid
+ number. */
+ {
+ FLOAT result;
+
+ /* We have to take care for special situation: a joker
+ might have written "0.0e100000" which is in fact
+ zero. */
+ if (lead_zero == -1)
+ result = negative ? -FLOAT_ZERO : FLOAT_ZERO;
+ else
+ {
+ /* Overflow or underflow. */
+ __set_errno (ERANGE);
+ result = (exp_negative ? FLOAT_ZERO :
+ negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL);
+ }
+
+ /* Accept all following digits as part of the exponent. */
+ do
+ ++cp;
+ while (*cp >= L_('0') && *cp <= L_('9'));
+
+ RETURN (result, cp);
+ /* NOTREACHED */
+ }
+
+ exponent += c - L_('0');
+ c = *++cp;
+ }
+ while (c >= L_('0') && c <= L_('9'));
+
+ if (exp_negative)
+ exponent = -exponent;
+ }
+ else
+ cp = expp;
+ }
+
+ /* We don't want to have to work with trailing zeroes after the radix. */
+ if (dig_no > int_no)
+ {
+ while (expp[-1] == L_('0'))
+ {
+ --expp;
+ --dig_no;
+ }
+ assert (dig_no >= int_no);
+ }
+
+ if (dig_no == int_no && dig_no > 0 && exponent < 0)
+ do
+ {
+ while (! (base == 16 ? ISXDIGIT (expp[-1]) : ISDIGIT (expp[-1])))
+ --expp;
+
+ if (expp[-1] != L_('0'))
+ break;
+
+ --expp;
+ --dig_no;
+ --int_no;
+ ++exponent;
+ }
+ while (dig_no > 0 && exponent < 0);
+
+ number_parsed:
+
+ /* The whole string is parsed. Store the address of the next character. */
+ if (endptr)
+ *endptr = (STRING_TYPE *) cp;
+
+ if (dig_no == 0)
+ return negative ? -FLOAT_ZERO : FLOAT_ZERO;
+
+ if (lead_zero)
+ {
+ /* Find the decimal point */
+#ifdef USE_WIDE_CHAR
+ while (*startp != decimal)
+ ++startp;
+#else
+ while (1)
+ {
+ if (*startp == decimal[0])
+ {
+ for (cnt = 1; decimal[cnt] != '\0'; ++cnt)
+ if (decimal[cnt] != startp[cnt])
+ break;
+ if (decimal[cnt] == '\0')
+ break;
+ }
+ ++startp;
+ }
+#endif
+ startp += lead_zero + decimal_len;
+ exponent -= base == 16 ? 4 * lead_zero : lead_zero;
+ dig_no -= lead_zero;
+ }
+
+ /* Now we have the number of digits in total and the integer digits as well
+ as the exponent and its sign. We can decide whether the read digits are
+ really integer digits or belong to the fractional part; i.e. we normalize
+ 123e-2 to 1.23. */
+ {
+ register int incr = (exponent < 0 ? MAX (-int_no, exponent)
+ : MIN (dig_no - int_no, exponent));
+ int_no += incr;
+ exponent -= incr;
+ }
+
+ if (int_no + exponent > MAX_10_EXP + 1)
+ {
+ __set_errno (ERANGE);
+ return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
+ }
+
+ if (exponent < MIN_10_EXP - (MANT_DIG + 1))
+ {
+ __set_errno (ERANGE);
+ return FLOAT_ZERO;
+ }
+ /* Read in the integer portion of the input string */
+ if (int_no > 0)
+ {
+ /* Read the integer part as a d32. */
+ int digcnt = int_no;
+
+ while (int_no > MAX_10_EXP + 1)
+ {
+ digcnt--;
+ exponent++;
+ }
+ do
+ {
+ /* There might be thousands separators or radix characters in
+ the string. But these all can be ignored because we know the
+ format of the number is correct and we have an exact number
+ of characters to read. */
+#ifdef USE_WIDE_CHAR
+ if (*startp < L_('0') || *startp > L_('9'))
+ if (base==10 || (*startp < L_('a') || *startp > L_('h')))
+ ++startp;
+#else
+ if (*startp < L_('0') || *startp > L_('9'))
+ if (base==10 || (*startp < L_('a') || *startp > L_('h')))
+ {
+ int inner = 0;
+ if (thousands != NULL && *startp == *thousands
+ && ({ for (inner = 1; thousands[inner] != '\0'; ++inner)
+ if (thousands[inner] != startp[inner])
+ break;
+ thousands[inner] == '\0'; }))
+ startp += inner;
+ else
+ startp += decimal_len;
+ }
+#endif
+ if(base == 10)
+ d32 = d32 * base + *startp - L_('0');
+ else
+ d32 = d32 * base + (*startp >= L_('0') && *startp <= L_('9') ?
+ -L_('0') : 10-L_('a')) + *startp;
+ ++startp;
+ }
+ while (--digcnt > 0);
+
+ }
+ /* If we haven't filled our datatype, read in the fractional digits */
+ if (int_no <= MANT_DIG && dig_no > int_no)
+ {
+ /* Read the decimal part as a FLOAT. */
+ int digcnt = dig_no - int_no;
+ FLOAT frac = FLOAT_ZERO;
+
+ /* There might be radix characters in
+ the string. But these all can be ignored because we know the
+ format of the number is correct and we have an exact number
+ of characters to read. */
+#ifdef USE_WIDE_CHAR
+ if (*startp < L_('0') || *startp > L_('9'))
+ ++startp;
+#else
+ if (*startp < '0' || *startp > '9')
+ startp += decimal_len;
+#endif
+
+ do
+ {
+ if(base == 10)
+ frac = frac/10 + *(startp+digcnt-1) - L_('0');
+ else
+ frac = frac/10 + (*(startp+digcnt-1) >= L_('0') &&
+ *(startp+digcnt-1) <= L_('9') ? -L_('0') : 10-L_('a'))
+ + *(startp+digcnt-1);
+ }
+ while (--digcnt > 0);
+ frac /= 10;
+
+ d32 += frac;
+ }
+
+ while(exponent-- > 0)
+ d32 *= 10;
+ while(++exponent < 0)
+ d32 /= 10;
+
+ return negative? -d32:d32;
+}
+
+/* This is of the form __strtod32_internal() */
+FLOAT
+FUNCTION_INTERNAL (const STRING_TYPE *nptr, STRING_TYPE **endptr, int group)
+{
+ return FUNCTION_L_INTERNAL (nptr,endptr,group,_NL_CURRENT_LOCALE);
+}
+
+/*#if defined _LIBC
+libc_hidden_def (FUNCTION_INTERNAL)
+#endif*/
+
+/* This is of the form strtod32() */
+FLOAT
+#ifdef weak_function
+weak_function
+#endif
+FUNCTION_NAME (const STRING_TYPE *nptr, STRING_TYPE **endptr)
+{
+ return FUNCTION_L_INTERNAL(nptr, endptr, 0, _NL_CURRENT_LOCALE);
+}
+
+libc_hidden_def (FUNCTION_INTERNAL)
diff --git a/libc/dfp/sysdeps/dfp/stdlib/strtod64.c b/libc/dfp/sysdeps/dfp/stdlib/strtod64.c
new file mode 100644
index 000000000..d581b64ce
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdlib/strtod64.c
@@ -0,0 +1,32 @@
+/* Convert string representing a number to Decimal Float value, using given locale.
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef FLOAT
+#define FLOAT _Decimal64
+#define FLOAT_HUGE_VAL DEC_INFINITY
+#define FLT DEC64
+#define FLOAT_SIZE 64
+#define FLOAT_ZERO 0.0DD
+#define SET_MANTISSA(x,y)
+#endif
+
+#include "strtod32.c"
diff --git a/libc/dfp/sysdeps/dfp/stdlib/wcstod128.c b/libc/dfp/sysdeps/dfp/stdlib/wcstod128.c
new file mode 100644
index 000000000..ef9b7d07e
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdlib/wcstod128.c
@@ -0,0 +1,24 @@
+/* Convert string representing a number to Decimal Float value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define USE_WIDE_CHAR 1
+
+#include <strtod128.c>
diff --git a/libc/dfp/sysdeps/dfp/stdlib/wcstod32.c b/libc/dfp/sysdeps/dfp/stdlib/wcstod32.c
new file mode 100644
index 000000000..3fb81eab5
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdlib/wcstod32.c
@@ -0,0 +1,24 @@
+/* Convert string representing a number to Decimal Float value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define USE_WIDE_CHAR 1
+
+#include <strtod32.c>
diff --git a/libc/dfp/sysdeps/dfp/stdlib/wcstod64.c b/libc/dfp/sysdeps/dfp/stdlib/wcstod64.c
new file mode 100644
index 000000000..82379880e
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/stdlib/wcstod64.c
@@ -0,0 +1,24 @@
+/* Convert string representing a number to Decimal Float value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define USE_WIDE_CHAR 1
+
+#include <strtod64.c>
diff --git a/libc/dfp/sysdeps/dfp/wcsmbs/wchar.h b/libc/dfp/sysdeps/dfp/wcsmbs/wchar.h
new file mode 100644
index 000000000..231d1facd
--- /dev/null
+++ b/libc/dfp/sysdeps/dfp/wcsmbs/wchar.h
@@ -0,0 +1,866 @@
+/* Copyright (C) 1995-2004,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * ISO C99 Standard: 7.24
+ * Extended multibyte and wide character utilities <wchar.h>
+ */
+
+#ifndef _WCHAR_H
+
+#ifndef __need_mbstate_t
+# define _WCHAR_H 1
+# include <features.h>
+#endif
+
+#ifdef _WCHAR_H
+/* Get FILE definition. */
+# define __need___FILE
+# ifdef __USE_UNIX98
+# define __need_FILE
+# endif
+# include <stdio.h>
+/* Get va_list definition. */
+# define __need___va_list
+# include <stdarg.h>
+
+/* Get size_t, wchar_t, wint_t and NULL from <stddef.h>. */
+# define __need_size_t
+# define __need_wchar_t
+# define __need_NULL
+#endif
+#define __need_wint_t
+#include <stddef.h>
+
+#include <bits/wchar.h>
+
+/* We try to get wint_t from <stddef.h>, but not all GCC versions define it
+ there. So define it ourselves if it remains undefined. */
+#ifndef _WINT_T
+/* Integral type unchanged by default argument promotions that can
+ hold any value corresponding to members of the extended character
+ set, as well as at least one value that does not correspond to any
+ member of the extended character set. */
+# define _WINT_T
+typedef unsigned int wint_t;
+#else
+/* Work around problems with the <stddef.h> file which doesn't put
+ wint_t in the std namespace. */
+# if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES \
+ && defined __WINT_TYPE__
+__BEGIN_NAMESPACE_STD
+typedef __WINT_TYPE__ wint_t;
+__END_NAMESPACE_STD
+# endif
+#endif
+
+
+#ifndef __mbstate_t_defined
+# define __mbstate_t_defined 1
+/* Conversion state information. */
+typedef struct
+{
+ int __count;
+ union
+ {
+ wint_t __wch;
+ char __wchb[4];
+ } __value; /* Value so far. */
+} __mbstate_t;
+#endif
+#undef __need_mbstate_t
+
+
+/* The rest of the file is only used if used if __need_mbstate_t is not
+ defined. */
+#ifdef _WCHAR_H
+
+__BEGIN_NAMESPACE_C99
+/* Public type. */
+typedef __mbstate_t mbstate_t;
+__END_NAMESPACE_C99
+#ifdef __USE_GNU
+__USING_NAMESPACE_C99(mbstate_t)
+#endif
+
+#ifndef WCHAR_MIN
+/* These constants might also be defined in <inttypes.h>. */
+# define WCHAR_MIN __WCHAR_MIN
+# define WCHAR_MAX __WCHAR_MAX
+#endif
+
+#ifndef WEOF
+# define WEOF (0xffffffffu)
+#endif
+
+/* For XPG4 compliance we have to define the stuff from <wctype.h> here
+ as well. */
+#if defined __USE_XOPEN && !defined __USE_UNIX98
+# include <wctype.h>
+#endif
+
+
+__BEGIN_DECLS
+
+__BEGIN_NAMESPACE_STD
+/* This incomplete type is defined in <time.h> but needed here because
+ of `wcsftime'. */
+struct tm;
+/* XXX We have to clean this up at some point. Since tm is in the std
+ namespace but wcsftime is in __c99 the type wouldn't be found
+ without inserting it in the global namespace. */
+__USING_NAMESPACE_STD(tm)
+__END_NAMESPACE_STD
+
+
+__BEGIN_NAMESPACE_C99
+/* Copy SRC to DEST. */
+extern wchar_t *wcscpy (wchar_t *__restrict __dest,
+ __const wchar_t *__restrict __src) __THROW;
+/* Copy no more than N wide-characters of SRC to DEST. */
+extern wchar_t *wcsncpy (wchar_t *__restrict __dest,
+ __const wchar_t *__restrict __src, size_t __n)
+ __THROW;
+
+/* Append SRC onto DEST. */
+extern wchar_t *wcscat (wchar_t *__restrict __dest,
+ __const wchar_t *__restrict __src) __THROW;
+/* Append no more than N wide-characters of SRC onto DEST. */
+extern wchar_t *wcsncat (wchar_t *__restrict __dest,
+ __const wchar_t *__restrict __src, size_t __n)
+ __THROW;
+
+/* Compare S1 and S2. */
+extern int wcscmp (__const wchar_t *__s1, __const wchar_t *__s2)
+ __THROW __attribute_pure__;
+/* Compare N wide-characters of S1 and S2. */
+extern int wcsncmp (__const wchar_t *__s1, __const wchar_t *__s2, size_t __n)
+ __THROW __attribute_pure__;
+__END_NAMESPACE_C99
+
+#ifdef __USE_GNU
+/* Compare S1 and S2, ignoring case. */
+extern int wcscasecmp (__const wchar_t *__s1, __const wchar_t *__s2) __THROW;
+
+/* Compare no more than N chars of S1 and S2, ignoring case. */
+extern int wcsncasecmp (__const wchar_t *__s1, __const wchar_t *__s2,
+ size_t __n) __THROW;
+
+/* Similar to the two functions above but take the information from
+ the provided locale and not the global locale. */
+# include <xlocale.h>
+
+extern int wcscasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
+ __locale_t __loc) __THROW;
+
+extern int wcsncasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
+ size_t __n, __locale_t __loc) __THROW;
+#endif
+
+__BEGIN_NAMESPACE_C99
+/* Compare S1 and S2, both interpreted as appropriate to the
+ LC_COLLATE category of the current locale. */
+extern int wcscoll (__const wchar_t *__s1, __const wchar_t *__s2) __THROW;
+/* Transform S2 into array pointed to by S1 such that if wcscmp is
+ applied to two transformed strings the result is the as applying
+ `wcscoll' to the original strings. */
+extern size_t wcsxfrm (wchar_t *__restrict __s1,
+ __const wchar_t *__restrict __s2, size_t __n) __THROW;
+__END_NAMESPACE_C99
+
+#ifdef __USE_GNU
+/* Similar to the two functions above but take the information from
+ the provided locale and not the global locale. */
+
+/* Compare S1 and S2, both interpreted as appropriate to the
+ LC_COLLATE category of the given locale. */
+extern int wcscoll_l (__const wchar_t *__s1, __const wchar_t *__s2,
+ __locale_t __loc) __THROW;
+
+/* Transform S2 into array pointed to by S1 such that if wcscmp is
+ applied to two transformed strings the result is the as applying
+ `wcscoll' to the original strings. */
+extern size_t wcsxfrm_l (wchar_t *__s1, __const wchar_t *__s2,
+ size_t __n, __locale_t __loc) __THROW;
+
+/* Duplicate S, returning an identical malloc'd string. */
+extern wchar_t *wcsdup (__const wchar_t *__s) __THROW __attribute_malloc__;
+#endif
+
+__BEGIN_NAMESPACE_C99
+/* Find the first occurrence of WC in WCS. */
+extern wchar_t *wcschr (__const wchar_t *__wcs, wchar_t __wc)
+ __THROW __attribute_pure__;
+/* Find the last occurrence of WC in WCS. */
+extern wchar_t *wcsrchr (__const wchar_t *__wcs, wchar_t __wc)
+ __THROW __attribute_pure__;
+__END_NAMESPACE_C99
+
+#ifdef __USE_GNU
+/* This function is similar to `wcschr'. But it returns a pointer to
+ the closing NUL wide character in case C is not found in S. */
+extern wchar_t *wcschrnul (__const wchar_t *__s, wchar_t __wc)
+ __THROW __attribute_pure__;
+#endif
+
+__BEGIN_NAMESPACE_C99
+/* Return the length of the initial segmet of WCS which
+ consists entirely of wide characters not in REJECT. */
+extern size_t wcscspn (__const wchar_t *__wcs, __const wchar_t *__reject)
+ __THROW __attribute_pure__;
+/* Return the length of the initial segmet of WCS which
+ consists entirely of wide characters in ACCEPT. */
+extern size_t wcsspn (__const wchar_t *__wcs, __const wchar_t *__accept)
+ __THROW __attribute_pure__;
+/* Find the first occurrence in WCS of any character in ACCEPT. */
+extern wchar_t *wcspbrk (__const wchar_t *__wcs, __const wchar_t *__accept)
+ __THROW __attribute_pure__;
+/* Find the first occurrence of NEEDLE in HAYSTACK. */
+extern wchar_t *wcsstr (__const wchar_t *__haystack, __const wchar_t *__needle)
+ __THROW __attribute_pure__;
+
+/* Divide WCS into tokens separated by characters in DELIM. */
+extern wchar_t *wcstok (wchar_t *__restrict __s,
+ __const wchar_t *__restrict __delim,
+ wchar_t **__restrict __ptr) __THROW;
+
+/* Return the number of wide characters in S. */
+extern size_t wcslen (__const wchar_t *__s) __THROW __attribute_pure__;
+__END_NAMESPACE_C99
+
+#ifdef __USE_XOPEN
+/* Another name for `wcsstr' from XPG4. */
+extern wchar_t *wcswcs (__const wchar_t *__haystack, __const wchar_t *__needle)
+ __THROW __attribute_pure__;
+#endif
+
+#ifdef __USE_GNU
+/* Return the number of wide characters in S, but at most MAXLEN. */
+extern size_t wcsnlen (__const wchar_t *__s, size_t __maxlen)
+ __THROW __attribute_pure__;
+#endif
+
+
+__BEGIN_NAMESPACE_C99
+/* Search N wide characters of S for C. */
+extern wchar_t *wmemchr (__const wchar_t *__s, wchar_t __c, size_t __n)
+ __THROW __attribute_pure__;
+
+/* Compare N wide characters of S1 and S2. */
+extern int wmemcmp (__const wchar_t *__restrict __s1,
+ __const wchar_t *__restrict __s2, size_t __n)
+ __THROW __attribute_pure__;
+
+/* Copy N wide characters of SRC to DEST. */
+extern wchar_t *wmemcpy (wchar_t *__restrict __s1,
+ __const wchar_t *__restrict __s2, size_t __n) __THROW;
+
+/* Copy N wide characters of SRC to DEST, guaranteeing
+ correct behavior for overlapping strings. */
+extern wchar_t *wmemmove (wchar_t *__s1, __const wchar_t *__s2, size_t __n)
+ __THROW;
+
+/* Set N wide characters of S to C. */
+extern wchar_t *wmemset (wchar_t *__s, wchar_t __c, size_t __n) __THROW;
+__END_NAMESPACE_C99
+
+#ifdef __USE_GNU
+/* Copy N wide characters of SRC to DEST and return pointer to following
+ wide character. */
+extern wchar_t *wmempcpy (wchar_t *__restrict __s1,
+ __const wchar_t *__restrict __s2, size_t __n)
+ __THROW;
+#endif
+
+
+__BEGIN_NAMESPACE_C99
+/* Determine whether C constitutes a valid (one-byte) multibyte
+ character. */
+extern wint_t btowc (int __c) __THROW;
+
+/* Determine whether C corresponds to a member of the extended
+ character set whose multibyte representation is a single byte. */
+extern int wctob (wint_t __c) __THROW;
+
+/* Determine whether PS points to an object representing the initial
+ state. */
+extern int mbsinit (__const mbstate_t *__ps) __THROW __attribute_pure__;
+
+/* Write wide character representation of multibyte character pointed
+ to by S to PWC. */
+extern size_t mbrtowc (wchar_t *__restrict __pwc,
+ __const char *__restrict __s, size_t __n,
+ mbstate_t *__p) __THROW;
+
+/* Write multibyte representation of wide character WC to S. */
+extern size_t wcrtomb (char *__restrict __s, wchar_t __wc,
+ mbstate_t *__restrict __ps) __THROW;
+
+/* Return number of bytes in multibyte character pointed to by S. */
+extern size_t __mbrlen (__const char *__restrict __s, size_t __n,
+ mbstate_t *__restrict __ps) __THROW;
+extern size_t mbrlen (__const char *__restrict __s, size_t __n,
+ mbstate_t *__restrict __ps) __THROW;
+__END_NAMESPACE_C99
+
+#ifdef __USE_EXTERN_INLINES
+/* Define inline function as optimization. */
+
+# ifndef __cplusplus
+/* We can use the BTOWC and WCTOB optimizations since we know that all
+ locales must use ASCII encoding for the values in the ASCII range
+ and because the wchar_t encoding is always ISO 10646. */
+extern wint_t __btowc_alias (int __c) __asm ("btowc");
+extern __inline wint_t
+__NTH (btowc (int __c))
+{ return (__builtin_constant_p (__c) && __c >= '\0' && __c <= '\x7f'
+ ? (wint_t) __c : __btowc_alias (__c)); }
+
+extern int __wctob_alias (wint_t __c) __asm ("wctob");
+extern __inline int
+__NTH (wctob (wint_t __wc))
+{ return (__builtin_constant_p (__wc) && __wc >= L'\0' && __wc <= L'\x7f'
+ ? (int) __wc : __wctob_alias (__wc)); }
+# endif
+
+extern __inline size_t
+__NTH (mbrlen (__const char *__restrict __s, size_t __n,
+ mbstate_t *__restrict __ps))
+{ return (__ps != NULL
+ ? mbrtowc (NULL, __s, __n, __ps) : __mbrlen (__s, __n, NULL)); }
+#endif
+
+__BEGIN_NAMESPACE_C99
+/* Write wide character representation of multibyte character string
+ SRC to DST. */
+extern size_t mbsrtowcs (wchar_t *__restrict __dst,
+ __const char **__restrict __src, size_t __len,
+ mbstate_t *__restrict __ps) __THROW;
+
+/* Write multibyte character representation of wide character string
+ SRC to DST. */
+extern size_t wcsrtombs (char *__restrict __dst,
+ __const wchar_t **__restrict __src, size_t __len,
+ mbstate_t *__restrict __ps) __THROW;
+__END_NAMESPACE_C99
+
+
+#ifdef __USE_GNU
+/* Write wide character representation of at most NMC bytes of the
+ multibyte character string SRC to DST. */
+extern size_t mbsnrtowcs (wchar_t *__restrict __dst,
+ __const char **__restrict __src, size_t __nmc,
+ size_t __len, mbstate_t *__restrict __ps) __THROW;
+
+/* Write multibyte character representation of at most NWC characters
+ from the wide character string SRC to DST. */
+extern size_t wcsnrtombs (char *__restrict __dst,
+ __const wchar_t **__restrict __src,
+ size_t __nwc, size_t __len,
+ mbstate_t *__restrict __ps) __THROW;
+#endif /* use GNU */
+
+
+/* The following functions are extensions found in X/Open CAE. */
+#ifdef __USE_XOPEN
+/* Determine number of column positions required for C. */
+extern int wcwidth (wchar_t __c) __THROW;
+
+/* Determine number of column positions required for first N wide
+ characters (or fewer if S ends before this) in S. */
+extern int wcswidth (__const wchar_t *__s, size_t __n) __THROW;
+#endif /* Use X/Open. */
+
+
+__BEGIN_NAMESPACE_C99
+/* Convert initial portion of the wide string NPTR to `double'
+ representation. */
+extern double wcstod (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr) __THROW;
+
+#ifdef __USE_ISOC99
+/* Likewise for `float' and `long double' sizes of floating-point numbers. */
+extern float wcstof (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr) __THROW;
+extern long double wcstold (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr) __THROW;
+#endif /* C99 */
+
+
+/* Convert initial portion of wide string NPTR to `long int'
+ representation. */
+extern long int wcstol (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base) __THROW;
+
+/* Convert initial portion of wide string NPTR to `unsigned long int'
+ representation. */
+extern unsigned long int wcstoul (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base)
+ __THROW;
+
+#if defined __USE_ISOC99 || (defined __GNUC__ && defined __USE_GNU)
+/* Convert initial portion of wide string NPTR to `long int'
+ representation. */
+__extension__
+extern long long int wcstoll (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base)
+ __THROW;
+
+/* Convert initial portion of wide string NPTR to `unsigned long long int'
+ representation. */
+__extension__
+extern unsigned long long int wcstoull (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ int __base) __THROW;
+#endif /* ISO C99 or GCC and GNU. */
+__END_NAMESPACE_C99
+
+#if defined __GNUC__ && defined __USE_GNU
+/* Convert initial portion of wide string NPTR to `long int'
+ representation. */
+__extension__
+extern long long int wcstoq (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base)
+ __THROW;
+
+/* Convert initial portion of wide string NPTR to `unsigned long long int'
+ representation. */
+__extension__
+extern unsigned long long int wcstouq (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ int __base) __THROW;
+#endif /* GCC and use GNU. */
+
+#ifdef __STDC_WANT_DEC_FP__
+extern _Decimal32 wcstod32 (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr) __THROW;
+
+extern _Decimal64 wcstod64 (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr) __THROW;
+
+extern _Decimal128 wcstod128 (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr) __THROW;
+#endif
+
+#ifdef __USE_GNU
+/* The concept of one static locale per category is not very well
+ thought out. Many applications will need to process its data using
+ information from several different locales. Another application is
+ the implementation of the internationalization handling in the
+ upcoming ISO C++ standard library. To support this another set of
+ the functions using locale data exist which have an additional
+ argument.
+
+ Attention: all these functions are *not* standardized in any form.
+ This is a proof-of-concept implementation. */
+
+/* Structure for reentrant locale using functions. This is an
+ (almost) opaque type for the user level programs. */
+# include <xlocale.h>
+
+/* Special versions of the functions above which take the locale to
+ use as an additional parameter. */
+extern long int wcstol_l (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base,
+ __locale_t __loc) __THROW;
+
+extern unsigned long int wcstoul_l (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ int __base, __locale_t __loc) __THROW;
+
+__extension__
+extern long long int wcstoll_l (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ int __base, __locale_t __loc) __THROW;
+
+__extension__
+extern unsigned long long int wcstoull_l (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ int __base, __locale_t __loc)
+ __THROW;
+
+extern double wcstod_l (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, __locale_t __loc)
+ __THROW;
+
+extern float wcstof_l (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, __locale_t __loc)
+ __THROW;
+
+extern long double wcstold_l (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ __locale_t __loc) __THROW;
+#endif /* GNU */
+
+
+/* The internal entry points for `wcstoX' take an extra flag argument
+ saying whether or not to parse locale-dependent number grouping. */
+extern double __wcstod_internal (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __group)
+ __THROW;
+extern float __wcstof_internal (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __group)
+ __THROW;
+extern long double __wcstold_internal (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ int __group) __THROW;
+
+#if !defined __wcstol_internal_defined \
+ && defined __OPTIMIZE__ && __GNUC__ >= 2
+extern long int __wcstol_internal (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ int __base, int __group) __THROW;
+# define __wcstol_internal_defined 1
+#endif
+#if !defined __wcstoul_internal_defined \
+ && defined __OPTIMIZE__ && __GNUC__ >= 2
+extern unsigned long int __wcstoul_internal (__const wchar_t *__restrict __npt,
+ wchar_t **__restrict __endptr,
+ int __base, int __group) __THROW;
+# define __wcstoul_internal_defined 1
+#endif
+#if !defined __wcstoll_internal_defined \
+ && defined __OPTIMIZE__ && __GNUC__ >= 2
+__extension__
+extern long long int __wcstoll_internal (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr,
+ int __base, int __group) __THROW;
+# define __wcstoll_internal_defined 1
+#endif
+#if !defined __wcstoull_internal_defined \
+ && defined __OPTIMIZE__ && __GNUC__ >= 2
+__extension__
+extern unsigned long long int __wcstoull_internal (__const wchar_t *
+ __restrict __nptr,
+ wchar_t **
+ __restrict __endptr,
+ int __base,
+ int __group) __THROW;
+# define __wcstoull_internal_defined 1
+#endif
+
+
+#if defined __OPTIMIZE__ && __GNUC__ >= 2
+/* Define inline functions which call the internal entry points. */
+__BEGIN_NAMESPACE_C99
+
+extern __inline double
+__NTH (wcstod (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr))
+{ return __wcstod_internal (__nptr, __endptr, 0); }
+extern __inline long int
+__NTH (wcstol (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base))
+{ return __wcstol_internal (__nptr, __endptr, __base, 0); }
+extern __inline unsigned long int
+__NTH (wcstoul (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base))
+{ return __wcstoul_internal (__nptr, __endptr, __base, 0); }
+__END_NAMESPACE_C99
+
+# ifdef __USE_GNU
+extern __inline float
+__NTH (wcstof (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr))
+{ return __wcstof_internal (__nptr, __endptr, 0); }
+# ifndef __LDBL_COMPAT
+extern __inline long double
+__NTH (wcstold (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr))
+{ return __wcstold_internal (__nptr, __endptr, 0); }
+# endif
+__extension__
+extern __inline long long int
+__NTH (wcstoq (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base))
+{ return __wcstoll_internal (__nptr, __endptr, __base, 0); }
+__extension__
+extern __inline unsigned long long int
+__NTH (wcstouq (__const wchar_t *__restrict __nptr,
+ wchar_t **__restrict __endptr, int __base))
+{ return __wcstoull_internal (__nptr, __endptr, __base, 0); }
+# endif /* Use GNU. */
+#endif /* Optimizing GCC >=2. */
+
+
+#ifdef __USE_GNU
+/* Copy SRC to DEST, returning the address of the terminating L'\0' in
+ DEST. */
+extern wchar_t *wcpcpy (wchar_t *__dest, __const wchar_t *__src) __THROW;
+
+/* Copy no more than N characters of SRC to DEST, returning the address of
+ the last character written into DEST. */
+extern wchar_t *wcpncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n)
+ __THROW;
+#endif /* use GNU */
+
+
+/* Wide character I/O functions. */
+#if defined __USE_ISOC99 || defined __USE_UNIX98
+__BEGIN_NAMESPACE_C99
+
+/* Select orientation for stream. */
+extern int fwide (__FILE *__fp, int __mode) __THROW;
+
+
+/* Write formatted output to STREAM.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int fwprintf (__FILE *__restrict __stream,
+ __const wchar_t *__restrict __format, ...)
+ /* __attribute__ ((__format__ (__wprintf__, 2, 3))) */;
+/* Write formatted output to stdout.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int wprintf (__const wchar_t *__restrict __format, ...)
+ /* __attribute__ ((__format__ (__wprintf__, 1, 2))) */;
+/* Write formatted output of at most N characters to S. */
+extern int swprintf (wchar_t *__restrict __s, size_t __n,
+ __const wchar_t *__restrict __format, ...)
+ __THROW /* __attribute__ ((__format__ (__wprintf__, 3, 4))) */;
+
+/* Write formatted output to S from argument list ARG.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int vfwprintf (__FILE *__restrict __s,
+ __const wchar_t *__restrict __format,
+ __gnuc_va_list __arg)
+ /* __attribute__ ((__format__ (__wprintf__, 2, 0))) */;
+/* Write formatted output to stdout from argument list ARG.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int vwprintf (__const wchar_t *__restrict __format,
+ __gnuc_va_list __arg)
+ /* __attribute__ ((__format__ (__wprintf__, 1, 0))) */;
+/* Write formatted output of at most N character to S from argument
+ list ARG. */
+extern int vswprintf (wchar_t *__restrict __s, size_t __n,
+ __const wchar_t *__restrict __format,
+ __gnuc_va_list __arg)
+ __THROW /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */;
+
+
+/* Read formatted input from STREAM.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int fwscanf (__FILE *__restrict __stream,
+ __const wchar_t *__restrict __format, ...)
+ /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */;
+/* Read formatted input from stdin.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int wscanf (__const wchar_t *__restrict __format, ...)
+ /* __attribute__ ((__format__ (__wscanf__, 1, 2))) */;
+/* Read formatted input from S. */
+extern int swscanf (__const wchar_t *__restrict __s,
+ __const wchar_t *__restrict __format, ...)
+ __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */;
+
+__END_NAMESPACE_C99
+#endif /* Use ISO C99 and Unix98. */
+
+#ifdef __USE_ISOC99
+__BEGIN_NAMESPACE_C99
+
+/* Read formatted input from S into argument list ARG.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int vfwscanf (__FILE *__restrict __s,
+ __const wchar_t *__restrict __format,
+ __gnuc_va_list __arg)
+ /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */;
+/* Read formatted input from stdin into argument list ARG.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int vwscanf (__const wchar_t *__restrict __format,
+ __gnuc_va_list __arg)
+ /* __attribute__ ((__format__ (__wscanf__, 1, 0))) */;
+/* Read formatted input from S into argument list ARG. */
+extern int vswscanf (__const wchar_t *__restrict __s,
+ __const wchar_t *__restrict __format,
+ __gnuc_va_list __arg)
+ __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */;
+
+__END_NAMESPACE_C99
+#endif /* Use ISO C99. */
+
+
+__BEGIN_NAMESPACE_C99
+/* Read a character from STREAM.
+
+ These functions are possible cancellation points and therefore not
+ marked with __THROW. */
+extern wint_t fgetwc (__FILE *__stream);
+extern wint_t getwc (__FILE *__stream);
+
+/* Read a character from stdin.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern wint_t getwchar (void);
+
+
+/* Write a character to STREAM.
+
+ These functions are possible cancellation points and therefore not
+ marked with __THROW. */
+extern wint_t fputwc (wchar_t __wc, __FILE *__stream);
+extern wint_t putwc (wchar_t __wc, __FILE *__stream);
+
+/* Write a character to stdout.
+
+ This function is a possible cancellation points and therefore not
+ marked with __THROW. */
+extern wint_t putwchar (wchar_t __wc);
+
+
+/* Get a newline-terminated wide character string of finite length
+ from STREAM.
+
+ This function is a possible cancellation points and therefore not
+ marked with __THROW. */
+extern wchar_t *fgetws (wchar_t *__restrict __ws, int __n,
+ __FILE *__restrict __stream);
+
+/* Write a string to STREAM.
+
+ This function is a possible cancellation points and therefore not
+ marked with __THROW. */
+extern int fputws (__const wchar_t *__restrict __ws,
+ __FILE *__restrict __stream);
+
+
+/* Push a character back onto the input buffer of STREAM.
+
+ This function is a possible cancellation points and therefore not
+ marked with __THROW. */
+extern wint_t ungetwc (wint_t __wc, __FILE *__stream);
+__END_NAMESPACE_C99
+
+
+#ifdef __USE_GNU
+/* These are defined to be equivalent to the `char' functions defined
+ in POSIX.1:1996.
+
+ These functions are not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation they are cancellation points and
+ therefore not marked with __THROW. */
+extern wint_t getwc_unlocked (__FILE *__stream);
+extern wint_t getwchar_unlocked (void);
+
+/* This is the wide character version of a GNU extension.
+
+ This function is not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation it is a cancellation point and
+ therefore not marked with __THROW. */
+extern wint_t fgetwc_unlocked (__FILE *__stream);
+
+/* Faster version when locking is not necessary.
+
+ This function is not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation it is a cancellation point and
+ therefore not marked with __THROW. */
+extern wint_t fputwc_unlocked (wchar_t __wc, __FILE *__stream);
+
+/* These are defined to be equivalent to the `char' functions defined
+ in POSIX.1:1996.
+
+ These functions are not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation they are cancellation points and
+ therefore not marked with __THROW. */
+extern wint_t putwc_unlocked (wchar_t __wc, __FILE *__stream);
+extern wint_t putwchar_unlocked (wchar_t __wc);
+
+
+/* This function does the same as `fgetws' but does not lock the stream.
+
+ This function is not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation it is a cancellation point and
+ therefore not marked with __THROW. */
+extern wchar_t *fgetws_unlocked (wchar_t *__restrict __ws, int __n,
+ __FILE *__restrict __stream);
+
+/* This function does the same as `fputws' but does not lock the stream.
+
+ This function is not part of POSIX and therefore no official
+ cancellation point. But due to similarity with an POSIX interface
+ or due to the implementation it is a cancellation point and
+ therefore not marked with __THROW. */
+extern int fputws_unlocked (__const wchar_t *__restrict __ws,
+ __FILE *__restrict __stream);
+#endif
+
+
+__BEGIN_NAMESPACE_C99
+/* Format TP into S according to FORMAT.
+ Write no more than MAXSIZE wide characters and return the number
+ of wide characters written, or 0 if it would exceed MAXSIZE. */
+extern size_t wcsftime (wchar_t *__restrict __s, size_t __maxsize,
+ __const wchar_t *__restrict __format,
+ __const struct tm *__restrict __tp) __THROW;
+__END_NAMESPACE_C99
+
+# ifdef __USE_GNU
+# include <xlocale.h>
+
+/* Similar to `wcsftime' but takes the information from
+ the provided locale and not the global locale. */
+extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
+ __const wchar_t *__restrict __format,
+ __const struct tm *__restrict __tp,
+ __locale_t __loc) __THROW;
+# endif
+
+/* The X/Open standard demands that most of the functions defined in
+ the <wctype.h> header must also appear here. This is probably
+ because some X/Open members wrote their implementation before the
+ ISO C standard was published and introduced the better solution.
+ We have to provide these definitions for compliance reasons but we
+ do this nonsense only if really necessary. */
+#if defined __USE_UNIX98 && !defined __USE_GNU
+# define __need_iswxxx
+# include <wctype.h>
+#endif
+
+/* Define some macros helping to catch buffer overflows. */
+#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+# include <bits/wchar2.h>
+#endif
+
+#ifdef __LDBL_COMPAT
+# include <bits/wchar-ldbl.h>
+#endif
+
+__END_DECLS
+
+#endif /* _WCHAR_H defined */
+
+#endif /* wchar.h */
diff --git a/libc/dfp/sysdeps/ieee754r/d128/acosd128.c b/libc/dfp/sysdeps/ieee754r/d128/acosd128.c
new file mode 100644
index 000000000..29b335256
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/acosd128.c
@@ -0,0 +1,25 @@
+/* Calculates the arccos(x)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/acosd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/acoshd128.c b/libc/dfp/sysdeps/ieee754r/d128/acoshd128.c
new file mode 100644
index 000000000..34ff0becb
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/acoshd128.c
@@ -0,0 +1,25 @@
+/* Calculates the arc that has the given tangent for a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/acoshd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/asind128.c b/libc/dfp/sysdeps/ieee754r/d128/asind128.c
new file mode 100644
index 000000000..cd09716da
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/asind128.c
@@ -0,0 +1,25 @@
+/* Calculates the arccos(x)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/asind32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/asinhd128.c b/libc/dfp/sysdeps/ieee754r/d128/asinhd128.c
new file mode 100644
index 000000000..db6b2f18d
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/asinhd128.c
@@ -0,0 +1,25 @@
+/* Calculates <descrption goes here> for a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/asinhd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/atan2d128.c b/libc/dfp/sysdeps/ieee754r/d128/atan2d128.c
new file mode 100644
index 000000000..216866b11
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/atan2d128.c
@@ -0,0 +1,25 @@
+/* Calculates the arc that has the given tangent for a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/atan2d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/atand128.c b/libc/dfp/sysdeps/ieee754r/d128/atand128.c
new file mode 100644
index 000000000..e787e76d5
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/atand128.c
@@ -0,0 +1,25 @@
+/* Calculates the arc that has the given tangent for a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/atand32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/atanhd128.c b/libc/dfp/sysdeps/ieee754r/d128/atanhd128.c
new file mode 100644
index 000000000..264d130e1
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/atanhd128.c
@@ -0,0 +1,25 @@
+/* Calculates the hyperbolic arc tangent (atanh) for a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/atanhd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/cbrtd128.c b/libc/dfp/sysdeps/ieee754r/d128/cbrtd128.c
new file mode 100644
index 000000000..0977ec393
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/cbrtd128.c
@@ -0,0 +1,25 @@
+/* Calculates the cube root function of _Decimal128 type x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/cbrtd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/ceild128.c b/libc/dfp/sysdeps/ieee754r/d128/ceild128.c
new file mode 100644
index 000000000..361d48650
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/ceild128.c
@@ -0,0 +1,25 @@
+/* Ceiling function for _Decimal128 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/ceild32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/copysignd128.c b/libc/dfp/sysdeps/ieee754r/d128/copysignd128.c
new file mode 100644
index 000000000..5eeb3df04
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/copysignd128.c
@@ -0,0 +1,25 @@
+/* Copies the sign from the second argument to the first
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/copysignd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/cosd128.c b/libc/dfp/sysdeps/ieee754r/d128/cosd128.c
new file mode 100644
index 000000000..d8c70448a
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/cosd128.c
@@ -0,0 +1,25 @@
+/* Calculate the cos(x) for a _Decimal128 format x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/cosd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/coshd128.c b/libc/dfp/sysdeps/ieee754r/d128/coshd128.c
new file mode 100644
index 000000000..a320ad5ea
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/coshd128.c
@@ -0,0 +1,25 @@
+/* Calculate the hyperbolic cos (cosh) for _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/coshd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/erfd128.c b/libc/dfp/sysdeps/ieee754r/d128/erfd128.c
new file mode 100644
index 000000000..26cab6197
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/erfd128.c
@@ -0,0 +1,25 @@
+/* Returns the error function of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/erfd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/exp2d128.c b/libc/dfp/sysdeps/ieee754r/d128/exp2d128.c
new file mode 100644
index 000000000..73fe20d79
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/exp2d128.c
@@ -0,0 +1,25 @@
+/* Returns the value of 2 raised to the power of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/exp2d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/expd128.c b/libc/dfp/sysdeps/ieee754r/d128/expd128.c
new file mode 100644
index 000000000..5a03a1b15
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/expd128.c
@@ -0,0 +1,25 @@
+/* Calculate e^x, where x is the given _Decimal128 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/expd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/expm1d128.c b/libc/dfp/sysdeps/ieee754r/d128/expm1d128.c
new file mode 100644
index 000000000..01e91d1c7
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/expm1d128.c
@@ -0,0 +1,25 @@
+/* Returns a value equivelent to exp(x) - 1
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/expm1d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/fabsd128.c b/libc/dfp/sysdeps/ieee754r/d128/fabsd128.c
new file mode 100644
index 000000000..4d6e15dbf
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/fabsd128.c
@@ -0,0 +1,25 @@
+/* Calculate the absolute value for a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/fabsd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/fdimd128.c b/libc/dfp/sysdeps/ieee754r/d128/fdimd128.c
new file mode 100644
index 000000000..464741fc6
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/fdimd128.c
@@ -0,0 +1,25 @@
+/* Returns the positive difference between the _Decimal128 type arguments
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/fdimd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/finited128.c b/libc/dfp/sysdeps/ieee754r/d128/finited128.c
new file mode 100644
index 000000000..e24298482
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/finited128.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if the _Decimal128 is non-infinite
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/finited32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/floord128.c b/libc/dfp/sysdeps/ieee754r/d128/floord128.c
new file mode 100644
index 000000000..c6fd2962d
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/floord128.c
@@ -0,0 +1,25 @@
+/* Floor function for _Decimal128 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/floord32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/fmad128.c b/libc/dfp/sysdeps/ieee754r/d128/fmad128.c
new file mode 100644
index 000000000..056008147
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/fmad128.c
@@ -0,0 +1,25 @@
+/* Floating point multiply and add (x * y + z)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/fmad32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/fmaxd128.c b/libc/dfp/sysdeps/ieee754r/d128/fmaxd128.c
new file mode 100644
index 000000000..a066b5ae4
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/fmaxd128.c
@@ -0,0 +1,25 @@
+/* Determine the maximum of two _Decimal128 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/fmaxd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/fmind128.c b/libc/dfp/sysdeps/ieee754r/d128/fmind128.c
new file mode 100644
index 000000000..a097a6ab5
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/fmind128.c
@@ -0,0 +1,25 @@
+/* Determine the minimum of two _Decimal128 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/fmind32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/fmodd128.c b/libc/dfp/sysdeps/ieee754r/d128/fmodd128.c
new file mode 100644
index 000000000..d39390929
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/fmodd128.c
@@ -0,0 +1,25 @@
+/* Returns the remainder of a floating point division
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/fmodd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/fpclassifyd128.c b/libc/dfp/sysdeps/ieee754r/d128/fpclassifyd128.c
new file mode 100644
index 000000000..0a4abbac5
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/fpclassifyd128.c
@@ -0,0 +1,25 @@
+/* Returns the type of floating point number from a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/fpclassifyd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/frexpd128.c b/libc/dfp/sysdeps/ieee754r/d128/frexpd128.c
new file mode 100644
index 000000000..b513d5076
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/frexpd128.c
@@ -0,0 +1,25 @@
+/* Break floating point number into normalized fraction and integral power of two
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/frexpd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/hypotd128.c b/libc/dfp/sysdeps/ieee754r/d128/hypotd128.c
new file mode 100644
index 000000000..af6479960
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/hypotd128.c
@@ -0,0 +1,25 @@
+/* Returns sqrt(x*x+y*y)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/hypotd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/ilogbd128.c b/libc/dfp/sysdeps/ieee754r/d128/ilogbd128.c
new file mode 100644
index 000000000..eaede83cc
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/ilogbd128.c
@@ -0,0 +1,26 @@
+/* Returns the unbiased exponent of the passed _Decimal128 value as an int
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+#define DFP_DEBUG(arg) printf("%DDf\n", arg)
+
+#include "../d32/ilogbd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/isgreaterd128.c b/libc/dfp/sysdeps/ieee754r/d128/isgreaterd128.c
new file mode 100644
index 000000000..36ec70a61
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/isgreaterd128.c
@@ -0,0 +1,25 @@
+/* Implements > for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/isgreaterd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/isgreaterequald128.c b/libc/dfp/sysdeps/ieee754r/d128/isgreaterequald128.c
new file mode 100644
index 000000000..a92a7eafc
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/isgreaterequald128.c
@@ -0,0 +1,25 @@
+/* Implements >= for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/isgreaterequald32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/isinfd128.c b/libc/dfp/sysdeps/ieee754r/d128/isinfd128.c
new file mode 100644
index 000000000..181caf97a
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/isinfd128.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if the _Decimal128 is infinite
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/isinfd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/islessd128.c b/libc/dfp/sysdeps/ieee754r/d128/islessd128.c
new file mode 100644
index 000000000..d501e205b
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/islessd128.c
@@ -0,0 +1,25 @@
+/* Implements < for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/islessd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/islessequald128.c b/libc/dfp/sysdeps/ieee754r/d128/islessequald128.c
new file mode 100644
index 000000000..9da116dea
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/islessequald128.c
@@ -0,0 +1,25 @@
+/* Implements <= for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/islessequald32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/islessgreaterd128.c b/libc/dfp/sysdeps/ieee754r/d128/islessgreaterd128.c
new file mode 100644
index 000000000..3073b7350
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/islessgreaterd128.c
@@ -0,0 +1,25 @@
+/* Implements <> for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/islessgreaterd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/isnand128.c b/libc/dfp/sysdeps/ieee754r/d128/isnand128.c
new file mode 100644
index 000000000..53ae63fc7
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/isnand128.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if the _Decimal128 is nan
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/isnand32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/isnormald128.c b/libc/dfp/sysdeps/ieee754r/d128/isnormald128.c
new file mode 100644
index 000000000..87ac2f625
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/isnormald128.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if the _Decimal128 is normalized
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/isnormald32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/isunorderedd128.c b/libc/dfp/sysdeps/ieee754r/d128/isunorderedd128.c
new file mode 100644
index 000000000..06167706a
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/isunorderedd128.c
@@ -0,0 +1,25 @@
+/* Returns true if either _Decimal128 is NaN
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/isunorderedd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/ldexpd128.c b/libc/dfp/sysdeps/ieee754r/d128/ldexpd128.c
new file mode 100644
index 000000000..a4af95dd1
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/ldexpd128.c
@@ -0,0 +1,25 @@
+/* Returns the _Decimal128 value * 2^ the integral value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/ldexpd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/lgammad128.c b/libc/dfp/sysdeps/ieee754r/d128/lgammad128.c
new file mode 100644
index 000000000..b2e31f56e
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/lgammad128.c
@@ -0,0 +1,25 @@
+/* Returns the natural logarithm of the absolute value of the Gamma function of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/lgammad32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/llrintd128.c b/libc/dfp/sysdeps/ieee754r/d128/llrintd128.c
new file mode 100644
index 000000000..29f2e9df9
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/llrintd128.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest (long long int) integer
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/llrintd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/llroundd128.c b/libc/dfp/sysdeps/ieee754r/d128/llroundd128.c
new file mode 100644
index 000000000..d0dc4ce9d
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/llroundd128.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest long long int value, ignoring rounding mode
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/llroundd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/log10d128.c b/libc/dfp/sysdeps/ieee754r/d128/log10d128.c
new file mode 100644
index 000000000..52bffcbb3
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/log10d128.c
@@ -0,0 +1,25 @@
+/* Calculate the Log (base 10) of a given _Decimal128 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/log10d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/log1pd128.c b/libc/dfp/sysdeps/ieee754r/d128/log1pd128.c
new file mode 100644
index 000000000..c424635d5
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/log1pd128.c
@@ -0,0 +1,25 @@
+/* Calculate the Natural Log of a given a _Decimal128 value + 1
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/log1pd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/log2d128.c b/libc/dfp/sysdeps/ieee754r/d128/log2d128.c
new file mode 100644
index 000000000..46cc2250c
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/log2d128.c
@@ -0,0 +1,25 @@
+/* Returns the base 2 logarithmic function of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/log2d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/logbd128.c b/libc/dfp/sysdeps/ieee754r/d128/logbd128.c
new file mode 100644
index 000000000..e1e6692a8
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/logbd128.c
@@ -0,0 +1,25 @@
+/* Returns the unbiased exponent of the passed _Decimal128 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/logbd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/logd128.c b/libc/dfp/sysdeps/ieee754r/d128/logd128.c
new file mode 100644
index 000000000..124cc0d0e
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/logd128.c
@@ -0,0 +1,25 @@
+/* Calculate the Natural Log of a given a _Decimal128 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/logd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/lrintd128.c b/libc/dfp/sysdeps/ieee754r/d128/lrintd128.c
new file mode 100644
index 000000000..6460f614e
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/lrintd128.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest (long int) integer
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/lrintd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/lroundd128.c b/libc/dfp/sysdeps/ieee754r/d128/lroundd128.c
new file mode 100644
index 000000000..fb0dc0603
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/lroundd128.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest long int value, ignoring rounding mode.
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/lroundd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/modfd128.c b/libc/dfp/sysdeps/ieee754r/d128/modfd128.c
new file mode 100644
index 000000000..18ebbdad4
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/modfd128.c
@@ -0,0 +1,25 @@
+/* Breaks the argument into integral and fractional parts for a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/modfd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/nand128.c b/libc/dfp/sysdeps/ieee754r/d128/nand128.c
new file mode 100644
index 000000000..452c3c848
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/nand128.c
@@ -0,0 +1,25 @@
+/* Returns a reprentation of NaN in the _Decimal128 format
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/nand32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/nearbyintd128.c b/libc/dfp/sysdeps/ieee754r/d128/nearbyintd128.c
new file mode 100644
index 000000000..420e6c84b
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/nearbyintd128.c
@@ -0,0 +1,26 @@
+/* Round to nearest integer _Decimal128 form
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+#include "../d32/nearbyintd32.c"
+
diff --git a/libc/dfp/sysdeps/ieee754r/d128/nextafterd128.c b/libc/dfp/sysdeps/ieee754r/d128/nextafterd128.c
new file mode 100644
index 000000000..52dfb3374
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/nextafterd128.c
@@ -0,0 +1,25 @@
+/* Returns the next representable neighbor of x in the direction of y
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/nextafterd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/nexttowardd128.c b/libc/dfp/sysdeps/ieee754r/d128/nexttowardd128.c
new file mode 100644
index 000000000..74e72f720
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/nexttowardd128.c
@@ -0,0 +1,26 @@
+/* Returns the next representable neighbor of x in the direction of y
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+#include <dfptypeconv128.h>
+
+#include "../d32/nexttowardd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/powd128.c b/libc/dfp/sysdeps/ieee754r/d128/powd128.c
new file mode 100644
index 000000000..6bec63a6c
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/powd128.c
@@ -0,0 +1,25 @@
+/* Calculate x^y, where x and y are _Decimal128 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/powd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/quantized128.c b/libc/dfp/sysdeps/ieee754r/d128/quantized128.c
new file mode 100644
index 000000000..fcf676683
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/quantized128.c
@@ -0,0 +1,25 @@
+/* Set the exponent of x to the exp of y, trying to preserve the value of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/quantized32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/remainderd128.c b/libc/dfp/sysdeps/ieee754r/d128/remainderd128.c
new file mode 100644
index 000000000..896627671
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/remainderd128.c
@@ -0,0 +1,25 @@
+/* Returns the result of x - ((int-round_even)(x/y)) * y
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/remainderd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/rintd128.c b/libc/dfp/sysdeps/ieee754r/d128/rintd128.c
new file mode 100644
index 000000000..4c50cf0e4
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/rintd128.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest integer
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/rintd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/roundd128.c b/libc/dfp/sysdeps/ieee754r/d128/roundd128.c
new file mode 100644
index 000000000..da59f4661
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/roundd128.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest integer value, ignores rounding mode
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/roundd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/samequantumd128.c b/libc/dfp/sysdeps/ieee754r/d128/samequantumd128.c
new file mode 100644
index 000000000..19f4405dc
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/samequantumd128.c
@@ -0,0 +1,25 @@
+/* Returns true if x and y have the same exponent
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/samequantumd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/scalblnd128.c b/libc/dfp/sysdeps/ieee754r/d128/scalblnd128.c
new file mode 100644
index 000000000..e1bd5aab8
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/scalblnd128.c
@@ -0,0 +1,25 @@
+/* Returns x * FLT_RADIX^y without computing the right side directly
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/scalblnd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/scalbnd128.c b/libc/dfp/sysdeps/ieee754r/d128/scalbnd128.c
new file mode 100644
index 000000000..e3bc182a9
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/scalbnd128.c
@@ -0,0 +1,25 @@
+/* Returns x * FLT_RADIX^y without computing the right side directly
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/scalbnd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/signbitd128.c b/libc/dfp/sysdeps/ieee754r/d128/signbitd128.c
new file mode 100644
index 000000000..aac74680b
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/signbitd128.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if _Decimal128 is negative
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/signbitd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/sind128.c b/libc/dfp/sysdeps/ieee754r/d128/sind128.c
new file mode 100644
index 000000000..639e8c792
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/sind128.c
@@ -0,0 +1,25 @@
+/* Calculate the sin(x) for a _Decimal128 format x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/sind32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/sinhd128.c b/libc/dfp/sysdeps/ieee754r/d128/sinhd128.c
new file mode 100644
index 000000000..21102d149
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/sinhd128.c
@@ -0,0 +1,25 @@
+/* Calculate the hyperbolic sin (sinh) for a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/sinhd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/sqrtd128.c b/libc/dfp/sysdeps/ieee754r/d128/sqrtd128.c
new file mode 100644
index 000000000..fdb4b2013
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/sqrtd128.c
@@ -0,0 +1,25 @@
+/* Returns the square root of a _Decimal128 type argument
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/sqrtd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/tand128.c b/libc/dfp/sysdeps/ieee754r/d128/tand128.c
new file mode 100644
index 000000000..a40a5f8c9
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/tand128.c
@@ -0,0 +1,25 @@
+/* Calculate the tan(x) for _Decimal128 format x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/tand32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/tanhd128.c b/libc/dfp/sysdeps/ieee754r/d128/tanhd128.c
new file mode 100644
index 000000000..7338beb34
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/tanhd128.c
@@ -0,0 +1,25 @@
+/* Calculate the hyperbolic tan (tanh) for a _Decimal128 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/tanhd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/tgammad128.c b/libc/dfp/sysdeps/ieee754r/d128/tgammad128.c
new file mode 100644
index 000000000..ea8e0e251
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/tgammad128.c
@@ -0,0 +1,25 @@
+/* Returns the result of integral[0->inf, t**(x-1) * e**(-t) dt]
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/tgammad32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d128/truncd128.c b/libc/dfp/sysdeps/ieee754r/d128/truncd128.c
new file mode 100644
index 000000000..697954381
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d128/truncd128.c
@@ -0,0 +1,25 @@
+/* Round a _Decimal128 type to the nearest but <= argument
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 128
+#include <decimal128.h>
+
+#include "../d32/truncd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d32/acosd32.c b/libc/dfp/sysdeps/ieee754r/d32/acosd32.c
new file mode 100644
index 000000000..ea5340a93
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/acosd32.c
@@ -0,0 +1,356 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+ */
+/* Calculates the arccos(x)
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ Modified for dfp by Joseph Kerian <jkerian@us.ibm.com>
+ This file is part of the GNU C Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* __ieee754_acosl(x)
+ * Method :
+ * acos(x) = pi/2 - asin(x)
+ * acos(-x) = pi/2 + asin(x)
+ * For |x| <= 0.375
+ * acos(x) = pi/2 - asin(x)
+ * Between .375 and .5 the approximation is
+ * acos(0.4375 + x) = acos(0.4375) + x P(x) / Q(x)
+ * Between .5 and .625 the approximation is
+ * acos(0.5625 + x) = acos(0.5625) + x rS(x) / sS(x)
+ * For x > 0.625,
+ * acos(x) = 2 asin(sqrt((1-x)/2))
+ * computed with an extended precision square root in the leading term.
+ * For x < -0.625
+ * acos(x) = pi - 2 asin(sqrt((1-|x|)/2))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ * Functions needed: __ieee754_sqrtl.
+ */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+#include <errno.h>
+
+#ifdef __STDC__
+static const _Decimal128
+#else
+static _Decimal128
+#endif
+ one = 1.0DL,
+ pio2_hi = 1.5707963267948966192313216916397514420986DL,
+ pio2_lo = 4.3359050650618905123985220130216759843812E-35DL,
+
+ /* acos(0.5625 + x) = acos(0.5625) + x rS(x) / sS(x)
+ -0.0625 <= x <= 0.0625
+ peak relative error 3.3e-35 */
+
+ rS0 = 5.619049346208901520945464704848780243887E0DL,
+ rS1 = -4.460504162777731472539175700169871920352E1DL,
+ rS2 = 1.317669505315409261479577040530751477488E2DL,
+ rS3 = -1.626532582423661989632442410808596009227E2DL,
+ rS4 = 3.144806644195158614904369445440583873264E1DL,
+ rS5 = 9.806674443470740708765165604769099559553E1DL,
+ rS6 = -5.708468492052010816555762842394927806920E1DL,
+ rS7 = -1.396540499232262112248553357962639431922E1DL,
+ rS8 = 1.126243289311910363001762058295832610344E1DL,
+ rS9 = 4.956179821329901954211277873774472383512E-1DL,
+ rS10 = -3.313227657082367169241333738391762525780E-1DL,
+
+ sS0 = -4.645814742084009935700221277307007679325E0DL,
+ sS1 = 3.879074822457694323970438316317961918430E1DL,
+ sS2 = -1.221986588013474694623973554726201001066E2DL,
+ sS3 = 1.658821150347718105012079876756201905822E2DL,
+ sS4 = -4.804379630977558197953176474426239748977E1DL,
+ sS5 = -1.004296417397316948114344573811562952793E2DL,
+ sS6 = 7.530281592861320234941101403870010111138E1DL,
+ sS7 = 1.270735595411673647119592092304357226607E1DL,
+ sS8 = -1.815144839646376500705105967064792930282E1DL,
+ sS9 = -7.821597334910963922204235247786840828217E-2DL,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ acosr5625 = 9.7338991014954640492751132535550279812151E-1DL,
+ pimacosr5625 = 2.1682027434402468335351320579240000860757E0DL,
+
+ /* acos(0.4375 + x) = acos(0.4375) + x rS(x) / sS(x)
+ -0.0625 <= x <= 0.0625
+ peak relative error 2.1e-35 */
+
+ P0 = 2.177690192235413635229046633751390484892E0DL,
+ P1 = -2.848698225706605746657192566166142909573E1DL,
+ P2 = 1.040076477655245590871244795403659880304E2DL,
+ P3 = -1.400087608918906358323551402881238180553E2DL,
+ P4 = 2.221047917671449176051896400503615543757E1DL,
+ P5 = 9.643714856395587663736110523917499638702E1DL,
+ P6 = -5.158406639829833829027457284942389079196E1DL,
+ P7 = -1.578651828337585944715290382181219741813E1DL,
+ P8 = 1.093632715903802870546857764647931045906E1DL,
+ P9 = 5.448925479898460003048760932274085300103E-1DL,
+ P10 = -3.315886001095605268470690485170092986337E-1DL,
+ Q0 = -1.958219113487162405143608843774587557016E0DL,
+ Q1 = 2.614577866876185080678907676023269360520E1DL,
+ Q2 = -9.990858606464150981009763389881793660938E1DL,
+ Q3 = 1.443958741356995763628660823395334281596E2DL,
+ Q4 = -3.206441012484232867657763518369723873129E1DL,
+ Q5 = -1.048560885341833443564920145642588991492E2DL,
+ Q6 = 6.745883931909770880159915641984874746358E1DL,
+ Q7 = 1.806809656342804436118449982647641392951E1DL,
+ Q8 = -1.770150690652438294290020775359580915464E1DL,
+ Q9 = -5.659156469628629327045433069052560211164E-1DL,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ acosr4375 = 1.1179797320499710475919903296900511518755E0DL,
+ pimacosr4375 = 2.0236129215398221908706530535894517323217E0DL,
+
+ /* asin(x) = x + x^3 pS(x^2) / qS(x^2)
+ 0 <= x <= 0.5
+ peak relative error 1.9e-35 */
+ pS0 = -8.358099012470680544198472400254596543711E2DL,
+ pS1 = 3.674973957689619490312782828051860366493E3DL,
+ pS2 = -6.730729094812979665807581609853656623219E3DL,
+ pS3 = 6.643843795209060298375552684423454077633E3DL,
+ pS4 = -3.817341990928606692235481812252049415993E3DL,
+ pS5 = 1.284635388402653715636722822195716476156E3DL,
+ pS6 = -2.410736125231549204856567737329112037867E2DL,
+ pS7 = 2.219191969382402856557594215833622156220E1DL,
+ pS8 = -7.249056260830627156600112195061001036533E-1DL,
+ pS9 = 1.055923570937755300061509030361395604448E-3DL,
+
+ qS0 = -5.014859407482408326519083440151745519205E3DL,
+ qS1 = 2.430653047950480068881028451580393430537E4DL,
+ qS2 = -4.997904737193653607449250593976069726962E4DL,
+ qS3 = 5.675712336110456923807959930107347511086E4DL,
+ qS4 = -3.881523118339661268482937768522572588022E4DL,
+ qS5 = 1.634202194895541569749717032234510811216E4DL,
+ qS6 = -4.151452662440709301601820849901296953752E3DL,
+ qS7 = 5.956050864057192019085175976175695342168E2DL,
+ qS8 = -4.175375777334867025769346564600396877176E1DL;
+ /* 1.000000000000000000000000000000000000000E0 */
+
+#include <math.h>
+
+#define FUNCTION_NAME acos
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ _Decimal128 z, r, w, p, q, s, t, f2, ix;
+ int32_t sign;
+
+ if(isnan(x))
+ return x+x;
+
+ sign = (x > 0.0DL)?0:1;
+ ix = FUNC_D(fabs) (x);
+
+ if (ix >= 1.0DL) /* |x| >= 1 */
+ {
+ if (ix == 1.0DL)
+ { /* |x| == 1 */
+ if (sign == 0)
+ return (DEC_TYPE)(0.0DL); /* acos(1) = 0 */
+ else
+ return (DEC_TYPE)((2.0DL * pio2_hi) + (2.0DL * pio2_lo)); /* acos(-1)= pi */
+ }
+ /* acos(|x| > 1) is NaN */
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ else if (ix < 0.5DL) /* |x| < 0.5 */
+ {
+ /* |x| < 2**-57 */
+ if (ix < 0.000000000000000000000000000000000000000000000000000000002DL)
+ return (DEC_TYPE)(pio2_hi + pio2_lo); //Should raise INEXACT
+ if (ix < 0.4375DL) /* |x| < .4375 */
+ {
+ /* Arcsine of x. */
+ z = x * x;
+ p = (((((((((pS9 * z
+ + pS8) * z
+ + pS7) * z
+ + pS6) * z
+ + pS5) * z
+ + pS4) * z
+ + pS3) * z
+ + pS2) * z
+ + pS1) * z
+ + pS0) * z;
+ q = (((((((( z
+ + qS8) * z
+ + qS7) * z
+ + qS6) * z
+ + qS5) * z
+ + qS4) * z
+ + qS3) * z
+ + qS2) * z
+ + qS1) * z
+ + qS0;
+ r = x + x * p / q;
+ z = pio2_hi - (r - pio2_lo);
+ return (DEC_TYPE)z;
+ }
+ /* .4375 <= |x| < .5 */
+ t = ix - 0.4375DL;
+ p = ((((((((((P10 * t
+ + P9) * t
+ + P8) * t
+ + P7) * t
+ + P6) * t
+ + P5) * t
+ + P4) * t
+ + P3) * t
+ + P2) * t
+ + P1) * t
+ + P0) * t;
+
+ q = (((((((((t
+ + Q9) * t
+ + Q8) * t
+ + Q7) * t
+ + Q6) * t
+ + Q5) * t
+ + Q4) * t
+ + Q3) * t
+ + Q2) * t
+ + Q1) * t
+ + Q0;
+ r = p / q;
+ if (sign)
+ r = pimacosr4375 - r;
+ else
+ r = acosr4375 + r;
+ return (DEC_TYPE)r;
+ }
+ else if (ix < 0.625DL) /* |x| < 0.625 */
+ {
+ t = ix - 0.5625DL;
+ p = ((((((((((rS10 * t
+ + rS9) * t
+ + rS8) * t
+ + rS7) * t
+ + rS6) * t
+ + rS5) * t
+ + rS4) * t
+ + rS3) * t
+ + rS2) * t
+ + rS1) * t
+ + rS0) * t;
+
+ q = (((((((((t
+ + sS9) * t
+ + sS8) * t
+ + sS7) * t
+ + sS6) * t
+ + sS5) * t
+ + sS4) * t
+ + sS3) * t
+ + sS2) * t
+ + sS1) * t
+ + sS0;
+ if (sign)
+ r = pimacosr5625 - p / q;
+ else
+ r = acosr5625 + p / q;
+ return (DEC_TYPE)r;
+ }
+ else
+ { /* |x| >= .625 */
+ z = (one - ix) * 0.5DL;
+ s = sqrtd128 (z);
+ /* Compute an extended precision square root from
+ the Newton iteration s -> 0.5 * (s + z / s).
+ The change w from s to the improved value is
+ w = 0.5 * (s + z / s) - s = (s^2 + z)/2s - s = (z - s^2)/2s.
+ Express s = f1 + f2 where f1 * f1 is exactly representable.
+ w = (z - s^2)/2s = (z - f1^2 - 2 f1 f2 - f2^2)/2s .
+ s + w has extended precision. */
+ p = s;
+ /*
+ u.value = s;
+ u.parts32.w2 = 0;
+ u.parts32.w3 = 0;
+ */
+ f2 = s - p;
+ w = z - p * p;
+ w = w - 2.0DL * p * f2;
+ w = w - f2 * f2;
+ w = w / (2.0DL * s);
+ /* Arcsine of s. */
+ p = (((((((((pS9 * z
+ + pS8) * z
+ + pS7) * z
+ + pS6) * z
+ + pS5) * z
+ + pS4) * z
+ + pS3) * z
+ + pS2) * z
+ + pS1) * z
+ + pS0) * z;
+ q = (((((((( z
+ + qS8) * z
+ + qS7) * z
+ + qS6) * z
+ + qS5) * z
+ + qS4) * z
+ + qS3) * z
+ + qS2) * z
+ + qS1) * z
+ + qS0;
+ r = s + (w + s * p / q);
+
+ if (sign)
+ w = pio2_hi + (pio2_lo - r);
+ else
+ w = r;
+ return (DEC_TYPE)(2.0DL * w);
+ }
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (x > DFP_CONSTANT(1.0) || x < DFP_CONSTANT(-1.0))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/acoshd32.c b/libc/dfp/sysdeps/ieee754r/d32/acoshd32.c
new file mode 100644
index 000000000..eb93d02d8
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/acoshd32.c
@@ -0,0 +1,103 @@
+/* Returns the hyperbolic arc cosine of a _Decimal32 type argument
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME acosh
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result, one;
+ decNumber dn_x, dn_one;
+
+ one=DFP_CONSTANT(1.0);
+ FUNC_CONVERT_TO_DN (&one, &dn_one);
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+
+ if (x<one) {
+ /* Domain error (invalid exception) if x < 1 (incl. -Inf) */
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ } else if (x==one) {
+ /* If x == +1, result is zero. */
+ return DFP_CONSTANT(0.0);
+ }
+
+// switch (___decCompare (&dn_x, &dn_one) )
+// {
+ /* Domain error (invalid exception) if x < 1 (incl. -Inf) */
+// case -1:
+// DFP_EXCEPT (FE_INVALID);
+// return DFP_NAN;
+// /* If x == +1, result is zero. */
+// case 0:
+// return DFP_CONSTANT(0.0);
+// }
+
+ /* Early exit for the infinite case (-Inf is handled above) */
+ if (___decNumberIsInfinite (&dn_x))
+ return x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+
+ /* using trig identity: acosh(x) = log(x+sqrt(x*x-1)) */
+ ___decNumberMultiply (&dn_result, &dn_x, &dn_x, &context);
+ ___decNumberSubtract (&dn_result, &dn_result, &dn_one, &context);
+ ___decNumberSquareRoot (&dn_result, &dn_result, &context);
+ ___decNumberAdd (&dn_result, &dn_result, &dn_x, &context);
+ ___decNumberLn (&dn_result, &dn_result, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (x < DFP_CONSTANT(1.0))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/asind32.c b/libc/dfp/sysdeps/ieee754r/d32/asind32.c
new file mode 100644
index 000000000..5e09866f9
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/asind32.c
@@ -0,0 +1,296 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ Long double expansions are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under the
+ following terms:
+*/
+
+/* Calculates the arcsin(x)
+ Modified for dfp by Joseph Kerian <jkerian@us.ibm.com>
+ This file is part of the GNU C Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* __ieee754_asin(x)
+ * Method :
+ * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
+ * we approximate asin(x) on [0,0.5] by
+ * asin(x) = x + x*x^2*R(x^2)
+ * Between .5 and .625 the approximation is
+ * asin(0.5625 + x) = asin(0.5625) + x rS(x) / sS(x)
+ * For x in [0.625,1]
+ * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ * then for x>0.98
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ * For x<=0.98, let pio4_hi = pio2_hi/2, then
+ * f = hi part of s;
+ * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
+ * and
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+#include <errno.h>
+
+#ifdef __STDC__
+static const _Decimal128
+#else
+static _Decimal128
+#endif
+ one = 1.0DL,
+ huge = 1.0e+300DL,
+ pio2_hi = 1.5707963267948966192313216916397514420986DL,
+ pio2_lo = 4.3359050650618905123985220130216759843812E-35DL,
+ pio4_hi = 7.8539816339744830961566084581987569936977E-1DL,
+
+ /* coefficient for R(x^2) */
+
+ /* asin(x) = x + x^3 pS(x^2) / qS(x^2)
+ 0 <= x <= 0.5
+ peak relative error 1.9e-35 */
+ pS0 = -8.358099012470680544198472400254596543711E2DL,
+ pS1 = 3.674973957689619490312782828051860366493E3DL,
+ pS2 = -6.730729094812979665807581609853656623219E3DL,
+ pS3 = 6.643843795209060298375552684423454077633E3DL,
+ pS4 = -3.817341990928606692235481812252049415993E3DL,
+ pS5 = 1.284635388402653715636722822195716476156E3DL,
+ pS6 = -2.410736125231549204856567737329112037867E2DL,
+ pS7 = 2.219191969382402856557594215833622156220E1DL,
+ pS8 = -7.249056260830627156600112195061001036533E-1DL,
+ pS9 = 1.055923570937755300061509030361395604448E-3DL,
+
+ qS0 = -5.014859407482408326519083440151745519205E3DL,
+ qS1 = 2.430653047950480068881028451580393430537E4DL,
+ qS2 = -4.997904737193653607449250593976069726962E4DL,
+ qS3 = 5.675712336110456923807959930107347511086E4DL,
+ qS4 = -3.881523118339661268482937768522572588022E4DL,
+ qS5 = 1.634202194895541569749717032234510811216E4DL,
+ qS6 = -4.151452662440709301601820849901296953752E3DL,
+ qS7 = 5.956050864057192019085175976175695342168E2DL,
+ qS8 = -4.175375777334867025769346564600396877176E1DL,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ /* asin(0.5625 + x) = asin(0.5625) + x rS(x) / sS(x)
+ -0.0625 <= x <= 0.0625
+ peak relative error 3.3e-35 */
+ rS0 = -5.619049346208901520945464704848780243887E0DL,
+ rS1 = 4.460504162777731472539175700169871920352E1DL,
+ rS2 = -1.317669505315409261479577040530751477488E2DL,
+ rS3 = 1.626532582423661989632442410808596009227E2DL,
+ rS4 = -3.144806644195158614904369445440583873264E1DL,
+ rS5 = -9.806674443470740708765165604769099559553E1DL,
+ rS6 = 5.708468492052010816555762842394927806920E1DL,
+ rS7 = 1.396540499232262112248553357962639431922E1DL,
+ rS8 = -1.126243289311910363001762058295832610344E1DL,
+ rS9 = -4.956179821329901954211277873774472383512E-1DL,
+ rS10 = 3.313227657082367169241333738391762525780E-1DL,
+
+ sS0 = -4.645814742084009935700221277307007679325E0DL,
+ sS1 = 3.879074822457694323970438316317961918430E1DL,
+ sS2 = -1.221986588013474694623973554726201001066E2DL,
+ sS3 = 1.658821150347718105012079876756201905822E2DL,
+ sS4 = -4.804379630977558197953176474426239748977E1DL,
+ sS5 = -1.004296417397316948114344573811562952793E2DL,
+ sS6 = 7.530281592861320234941101403870010111138E1DL,
+ sS7 = 1.270735595411673647119592092304357226607E1DL,
+ sS8 = -1.815144839646376500705105967064792930282E1DL,
+ sS9 = -7.821597334910963922204235247786840828217E-2DL,
+ /* 1.000000000000000000000000000000000000000E0 */
+
+ asinr5625 = 5.9740641664535021430381036628424864397707E-1DL;
+
+#include <math.h>
+
+#define FUNCTION_NAME asin
+
+#include <dfpmacro.h>
+
+
+//#include "math_private.h"
+//long double sqrtl (long double);
+
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ _Decimal128 t, w, p, q, c, r, s, ix;
+ int32_t sign, flag;
+
+ if(isnan(x))
+ return x+x;
+ flag = 0;
+ sign = (x < 0.0DL)?1:0;
+
+ ix = FUNC_D(fabs) (x);
+
+ if (ix >= 1.0DL) /* |x|>= 1 */
+ {
+ /* asin(1)=+-pi/2 with inexact */
+ if (ix == 1.0DL)
+ return (DEC_TYPE)(x * pio2_hi + x * pio2_lo);
+ /* asin(|x|>1) is NaN */
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ else if (ix < 0.5DL) /* |x| < 0.5 */
+ {
+ if (ix < 0.000000000000000000000000000000000000000000000000000000002DL) /* |x| < 2**-57 */
+ {
+ if (huge + x > one)
+ return x; /* return x with inexact if x!=0 */
+ t = 0.0DL;
+ }
+ else
+ {
+ t = x * x;
+ /* Mark to use pS, qS later on. */
+ flag = 1;
+ }
+ }
+ else if (ix < 0.625DL) /* 0.625 */
+ {
+ t = ix - 0.5625DL;
+ p = ((((((((((rS10 * t
+ + rS9) * t
+ + rS8) * t
+ + rS7) * t
+ + rS6) * t
+ + rS5) * t
+ + rS4) * t
+ + rS3) * t
+ + rS2) * t
+ + rS1) * t
+ + rS0) * t;
+
+ q = ((((((((( t
+ + sS9) * t
+ + sS8) * t
+ + sS7) * t
+ + sS6) * t
+ + sS5) * t
+ + sS4) * t
+ + sS3) * t
+ + sS2) * t
+ + sS1) * t
+ + sS0;
+ t = asinr5625 + p / q;
+ if (sign == 0)
+ return (DEC_TYPE)t;
+ else
+ return (DEC_TYPE)(-t);
+ }
+ else
+ {
+ /* 1 > |x| >= 0.625 */
+ w = one - ix;
+ t = w * 0.5DL;
+ }
+
+ p = (((((((((pS9 * t
+ + pS8) * t
+ + pS7) * t
+ + pS6) * t
+ + pS5) * t
+ + pS4) * t
+ + pS3) * t
+ + pS2) * t
+ + pS1) * t
+ + pS0) * t;
+
+ q = (((((((( t
+ + qS8) * t
+ + qS7) * t
+ + qS6) * t
+ + qS5) * t
+ + qS4) * t
+ + qS3) * t
+ + qS2) * t
+ + qS1) * t
+ + qS0;
+
+ if (flag) /* 2^-57 < |x| < 0.5 */
+ {
+ w = p / q;
+ return (DEC_TYPE)(x + x * w);
+ }
+
+ s = __sqrtd128 (t);
+ if (ix >= 0.975DL) /* |x| > 0.975 */
+ {
+ w = p / q;
+ t = pio2_hi - (2.0DL * (s + s * w) - pio2_lo);
+ }
+ else
+ {
+ w = s;
+/* Look into the reason this code was here
+ u.value = s;
+ u.parts32.w3 = 0;
+ u.parts32.w2 = 0;
+ w = u.value;
+ */
+ c = (t - w * w) / (s + w);
+ r = p / q;
+ p = 2.0DL * s * r - (pio2_lo - 2.0DL * c);
+ q = pio4_hi - 2.0DL * w;
+ t = pio4_hi - (p - q);
+ }
+
+ if (sign == 0)
+ return (DEC_TYPE)t;
+ else
+ return (DEC_TYPE)(-t);
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (x > DFP_CONSTANT(1.0) || x < DFP_CONSTANT(-1.0))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/asinhd32.c b/libc/dfp/sysdeps/ieee754r/d32/asinhd32.c
new file mode 100644
index 000000000..fddcdd4ab
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/asinhd32.c
@@ -0,0 +1,68 @@
+/* Returns the hyperbolic arc sine of a _Decimal32 type argument
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME asinh
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result, one;
+ decNumber dn_x, dn_one;
+
+ one = DFP_CONSTANT(1.0);
+ FUNC_CONVERT_TO_DN (&one, &dn_one);
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsZero (&dn_x)
+ || ___decNumberIsInfinite (&dn_x))
+ {
+ return x + x;
+ }
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+
+ /* using trig identity: acosh(x) = log(x+sqrt(x*x-1)) */
+ ___decNumberMultiply (&dn_result, &dn_x, &dn_x, &context);
+ ___decNumberAdd (&dn_result, &dn_result, &dn_one, &context);
+ ___decNumberSquareRoot (&dn_result, &dn_result, &context);
+ ___decNumberAdd (&dn_result, &dn_result, &dn_x, &context);
+ ___decNumberLn (&dn_result, &dn_result, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/atan2d32.c b/libc/dfp/sysdeps/ieee754r/d32/atan2d32.c
new file mode 100644
index 000000000..a1f24b794
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/atan2d32.c
@@ -0,0 +1,105 @@
+/* Calculates the arc that has the given tangent for a _Decimal32 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+ Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME atan2
+
+#include <dfpmacro.h>
+
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE y, DEC_TYPE x)
+{
+/* This needs to be kept in the range of _Decimal32, and only added
+ * to fairly large numbers (sizeable fractions of pi) */
+ const DEC_TYPE generate_inexact = DFP_CONSTANT(1e-94);
+
+ decContext context;
+ decNumber dn_result, dn_temp;
+ DEC_TYPE result;
+ decNumber dn_x, dn_y;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&y, &dn_y);
+
+ /* If either argument is NaN, return NaN */
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsNaN (&dn_y))
+ return x+y;
+
+ /* If x,y are both non-inf, non-NaN, non-zero, calculate as normal */
+ if (!___decNumberIsInfinite (&dn_x) && !___decNumberIsZero (&dn_y)
+ && !___decNumberIsInfinite (&dn_y) && !___decNumberIsZero (&dn_x))
+ {
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberDivide (&dn_temp, &dn_y, &dn_x, &context);
+ ___decNumberAtan (&dn_result, &dn_temp, &context);
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ /* decNumberAtan doesn't quite return the values in the ranges we
+ * want for x < 0. So we need to do some correction */
+ if (___decNumberIsNegative (&dn_x))
+ {
+ if (___decNumberIsNegative (&dn_y))
+ return result - M_PIdl;
+ else
+ return result + M_PIdl;
+ }
+ else
+ return result;
+ }
+
+ /* If x and y are both inf, the result depends on the sign of x */
+ if (___decNumberIsInfinite (&dn_y) && ___decNumberIsInfinite (&dn_x))
+ {
+ if (___decNumberIsNegative (&dn_x) )
+ result = (DEC_TYPE)(3.0DL * M_PI_4dl) + generate_inexact;
+ else
+ result = (DEC_TYPE) M_PI_4dl + generate_inexact;
+ }
+ /* If y is non-zero and x is non-inf, the result is +-pi/2 */
+ else if (!___decNumberIsZero (&dn_y) && !___decNumberIsInfinite (&dn_x) )
+ result = (DEC_TYPE)M_PI_2dl;
+ else /* Otherwise it is +0 if x is positive, +pi if x is neg */
+ {
+ if (___decNumberIsNegative (&dn_x))
+ result = ((DEC_TYPE) M_PIdl) - generate_inexact;
+ else
+ result = DFP_CONSTANT (0.0);
+ }
+
+ /* Atan2 will be negative if y<0 */
+ if (___decNumberIsNegative (&dn_y))
+ return -result;
+ else
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/atand32.c b/libc/dfp/sysdeps/ieee754r/d32/atand32.c
new file mode 100644
index 000000000..f5f9ff9fe
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/atand32.c
@@ -0,0 +1,64 @@
+/* Calculates the arc that has the given tangent for a _Decimal32 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME atan
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ if (___decNumberIsInfinite (&dn_x))
+ {
+ if (___decNumberIsNegative (&dn_x))
+ result = -M_PI_2dl;
+ else
+ result = M_PI_2dl;
+ }
+ else
+ {
+ ___decNumberAtan (&dn_result, &dn_x, &context);
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ }
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/atanhd32.c b/libc/dfp/sysdeps/ieee754r/d32/atanhd32.c
new file mode 100644
index 000000000..b0f90464f
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/atanhd32.c
@@ -0,0 +1,110 @@
+/* Calculate the hyperbolic arc tangent (atanh) for _Decimal32 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME atanh
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result, one, temp;
+ decNumber dn_x, dn_temp, dn_one;
+/* int comp;*/
+
+ one=DFP_CONSTANT(1.0);
+ FUNC_CONVERT_TO_DN (&one, &dn_one);
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+
+ /* Handle NaN and early exit for x==0 */
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsZero (&dn_x))
+ return x + x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberAbs (&dn_temp, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_temp, &temp, &context);
+ if(temp==one) {
+ /* |x| == 1 -> Pole Error */
+ DFP_EXCEPT (FE_DIVBYZERO);
+ return ___decNumberIsNegative(&dn_x) ? -DFP_HUGE_VAL:DFP_HUGE_VAL;
+ } else if (temp>one) {
+ /* |x| > 1 -> Domain Error (this handles +-Inf too) */
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+
+// comp = ___decCompare (&dn_temp, &dn_one);
+// switch (comp)
+// {
+// case 0: /* |x| == 1 -> Pole Error */
+// DFP_EXCEPT (FE_DIVBYZERO);
+// return ___decNumberIsNegative(&dn_x) ? -DFP_HUGE_VAL:DFP_HUGE_VAL;
+// case 1: /* |x| > 1 -> Domain Error (this handles +-Inf too) */
+// DFP_EXCEPT (FE_INVALID);
+// return DFP_NAN;
+// }
+
+ /* Using trig identity: atanh(x) = 1/2 * log((1+x)/(1-x)) */
+ ___decNumberAdd (&dn_result, &dn_one, &dn_x, &context);
+ ___decNumberSubtract (&dn_temp, &dn_one, &dn_x, &context);
+ ___decNumberDivide (&dn_result, &dn_result, &dn_temp, &context);
+ ___decNumberLn (&dn_result, &dn_result, &context);
+ ___decNumberAdd (&dn_temp, &dn_one, &dn_one, &context); /* 2 */
+ ___decNumberDivide (&dn_result, &dn_result, &dn_temp, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (x < DFP_CONSTANT(-1.0) || x > DFP_CONSTANT(1.0))
+ DFP_ERRNO (EDOM);
+ /* The normal glibc ieee754 k_standard.c file does not follow c99 or POSIX
+ * with regard to atanh pole errors. atan(+-1.0) [the binary version] will
+ * set errno to EDOM. Hopefully this will get worked out soon. */
+ if (x == DFP_CONSTANT(-1.0) || x == DFP_CONSTANT(1.0))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/cbrtd32.c b/libc/dfp/sysdeps/ieee754r/d32/cbrtd32.c
new file mode 100644
index 000000000..ef47d4f2a
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/cbrtd32.c
@@ -0,0 +1,155 @@
+/* cbrtd32.c
+ * DESCRIPTION:
+ * Returns the cube root of the argument, which may be negative.
+ *
+ * Range reduction involves determining the power of 2 of
+ * the argument. A polynomial of degree 2 applied to the
+ * mantissa, and multiplication by the cube root of 1, 2, or 4
+ * approximates the root to within about 0.1%. Then Newton's
+ * iteration is used three times to converge to an accurate
+ * result.
+ *
+ * ACCURACY:
+ * Relative error:
+ * arithmetic domain # trials peak rms
+ * IEEE -8,8 100000 1.3e-34 3.9e-35
+ * IEEE exp(+-707) 100000 1.3e-34 4.3e-35
+ */
+
+/*
+Cephes Math Library Release 2.2: January, 1991
+Copyright 1984, 1991 by Stephen L. Moshier
+Adapted for glibc October, 2001.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Calculates the cube root function of _Decimal32 type x
+ Adapted for dfp by Joseph Kerian (jkerian@us.ibm.com)
+ at IBM Corporation, 2006
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+ */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <math.h>
+//#include "math_private.h"
+
+#define FUNCTION_NAME cbrt
+
+#include <dfpmacro.h>
+
+
+/* Replace with:
+ * cbrt(10) and cbrt(100)
+ * and
+ * cbrt(-10) and cbrt(-100)
+ *
+ * used 'bc' to get these and then trunced by hand.
+ * echo 'scale=44;e(1/3*(l(10)))' | bc -l
+ * echo 'scale=44;e(1/3*(l(100)))' | bc -l
+ * echo 'scale=45;e(1/3*(l(1/10)))' | bc -l
+ * echo 'scale=45;e(1/3*(l(1/100)))' | bc -l
+ */
+static const _Decimal128
+ CBRT10 = 2.154434690031883721759293566519350495259345DL,
+ CBRT100 = 4.641588833612778892410076350919446576551349DL,
+ CBRT10I = 0.4641588833612778892410076350919446576551349DL,
+ CBRT100I = 0.2154434690031883721759293566519350495259345DL;
+
+// CBRT2 = 1.259921049894873164767210607278228350570251DL,
+// CBRT4 = 1.587401051968199474751705639272308260391493DL,
+// CBRT2I= 0.7937005259840997373758528196361541301957467DL,
+// CBRT4I= 0.6299605249474365823836053036391141752851257DL;
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ int e, rem, sign;
+ _Decimal128 z;
+
+ if (! FUNC_D(__finite) (x)) /* cbrt(x:x=inf/nan/-inf) = x+x (for sNaN) */
+ return x + x;
+
+ if (x == DFP_CONSTANT(0.0)) /* cbrt(0) = 0 */
+ return (x);
+
+ if (x > DFP_CONSTANT(0.0))
+ sign = 1;
+ else
+ {
+ sign = -1;
+ x = -x;
+ }
+
+ z = x;
+ /* extract power of 2, leaving mantissa between 0.5 and 1 */
+ x = FUNC_D(frexp) (x, &e);
+
+ /* Approximate cube root of number between .5 and 1,
+ peak relative error = 1.2e-6 */
+ x = ((((1.3584464340920900529734e-1DL * x
+ - 6.3986917220457538402318e-1DL) * x
+ + 1.2875551670318751538055e0DL) * x
+ - 1.4897083391357284957891e0DL) * x
+ + 1.3304961236013647092521e0DL) * x + 3.7568280825958912391243e-1DL;
+
+ /* exponent divided by 3 */
+ if (e >= 0)
+ {
+ rem = e;
+ e /= 3;
+ rem -= 3 * e;
+ if (rem == 1)
+ //x *= CBRT2;
+ x *= CBRT10;
+ else if (rem == 2)
+ //x *= CBRT4;
+ x *= CBRT100;
+ }
+ else
+ { /* argument less than 1 */
+ e = -e;
+ rem = e;
+ e /= 3;
+ rem -= 3 * e;
+ if (rem == 1)
+ //x *= CBRT2I;
+ x *= CBRT10I;
+ else if (rem == 2)
+ //x *= CBRT4I;
+ x *= CBRT100I;
+ e = -e;
+ }
+
+ /* multiply by power of 2 */
+ x = FUNC_D(ldexp) (x, e);
+
+ /* Newton iteration */
+ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333DL;
+ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333DL;
+ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333DL;
+
+ if (sign < 0)
+ x = -x;
+ return (x);
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/ceild32.c b/libc/dfp/sysdeps/ieee754r/d32/ceild32.c
new file mode 100644
index 000000000..8f55abf4d
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/ceild32.c
@@ -0,0 +1,57 @@
+/* Ceiling function for _Decimal32 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME ceil
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsInfinite (&dn_x)
+ || ___decNumberIsZero (&dn_x) )
+ return x+x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ context.round = DEC_ROUND_CEILING;
+ ___decNumberToIntegralValue (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/copysignd32.c b/libc/dfp/sysdeps/ieee754r/d32/copysignd32.c
new file mode 100644
index 000000000..238ca4435
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/copysignd32.c
@@ -0,0 +1,57 @@
+/* Copies the sign from the second argument to the first
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME copysign
+
+#include <dfpmacro.h>
+
+#define ___decNumberNegate(dn) (((dn)->bits)^=DECNEG)
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&y, &dn_y);
+
+ if(___decNumberIsNegative (&dn_x) != ___decNumberIsNegative (&dn_y))
+ ___decNumberNegate (&dn_x);
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ FUNC_CONVERT_FROM_DN (&dn_x, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/cosd32.c b/libc/dfp/sysdeps/ieee754r/d32/cosd32.c
new file mode 100644
index 000000000..e1837eb09
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/cosd32.c
@@ -0,0 +1,79 @@
+/* Calculate the cos(x) for a _Decimal32 format x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME cos
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+
+ if (___decNumberIsZero (&dn_x))
+ return DFP_CONSTANT(1.0);
+
+ if (___decNumberIsInfinite (&dn_x))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberCos (&dn_result, &dn_x, &context);
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (isinf(x))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/coshd32.c b/libc/dfp/sysdeps/ieee754r/d32/coshd32.c
new file mode 100644
index 000000000..1d5952a58
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/coshd32.c
@@ -0,0 +1,79 @@
+/* Calculate the hyperbolic cos (cosh) for _Decimal32 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME cosh
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+ if (___decNumberIsZero (&dn_x))
+ return DFP_CONSTANT(1.0);
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ if (___decNumberIsInfinite (&dn_x))
+ ___decNumberAbs (&dn_result, &dn_x, &context);
+ else
+ ___decNumberCosh (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT(FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (FUNC_D(__finite)(x) && !FUNC_D(__finite)(z))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/erfd32.c b/libc/dfp/sysdeps/ieee754r/d32/erfd32.c
new file mode 100644
index 000000000..7f6bac856
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/erfd32.c
@@ -0,0 +1,962 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* Modifications and expansions for 128-bit long double are
+ Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
+ and are incorporated herein by permission of the author. The author
+ reserves the right to distribute this material elsewhere under different
+ copying permissions. These modifications are distributed here under
+ the following terms:
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Returns the error function of x
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ Modified for dfp by Joseph Kerian <jkerian@us.ibm.com>
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Modifications for decNumber C Library:
+ Author(s): Joseph Kerian <jkerian@us.ibm.com> */
+
+/* double erf(double x)
+ * double erfc(double x)
+ * x
+ * 2 |\
+ * erf(x) = --------- | exp(-t*t)dt
+ * sqrt(pi) \|
+ * 0
+ *
+ * erfc(x) = 1-erf(x)
+ * Note that
+ * erf(-x) = -erf(x)
+ * erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ * 1. erf(x) = x + x*R(x^2) for |x| in [0, 7/8]
+ * Remark. The formula is derived by noting
+ * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ * and that
+ * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ * is close to one.
+ *
+ * 1a. erf(x) = 1 - erfc(x), for |x| > 1.0
+ * erfc(x) = 1 - erf(x) if |x| < 1/4
+ *
+ * 2. For |x| in [7/8, 1], let s = |x| - 1, and
+ * c = 0.84506291151 rounded to single (24 bits)
+ * erf(s + c) = sign(x) * (c + P1(s)/Q1(s))
+ * Remark: here we use the taylor series expansion at x=1.
+ * erf(1+s) = erf(1) + s*Poly(s)
+ * = 0.845.. + P1(s)/Q1(s)
+ * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ *
+ * 3. For x in [1/4, 5/4],
+ * erfc(s + const) = erfc(const) + s P1(s)/Q1(s)
+ * for const = 1/4, 3/8, ..., 9/8
+ * and 0 <= s <= 1/8 .
+ *
+ * 4. For x in [5/4, 107],
+ * erfc(x) = (1/x)*exp(-x*x-0.5625 + R(z))
+ * z=1/x^2
+ * The interval is partitioned into several segments
+ * of width 1/8 in 1/x.
+ *
+ * Note1:
+ * To compute exp(-x*x-0.5625+R/S), let s be a single
+ * precision number and s := x; then
+ * -x*x = -s*s + (s-x)*(s+x)
+ * exp(-x*x-0.5626+R/S) =
+ * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ * Note2:
+ * Here 4 and 5 make use of the asymptotic series
+ * exp(-x*x)
+ * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ * x*sqrt(pi)
+ *
+ * 5. For inf > x >= 107
+ * erf(x) = sign(x) *(1 - tiny) (raise inexact)
+ * erfc(x) = tiny*tiny (raise underflow) if x > 0
+ * = 2 - tiny if x<0
+ *
+ * 7. Special case:
+ * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
+ * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ * erfc/erf(NaN) is NaN
+ */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <math.h>
+
+#define FUNCTION_NAME erf
+
+#include <dfpmacro.h>
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static _Decimal128
+neval (_Decimal128 x, const _Decimal128 *p, int n)
+{
+ _Decimal128 y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static _Decimal128
+deval (_Decimal128 x, const _Decimal128 *p, int n)
+{
+ _Decimal128 y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+
+static const _Decimal128
+tiny = 1e-4931DL,
+ half = 0.5DL,
+ one = 1.0DL,
+ two = 2.0DL,
+ /* 2/sqrt(pi) - 1 */
+ efx = 1.2837916709551257389615890312154517168810E-1DL,
+ /* 8 * (2/sqrt(pi) - 1) */
+ efx8 = 1.0270333367641005911692712249723613735048E0DL;
+
+
+/* erf(x) = x + x R(x^2)
+ 0 <= x <= 7/8
+ Peak relative error 1.8e-35 */
+#define NTN1 8
+static const _Decimal128 TN1[NTN1 + 1] =
+{
+ -3.858252324254637124543172907442106422373E10DL,
+ 9.580319248590464682316366876952214879858E10DL,
+ 1.302170519734879977595901236693040544854E10DL,
+ 2.922956950426397417800321486727032845006E9DL,
+ 1.764317520783319397868923218385468729799E8DL,
+ 1.573436014601118630105796794840834145120E7DL,
+ 4.028077380105721388745632295157816229289E5DL,
+ 1.644056806467289066852135096352853491530E4DL,
+ 3.390868480059991640235675479463287886081E1DL
+};
+#define NTD1 8
+static const _Decimal128 TD1[NTD1 + 1] =
+{
+ -3.005357030696532927149885530689529032152E11DL,
+ -1.342602283126282827411658673839982164042E11DL,
+ -2.777153893355340961288511024443668743399E10DL,
+ -3.483826391033531996955620074072768276974E9DL,
+ -2.906321047071299585682722511260895227921E8DL,
+ -1.653347985722154162439387878512427542691E7DL,
+ -6.245520581562848778466500301865173123136E5DL,
+ -1.402124304177498828590239373389110545142E4DL,
+ -1.209368072473510674493129989468348633579E2DL
+/* 1.0E0 */
+};
+
+
+/* erf(z+1) = erf_const + P(z)/Q(z)
+ -.125 <= z <= 0
+ Peak relative error 7.3e-36 */
+static const _Decimal128 erf_const = 0.845062911510467529296875DL;
+#define NTN2 8
+static const _Decimal128 TN2[NTN2 + 1] =
+{
+ -4.088889697077485301010486931817357000235E1DL,
+ 7.157046430681808553842307502826960051036E3DL,
+ -2.191561912574409865550015485451373731780E3DL,
+ 2.180174916555316874988981177654057337219E3DL,
+ 2.848578658049670668231333682379720943455E2DL,
+ 1.630362490952512836762810462174798925274E2DL,
+ 6.317712353961866974143739396865293596895E0DL,
+ 2.450441034183492434655586496522857578066E1DL,
+ 5.127662277706787664956025545897050896203E-1DL
+};
+#define NTD2 8
+static const _Decimal128 TD2[NTD2 + 1] =
+{
+ 1.731026445926834008273768924015161048885E4DL,
+ 1.209682239007990370796112604286048173750E4DL,
+ 1.160950290217993641320602282462976163857E4DL,
+ 5.394294645127126577825507169061355698157E3DL,
+ 2.791239340533632669442158497532521776093E3DL,
+ 8.989365571337319032943005387378993827684E2DL,
+ 2.974016493766349409725385710897298069677E2DL,
+ 6.148192754590376378740261072533527271947E1DL,
+ 1.178502892490738445655468927408440847480E1DL
+ /* 1.0E0 */
+};
+
+
+/* erfc(x + 0.25) = erfc(0.25) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.4e-35 */
+#define NRNr13 8
+static const _Decimal128 RNr13[NRNr13 + 1] =
+{
+ -2.353707097641280550282633036456457014829E3DL,
+ 3.871159656228743599994116143079870279866E2DL,
+ -3.888105134258266192210485617504098426679E2DL,
+ -2.129998539120061668038806696199343094971E1DL,
+ -8.125462263594034672468446317145384108734E1DL,
+ 8.151549093983505810118308635926270319660E0DL,
+ -5.033362032729207310462422357772568553670E0DL,
+ -4.253956621135136090295893547735851168471E-2DL,
+ -8.098602878463854789780108161581050357814E-2DL
+};
+#define NRDr13 7
+static const _Decimal128 RDr13[NRDr13 + 1] =
+{
+ 2.220448796306693503549505450626652881752E3DL,
+ 1.899133258779578688791041599040951431383E2DL,
+ 1.061906712284961110196427571557149268454E3DL,
+ 7.497086072306967965180978101974566760042E1DL,
+ 2.146796115662672795876463568170441327274E2DL,
+ 1.120156008362573736664338015952284925592E1DL,
+ 2.211014952075052616409845051695042741074E1DL,
+ 6.469655675326150785692908453094054988938E-1DL
+ /* 1.0E0 */
+};
+/* erfc(0.25) = C13a + C13b to extra precision. */
+static const _Decimal128 C13a = 0.723663330078125DL;
+static const _Decimal128 C13b = 1.0279753638067014931732235184287934646022E-5DL;
+
+
+/* erfc(x + 0.375) = erfc(0.375) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.2e-35 */
+#define NRNr14 8
+static const _Decimal128 RNr14[NRNr14 + 1] =
+{
+ -2.446164016404426277577283038988918202456E3DL,
+ 6.718753324496563913392217011618096698140E2DL,
+ -4.581631138049836157425391886957389240794E2DL,
+ -2.382844088987092233033215402335026078208E1DL,
+ -7.119237852400600507927038680970936336458E1DL,
+ 1.313609646108420136332418282286454287146E1DL,
+ -6.188608702082264389155862490056401365834E0DL,
+ -2.787116601106678287277373011101132659279E-2DL,
+ -2.230395570574153963203348263549700967918E-2DL
+};
+#define NRDr14 7
+static const _Decimal128 RDr14[NRDr14 + 1] =
+{
+ 2.495187439241869732696223349840963702875E3DL,
+ 2.503549449872925580011284635695738412162E2DL,
+ 1.159033560988895481698051531263861842461E3DL,
+ 9.493751466542304491261487998684383688622E1DL,
+ 2.276214929562354328261422263078480321204E2DL,
+ 1.367697521219069280358984081407807931847E1DL,
+ 2.276988395995528495055594829206582732682E1DL,
+ 7.647745753648996559837591812375456641163E-1DL
+ /* 1.0E0 */
+};
+/* erfc(0.375) = C14a + C14b to extra precision. */
+static const _Decimal128 C14a = 0.5958709716796875DL;
+static const _Decimal128 C14b = 1.2118885490201676174914080878232469565953E-5DL;
+
+/* erfc(x + 0.5) = erfc(0.5) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 4.7e-36 */
+#define NRNr15 8
+static const _Decimal128 RNr15[NRNr15 + 1] =
+{
+ -2.624212418011181487924855581955853461925E3DL,
+ 8.473828904647825181073831556439301342756E2DL,
+ -5.286207458628380765099405359607331669027E2DL,
+ -3.895781234155315729088407259045269652318E1DL,
+ -6.200857908065163618041240848728398496256E1DL,
+ 1.469324610346924001393137895116129204737E1DL,
+ -6.961356525370658572800674953305625578903E0DL,
+ 5.145724386641163809595512876629030548495E-3DL,
+ 1.990253655948179713415957791776180406812E-2DL
+};
+#define NRDr15 7
+static const _Decimal128 RDr15[NRDr15 + 1] =
+{
+ 2.986190760847974943034021764693341524962E3DL,
+ 5.288262758961073066335410218650047725985E2DL,
+ 1.363649178071006978355113026427856008978E3DL,
+ 1.921707975649915894241864988942255320833E2DL,
+ 2.588651100651029023069013885900085533226E2DL,
+ 2.628752920321455606558942309396855629459E1DL,
+ 2.455649035885114308978333741080991380610E1DL,
+ 1.378826653595128464383127836412100939126E0DL
+ /* 1.0E0 */
+};
+/* erfc(0.5) = C15a + C15b to extra precision. */
+static const _Decimal128 C15a = 0.4794921875DL;
+static const _Decimal128 C15b = 7.9346869534623172533461080354712635484242E-6DL;
+
+/* erfc(x + 0.625) = erfc(0.625) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 5.1e-36 */
+#define NRNr16 8
+static const _Decimal128 RNr16[NRNr16 + 1] =
+{
+ -2.347887943200680563784690094002722906820E3DL,
+ 8.008590660692105004780722726421020136482E2DL,
+ -5.257363310384119728760181252132311447963E2DL,
+ -4.471737717857801230450290232600243795637E1DL,
+ -4.849540386452573306708795324759300320304E1DL,
+ 1.140885264677134679275986782978655952843E1DL,
+ -6.731591085460269447926746876983786152300E0DL,
+ 1.370831653033047440345050025876085121231E-1DL,
+ 2.022958279982138755020825717073966576670E-2DL,
+};
+#define NRDr16 7
+static const _Decimal128 RDr16[NRDr16 + 1] =
+{
+ 3.075166170024837215399323264868308087281E3DL,
+ 8.730468942160798031608053127270430036627E2DL,
+ 1.458472799166340479742581949088453244767E3DL,
+ 3.230423687568019709453130785873540386217E2DL,
+ 2.804009872719893612081109617983169474655E2DL,
+ 4.465334221323222943418085830026979293091E1DL,
+ 2.612723259683205928103787842214809134746E1DL,
+ 2.341526751185244109722204018543276124997E0DL,
+ /* 1.0E0 */
+};
+/* erfc(0.625) = C16a + C16b to extra precision. */
+static const _Decimal128 C16a = 0.3767547607421875DL;
+static const _Decimal128 C16b = 4.3570693945275513594941232097252997287766E-6DL;
+
+/* erfc(x + 0.75) = erfc(0.75) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.7e-35 */
+#define NRNr17 8
+static const _Decimal128 RNr17[NRNr17 + 1] =
+{
+ -1.767068734220277728233364375724380366826E3DL,
+ 6.693746645665242832426891888805363898707E2DL,
+ -4.746224241837275958126060307406616817753E2DL,
+ -2.274160637728782675145666064841883803196E1DL,
+ -3.541232266140939050094370552538987982637E1DL,
+ 6.988950514747052676394491563585179503865E0DL,
+ -5.807687216836540830881352383529281215100E0DL,
+ 3.631915988567346438830283503729569443642E-1DL,
+ -1.488945487149634820537348176770282391202E-2DL
+};
+#define NRDr17 7
+static const _Decimal128 RDr17[NRDr17 + 1] =
+{
+ 2.748457523498150741964464942246913394647E3DL,
+ 1.020213390713477686776037331757871252652E3DL,
+ 1.388857635935432621972601695296561952738E3DL,
+ 3.903363681143817750895999579637315491087E2DL,
+ 2.784568344378139499217928969529219886578E2DL,
+ 5.555800830216764702779238020065345401144E1DL,
+ 2.646215470959050279430447295801291168941E1DL,
+ 2.984905282103517497081766758550112011265E0DL,
+ /* 1.0E0 */
+};
+/* erfc(0.75) = C17a + C17b to extra precision. */
+static const _Decimal128 C17a = 0.2888336181640625DL;
+static const _Decimal128 C17b = 1.0748182422368401062165408589222625794046E-5DL;
+
+
+/* erfc(x + 0.875) = erfc(0.875) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 2.2e-35 */
+#define NRNr18 8
+static const _Decimal128 RNr18[NRNr18 + 1] =
+{
+ -1.342044899087593397419622771847219619588E3DL,
+ 6.127221294229172997509252330961641850598E2DL,
+ -4.519821356522291185621206350470820610727E2DL,
+ 1.223275177825128732497510264197915160235E1DL,
+ -2.730789571382971355625020710543532867692E1DL,
+ 4.045181204921538886880171727755445395862E0DL,
+ -4.925146477876592723401384464691452700539E0DL,
+ 5.933878036611279244654299924101068088582E-1DL,
+ -5.557645435858916025452563379795159124753E-2DL
+};
+#define NRDr18 7
+static const _Decimal128 RDr18[NRDr18 + 1] =
+{
+ 2.557518000661700588758505116291983092951E3DL,
+ 1.070171433382888994954602511991940418588E3DL,
+ 1.344842834423493081054489613250688918709E3DL,
+ 4.161144478449381901208660598266288188426E2DL,
+ 2.763670252219855198052378138756906980422E2DL,
+ 5.998153487868943708236273854747564557632E1DL,
+ 2.657695108438628847733050476209037025318E1DL,
+ 3.252140524394421868923289114410336976512E0DL,
+ /* 1.0E0 */
+};
+/* erfc(0.875) = C18a + C18b to extra precision. */
+static const _Decimal128 C18a = 0.215911865234375DL;
+static const _Decimal128 C18b = 1.3073705765341685464282101150637224028267E-5DL;
+
+/* erfc(x + 1.0) = erfc(1.0) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 1.6e-35 */
+#define NRNr19 8
+static const _Decimal128 RNr19[NRNr19 + 1] =
+{
+ -1.139180936454157193495882956565663294826E3DL,
+ 6.134903129086899737514712477207945973616E2DL,
+ -4.628909024715329562325555164720732868263E2DL,
+ 4.165702387210732352564932347500364010833E1DL,
+ -2.286979913515229747204101330405771801610E1DL,
+ 1.870695256449872743066783202326943667722E0DL,
+ -4.177486601273105752879868187237000032364E0DL,
+ 7.533980372789646140112424811291782526263E-1DL,
+ -8.629945436917752003058064731308767664446E-2DL
+};
+#define NRDr19 7
+static const _Decimal128 RDr19[NRDr19 + 1] =
+{
+ 2.744303447981132701432716278363418643778E3DL,
+ 1.266396359526187065222528050591302171471E3DL,
+ 1.466739461422073351497972255511919814273E3DL,
+ 4.868710570759693955597496520298058147162E2DL,
+ 2.993694301559756046478189634131722579643E2DL,
+ 6.868976819510254139741559102693828237440E1DL,
+ 2.801505816247677193480190483913753613630E1DL,
+ 3.604439909194350263552750347742663954481E0DL,
+ /* 1.0E0 */
+};
+/* erfc(1.0) = C19a + C19b to extra precision. */
+static const _Decimal128 C19a = 0.15728759765625DL;
+static const _Decimal128 C19b = 1.1609394035130658779364917390740703933002E-5DL;
+
+/* erfc(x + 1.125) = erfc(1.125) + x R(x)
+ 0 <= x < 0.125
+ Peak relative error 3.6e-36 */
+#define NRNr20 8
+static const _Decimal128 RNr20[NRNr20 + 1] =
+{
+ -9.652706916457973956366721379612508047640E2DL,
+ 5.577066396050932776683469951773643880634E2DL,
+ -4.406335508848496713572223098693575485978E2DL,
+ 5.202893466490242733570232680736966655434E1DL,
+ -1.931311847665757913322495948705563937159E1DL,
+ -9.364318268748287664267341457164918090611E-2DL,
+ -3.306390351286352764891355375882586201069E0DL,
+ 7.573806045289044647727613003096916516475E-1DL,
+ -9.611744011489092894027478899545635991213E-2DL
+};
+#define NRDr20 7
+static const _Decimal128 RDr20[NRDr20 + 1] =
+{
+ 3.032829629520142564106649167182428189014E3DL,
+ 1.659648470721967719961167083684972196891E3DL,
+ 1.703545128657284619402511356932569292535E3DL,
+ 6.393465677731598872500200253155257708763E2DL,
+ 3.489131397281030947405287112726059221934E2DL,
+ 8.848641738570783406484348434387611713070E1DL,
+ 3.132269062552392974833215844236160958502E1DL,
+ 4.430131663290563523933419966185230513168E0DL
+ /* 1.0E0 */
+};
+/* erfc(1.125) = C20a + C20b to extra precision. */
+static const _Decimal128 C20a = 0.111602783203125DL;
+static const _Decimal128 C20b = 8.9850951672359304215530728365232161564636E-6DL;
+
+/* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2))
+ 7/8 <= 1/x < 1
+ Peak relative error 1.4e-35 */
+#define NRNr8 9
+static const _Decimal128 RNr8[NRNr8 + 1] =
+{
+ 3.587451489255356250759834295199296936784E1DL,
+ 5.406249749087340431871378009874875889602E2DL,
+ 2.931301290625250886238822286506381194157E3DL,
+ 7.359254185241795584113047248898753470923E3DL,
+ 9.201031849810636104112101947312492532314E3DL,
+ 5.749697096193191467751650366613289284777E3DL,
+ 1.710415234419860825710780802678697889231E3DL,
+ 2.150753982543378580859546706243022719599E2DL,
+ 8.740953582272147335100537849981160931197E0DL,
+ 4.876422978828717219629814794707963640913E-2DL
+};
+#define NRDr8 8
+static const _Decimal128 RDr8[NRDr8 + 1] =
+{
+ 6.358593134096908350929496535931630140282E1DL,
+ 9.900253816552450073757174323424051765523E2DL,
+ 5.642928777856801020545245437089490805186E3DL,
+ 1.524195375199570868195152698617273739609E4DL,
+ 2.113829644500006749947332935305800887345E4DL,
+ 1.526438562626465706267943737310282977138E4DL,
+ 5.561370922149241457131421914140039411782E3DL,
+ 9.394035530179705051609070428036834496942E2DL,
+ 6.147019596150394577984175188032707343615E1DL
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2))
+ 0.75 <= 1/x <= 0.875
+ Peak relative error 2.0e-36 */
+#define NRNr7 9
+static const _Decimal128 RNr7[NRNr7 + 1] =
+{
+ 1.686222193385987690785945787708644476545E1DL,
+ 1.178224543567604215602418571310612066594E3DL,
+ 1.764550584290149466653899886088166091093E4DL,
+ 1.073758321890334822002849369898232811561E5DL,
+ 3.132840749205943137619839114451290324371E5DL,
+ 4.607864939974100224615527007793867585915E5DL,
+ 3.389781820105852303125270837910972384510E5DL,
+ 1.174042187110565202875011358512564753399E5DL,
+ 1.660013606011167144046604892622504338313E4DL,
+ 6.700393957480661937695573729183733234400E2DL
+};
+#define NRDr7 9
+static const _Decimal128 RDr7[NRDr7 + 1] =
+{
+-1.709305024718358874701575813642933561169E3DL,
+-3.280033887481333199580464617020514788369E4DL,
+-2.345284228022521885093072363418750835214E5DL,
+-8.086758123097763971926711729242327554917E5DL,
+-1.456900414510108718402423999575992450138E6DL,
+-1.391654264881255068392389037292702041855E6DL,
+-6.842360801869939983674527468509852583855E5DL,
+-1.597430214446573566179675395199807533371E5DL,
+-1.488876130609876681421645314851760773480E4DL,
+-3.511762950935060301403599443436465645703E2DL
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 5/8 <= 1/x < 3/4
+ Peak relative error 1.9e-35 */
+#define NRNr6 9
+static const _Decimal128 RNr6[NRNr6 + 1] =
+{
+ 1.642076876176834390623842732352935761108E0DL,
+ 1.207150003611117689000664385596211076662E2DL,
+ 2.119260779316389904742873816462800103939E3DL,
+ 1.562942227734663441801452930916044224174E4DL,
+ 5.656779189549710079988084081145693580479E4DL,
+ 1.052166241021481691922831746350942786299E5DL,
+ 9.949798524786000595621602790068349165758E4DL,
+ 4.491790734080265043407035220188849562856E4DL,
+ 8.377074098301530326270432059434791287601E3DL,
+ 4.506934806567986810091824791963991057083E2DL
+};
+#define NRDr6 9
+static const _Decimal128 RDr6[NRDr6 + 1] =
+{
+-1.664557643928263091879301304019826629067E2DL,
+-3.800035902507656624590531122291160668452E3DL,
+-3.277028191591734928360050685359277076056E4DL,
+-1.381359471502885446400589109566587443987E5DL,
+-3.082204287382581873532528989283748656546E5DL,
+-3.691071488256738343008271448234631037095E5DL,
+-2.300482443038349815750714219117566715043E5DL,
+-6.873955300927636236692803579555752171530E4DL,
+-8.262158817978334142081581542749986845399E3DL,
+-2.517122254384430859629423488157361983661E2DL
+ /* 1.00 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/2 <= 1/x < 5/8
+ Peak relative error 4.6e-36 */
+#define NRNr5 10
+static const _Decimal128 RNr5[NRNr5 + 1] =
+{
+-3.332258927455285458355550878136506961608E-3DL,
+-2.697100758900280402659586595884478660721E-1DL,
+-6.083328551139621521416618424949137195536E0DL,
+-6.119863528983308012970821226810162441263E1DL,
+-3.176535282475593173248810678636522589861E2DL,
+-8.933395175080560925809992467187963260693E2DL,
+-1.360019508488475978060917477620199499560E3DL,
+-1.075075579828188621541398761300910213280E3DL,
+-4.017346561586014822824459436695197089916E2DL,
+-5.857581368145266249509589726077645791341E1DL,
+-2.077715925587834606379119585995758954399E0DL
+};
+#define NRDr5 9
+static const _Decimal128 RDr5[NRDr5 + 1] =
+{
+ 3.377879570417399341550710467744693125385E-1DL,
+ 1.021963322742390735430008860602594456187E1DL,
+ 1.200847646592942095192766255154827011939E2DL,
+ 7.118915528142927104078182863387116942836E2DL,
+ 2.318159380062066469386544552429625026238E3DL,
+ 4.238729853534009221025582008928765281620E3DL,
+ 4.279114907284825886266493994833515580782E3DL,
+ 2.257277186663261531053293222591851737504E3DL,
+ 5.570475501285054293371908382916063822957E2DL,
+ 5.142189243856288981145786492585432443560E1DL
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 3/8 <= 1/x < 1/2
+ Peak relative error 2.0e-36 */
+#define NRNr4 10
+static const _Decimal128 RNr4[NRNr4 + 1] =
+{
+ 3.258530712024527835089319075288494524465E-3DL,
+ 2.987056016877277929720231688689431056567E-1DL,
+ 8.738729089340199750734409156830371528862E0DL,
+ 1.207211160148647782396337792426311125923E2DL,
+ 8.997558632489032902250523945248208224445E2DL,
+ 3.798025197699757225978410230530640879762E3DL,
+ 9.113203668683080975637043118209210146846E3DL,
+ 1.203285891339933238608683715194034900149E4DL,
+ 8.100647057919140328536743641735339740855E3DL,
+ 2.383888249907144945837976899822927411769E3DL,
+ 2.127493573166454249221983582495245662319E2DL
+};
+#define NRDr4 10
+static const _Decimal128 RDr4[NRDr4 + 1] =
+{
+-3.303141981514540274165450687270180479586E-1DL,
+-1.353768629363605300707949368917687066724E1DL,
+-2.206127630303621521950193783894598987033E2DL,
+-1.861800338758066696514480386180875607204E3DL,
+-8.889048775872605708249140016201753255599E3DL,
+-2.465888106627948210478692168261494857089E4DL,
+-3.934642211710774494879042116768390014289E4DL,
+-3.455077258242252974937480623730228841003E4DL,
+-1.524083977439690284820586063729912653196E4DL,
+-2.810541887397984804237552337349093953857E3DL,
+-1.343929553541159933824901621702567066156E2DL
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/4 <= 1/x < 3/8
+ Peak relative error 8.4e-37 */
+#define NRNr3 11
+static const _Decimal128 RNr3[NRNr3 + 1] =
+{
+-1.952401126551202208698629992497306292987E-6DL,
+-2.130881743066372952515162564941682716125E-4DL,
+-8.376493958090190943737529486107282224387E-3DL,
+-1.650592646560987700661598877522831234791E-1DL,
+-1.839290818933317338111364667708678163199E0DL,
+-1.216278715570882422410442318517814388470E1DL,
+-4.818759344462360427612133632533779091386E1DL,
+-1.120994661297476876804405329172164436784E2DL,
+-1.452850765662319264191141091859300126931E2DL,
+-9.485207851128957108648038238656777241333E1DL,
+-2.563663855025796641216191848818620020073E1DL,
+-1.787995944187565676837847610706317833247E0DL
+};
+#define NRDr3 10
+static const _Decimal128 RDr3[NRDr3 + 1] =
+{
+ 1.979130686770349481460559711878399476903E-4DL,
+ 1.156941716128488266238105813374635099057E-2DL,
+ 2.752657634309886336431266395637285974292E-1DL,
+ 3.482245457248318787349778336603569327521E0DL,
+ 2.569347069372696358578399521203959253162E1DL,
+ 1.142279000180457419740314694631879921561E2DL,
+ 3.056503977190564294341422623108332700840E2DL,
+ 4.780844020923794821656358157128719184422E2DL,
+ 4.105972727212554277496256802312730410518E2DL,
+ 1.724072188063746970865027817017067646246E2DL,
+ 2.815939183464818198705278118326590370435E1DL
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/8 <= 1/x < 1/4
+ Peak relative error 1.5e-36 */
+#define NRNr2 11
+static const _Decimal128 RNr2[NRNr2 + 1] =
+{
+-2.638914383420287212401687401284326363787E-8DL,
+-3.479198370260633977258201271399116766619E-6DL,
+-1.783985295335697686382487087502222519983E-4DL,
+-4.777876933122576014266349277217559356276E-3DL,
+-7.450634738987325004070761301045014986520E-2DL,
+-7.068318854874733315971973707247467326619E-1DL,
+-4.113919921935944795764071670806867038732E0DL,
+-1.440447573226906222417767283691888875082E1DL,
+-2.883484031530718428417168042141288943905E1DL,
+-2.990886974328476387277797361464279931446E1DL,
+-1.325283914915104866248279787536128997331E1DL,
+-1.572436106228070195510230310658206154374E0DL
+};
+#define NRDr2 10
+static const _Decimal128 RDr2[NRDr2 + 1] =
+{
+ 2.675042728136731923554119302571867799673E-6DL,
+ 2.170997868451812708585443282998329996268E-4DL,
+ 7.249969752687540289422684951196241427445E-3DL,
+ 1.302040375859768674620410563307838448508E-1DL,
+ 1.380202483082910888897654537144485285549E0DL,
+ 8.926594113174165352623847870299170069350E0DL,
+ 3.521089584782616472372909095331572607185E1DL,
+ 8.233547427533181375185259050330809105570E1DL,
+ 1.072971579885803033079469639073292840135E2DL,
+ 6.943803113337964469736022094105143158033E1DL,
+ 1.775695341031607738233608307835017282662E1DL
+ /* 1.0E0 */
+};
+
+/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2))
+ 1/128 <= 1/x < 1/8
+ Peak relative error 2.2e-36 */
+#define NRNr1 9
+static const _Decimal128 RNr1[NRNr1 + 1] =
+{
+-4.250780883202361946697751475473042685782E-8DL,
+-5.375777053288612282487696975623206383019E-6DL,
+-2.573645949220896816208565944117382460452E-4DL,
+-6.199032928113542080263152610799113086319E-3DL,
+-8.262721198693404060380104048479916247786E-2DL,
+-6.242615227257324746371284637695778043982E-1DL,
+-2.609874739199595400225113299437099626386E0DL,
+-5.581967563336676737146358534602770006970E0DL,
+-5.124398923356022609707490956634280573882E0DL,
+-1.290865243944292370661544030414667556649E0DL
+};
+#define NRDr1 8
+static const _Decimal128 RDr1[NRDr1 + 1] =
+{
+ 4.308976661749509034845251315983612976224E-6DL,
+ 3.265390126432780184125233455960049294580E-4DL,
+ 9.811328839187040701901866531796570418691E-3DL,
+ 1.511222515036021033410078631914783519649E-1DL,
+ 1.289264341917429958858379585970225092274E0DL,
+ 6.147640356182230769548007536914983522270E0DL,
+ 1.573966871337739784518246317003956180750E1DL,
+ 1.955534123435095067199574045529218238263E1DL,
+ 9.472613121363135472247929109615785855865E0DL
+ /* 1.0E0 */
+};
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ _Decimal128 a, y, z;
+ int32_t sign;
+
+ sign = (x < 0.0DL);
+ a = FUNC_D(__fabs) (x);
+
+ if (a >= 0x7fff0000) /* erf(nan)=nan */
+ return (DEC_TYPE) ((1 - (sign<<1)) + one / x); /* erf(+-inf)=+-1 */
+
+ if (a >= 1.0DL) /* |x| >= 1.0 */
+ {
+ y = FUNC_D(__erfc) (x);
+ return (one - y);
+ /* return (one - __erfcl (x)); */
+ }
+ z = x * x;
+ if (a < 0.875DL) /* a < 0.875 */
+ {
+ if (a < 2.0E-57DL) /* |x|<2**-57 */
+ {
+ if (a < 0x00080000) //TODO:What is this number?
+ return (DEC_TYPE)(0.125DL * (8.0DL * x + efx8 * x));
+ /*avoid underflow */
+ return (DEC_TYPE)(x + efx * x);
+ }
+ y = a + a * neval (z, TN1, NTN1) / deval (z, TD1, NTD1);
+ }
+ else
+ {
+ a = a - one;
+ y = erf_const + neval (a, TN2, NTN2) / deval (a, TD2, NTD2);
+ }
+
+ if (sign) /* x < 0 */
+ y = -y;
+ return( (DEC_TYPE)y );
+}
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
+
+
+/* This is a bit sloppy, but it works */
+#undef FUNCTION_NAME
+#define FUNCTION_NAME erfc
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ _Decimal128 y=0.0DL, z, p, r, ix;
+ int32_t i, sign;
+
+ sign = (x < 0.0DL);
+ ix = FUNC_D(__fabs) (x);
+
+ if (ix >= 0x7fff0000)
+ { /* erfc(nan)=nan */
+ /* erfc(+-inf)=0,2 */
+ return (DEC_TYPE) ((sign << 1) + one / x);
+ }
+
+ if (ix < 0.25DL) /* |x| <1/4 */
+ {
+ if (ix < 2.0E-114DL) /* |x|<2**-114 */
+ return (DEC_TYPE)(one - x);
+ return (DEC_TYPE)(one - FUNC_D(__erf) (x));
+ }
+ x = ix;
+ if (ix < 1.25DL) /* 1.25 */
+ {
+ i = 8.0DF * x;
+ switch (i)
+ {
+ case 2:
+ z = x - 0.25DL;
+ y = C13b + z * neval (z, RNr13, NRNr13) / deval (z, RDr13, NRDr13);
+ y += C13a;
+ break;
+ case 3:
+ z = x - 0.375DL;
+ y = C14b + z * neval (z, RNr14, NRNr14) / deval (z, RDr14, NRDr14);
+ y += C14a;
+ break;
+ case 4:
+ z = x - 0.5DL;
+ y = C15b + z * neval (z, RNr15, NRNr15) / deval (z, RDr15, NRDr15);
+ y += C15a;
+ break;
+ case 5:
+ z = x - 0.625DL;
+ y = C16b + z * neval (z, RNr16, NRNr16) / deval (z, RDr16, NRDr16);
+ y += C16a;
+ break;
+ case 6:
+ z = x - 0.75DL;
+ y = C17b + z * neval (z, RNr17, NRNr17) / deval (z, RDr17, NRDr17);
+ y += C17a;
+ break;
+ case 7:
+ z = x - 0.875DL;
+ y = C18b + z * neval (z, RNr18, NRNr18) / deval (z, RDr18, NRDr18);
+ y += C18a;
+ break;
+ case 8:
+ z = x - 1.0DL;
+ y = C19b + z * neval (z, RNr19, NRNr19) / deval (z, RDr19, NRDr19);
+ y += C19a;
+ break;
+ case 9:
+ z = x - 1.125DL;
+ y = C20b + z * neval (z, RNr20, NRNr20) / deval (z, RDr20, NRDr20);
+ y += C20a;
+ break;
+ }
+ if (sign)
+ y = 2.0DF - y;
+ return y;
+ }
+ /* 1.25 < |x| < 107 */
+ if (ix < 107.0DF)
+ {
+ /* x < -9 */
+ if (x > 9.0DF && sign)
+ return two - tiny;
+
+ z = one / (x * x);
+ i = 8.0DF / x;
+ switch (i)
+ {
+ default:
+ case 0:
+ p = neval (z, RNr1, NRNr1) / deval (z, RDr1, NRDr1);
+ break;
+ case 1:
+ p = neval (z, RNr2, NRNr2) / deval (z, RDr2, NRDr2);
+ break;
+ case 2:
+ p = neval (z, RNr3, NRNr3) / deval (z, RDr3, NRDr3);
+ break;
+ case 3:
+ p = neval (z, RNr4, NRNr4) / deval (z, RDr4, NRDr4);
+ break;
+ case 4:
+ p = neval (z, RNr5, NRNr5) / deval (z, RDr5, NRDr5);
+ break;
+ case 5:
+ p = neval (z, RNr6, NRNr6) / deval (z, RDr6, NRDr6);
+ break;
+ case 6:
+ p = neval (z, RNr7, NRNr7) / deval (z, RDr7, NRDr7);
+ break;
+ case 7:
+ p = neval (z, RNr8, NRNr8) / deval (z, RDr8, NRDr8);
+ break;
+ }
+ /* Trim the value?
+ u.value = x;
+ u.parts32.w3 = 0;
+ u.parts32.w2 &= 0xfe000000;
+ z = u.value;
+ */
+ z = ix;
+ r = expd128 (-z * z - 0.5625DF) * expd128 ((z - x) * (z + x) + p);
+ if (!sign)
+ return (DEC_TYPE)(r / x);
+ else
+ return (DEC_TYPE)(two - r / x);
+ }
+ else
+ {
+ if (!sign)
+ return (DEC_TYPE)(tiny * tiny);
+ else
+ return (DEC_TYPE)(two - tiny);
+ }
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/exp2d32.c b/libc/dfp/sysdeps/ieee754r/d32/exp2d32.c
new file mode 100644
index 000000000..ab3a51466
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/exp2d32.c
@@ -0,0 +1,81 @@
+/* Returns the value of 2 raised to the power of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME exp2
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_two;
+ DEC_TYPE two = DFP_CONSTANT(2.0);
+
+ FUNC_CONVERT_TO_DN (&two, &dn_two);
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+
+ if (___decNumberIsInfinite (&dn_x) )
+ return ___decNumberIsNegative (&dn_x) ? DFP_CONSTANT(0.0) : x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ /* ___decNumberPow (&dn_result, &dn_two, &dn_x, &context); */
+ ___decNumberPower (&dn_result, &dn_two, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ if(context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/expd32.c b/libc/dfp/sysdeps/ieee754r/d32/expd32.c
new file mode 100644
index 000000000..2ccee2c7f
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/expd32.c
@@ -0,0 +1,81 @@
+/* Calculate e^x, where x is the given _Decimal32 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME exp
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ if (___decNumberIsInfinite(&dn_x)) {
+ if (___decNumberIsNegative(&dn_x)) {
+ ___decNumberZero(&dn_result); /* exp(-inf) = 0 */
+ } else {
+ dn_result = dn_x; /* exp(inf) = inf */
+ }
+ } else {
+ ___decNumberExp(&dn_result, &dn_x, &context);
+ }
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+ if (context.status & DEC_Underflow)
+ DFP_EXCEPT (FE_UNDERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/expm1d32.c b/libc/dfp/sysdeps/ieee754r/d32/expm1d32.c
new file mode 100644
index 000000000..3f33fbf8f
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/expm1d32.c
@@ -0,0 +1,80 @@
+/* Returns a value equivelent to exp(x) - 1
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME expm1
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_one;
+ decNumber dn_exponent;
+ DEC_TYPE one = DFP_CONSTANT(1.0);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&one, &dn_one);
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+
+ if (___decNumberIsInfinite (&dn_x))
+ return ___decNumberIsNegative (&dn_x) ? DFP_CONSTANT(-1.0) : x;
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ ___decNumberExp(&dn_exponent, &dn_x, &context);
+ ___decNumberSubtract(&dn_result, &dn_exponent, &dn_one, &context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/fabsd32.c b/libc/dfp/sysdeps/ieee754r/d32/fabsd32.c
new file mode 100644
index 000000000..00466f695
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/fabsd32.c
@@ -0,0 +1,53 @@
+/* Calculate the absolute value for a _Decimal32 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME fabs
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberAbs (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/fdimd32.c b/libc/dfp/sysdeps/ieee754r/d32/fdimd32.c
new file mode 100644
index 000000000..d19bf88ef
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/fdimd32.c
@@ -0,0 +1,85 @@
+/* Returns the positive difference between the _Decimal32 type arguments
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#define FUNCTION_NAME fdim
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_y;
+ decNumber dn_diff;
+ DEC_TYPE temp_diff;
+ DEC_TYPE temp_result;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&y, &dn_y);
+
+ if(___decNumberIsNaN (&dn_x) || ___decNumberIsNaN (&dn_y))
+ return x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberSubtract (&dn_diff, &dn_x, &dn_y, &context);
+ ___decNumberSubtract (&dn_result, &dn_x, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_diff, &temp_diff, &context);
+ FUNC_CONVERT_FROM_DN (&dn_result, &temp_result, &context);
+ if(temp_diff>temp_result)
+ ___decNumberAdd (&dn_result,&dn_result,&dn_diff,&context);
+ /* if(___decCompare (&dn_diff,&dn_result) == 1)
+ ___decNumberAdd (&dn_result,&dn_result,&dn_diff,&context);
+ */
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/finited32.c b/libc/dfp/sysdeps/ieee754r/d32/finited32.c
new file mode 100644
index 000000000..54f472398
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/finited32.c
@@ -0,0 +1,48 @@
+/* Returns non-zero if the _Decimal32 is non-infinite
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME finite
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+
+ if(___decNumberIsNaN(&dn_x))
+ return 0;
+
+ return ___decNumberIsInfinite(&dn_x)?0:1;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/floord32.c b/libc/dfp/sysdeps/ieee754r/d32/floord32.c
new file mode 100644
index 000000000..463db0bdd
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/floord32.c
@@ -0,0 +1,57 @@
+/* Floor function for _Decimal32 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME floor
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsInfinite (&dn_x)
+ || ___decNumberIsZero (&dn_x) )
+ return x+x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ context.round = DEC_ROUND_FLOOR;
+ ___decNumberToIntegralValue (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/fmad32.c b/libc/dfp/sysdeps/ieee754r/d32/fmad32.c
new file mode 100644
index 000000000..6c44ce11e
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/fmad32.c
@@ -0,0 +1,105 @@
+/* Floating point multiply and add (x * y + z)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME fma
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y, DEC_TYPE z)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_y;
+ decNumber dn_product;
+ decNumber dn_z;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&y, &dn_y);
+ FUNC_CONVERT_TO_DN (&z, &dn_z);
+
+ /* If x or y is NaN, return NaN */
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsNaN (&dn_y))
+ return x+y;
+
+ /* Domain error if x or y is Inf, the other is 0 */
+ if ( (___decNumberIsInfinite (&dn_x) && ___decNumberIsZero (&dn_y)) ||
+ (___decNumberIsInfinite (&dn_y) && ___decNumberIsZero (&dn_x)) )
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ /* If x and y are not 0,Inf or Inf,0, and z is NaN, return NaN */
+ if (___decNumberIsNaN (&dn_z))
+ return z+z;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberMultiply (&dn_product, &dn_x, &dn_y, &context);
+
+ /* Domain error if x*y = Inf and z=Inf (with opposite signs) */
+ if (___decNumberIsInfinite (&dn_product) && ___decNumberIsInfinite (&dn_z) &&
+ (___decNumberIsNegative (&dn_product) != ___decNumberIsNegative (&dn_z)))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ ___decNumberAdd (&dn_result, &dn_product, &dn_z, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y, DEC_TYPE z)
+{
+ DEC_TYPE r = IEEE_FUNCTION_NAME (x, y, z);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return r;
+ if ( (FUNC_D(__isinf) (x) && y == DFP_CONSTANT(0.0)) ||
+ (FUNC_D(__isinf) (y) && x == DFP_CONSTANT(0.0)) )
+ DFP_ERRNO(EDOM);
+ else if (FUNC_D (__isinf) (z))
+ {
+ int isneg = FUNC_D(__signbit) (x) ^ FUNC_D(__signbit) (y);
+ int inf = FUNC_D(__isinf) (x) | FUNC_D(__isinf) (y);
+ if ( inf && FUNC_D (__signbit) (z) != isneg)
+ DFP_ERRNO (EDOM);
+ }
+#endif
+ return r;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/fmaxd32.c b/libc/dfp/sysdeps/ieee754r/d32/fmaxd32.c
new file mode 100644
index 000000000..bedc9fe29
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/fmaxd32.c
@@ -0,0 +1,58 @@
+/* Determine the maximum of two _Decimal32 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME fmax
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ ___decNumberMax(&dn_result, &dn_x, &dn_y, &context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/fmind32.c b/libc/dfp/sysdeps/ieee754r/d32/fmind32.c
new file mode 100644
index 000000000..d45635b4a
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/fmind32.c
@@ -0,0 +1,58 @@
+/* Determine the minimum of two _Decimal32 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME fmin
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ ___decNumberMin(&dn_result, &dn_x, &dn_y, &context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/fmodd32.c b/libc/dfp/sysdeps/ieee754r/d32/fmodd32.c
new file mode 100644
index 000000000..bdccbec20
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/fmodd32.c
@@ -0,0 +1,86 @@
+/* Returns the remainder of a floating point division
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#define FUNCTION_NAME fmod
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ decNumber dn_result;
+/* decNumber dn_mult; */
+/* decNumber dn_rounded; */
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsNaN (&dn_y) )
+ return x+y;
+ if (___decNumberIsZero (&dn_y) || ___decNumberIsInfinite (&dn_x))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ if (___decNumberIsZero (&dn_x) || ___decNumberIsInfinite (&dn_y))
+ return x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+/* ___decNumberDivide (&dn_mult, &dn_x, &dn_y, &context);
+ context.round = DEC_ROUND_DOWN;
+ ___decNumberToIntegralValue (&dn_rounded, &dn_mult, &context);
+ ___decNumberMultiply (&dn_mult, &dn_rounded, &dn_y, &context);
+ ___decNumberSubtract (&dn_result, &dn_x, &dn_mult, &context); */
+
+ ___decNumberRemainder(&dn_result, &dn_x, &dn_y, &context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__isinf) (x) || y == DFP_CONSTANT(0.0))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/fpclassifyd32.c b/libc/dfp/sysdeps/ieee754r/d32/fpclassifyd32.c
new file mode 100644
index 000000000..831a35ffa
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/fpclassifyd32.c
@@ -0,0 +1,139 @@
+/* Returns the type of floating point number from a _Decimal32 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <math.h>
+#include <endian.h>
+
+#define FUNCTION_NAME fpclassify
+
+#include <float.h>
+#include <dfpmacro.h>
+
+#if BYTE_ORDER == BIG_ENDIAN
+# define END_FIX(i) i
+#else
+# define END_FIX(i) (_DECIMAL_SIZE/8 - 1 - i)
+#endif
+
+#if _DECIMAL_SIZE == 32
+# define comb_shift 5
+# define min_normal_exp 5
+# define getExpCont(array) ((((array)[END_FIX(0)] & 0x03) << 4) | \
+ ((unsigned)(array)[END_FIX(1)]>>4) )
+#elif _DECIMAL_SIZE == 64
+# define comb_shift 7
+# define min_normal_exp 14
+# define getExpCont(array) ((((array)[END_FIX(0)] & 0x03) << 6) | \
+ ((unsigned)(array)[END_FIX(1)]>>2) )
+#elif _DECIMAL_SIZE == 128
+# define comb_shift 11
+# define min_normal_exp 32
+# define getExpCont(array) ((((array)[END_FIX(0)] & 0x03) << 10) | \
+ ((unsigned)(array)[END_FIX(1)] << 2) | \
+ ((unsigned)(array)[END_FIX(2)] >> 6) )
+#endif
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ uint8_t top_byte;
+ union
+ {
+ DEC_TYPE dec;
+ uint8_t bytes[_DECIMAL_SIZE/8];
+ } u_conv;
+ uint8_t comb, msd;
+ uint16_t exp;
+ int i;
+
+ u_conv.dec = x;
+ top_byte = u_conv.bytes[END_FIX(0)];
+
+ if((top_byte & DECIMAL_NaN) == DECIMAL_NaN)
+ return FP_NAN;
+ if((top_byte & DECIMAL_Inf) == DECIMAL_Inf)
+ return FP_INFINITE;
+
+ /* It wasn't an easy case, so extract the most significant digit
+ * and part of the exponant from the combination field*/
+// comb = top_byte >> 2;
+ comb = (top_byte >> 2) & 0x1F; /* Mask off the signbit. */
+ if (comb >= 0x18)
+ {
+ msd = 8 + (comb & 0x01);
+ exp = (comb & 0x06) << comb_shift;
+ }
+ else
+ {
+ msd = comb & 0x07;
+ exp = (comb & 0x18) << (comb_shift-2);
+ }
+ /* Fetch the rest of the (still biased) exp */
+ exp += getExpCont(u_conv.bytes);
+
+ /* If the Most significant digit !=0, either subnormal or normal */
+ if(msd != 0)
+ return (exp < min_normal_exp) ? FP_SUBNORMAL : FP_NORMAL;
+
+ /* Clean the exponent out of the byte array */
+#if _DECIMAL_SIZE == 32
+ u_conv.bytes[END_FIX(1)] &= 0x0f;
+#elif _DECIMAL_SIZE == 64
+ u_conv.bytes[END_FIX(1)] &= 0x03;
+#elif _DECIMAL_SIZE == 128
+ u_conv.bytes[END_FIX(1)] = 0;
+ u_conv.bytes[END_FIX(2)] &= 0x3f;
+#endif
+
+ /* Run backwards through the array, checking that each one is zero. If we
+ * don't find a non-zero then the number is FP_ZERO. If we find non-zero then
+ * we determine whether it is normal or subnormal.
+ *
+ * There is an issue when we receive a value like 10e-96. Although the number
+ * is representable in the normal range (i.e. 1e-95), the encoding for this
+ * particular number has been given to us in this slightly screwy format.
+ * Techincally -96 exceeds the minimum exponent for _Decimal32 but it is still
+ * 'normal'. We will rely on the runtime for comparison of 'x' against
+ * __DEC32_MIN__. The comparison will be correct regardless of how this
+ * boundary case is encoded.
+ */
+
+ /* Hopefully none of these comparisons re-invoke fpclassifyd[32|64|128] */
+ if(x == DFP_CONSTANT(0.0) || x == DFP_CONSTANT(-0.0))
+ return FP_ZERO;
+ else if((exp > min_normal_exp) || (x >= DFP_MIN))
+ {
+ /* e.g. (for the examples exp hasn't been unbiased).
+ * exp == -94
+ * x (10E-96 -> 1E-95) == DEC32_MIN (1E-95DF)
+ * x (2300E-96 -> 23E-94) > DEC32_MIN */
+ return FP_NORMAL;
+ }
+ else /* x < DEC_TYPE_MIN */
+ return FP_SUBNORMAL;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/frexpd32.c b/libc/dfp/sysdeps/ieee754r/d32/frexpd32.c
new file mode 100644
index 000000000..3520ace2b
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/frexpd32.c
@@ -0,0 +1,58 @@
+/* Break floating point number into normalized fraction and integral power of two
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME frexp
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, int *y)
+{
+ DEC_TYPE result;
+ decNumber dn_x;
+ decContext context;
+
+ *y = 0;
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsInfinite (&dn_x)
+ || ___decNumberIsZero (&dn_x))
+ return x+x;
+
+ *y = dn_x.digits + dn_x.exponent;
+ dn_x.exponent = -dn_x.digits;
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ FUNC_CONVERT_FROM_DN (&dn_x, &result, &context);
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/hypotd32.c b/libc/dfp/sysdeps/ieee754r/d32/hypotd32.c
new file mode 100644
index 000000000..4edf0be1a
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/hypotd32.c
@@ -0,0 +1,85 @@
+/* Returns sqrt(x*x+y*y)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME hypot
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_xx;
+ decNumber dn_y;
+ decNumber dn_yy;
+ decNumber dn_sum;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&y, &dn_y);
+ if (___decNumberIsInfinite (&dn_x))
+ return x;
+ if (___decNumberIsInfinite (&dn_y))
+ return y;
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsNaN (&dn_y))
+ return x+y;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberMultiply (&dn_xx, &dn_x, &dn_x, &context);
+ ___decNumberMultiply (&dn_yy, &dn_y, &dn_y, &context);
+ ___decNumberAdd (&dn_sum, &dn_xx, &dn_yy, &context);
+ ___decNumberSquareRoot (&dn_result, &dn_sum, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x) && FUNC_D(__finite) (y))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/ilogbd32.c b/libc/dfp/sysdeps/ieee754r/d32/ilogbd32.c
new file mode 100644
index 000000000..8064a6cb3
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/ilogbd32.c
@@ -0,0 +1,101 @@
+/* Returns the unbiased exponent of the passed _Decimal32 value as an int
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define DFP_DEBUG(arg) printf("%Hf\n", arg)
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME ilogb
+
+#include <dfpmacro.h>
+
+int
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE result;
+ decContext context;
+ decNumber dn_result;
+ decNumber dn_x;
+ decNumber dn_absx;
+ decNumber dn_logx;
+ /* int i_result; */
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ if (___decNumberIsZero (&dn_x))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return FP_ILOGB0;
+ }
+ if (___decNumberIsInfinite (&dn_x))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return INT_MAX;
+ }
+ if (___decNumberIsNaN (&dn_x))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return FP_ILOGBNAN;
+ }
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ ___decNumberAbs(&dn_absx, &dn_x, &context);
+
+ /* For DFP, we use radix 10 instead of whatever FLT_RADIX
+ happens to be */
+ ___decNumberLog10(&dn_logx, &dn_absx, &context);
+
+ /* Capture the case where truncation will return the wrong result. */
+ if (x < DFP_CONSTANT(1.0) && x > DFP_CONSTANT(-1.0))
+ context.round = DEC_ROUND_UP; /* round away from zero */
+ else
+ context.round = DEC_ROUND_DOWN; /* truncate */
+ ___decNumberToIntegralValue(&dn_result, &dn_logx, &context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+ /* Use _Decimal* to int casting. */
+ return (int)result;
+}
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ int z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(x == DFP_CONSTANT(0.0) || isinf(x) || isnan(x) ||
+ x > INT_MAX || x < INT_MIN)
+ DFP_ERRNO(EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/isgreaterd32.c b/libc/dfp/sysdeps/ieee754r/d32/isgreaterd32.c
new file mode 100644
index 000000000..0030ca936
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/isgreaterd32.c
@@ -0,0 +1,52 @@
+/* Implements > for _Decimal32
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME isgreater
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return 0;
+
+ /*return ___decCompare(&dn_x,&dn_y) == 1; */
+ return x>y;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/isgreaterequald32.c b/libc/dfp/sysdeps/ieee754r/d32/isgreaterequald32.c
new file mode 100644
index 000000000..11b47628b
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/isgreaterequald32.c
@@ -0,0 +1,52 @@
+/* Implements >= for _Decimal32
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME isgreaterequal
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return 0;
+
+ /*return ___decCompare(&dn_x,&dn_y) != -1; */
+ return x>=y;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/isinfd32.c b/libc/dfp/sysdeps/ieee754r/d32/isinfd32.c
new file mode 100644
index 000000000..e72a54eec
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/isinfd32.c
@@ -0,0 +1,54 @@
+/* Returns non-zero if the _Decimal32 is infinite
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <math.h>
+#include <endian.h>
+
+#define FUNCTION_NAME isinf
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ uint8_t top_byte;
+ union
+ {
+ DEC_TYPE dec;
+ uint8_t bytes[_DECIMAL_SIZE/8];
+ } u_conv;
+
+ u_conv.dec = x;
+#if BYTE_ORDER == BIG_ENDIAN
+ top_byte = u_conv.bytes[0];
+#else
+ top_byte = u.conv.bytes[_DECIMAL_SIZE/8 -1];
+#endif
+
+ return (top_byte & DECIMAL_Inf) == DECIMAL_Inf;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/islessd32.c b/libc/dfp/sysdeps/ieee754r/d32/islessd32.c
new file mode 100644
index 000000000..b0ebb53f1
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/islessd32.c
@@ -0,0 +1,52 @@
+/* Implements < for _Decimal32
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME isless
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return 0;
+
+ /*return ___decCompare(&dn_x,&dn_y) == -1; */
+ return x<y;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/islessequald32.c b/libc/dfp/sysdeps/ieee754r/d32/islessequald32.c
new file mode 100644
index 000000000..97f455117
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/islessequald32.c
@@ -0,0 +1,52 @@
+/* Implements <= for _Decimal32
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME islessequal
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return 0;
+
+ /*return ___decCompare(&dn_x, &dn_y) != 1; */
+ return x<=y;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/islessgreaterd32.c b/libc/dfp/sysdeps/ieee754r/d32/islessgreaterd32.c
new file mode 100644
index 000000000..60be248f2
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/islessgreaterd32.c
@@ -0,0 +1,52 @@
+/* Implements <> for _Decimal32
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME islessgreater
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return 0;
+
+ /*return ___decCompare(&dn_x,&dn_y) != 0; */
+ return (x) < (y) || (x) > (y);
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/isnand32.c b/libc/dfp/sysdeps/ieee754r/d32/isnand32.c
new file mode 100644
index 000000000..20b40239c
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/isnand32.c
@@ -0,0 +1,54 @@
+/* Returns non-zero if the _Decimal32 is nan
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <math.h>
+#include <endian.h>
+
+#define FUNCTION_NAME isnan
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ uint8_t top_byte;
+ union
+ {
+ DEC_TYPE dec;
+ uint8_t bytes[_DECIMAL_SIZE/8];
+ } u_conv;
+
+ u_conv.dec = x;
+#if BYTE_ORDER == BIG_ENDIAN
+ top_byte = u_conv.bytes[0];
+#else
+ top_byte = u_conv.bytes[_DECIMAL_SIZE/8 - 1];
+#endif
+
+ return (top_byte & DECIMAL_NaN) == DECIMAL_NaN;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/isnormald32.c b/libc/dfp/sysdeps/ieee754r/d32/isnormald32.c
new file mode 100644
index 000000000..1c505e37e
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/isnormald32.c
@@ -0,0 +1,67 @@
+/* Returns non-zero if the _Decimal32 is normalized
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decNumber.h>
+#include <math.h>
+
+#include <float.h> /* Includes definitions of DEC##_MIN */
+
+#define FUNCTION_NAME isnormal
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE min = DFP_MIN;
+ DEC_TYPE result;
+ /*decNumber dn_min; */
+ decContext context;
+ decNumber dn_x;
+ decNumber dn_result;
+
+
+/* FUNC_CONVERT_TO_DN(&min, &dn_min); */
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsInfinite(&dn_x) ||
+ ___decNumberIsZero(&dn_x))
+ return 0;
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ ___decNumberAbs(&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ if(result<min)
+ return 0;
+
+ /* if(___decCompare(&dn_result, &dn_min) == -1)
+ return 0; */
+
+ return 1;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/isunorderedd32.c b/libc/dfp/sysdeps/ieee754r/d32/isunorderedd32.c
new file mode 100644
index 000000000..5d4608b1c
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/isunorderedd32.c
@@ -0,0 +1,39 @@
+/* Returns true if either _Decimal32 is NaN
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <math.h>
+
+#define FUNCTION_NAME isunordered
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ return FUNC_D(__isnan) (x) || FUNC_D(__isnan) (y);
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/ldexpd32.c b/libc/dfp/sysdeps/ieee754r/d32/ldexpd32.c
new file mode 100644
index 000000000..1019c0854
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/ldexpd32.c
@@ -0,0 +1,81 @@
+/* Returns the _Decimal32 value * 2^ the integral value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#define FUNCTION_NAME ldexp
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, int y)
+{
+ decContext context;
+ DEC_TYPE result;
+ decNumber dn_x;
+ long newexp;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsZero (&dn_x) ||
+ ___decNumberIsInfinite (&dn_x))
+ return x+x;
+ if (y == 0)
+ return x;
+
+ /* ldexp(x,y) is just x*10**y, which is equivalent to increasing the exponent
+ * by y + 1. */
+ newexp = dn_x.exponent + y + 1;
+ if(newexp > INT_MAX)
+ newexp = INT_MAX;
+ if(newexp < -INT_MAX)
+ newexp = -INT_MAX;
+ dn_x.exponent = newexp;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ FUNC_CONVERT_FROM_DN (&dn_x, &result, &context);
+
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, int y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/lgammad32.c b/libc/dfp/sysdeps/ieee754r/d32/lgammad32.c
new file mode 100644
index 000000000..092e83902
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/lgammad32.c
@@ -0,0 +1,1080 @@
+/* lgammal
+ *
+ * Natural logarithm of gamma function
+ *
+ *
+ *
+ * SYNOPSIS:
+ *
+ * _Decimal128 x, y, lgammal();
+ * extern int sgngam;
+ *
+ * y = lgammal(x);
+ *
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base e (2.718...) logarithm of the absolute
+ * value of the gamma function of the argument.
+ * The sign (+1 or -1) of the gamma function is returned in a
+ * global (extern) variable named sgngam.
+ *
+ * The positive domain is partitioned into numerous segments for approximation.
+ * For x > 10,
+ * log gamma(x) = (x - 0.5) log(x) - x + log sqrt(2 pi) + 1/x R(1/x^2)
+ * Near the minimum at x = x0 = 1.46... the approximation is
+ * log gamma(x0 + z) = log gamma(x0) + z^2 P(z)/Q(z)
+ * for small z.
+ * Elsewhere between 0 and 10,
+ * log gamma(n + z) = log gamma(n) + z P(z)/Q(z)
+ * for various selected n and small z.
+ *
+ * The cosecant reflection formula is employed for negative arguments.
+ *
+ *
+ *
+ * ACCURACY:
+ *
+ *
+ * arithmetic domain # trials peak rms
+ * Relative error:
+ * IEEE 10, 30 100000 3.9e-34 9.8e-35
+ * IEEE 0, 10 100000 3.8e-34 5.3e-35
+ * Absolute error:
+ * IEEE -10, 0 100000 8.0e-34 8.0e-35
+ * IEEE -30, -10 100000 4.4e-34 1.0e-34
+ * IEEE -100, 100 100000 1.0e-34
+ *
+ * The absolute error criterion is the same as relative error
+ * when the function magnitude is greater than one but it is absolute
+ * when the magnitude is less than one.
+ *
+ */
+
+/* Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Modifications for decNumber C Library:
+ Author(s): Joseph Kerian <jkerian@us.ibm.com> */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <float.h>
+#include <errno.h>
+
+#define FUNCTION_NAME lgamma
+
+#include <dfpmacro.h>
+
+static const _Decimal128 PIDL = 3.1415926535897932384626433832795028841972E0DL;
+static const _Decimal128 MAXDLGM = 1.0485738685148938358098967157129705071571E4928DL;
+static const _Decimal128 one = 1.0DL;
+static const _Decimal128 zero = 0.0DL;
+static const _Decimal128 huge = 1.0e4000DL;
+
+/* log gamma(x) = ( x - 0.5 ) * log(x) - x + DLS2PI + 1/x P(1/x^2)
+ 1/x <= 0.0741 (x >= 13.495...)
+ Peak relative error 1.5e-36 */
+static const _Decimal128 ls2pi = 9.1893853320467274178032973640561763986140E-1DL;
+#define NRASY 12
+static const _Decimal128 RASY[NRASY + 1] =
+{
+ 8.333333333333333333333333333310437112111E-2DL,
+ -2.777777777777777777777774789556228296902E-3DL,
+ 7.936507936507936507795933938448586499183E-4DL,
+ -5.952380952380952041799269756378148574045E-4DL,
+ 8.417508417507928904209891117498524452523E-4DL,
+ -1.917526917481263997778542329739806086290E-3DL,
+ 6.410256381217852504446848671499409919280E-3DL,
+ -2.955064066900961649768101034477363301626E-2DL,
+ 1.796402955865634243663453415388336954675E-1DL,
+ -1.391522089007758553455753477688592767741E0DL,
+ 1.326130089598399157988112385013829305510E1DL,
+ -1.420412699593782497803472576479997819149E2DL,
+ 1.218058922427762808938869872528846787020E3DL
+};
+
+
+/* log gamma(x+13) = log gamma(13) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 12.5 <= x+13 <= 13.5
+ Peak relative error 1.1e-36 */
+static const _Decimal128 lgam13a = 1.9987213134765625E1DL;
+static const _Decimal128 lgam13b = 1.3608962611495173623870550785125024484248E-6DL;
+#define NRN13 7
+static const _Decimal128 RN13[NRN13 + 1] =
+{
+ 8.591478354823578150238226576156275285700E11DL,
+ 2.347931159756482741018258864137297157668E11DL,
+ 2.555408396679352028680662433943000804616E10DL,
+ 1.408581709264464345480765758902967123937E9DL,
+ 4.126759849752613822953004114044451046321E7DL,
+ 6.133298899622688505854211579222889943778E5DL,
+ 3.929248056293651597987893340755876578072E3DL,
+ 6.850783280018706668924952057996075215223E0DL
+};
+#define NRD13 6
+static const _Decimal128 RD13[NRD13 + 1] =
+{
+ 3.401225382297342302296607039352935541669E11DL,
+ 8.756765276918037910363513243563234551784E10DL,
+ 8.873913342866613213078554180987647243903E9DL,
+ 4.483797255342763263361893016049310017973E8DL,
+ 1.178186288833066430952276702931512870676E7DL,
+ 1.519928623743264797939103740132278337476E5DL,
+ 7.989298844938119228411117593338850892311E2DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+12) = log gamma(12) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 11.5 <= x+12 <= 12.5
+ Peak relative error 4.1e-36 */
+static const _Decimal128 lgam12a = 1.75023040771484375E1DL;
+static const _Decimal128 lgam12b = 3.7687254483392876529072161996717039575982E-6DL;
+#define NRN12 7
+static const _Decimal128 RN12[NRN12 + 1] =
+{
+ 4.709859662695606986110997348630997559137E11DL,
+ 1.398713878079497115037857470168777995230E11DL,
+ 1.654654931821564315970930093932954900867E10DL,
+ 9.916279414876676861193649489207282144036E8DL,
+ 3.159604070526036074112008954113411389879E7DL,
+ 5.109099197547205212294747623977502492861E5DL,
+ 3.563054878276102790183396740969279826988E3DL,
+ 6.769610657004672719224614163196946862747E0DL
+};
+#define NRD12 6
+static const _Decimal128 RD12[NRD12 + 1] =
+{
+ 1.928167007860968063912467318985802726613E11DL,
+ 5.383198282277806237247492369072266389233E10DL,
+ 5.915693215338294477444809323037871058363E9DL,
+ 3.241438287570196713148310560147925781342E8DL,
+ 9.236680081763754597872713592701048455890E6DL,
+ 1.292246897881650919242713651166596478850E5DL,
+ 7.366532445427159272584194816076600211171E2DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+11) = log gamma(11) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 10.5 <= x+11 <= 11.5
+ Peak relative error 1.8e-35 */
+static const _Decimal128 lgam11a = 1.5104400634765625E1DL;
+static const _Decimal128 lgam11b = 1.1938309890295225709329251070371882250744E-5DL;
+#define NRN11 7
+static const _Decimal128 RN11[NRN11 + 1] =
+{
+ 2.446960438029415837384622675816736622795E11DL,
+ 7.955444974446413315803799763901729640350E10DL,
+ 1.030555327949159293591618473447420338444E10DL,
+ 6.765022131195302709153994345470493334946E8DL,
+ 2.361892792609204855279723576041468347494E7DL,
+ 4.186623629779479136428005806072176490125E5DL,
+ 3.202506022088912768601325534149383594049E3DL,
+ 6.681356101133728289358838690666225691363E0DL
+};
+#define NRD11 6
+static const _Decimal128 RD11[NRD11 + 1] =
+{
+ 1.040483786179428590683912396379079477432E11DL,
+ 3.172251138489229497223696648369823779729E10DL,
+ 3.806961885984850433709295832245848084614E9DL,
+ 2.278070344022934913730015420611609620171E8DL,
+ 7.089478198662651683977290023829391596481E6DL,
+ 1.083246385105903533237139380509590158658E5DL,
+ 6.744420991491385145885727942219463243597E2DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+10) = log gamma(10) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 9.5 <= x+10 <= 10.5
+ Peak relative error 5.4e-37 */
+static const _Decimal128 lgam10a = 1.280181884765625E1DL;
+static const _Decimal128 lgam10b = 8.6324252196112077178745667061642811492557E-6DL;
+#define NRN10 7
+static const _Decimal128 RN10[NRN10 + 1] =
+{
+ -1.239059737177249934158597996648808363783E14DL,
+ -4.725899566371458992365624673357356908719E13DL,
+ -7.283906268647083312042059082837754850808E12DL,
+ -5.802855515464011422171165179767478794637E11DL,
+ -2.532349691157548788382820303182745897298E10DL,
+ -5.884260178023777312587193693477072061820E8DL,
+ -6.437774864512125749845840472131829114906E6DL,
+ -2.350975266781548931856017239843273049384E4DL
+};
+#define NRD10 7
+static const _Decimal128 RD10[NRD10 + 1] =
+{
+ -5.502645997581822567468347817182347679552E13DL,
+ -1.970266640239849804162284805400136473801E13DL,
+ -2.819677689615038489384974042561531409392E12DL,
+ -2.056105863694742752589691183194061265094E11DL,
+ -8.053670086493258693186307810815819662078E9DL,
+ -1.632090155573373286153427982504851867131E8DL,
+ -1.483575879240631280658077826889223634921E6DL,
+ -4.002806669713232271615885826373550502510E3DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+9) = log gamma(9) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 8.5 <= x+9 <= 9.5
+ Peak relative error 3.6e-36 */
+static const _Decimal128 lgam9a = 1.06045989990234375E1DL;
+static const _Decimal128 lgam9b = 3.9037218127284172274007216547549861681400E-6DL;
+#define NRN9 7
+static const _Decimal128 RN9[NRN9 + 1] =
+{
+ -4.936332264202687973364500998984608306189E13DL,
+ -2.101372682623700967335206138517766274855E13DL,
+ -3.615893404644823888655732817505129444195E12DL,
+ -3.217104993800878891194322691860075472926E11DL,
+ -1.568465330337375725685439173603032921399E10DL,
+ -4.073317518162025744377629219101510217761E8DL,
+ -4.983232096406156139324846656819246974500E6DL,
+ -2.036280038903695980912289722995505277253E4DL
+};
+#define NRD9 7
+static const _Decimal128 RD9[NRD9 + 1] =
+{
+ -2.306006080437656357167128541231915480393E13DL,
+ -9.183606842453274924895648863832233799950E12DL,
+ -1.461857965935942962087907301194381010380E12DL,
+ -1.185728254682789754150068652663124298303E11DL,
+ -5.166285094703468567389566085480783070037E9DL,
+ -1.164573656694603024184768200787835094317E8DL,
+ -1.177343939483908678474886454113163527909E6DL,
+ -3.529391059783109732159524500029157638736E3DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+8) = log gamma(8) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 7.5 <= x+8 <= 8.5
+ Peak relative error 2.4e-37 */
+static const _Decimal128 lgam8a = 8.525146484375E0DL;
+static const _Decimal128 lgam8b = 1.4876690414300165531036347125050759667737E-5DL;
+#define NRN8 8
+static const _Decimal128 RN8[NRN8 + 1] =
+{
+ 6.600775438203423546565361176829139703289E11DL,
+ 3.406361267593790705240802723914281025800E11DL,
+ 7.222460928505293914746983300555538432830E10DL,
+ 8.102984106025088123058747466840656458342E9DL,
+ 5.157620015986282905232150979772409345927E8DL,
+ 1.851445288272645829028129389609068641517E7DL,
+ 3.489261702223124354745894067468953756656E5DL,
+ 2.892095396706665774434217489775617756014E3DL,
+ 6.596977510622195827183948478627058738034E0DL
+};
+#define NRD8 7
+static const _Decimal128 RD8[NRD8 + 1] =
+{
+ 3.274776546520735414638114828622673016920E11DL,
+ 1.581811207929065544043963828487733970107E11DL,
+ 3.108725655667825188135393076860104546416E10DL,
+ 3.193055010502912617128480163681842165730E9DL,
+ 1.830871482669835106357529710116211541839E8DL,
+ 5.790862854275238129848491555068073485086E6DL,
+ 9.305213264307921522842678835618803553589E4DL,
+ 6.216974105861848386918949336819572333622E2DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+7) = log gamma(7) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 6.5 <= x+7 <= 7.5
+ Peak relative error 3.2e-36 */
+static const _Decimal128 lgam7a = 6.5792388916015625E0DL;
+static const _Decimal128 lgam7b = 1.2320408538495060178292903945321122583007E-5DL;
+#define NRN7 8
+static const _Decimal128 RN7[NRN7 + 1] =
+{
+ 2.065019306969459407636744543358209942213E11DL,
+ 1.226919919023736909889724951708796532847E11DL,
+ 2.996157990374348596472241776917953749106E10DL,
+ 3.873001919306801037344727168434909521030E9DL,
+ 2.841575255593761593270885753992732145094E8DL,
+ 1.176342515359431913664715324652399565551E7DL,
+ 2.558097039684188723597519300356028511547E5DL,
+ 2.448525238332609439023786244782810774702E3DL,
+ 6.460280377802030953041566617300902020435E0DL
+};
+#define NRD7 7
+static const _Decimal128 RD7[NRD7 + 1] =
+{
+ 1.102646614598516998880874785339049304483E11DL,
+ 6.099297512712715445879759589407189290040E10DL,
+ 1.372898136289611312713283201112060238351E10DL,
+ 1.615306270420293159907951633566635172343E9DL,
+ 1.061114435798489135996614242842561967459E8DL,
+ 3.845638971184305248268608902030718674691E6DL,
+ 7.081730675423444975703917836972720495507E4DL,
+ 5.423122582741398226693137276201344096370E2DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+6) = log gamma(6) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 5.5 <= x+6 <= 6.5
+ Peak relative error 6.2e-37 */
+static const _Decimal128 lgam6a = 4.7874908447265625E0DL;
+static const _Decimal128 lgam6b = 8.9805548349424770093452324304839959231517E-7DL;
+#define NRN6 8
+static const _Decimal128 RN6[NRN6 + 1] =
+{
+ -3.538412754670746879119162116819571823643E13DL,
+ -2.613432593406849155765698121483394257148E13DL,
+ -8.020670732770461579558867891923784753062E12DL,
+ -1.322227822931250045347591780332435433420E12DL,
+ -1.262809382777272476572558806855377129513E11DL,
+ -7.015006277027660872284922325741197022467E9DL,
+ -2.149320689089020841076532186783055727299E8DL,
+ -3.167210585700002703820077565539658995316E6DL,
+ -1.576834867378554185210279285358586385266E4DL
+};
+#define NRD6 8
+static const _Decimal128 RD6[NRD6 + 1] =
+{
+ -2.073955870771283609792355579558899389085E13DL,
+ -1.421592856111673959642750863283919318175E13DL,
+ -4.012134994918353924219048850264207074949E12DL,
+ -6.013361045800992316498238470888523722431E11DL,
+ -5.145382510136622274784240527039643430628E10DL,
+ -2.510575820013409711678540476918249524123E9DL,
+ -6.564058379709759600836745035871373240904E7DL,
+ -7.861511116647120540275354855221373571536E5DL,
+ -2.821943442729620524365661338459579270561E3DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+5) = log gamma(5) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 4.5 <= x+5 <= 5.5
+ Peak relative error 3.4e-37 */
+static const _Decimal128 lgam5a = 3.17803955078125E0DL;
+static const _Decimal128 lgam5b = 1.4279566695619646941601297055408873990961E-5DL;
+#define NRN5 9
+static const _Decimal128 RN5[NRN5 + 1] =
+{
+ 2.010952885441805899580403215533972172098E11DL,
+ 1.916132681242540921354921906708215338584E11DL,
+ 7.679102403710581712903937970163206882492E10DL,
+ 1.680514903671382470108010973615268125169E10DL,
+ 2.181011222911537259440775283277711588410E9DL,
+ 1.705361119398837808244780667539728356096E8DL,
+ 7.792391565652481864976147945997033946360E6DL,
+ 1.910741381027985291688667214472560023819E5DL,
+ 2.088138241893612679762260077783794329559E3DL,
+ 6.330318119566998299106803922739066556550E0DL
+};
+#define NRD5 8
+static const _Decimal128 RD5[NRD5 + 1] =
+{
+ 1.335189758138651840605141370223112376176E11DL,
+ 1.174130445739492885895466097516530211283E11DL,
+ 4.308006619274572338118732154886328519910E10DL,
+ 8.547402888692578655814445003283720677468E9DL,
+ 9.934628078575618309542580800421370730906E8DL,
+ 6.847107420092173812998096295422311820672E7DL,
+ 2.698552646016599923609773122139463150403E6DL,
+ 5.526516251532464176412113632726150253215E4DL,
+ 4.772343321713697385780533022595450486932E2DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+4) = log gamma(4) + x P(x)/Q(x)
+ -0.5 <= x <= 0.5
+ 3.5 <= x+4 <= 4.5
+ Peak relative error 6.7e-37 */
+static const _Decimal128 lgam4a = 1.791748046875E0DL;
+static const _Decimal128 lgam4b = 1.1422353055000812477358380702272722990692E-5DL;
+#define NRN4 9
+static const _Decimal128 RN4[NRN4 + 1] =
+{
+ -1.026583408246155508572442242188887829208E13DL,
+ -1.306476685384622809290193031208776258809E13DL,
+ -7.051088602207062164232806511992978915508E12DL,
+ -2.100849457735620004967624442027793656108E12DL,
+ -3.767473790774546963588549871673843260569E11DL,
+ -4.156387497364909963498394522336575984206E10DL,
+ -2.764021460668011732047778992419118757746E9DL,
+ -1.036617204107109779944986471142938641399E8DL,
+ -1.895730886640349026257780896972598305443E6DL,
+ -1.180509051468390914200720003907727988201E4DL
+};
+#define NRD4 9
+static const _Decimal128 RD4[NRD4 + 1] =
+{
+ -8.172669122056002077809119378047536240889E12DL,
+ -9.477592426087986751343695251801814226960E12DL,
+ -4.629448850139318158743900253637212801682E12DL,
+ -1.237965465892012573255370078308035272942E12DL,
+ -1.971624313506929845158062177061297598956E11DL,
+ -1.905434843346570533229942397763361493610E10DL,
+ -1.089409357680461419743730978512856675984E9DL,
+ -3.416703082301143192939774401370222822430E7DL,
+ -4.981791914177103793218433195857635265295E5DL,
+ -2.192507743896742751483055798411231453733E3DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+3) = log gamma(3) + x P(x)/Q(x)
+ -0.25 <= x <= 0.5
+ 2.75 <= x+3 <= 3.5
+ Peak relative error 6.0e-37 */
+static const _Decimal128 lgam3a = 6.93145751953125E-1DL;
+static const _Decimal128 lgam3b = 1.4286068203094172321214581765680755001344E-6DL;
+
+#define NRN3 9
+static const _Decimal128 RN3[NRN3 + 1] =
+{
+ -4.813901815114776281494823863935820876670E11DL,
+ -8.425592975288250400493910291066881992620E11DL,
+ -6.228685507402467503655405482985516909157E11DL,
+ -2.531972054436786351403749276956707260499E11DL,
+ -6.170200796658926701311867484296426831687E10DL,
+ -9.211477458528156048231908798456365081135E9DL,
+ -8.251806236175037114064561038908691305583E8DL,
+ -4.147886355917831049939930101151160447495E7DL,
+ -1.010851868928346082547075956946476932162E6DL,
+ -8.333374463411801009783402800801201603736E3DL
+};
+#define NRD3 9
+static const _Decimal128 RD3[NRD3 + 1] =
+{
+ -5.216713843111675050627304523368029262450E11DL,
+ -8.014292925418308759369583419234079164391E11DL,
+ -5.180106858220030014546267824392678611990E11DL,
+ -1.830406975497439003897734969120997840011E11DL,
+ -3.845274631904879621945745960119924118925E10DL,
+ -4.891033385370523863288908070309417710903E9DL,
+ -3.670172254411328640353855768698287474282E8DL,
+ -1.505316381525727713026364396635522516989E7DL,
+ -2.856327162923716881454613540575964890347E5DL,
+ -1.622140448015769906847567212766206894547E3DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+2.5) = log gamma(2.5) + x P(x)/Q(x)
+ -0.125 <= x <= 0.25
+ 2.375 <= x+2.5 <= 2.75 */
+static const _Decimal128 lgam2r5a = 2.8466796875E-1DL;
+static const _Decimal128 lgam2r5b = 1.4901722919159632494669682701924320137696E-5DL;
+#define NRN2r5 8
+static const _Decimal128 RN2r5[NRN2r5 + 1] =
+{
+ -4.676454313888335499356699817678862233205E9DL,
+ -9.361888347911187924389905984624216340639E9DL,
+ -7.695353600835685037920815799526540237703E9DL,
+ -3.364370100981509060441853085968900734521E9DL,
+ -8.449902011848163568670361316804900559863E8DL,
+ -1.225249050950801905108001246436783022179E8DL,
+ -9.732972931077110161639900388121650470926E6DL,
+ -3.695711763932153505623248207576425983573E5DL,
+ -4.717341584067827676530426007495274711306E3DL
+};
+#define NRD2r5 8
+static const _Decimal128 RD2r5[NRD2r5 + 1] =
+{
+ -6.650657966618993679456019224416926875619E9DL,
+ -1.099511409330635807899718829033488771623E10DL,
+ -7.482546968307837168164311101447116903148E9DL,
+ -2.702967190056506495988922973755870557217E9DL,
+ -5.570008176482922704972943389590409280950E8DL,
+ -6.536934032192792470926310043166993233231E7DL,
+ -4.101991193844953082400035444146067511725E6DL,
+ -1.174082735875715802334430481065526664020E5DL,
+ -9.932840389994157592102947657277692978511E2DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+2) = x P(x)/Q(x)
+ -0.125 <= x <= +0.375
+ 1.875 <= x+2 <= 2.375
+ Peak relative error 4.6e-36 */
+#define NRN2 9
+static const _Decimal128 RN2[NRN2 + 1] =
+{
+ -3.716661929737318153526921358113793421524E9DL,
+ -1.138816715030710406922819131397532331321E10DL,
+ -1.421017419363526524544402598734013569950E10DL,
+ -9.510432842542519665483662502132010331451E9DL,
+ -3.747528562099410197957514973274474767329E9DL,
+ -8.923565763363912474488712255317033616626E8DL,
+ -1.261396653700237624185350402781338231697E8DL,
+ -9.918402520255661797735331317081425749014E6DL,
+ -3.753996255897143855113273724233104768831E5DL,
+ -4.778761333044147141559311805999540765612E3DL
+};
+#define NRD2 9
+static const _Decimal128 RD2[NRD2 + 1] =
+{
+ -8.790916836764308497770359421351673950111E9DL,
+ -2.023108608053212516399197678553737477486E10DL,
+ -1.958067901852022239294231785363504458367E10DL,
+ -1.035515043621003101254252481625188704529E10DL,
+ -3.253884432621336737640841276619272224476E9DL,
+ -6.186383531162456814954947669274235815544E8DL,
+ -6.932557847749518463038934953605969951466E7DL,
+ -4.240731768287359608773351626528479703758E6DL,
+ -1.197343995089189188078944689846348116630E5DL,
+ -1.004622911670588064824904487064114090920E3DL
+/* 1.0E0 */
+};
+
+
+/* log gamma(x+1.75) = log gamma(1.75) + x P(x)/Q(x)
+ -0.125 <= x <= +0.125
+ 1.625 <= x+1.75 <= 1.875
+ Peak relative error 9.2e-37 */
+static const _Decimal128 lgam1r75a = -8.441162109375E-2DL;
+static const _Decimal128 lgam1r75b = 1.0500073264444042213965868602268256157604E-5DL;
+#define NRN1r75 8
+static const _Decimal128 RN1r75[NRN1r75 + 1] =
+{
+ -5.221061693929833937710891646275798251513E7DL,
+ -2.052466337474314812817883030472496436993E8DL,
+ -2.952718275974940270675670705084125640069E8DL,
+ -2.132294039648116684922965964126389017840E8DL,
+ -8.554103077186505960591321962207519908489E7DL,
+ -1.940250901348870867323943119132071960050E7DL,
+ -2.379394147112756860769336400290402208435E6DL,
+ -1.384060879999526222029386539622255797389E5DL,
+ -2.698453601378319296159355612094598695530E3DL
+};
+#define NRD1r75 8
+static const _Decimal128 RD1r75[NRD1r75 + 1] =
+{
+ -2.109754689501705828789976311354395393605E8DL,
+ -5.036651829232895725959911504899241062286E8DL,
+ -4.954234699418689764943486770327295098084E8DL,
+ -2.589558042412676610775157783898195339410E8DL,
+ -7.731476117252958268044969614034776883031E7DL,
+ -1.316721702252481296030801191240867486965E7DL,
+ -1.201296501404876774861190604303728810836E6DL,
+ -5.007966406976106636109459072523610273928E4DL,
+ -6.155817990560743422008969155276229018209E2DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+x0) = y0 + x^2 P(x)/Q(x)
+ -0.0867 <= x <= +0.1634
+ 1.374932... <= x+x0 <= 1.625032...
+ Peak relative error 4.0e-36 */
+static const _Decimal128 x0a = 1.4616241455078125DL;
+static const _Decimal128 x0b = 7.9994605498412626595423257213002588621246E-6DL;
+static const _Decimal128 y0a = -1.21490478515625E-1DL;
+static const _Decimal128 y0b = 4.1879797753919044854428223084178486438269E-6DL;
+#define NRN1r5 8
+static const _Decimal128 RN1r5[NRN1r5 + 1] =
+{
+ 6.827103657233705798067415468881313128066E5DL,
+ 1.910041815932269464714909706705242148108E6DL,
+ 2.194344176925978377083808566251427771951E6DL,
+ 1.332921400100891472195055269688876427962E6DL,
+ 4.589080973377307211815655093824787123508E5DL,
+ 8.900334161263456942727083580232613796141E4DL,
+ 9.053840838306019753209127312097612455236E3DL,
+ 4.053367147553353374151852319743594873771E2DL,
+ 5.040631576303952022968949605613514584950E0DL
+};
+#define NRD1r5 8
+static const _Decimal128 RD1r5[NRD1r5 + 1] =
+{
+ 1.411036368843183477558773688484699813355E6DL,
+ 4.378121767236251950226362443134306184849E6DL,
+ 5.682322855631723455425929877581697918168E6DL,
+ 3.999065731556977782435009349967042222375E6DL,
+ 1.653651390456781293163585493620758410333E6DL,
+ 4.067774359067489605179546964969435858311E5DL,
+ 5.741463295366557346748361781768833633256E4DL,
+ 4.226404539738182992856094681115746692030E3DL,
+ 1.316980975410327975566999780608618774469E2DL,
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x+1.25) = log gamma(1.25) + x P(x)/Q(x)
+ -.125 <= x <= +.125
+ 1.125 <= x+1.25 <= 1.375
+ Peak relative error = 4.9e-36 */
+static const _Decimal128 lgam1r25a = -9.82818603515625E-2DL;
+static const _Decimal128 lgam1r25b = 1.0023929749338536146197303364159774377296E-5DL;
+#define NRN1r25 9
+static const _Decimal128 RN1r25[NRN1r25 + 1] =
+{
+ -9.054787275312026472896002240379580536760E4DL,
+ -8.685076892989927640126560802094680794471E4DL,
+ 2.797898965448019916967849727279076547109E5DL,
+ 6.175520827134342734546868356396008898299E5DL,
+ 5.179626599589134831538516906517372619641E5DL,
+ 2.253076616239043944538380039205558242161E5DL,
+ 5.312653119599957228630544772499197307195E4DL,
+ 6.434329437514083776052669599834938898255E3DL,
+ 3.385414416983114598582554037612347549220E2DL,
+ 4.907821957946273805080625052510832015792E0DL
+};
+#define NRD1r25 8
+static const _Decimal128 RD1r25[NRD1r25 + 1] =
+{
+ 3.980939377333448005389084785896660309000E5DL,
+ 1.429634893085231519692365775184490465542E6DL,
+ 2.145438946455476062850151428438668234336E6DL,
+ 1.743786661358280837020848127465970357893E6DL,
+ 8.316364251289743923178092656080441655273E5DL,
+ 2.355732939106812496699621491135458324294E5DL,
+ 3.822267399625696880571810137601310855419E4DL,
+ 3.228463206479133236028576845538387620856E3DL,
+ 1.152133170470059555646301189220117965514E2DL
+ /* 1.0E0DL */
+};
+
+
+/* log gamma(x + 1) = x P(x)/Q(x)
+ 0.0 <= x <= +0.125
+ 1.0 <= x+1 <= 1.125
+ Peak relative error 1.1e-35 */
+#define NRN1 8
+static const _Decimal128 RN1[NRN1 + 1] =
+{
+ -9.987560186094800756471055681088744738818E3DL,
+ -2.506039379419574361949680225279376329742E4DL,
+ -1.386770737662176516403363873617457652991E4DL,
+ 1.439445846078103202928677244188837130744E4DL,
+ 2.159612048879650471489449668295139990693E4DL,
+ 1.047439813638144485276023138173676047079E4DL,
+ 2.250316398054332592560412486630769139961E3DL,
+ 1.958510425467720733041971651126443864041E2DL,
+ 4.516830313569454663374271993200291219855E0DL
+};
+#define NRD1 7
+static const _Decimal128 RD1[NRD1 + 1] =
+{
+ 1.730299573175751778863269333703788214547E4DL,
+ 6.807080914851328611903744668028014678148E4DL,
+ 1.090071629101496938655806063184092302439E5DL,
+ 9.124354356415154289343303999616003884080E4DL,
+ 4.262071638655772404431164427024003253954E4DL,
+ 1.096981664067373953673982635805821283581E4DL,
+ 1.431229503796575892151252708527595787588E3DL,
+ 7.734110684303689320830401788262295992921E1DL
+ /* 1.0E0 */
+};
+
+
+/* log gamma(x + 1) = x P(x)/Q(x)
+ -0.125 <= x <= 0
+ 0.875 <= x+1 <= 1.0
+ Peak relative error 7.0e-37 */
+#define NRNr9 8
+static const _Decimal128 RNr9[NRNr9 + 1] =
+{
+ 4.441379198241760069548832023257571176884E5DL,
+ 1.273072988367176540909122090089580368732E6DL,
+ 9.732422305818501557502584486510048387724E5DL,
+ -5.040539994443998275271644292272870348684E5DL,
+ -1.208719055525609446357448132109723786736E6DL,
+ -7.434275365370936547146540554419058907156E5DL,
+ -2.075642969983377738209203358199008185741E5DL,
+ -2.565534860781128618589288075109372218042E4DL,
+ -1.032901669542994124131223797515913955938E3DL,
+};
+#define NRDr9 8
+static const _Decimal128 RDr9[NRDr9 + 1] =
+{
+ -7.694488331323118759486182246005193998007E5DL,
+ -3.301918855321234414232308938454112213751E6DL,
+ -5.856830900232338906742924836032279404702E6DL,
+ -5.540672519616151584486240871424021377540E6DL,
+ -3.006530901041386626148342989181721176919E6DL,
+ -9.350378280513062139466966374330795935163E5DL,
+ -1.566179100031063346901755685375732739511E5DL,
+ -1.205016539620260779274902967231510804992E4DL,
+ -2.724583156305709733221564484006088794284E2DL
+/* 1.0E0 */
+};
+
+
+/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */
+
+static _Decimal128
+neval (_Decimal128 x, const _Decimal128 *p, int n)
+{
+ _Decimal128 y;
+
+ p += n;
+ y = *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+
+/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */
+
+static _Decimal128
+deval (_Decimal128 x, const _Decimal128 *p, int n)
+{
+ _Decimal128 y;
+
+ p += n;
+ y = x + *p--;
+ do
+ {
+ y = y * x + *p--;
+ }
+ while (--n > 0);
+ return y;
+}
+
+/* The 128bit version is used by all three sizes */
+extern _Decimal128 __lgamma_rd128 (_Decimal128, int *);
+
+DEC_TYPE
+FUNC_D (__lgamma_r) (DEC_TYPE x, int *signgamp)
+{
+ _Decimal128 p, q, w, z, nx;
+ int i, nn;
+
+ *signgamp = 1;
+
+ if (isinf (x) || isnan(x))
+ return x * x;
+
+ if (x < 0.0DL)
+ {
+ q = -x;
+ p = floord128 (q);
+ /* Argument is a negative Integer: Pole Error */
+ if (p == q)
+ {
+ DFP_EXCEPT (FE_DIVBYZERO);
+ return DFP_HUGE_VAL;
+ }
+ i = p;
+ if ((i & 1) == 0)
+ *signgamp = -1;
+ z = q - p;
+ if (z > 0.5DL)
+ {
+ p += 1.0DL;
+ z = p - q;
+ }
+ z = q * sind128 (M_PIdl * z);
+ if (z == 0.0DL)
+ {
+ DFP_EXCEPT (FE_OVERFLOW);
+ return (DEC_TYPE)(*signgamp * huge * huge);
+ }
+ w = __lgamma_rd128 (q, &i);
+ z = logd128 (M_PIdl / z) - w;
+ return (DEC_TYPE)(z);
+ }
+
+ if (x < 13.5DL)
+ {
+ p = 0.0DL;
+ nx = (x + 0.5DL);
+ nn = nx;
+ switch (nn)
+ {
+ case 0:
+ /* log gamma (x + 1) = log(x) + log gamma(x) */
+ if (x <= 0.125DL)
+ {
+ p = x * neval (x, RN1, NRN1) / deval (x, RD1, NRD1);
+ }
+ else if (x <= 0.375DL)
+ {
+ z = x - 0.25DL;
+ p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25);
+ p += lgam1r25b;
+ p += lgam1r25a;
+ }
+ else if (x <= 0.625DL)
+ {
+ z = x + (1.0DL - x0a);
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ else if (x <= 0.875DL)
+ {
+ z = x - 0.75DL;
+ p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75);
+ p += lgam1r75b;
+ p += lgam1r75a;
+ }
+ else
+ {
+ z = x - 1.0DL;
+ p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2);
+ }
+ p = p - FUNC_D(log) (x);
+ break;
+
+ case 1:
+ if (x < 0.875DL)
+ {
+ if (x <= 0.625DL)
+ {
+ z = x + (1.0DL - x0a);
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ else if (x <= 0.875DL)
+ {
+ z = x - 0.75DL;
+ p = z * neval (z, RN1r75, NRN1r75)
+ / deval (z, RD1r75, NRD1r75);
+ p += lgam1r75b;
+ p += lgam1r75a;
+ }
+ else
+ {
+ z = x - 1.0DL;
+ p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2);
+ }
+ p = p - FUNC_D(log) (x);
+ }
+ else if (x < 1.0DL)
+ {
+ z = x - 1.0DL;
+ p = z * neval (z, RNr9, NRNr9) / deval (z, RDr9, NRDr9);
+ }
+ else if (x == 1.0DL)
+ p = 0.0DL;
+ else if (x <= 1.125DL)
+ {
+ z = x - 1.0DL;
+ p = z * neval (z, RN1, NRN1) / deval (z, RD1, NRD1);
+ }
+ else if (x <= 1.375DL)
+ {
+ z = x - 1.25DL;
+ p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25);
+ p += lgam1r25b;
+ p += lgam1r25a;
+ }
+ else
+ {
+ /* 1.375 <= x+x0 <= 1.625 */
+ z = x - x0a;
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ break;
+
+ case 2:
+ if (x < 1.625DL)
+ {
+ z = x - x0a;
+ z = z - x0b;
+ p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5);
+ p = p * z * z;
+ p = p + y0b;
+ p = p + y0a;
+ }
+ else if (x < 1.875DL)
+ {
+ z = x - 1.75DL;
+ p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75);
+ p += lgam1r75b;
+ p += lgam1r75a;
+ }
+ else if (x == 2.0DL)
+ p = 0.0DL;
+ else if (x < 2.375DL)
+ {
+ z = x - 2.0DL;
+ p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2);
+ }
+ else
+ {
+ z = x - 2.5DL;
+ p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5);
+ p += lgam2r5b;
+ p += lgam2r5a;
+ }
+ break;
+
+ case 3:
+ if (x < 2.75DL)
+ {
+ z = x - 2.5DL;
+ p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5);
+ p += lgam2r5b;
+ p += lgam2r5a;
+ }
+ else
+ {
+ z = x - 3.0DL;
+ p = z * neval (z, RN3, NRN3) / deval (z, RD3, NRD3);
+ p += lgam3b;
+ p += lgam3a;
+ }
+ break;
+
+ case 4:
+ z = x - 4.0DL;
+ p = z * neval (z, RN4, NRN4) / deval (z, RD4, NRD4);
+ p += lgam4b;
+ p += lgam4a;
+ break;
+
+ case 5:
+ z = x - 5.0DL;
+ p = z * neval (z, RN5, NRN5) / deval (z, RD5, NRD5);
+ p += lgam5b;
+ p += lgam5a;
+ break;
+
+ case 6:
+ z = x - 6.0DL;
+ p = z * neval (z, RN6, NRN6) / deval (z, RD6, NRD6);
+ p += lgam6b;
+ p += lgam6a;
+ break;
+
+ case 7:
+ z = x - 7.0DL;
+ p = z * neval (z, RN7, NRN7) / deval (z, RD7, NRD7);
+ p += lgam7b;
+ p += lgam7a;
+ break;
+
+ case 8:
+ z = x - 8.0DL;
+ p = z * neval (z, RN8, NRN8) / deval (z, RD8, NRD8);
+ p += lgam8b;
+ p += lgam8a;
+ break;
+
+ case 9:
+ z = x - 9.0DL;
+ p = z * neval (z, RN9, NRN9) / deval (z, RD9, NRD9);
+ p += lgam9b;
+ p += lgam9a;
+ break;
+
+ case 10:
+ z = x - 10.0DL;
+ p = z * neval (z, RN10, NRN10) / deval (z, RD10, NRD10);
+ p += lgam10b;
+ p += lgam10a;
+ break;
+
+ case 11:
+ z = x - 11.0DL;
+ p = z * neval (z, RN11, NRN11) / deval (z, RD11, NRD11);
+ p += lgam11b;
+ p += lgam11a;
+ break;
+
+ case 12:
+ z = x - 12.0DL;
+ p = z * neval (z, RN12, NRN12) / deval (z, RD12, NRD12);
+ p += lgam12b;
+ p += lgam12a;
+ break;
+
+ case 13:
+ z = x - 13.0DL;
+ p = z * neval (z, RN13, NRN13) / deval (z, RD13, NRD13);
+ p += lgam13b;
+ p += lgam13a;
+ break;
+ }
+ return (DEC_TYPE) p;
+ }
+
+ if (x >= (DEC_TYPE)DEC_INFINITY)
+ {
+ DFP_EXCEPT (FE_OVERFLOW);
+ return (DEC_TYPE)(*signgamp * huge * huge);
+ }
+
+ q = ls2pi - x;
+ q = (x - 0.5DL) * FUNC_D(log) (x) + q;
+ if (x <= 1.0e18DL)
+ {
+ p = 1.0DL / (x * x);
+ q += neval (p, RASY, NRASY) / x;
+ }
+ return (DEC_TYPE)(q);
+}
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x) {
+ int local_signgam;
+ DEC_TYPE retval;
+ retval = FUNC_D (__lgamma_r) (x,&local_signgam);
+ return retval;
+}
+
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ /* For this particular case, both the Pole and Overflow error make the same
+ * finite x -> infinite z result, and both generate an ERANGE errno */
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/llrintd32.c b/libc/dfp/sysdeps/ieee754r/d32/llrintd32.c
new file mode 100644
index 000000000..bd47c8d17
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/llrintd32.c
@@ -0,0 +1,35 @@
+/* Rounds to the nearest (long long int) integer
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <math.h>
+#include <errno.h>
+#include <fenv.h>
+
+#define FUNCTION_NAME llrint
+#include <mapround.h>
+#define __ROUND_MODE __dn_getround()
+
+#include "llroundd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d32/llroundd32.c b/libc/dfp/sysdeps/ieee754r/d32/llroundd32.c
new file mode 100644
index 000000000..e093953a2
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/llroundd32.c
@@ -0,0 +1,89 @@
+/* Rounds to the nearest long long int value, ignoring rounding mode
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <fenv.h>
+
+#ifndef FUNCTION_NAME
+# define FUNCTION_NAME llround
+#endif
+#include <dfpmacro.h>
+
+#ifndef __ROUND_RETURN_TYPE
+# define __ROUND_RETURN_TYPE long long int
+# define __MIN_VALUE LLONG_MIN
+# define __MAX_VALUE LLONG_MAX
+#endif
+
+#ifndef __ROUND_MODE
+# define __ROUND_MODE DEC_ROUND_HALF_UP
+#endif
+
+__ROUND_RETURN_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE result;
+ decContext context;
+ decNumber dn_result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsInfinite (&dn_x)
+ || x > __MAX_VALUE || x < __MIN_VALUE)
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return (__ROUND_RETURN_TYPE) x;
+ }
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ context.round = __ROUND_MODE;
+ ___decNumberToIntegralValue (&dn_result,&dn_x,&context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+ /* Use _Decimal* to __ROUND_RETURN_TYPE casting. */
+ return (__ROUND_RETURN_TYPE)result;
+
+/* return (__ROUND_RETURN_TYPE)___decNumberToInteger (&dn_result); */
+}
+
+__ROUND_RETURN_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ __ROUND_RETURN_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (FUNC_D(isnan) (x) || FUNC_D(isinf) (x)
+ || x > __MAX_VALUE || x < __MIN_VALUE)
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/log10d32.c b/libc/dfp/sysdeps/ieee754r/d32/log10d32.c
new file mode 100644
index 000000000..f5824d4a2
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/log10d32.c
@@ -0,0 +1,85 @@
+/* Calculate the Log (base 10) of a given _Decimal32 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME log10
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+ if (___decNumberIsZero (&dn_x)) /* If x == 0: Pole Error */
+ {
+ DFP_EXCEPT (FE_DIVBYZERO);
+ return -DFP_HUGE_VAL;
+ }
+ if (___decNumberIsNegative (&dn_x)) /* If x < 0: Domain Error */
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ if (___decNumberIsInfinite (&dn_x))
+ return x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberLog10 (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (x < DFP_CONSTANT(0.0))
+ DFP_ERRNO (EDOM);
+ if (x == DFP_CONSTANT(0.0))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/log1pd32.c b/libc/dfp/sysdeps/ieee754r/d32/log1pd32.c
new file mode 100644
index 000000000..a1e2207a4
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/log1pd32.c
@@ -0,0 +1,91 @@
+/* Calculate the Natural Log of (a _Decimal32 value + 1)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME log1p
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_sum;
+ decNumber dn_one;
+ DEC_TYPE one = DFP_CONSTANT(1.0);
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&one, &dn_one);
+
+ /* For NaN, 0, or +Inf, just return x */
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsZero (&dn_x) ||
+ (___decNumberIsInfinite (&dn_x) && !___decNumberIsNegative (&dn_x)))
+ return x+x;
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ ___decNumberAdd(&dn_sum, &dn_x, &dn_one, &context);
+ if (___decNumberIsZero(&dn_sum)) /* Pole Error if x was -1 */
+ {
+ DFP_EXCEPT (FE_DIVBYZERO);
+ return -DFP_HUGE_VAL;
+ }
+ if (___decNumberIsNegative(&dn_sum)) /* Domain Error if x < -1 */
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+
+ ___decNumberLn(&dn_result, &dn_sum, &context);
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (x == DFP_CONSTANT(-1.0))
+ DFP_ERRNO (ERANGE);
+ if (x < DFP_CONSTANT(-1.0))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/log2d32.c b/libc/dfp/sysdeps/ieee754r/d32/log2d32.c
new file mode 100644
index 000000000..a72d463b4
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/log2d32.c
@@ -0,0 +1,93 @@
+/* Returns the base 2 logarithmic function of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME log2
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_two;
+ decNumber dn_logtwo;
+ decNumber dn_logx;
+ DEC_TYPE two = DFP_CONSTANT(2.0);
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&two, &dn_two);
+
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+ if (___decNumberIsZero (&dn_x)) /* If x == 0: Pole Error */
+ {
+ DFP_EXCEPT (FE_DIVBYZERO);
+ return -DFP_HUGE_VAL;
+ }
+ if (___decNumberIsNegative (&dn_x)) /* If x < 0,: Domain Error */
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ if (___decNumberIsInfinite (&dn_x))
+ return x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ // log_2 (x) = log_10 (x) / log_10 (2)
+ ___decNumberLog10 (&dn_logx, &dn_x, &context);
+ ___decNumberLog10 (&dn_logtwo, &dn_two, &context);
+ ___decNumberDivide (&dn_result, &dn_logx, &dn_logtwo, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (x == DFP_CONSTANT(0.0))
+ DFP_ERRNO (ERANGE);
+ if (x < DFP_CONSTANT(0.0))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/logbd32.c b/libc/dfp/sysdeps/ieee754r/d32/logbd32.c
new file mode 100644
index 000000000..63e28ca0f
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/logbd32.c
@@ -0,0 +1,88 @@
+/* Returns the unbiased exponent of the passed _Decimal32 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME logb
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_x2;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsInfinite (&dn_x))
+ return x+x;
+ if (___decNumberIsZero (&dn_x)) /* Pole Error if x==0 */
+ {
+ DFP_EXCEPT (FE_DIVBYZERO);
+ return -DFP_HUGE_VAL;
+ }
+ if (___decNumberIsInfinite (&dn_x) && ___decNumberIsNegative (&dn_x))
+ return -x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberAbs (&dn_x2, &dn_x, &context);
+ /* For DFP, we use radix 10 instead of whatever FLT_RADIX
+ happens to be */
+ ___decNumberLog10 (&dn_x, &dn_x2, &context);
+
+ /* Capture the case where truncation will return the wrong result. */
+ if (x < DFP_CONSTANT(1.0) && x > DFP_CONSTANT(-1.0))
+ context.round = DEC_ROUND_UP; /* round away from zero */
+ else
+ context.round = DEC_ROUND_DOWN; /* truncate */
+ ___decNumberToIntegralValue (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (x == DFP_CONSTANT(0.0))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/logd32.c b/libc/dfp/sysdeps/ieee754r/d32/logd32.c
new file mode 100644
index 000000000..0f11b3cc2
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/logd32.c
@@ -0,0 +1,85 @@
+/* Calculate the Natural Log of a given a _Decimal32 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME log
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+ if (___decNumberIsZero (&dn_x)) /* If x == 0: Pole Error */
+ {
+ DFP_EXCEPT (FE_DIVBYZERO);
+ return -DFP_HUGE_VAL;
+ }
+ if (___decNumberIsNegative (&dn_x)) /* If x < 0,: Domain Error */
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ if (___decNumberIsInfinite (&dn_x))
+ return x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberLn(&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (x == DFP_CONSTANT(0.0))
+ DFP_ERRNO (ERANGE);
+ if (x < DFP_CONSTANT(0.0))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/lrintd32.c b/libc/dfp/sysdeps/ieee754r/d32/lrintd32.c
new file mode 100644
index 000000000..ae5c05b21
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/lrintd32.c
@@ -0,0 +1,37 @@
+/* Rounds to the nearest (long int) integer
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <math.h>
+#include <fenv.h>
+
+#define FUNCTION_NAME lrint
+#define __ROUND_RETURN_TYPE long int
+#define __MIN_VALUE LONG_MIN
+#define __MAX_VALUE LONG_MAX
+#include <mapround.h>
+#define __ROUND_MODE __dn_getround()
+
+#include "llroundd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d32/lroundd32.c b/libc/dfp/sysdeps/ieee754r/d32/lroundd32.c
new file mode 100644
index 000000000..64a36d56a
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/lroundd32.c
@@ -0,0 +1,37 @@
+/* Rounds to the nearest long int value, ignoring rounding mode.
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <math.h>
+#include <fenv.h>
+
+#define FUNCTION_NAME lround
+#define __ROUND_RETURN_TYPE long int
+#define __MIN_VALUE LONG_MIN
+#define __MAX_VALUE LONG_MAX
+
+//Implementation is done in llround
+#include "llroundd32.c"
+
diff --git a/libc/dfp/sysdeps/ieee754r/d32/modfd32.c b/libc/dfp/sysdeps/ieee754r/d32/modfd32.c
new file mode 100644
index 000000000..c2e5a6e87
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/modfd32.c
@@ -0,0 +1,64 @@
+/* Breaks the argument into integral and fractional parts for a _Decimal32 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME modf
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE *y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x))
+ {
+ *y = x;
+ return x+x;
+ }
+ if (___decNumberIsInfinite (&dn_x))
+ return DFP_CONSTANT(0.0)/x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ context.round = DEC_ROUND_DOWN; /* round towards zero */
+ ___decNumberToIntegralValue (&dn_result, &dn_x, &context);
+ ___decNumberSubtract (&dn_y, &dn_x, &dn_result, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, y, &context);
+ FUNC_CONVERT_FROM_DN (&dn_y, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/nand32.c b/libc/dfp/sysdeps/ieee754r/d32/nand32.c
new file mode 100644
index 000000000..38a1ad8b0
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/nand32.c
@@ -0,0 +1,54 @@
+/* Returns a reprentation of NaN in the _Decimal32 format
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+//TODO: Use sprintf&strtod32 like glibc/math/s_nanX.c
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME nan
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (const char *tagp)
+{
+/* decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ ___decNumberFromString(&dn_result, x, &context);
+ dn_result.bits |= DECNAN;
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+*/
+ return (DEC_TYPE)DEC_NAN;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/nearbyintd32.c b/libc/dfp/sysdeps/ieee754r/d32/nearbyintd32.c
new file mode 100644
index 000000000..861a26bcc
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/nearbyintd32.c
@@ -0,0 +1,75 @@
+/* Round to nearest integer _Decimal32 form
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <fenv.h>
+#include <mapround.h>
+
+#define FUNCTION_NAME nearbyint
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decNumber dn_x,dn_result;
+ decContext context;
+ DEC_TYPE result;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ ___decContextDefault (&context,DEFAULT_CONTEXT);
+
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsInfinite (&dn_x) ||
+ ___decNumberIsZero (&dn_x))
+ return x+x;
+
+ context.round = __dn_getround();
+ ___decNumberToIntegralValue (&dn_result,&dn_x,&context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (!finited32 (z) && finited32 (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/nextafterd32.c b/libc/dfp/sysdeps/ieee754r/d32/nextafterd32.c
new file mode 100644
index 000000000..34e6790f0
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/nextafterd32.c
@@ -0,0 +1,96 @@
+/* Returns the next representable neighbor of x in the direction of y
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <float.h>
+#include <errno.h>
+
+#define FUNCTION_NAME nextafter
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ DEC_TYPE epsilon;
+ decNumber dn_x;
+ decNumber dn_y;
+ decNumber dn_epsilon;
+/* int comparison;*/
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&y, &dn_y);
+
+ /* Early exit for nan's */
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+ if (___decNumberIsNaN (&dn_y))
+ return y+y;
+
+ /*comparison = ___decCompare (&dn_x, &dn_y); */
+ /* Early exit for equal values */
+ /*if (comparison == 0) */
+ if (x==y)
+ return x;
+
+ epsilon = DFP_EPSILON;
+ FUNC_CONVERT_TO_DN (&epsilon, &dn_epsilon);
+
+ dn_epsilon.exponent += dn_x.digits+dn_x.exponent-1;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+/* if (comparison > 0)*/
+ if (x>y)
+ ___decNumberSubtract (&dn_result,&dn_x,&dn_epsilon,&context);
+ else
+ ___decNumberAdd (&dn_result,&dn_x,&dn_epsilon,&context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+ /* TODO: Handle underflow here */
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/nexttowardd32.c b/libc/dfp/sysdeps/ieee754r/d32/nexttowardd32.c
new file mode 100644
index 000000000..53f8a1ffe
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/nexttowardd32.c
@@ -0,0 +1,100 @@
+/* Returns the next representable neighbor of x in the direction of y
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+/* Always include this since we need a _Decimal128 converted to a decNumber */
+# include <decimal128.h>
+# include <dfptypeconv128.h>
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+#include <float.h>
+
+#define FUNCTION_NAME nexttoward
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, _Decimal128 y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ DEC_TYPE epsilon;
+ decNumber dn_x;
+ decNumber dn_y;
+ decNumber dn_epsilon;
+/* int comparison; */
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ __DECIMAL_TO_DECNUMBER(&y, &dn_y, 128);
+
+ /* Early exit for nan's */
+ if (___decNumberIsNaN(&dn_x))
+ return x;
+ if (___decNumberIsNaN(&dn_y))
+ return y;
+
+ /*comparison = ___decCompare(&dn_x, &dn_y); */
+ /* Early exit for equal values */
+ /*if (comparison == 0) */
+ if (x==y)
+ return x;
+
+ epsilon = DFP_EPSILON;
+ FUNC_CONVERT_TO_DN(&epsilon, &dn_epsilon);
+
+ dn_epsilon.exponent += dn_x.digits+dn_x.exponent-1;
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ /*if (comparison > 0)*/
+ if (x>y)
+ ___decNumberSubtract(&dn_result,&dn_x,&dn_epsilon,&context);
+ else
+ ___decNumberAdd(&dn_result,&dn_x,&dn_epsilon,&context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, _Decimal128 y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+ /* TODO: Handle underflow */
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/powd32.c b/libc/dfp/sysdeps/ieee754r/d32/powd32.c
new file mode 100644
index 000000000..879646224
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/powd32.c
@@ -0,0 +1,188 @@
+/* Calculate x^y, where x and y are _Decimal32 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* Chart of special cases (~ means the normal pow calculation)
+ PoleEr = Pole Error (returns +-Inf),
+ DomErr = Domain Error (returns NaN): only if non-int
+
+x y-> -Inf -oddInt - +-0 + +oddInt +Inf NAN
+-Inf +0 -0 +0 +1.0 +Inf -Inf +Inf NaN
+(-Inf,-1) +0 ~ DomErr* +1.0 DomErr* ~ +Inf NaN
+-1 +1.0 ~ DomErr* +1.0 DomErr* ~ +1.0 NaN
+(-1,-0) +Inf ~ DomErr* +1.0 DomErr* ~ +1.0 NaN
+-0 +Inf -PoleEr +PoleEr +1.0 +0 -0 +0 NaN
++0 +Inf +PoleEr +PoleEr +1.0 +0 +0 +0 NaN
+(+0,+1) +Inf ~ ~ +1.0 ~ ~ +0 NaN
++1 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0 +1.0
+(+1,+Inf) +0 ~ ~ +1.0 ~ ~ +Inf NaN
++Inf +0 +0 +0 +1.0 +Inf +Inf +Inf NaN
+NAN NaN NaN NaN +1.0 NaN NaN NaN NaN
+*/
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME pow
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ DEC_TYPE absx;
+ decNumber dn_x;
+ decNumber dn_absx;
+ decNumber dn_y;
+ decNumber dn_one;
+ decNumber dn_two;
+ decNumber dn_temp;
+ decNumber dn_temp2;
+ decNumber dn_temp3;
+ int y_is_int;
+ int y_is_oddint=0;
+ int abs_x_vs_1;
+ DEC_TYPE one = DFP_CONSTANT(1.0);
+ DEC_TYPE two = DFP_CONSTANT(2.0);
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&y, &dn_y);
+ FUNC_CONVERT_TO_DN (&one, &dn_one);
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ if (___decNumberIsZero (&dn_y))
+ return one;
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+
+ ___decNumberAbs (&dn_absx, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_absx, &absx, &context);
+ if(absx<one)
+ abs_x_vs_1 = -1;
+ else if (absx==one)
+ abs_x_vs_1 = 0;
+ else
+ abs_x_vs_1 = 1;
+
+/* abs_x_vs_1 = ___decCompare(&dn_absx, &dn_one); */
+ if(abs_x_vs_1 == 0 && !___decNumberIsNegative (&dn_x)) /* If x == +1 */
+ return one;
+ if (___decNumberIsNaN (&dn_y))
+ return y+y;
+
+ /* Detect if y is odd/an integer */
+ ___decNumberToIntegralValue (&dn_temp, &dn_y, &context);
+ ___decNumberSubtract (&dn_temp2, &dn_temp, &dn_y, &context);
+ y_is_int = ___decNumberIsZero (&dn_temp2);
+ if (y_is_int)
+ {
+ FUNC_CONVERT_TO_DN (&two, &dn_two);
+ ___decNumberDivide (&dn_temp, &dn_y, &dn_two, &context);
+ ___decNumberToIntegralValue (&dn_temp2, &dn_temp, &context);
+ ___decNumberSubtract (&dn_temp3, &dn_temp2, &dn_temp, &context);
+ y_is_oddint = !___decNumberIsZero (&dn_temp3);
+ }
+
+ /* Handle all special cases for which x = +-0 */
+ if (___decNumberIsZero (&dn_x))
+ {
+ if(___decNumberIsNegative (&dn_y))
+ {
+ if (___decNumberIsInfinite (&dn_y)) /* +-0^-Inf = +Inf */
+ return -y;
+ /* Pole Error for x = +-0, y < 0 */
+ DFP_EXCEPT (FE_DIVBYZERO);
+ return ___decNumberIsNegative(&dn_x) && y_is_oddint ?
+ -DFP_HUGE_VAL : DFP_HUGE_VAL;
+ }
+ return ___decNumberIsNegative(&dn_x) && y_is_oddint ?
+ -DFP_CONSTANT(0.0) : DFP_CONSTANT(0.0);
+ }
+
+ /* Handle remaining special cases for x = +-Inf or y = +-Inf */
+ if (___decNumberIsInfinite (&dn_x) || ___decNumberIsInfinite (&dn_y))
+ {
+ if (abs_x_vs_1 == 0) /* If (-1)^(+-Inf) */
+ return one;
+ if (abs_x_vs_1 < 0) /* x^(+-Inf), where 0<x<1 */
+ return ___decNumberIsNegative (&dn_y) ? DFP_HUGE_VAL
+ : DFP_CONSTANT(0.0);
+ if (___decNumberIsNegative (&dn_y))
+ result = DFP_CONSTANT(0.0);
+ else
+ result = (DEC_TYPE)DEC_INFINITY;
+ if (y_is_oddint && ___decNumberIsNegative(&dn_x))
+ result = -result;
+ return result;
+ }
+
+ /* Domain Error: x < 0 && y is a finite non-int */
+ if (___decNumberIsNegative (&dn_x) && !y_is_int)
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+
+ ___decNumberPower (&dn_result, &dn_x, &dn_y, &context);
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+ if (context.status & DEC_Underflow)
+ DFP_EXCEPT (FE_UNDERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ /* Pole error: x = 0, y < 0 (non-inf). Set ERANGE in accordance with C99 */
+ if (x == DFP_CONSTANT(0.0) && FUNC_D(__finite)(y) && y < DFP_CONSTANT(0.0))
+ DFP_ERRNO (ERANGE);
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x) && FUNC_D(__finite) (y))
+ {
+ if (__isnan(z)) /* Domain error was triggered, x < 0 and y was not an
+ odd int */
+ DFP_ERRNO (EDOM);
+ else /* Overflow */
+ DFP_ERRNO (ERANGE);
+ }
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/quantized32.c b/libc/dfp/sysdeps/ieee754r/d32/quantized32.c
new file mode 100644
index 000000000..4dcac97c4
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/quantized32.c
@@ -0,0 +1,59 @@
+/* Set the exponent of x to the exp of y, trying to preserve the value of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <fenv.h>
+#include <mapround.h>
+
+#define FUNCTION_NAME quantize
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ context.round = __dn_getround();
+ ___decNumberQuantize(&dn_result, &dn_x, &dn_y, &context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/remainderd32.c b/libc/dfp/sysdeps/ieee754r/d32/remainderd32.c
new file mode 100644
index 000000000..bb047751d
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/remainderd32.c
@@ -0,0 +1,83 @@
+/* Returns the result of x - ((int-round_even)(x/y)) * y
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#define FUNCTION_NAME remainder
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+ decNumber dn_y;
+ decNumber dn_mult;
+ decNumber dn_rounded;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ FUNC_CONVERT_TO_DN (&y, &dn_y);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsNaN (&dn_y))
+ return x+y;
+
+ /* Domain Error: x = +-Inf, or y = +-0 and x is non-NaN */
+ if (___decNumberIsInfinite (&dn_x) || ___decNumberIsZero (&dn_y))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return (x - x) / (x - x);
+ }
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberDivide (&dn_mult, &dn_x, &dn_y, &context);
+ context.round = DEC_ROUND_HALF_EVEN;
+ ___decNumberToIntegralValue (&dn_rounded, &dn_mult, &context);
+ ___decNumberMultiply (&dn_mult, &dn_rounded, &dn_y, &context);
+ ___decNumberSubtract (&dn_result, &dn_x, &dn_mult, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(isinf) (x) || (!FUNC_D(isnan) (x) && y == DFP_CONSTANT(0.0)))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/rintd32.c b/libc/dfp/sysdeps/ieee754r/d32/rintd32.c
new file mode 100644
index 000000000..a5e7701dc
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/rintd32.c
@@ -0,0 +1,31 @@
+/* Rounds to the nearest integer
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#define FUNCTION_NAME rint
+#include <mapround.h>
+#define __ROUND_MODE __dn_getround()
+
+#include "roundd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d32/roundd32.c b/libc/dfp/sysdeps/ieee754r/d32/roundd32.c
new file mode 100644
index 000000000..133d4f50c
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/roundd32.c
@@ -0,0 +1,68 @@
+/* Rounds to the nearest integer value, ignores rounding mode
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <fenv.h>
+
+#ifndef FUNCTION_NAME
+# define FUNCTION_NAME round
+# define __ROUND_MODE DEC_ROUND_HALF_UP
+#endif
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsInfinite (&dn_x) ||
+ ___decNumberIsZero (&dn_x))
+ return x+x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ context.round = __ROUND_MODE;
+ ___decNumberToIntegralValue (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+/* Regarding errno's:
+ * Although they are specified in the relevent specs, Overflow errors cannot
+ * actually occur with dfp types, therefore no errno wrappers are provided */
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/samequantumd32.c b/libc/dfp/sysdeps/ieee754r/d32/samequantumd32.c
new file mode 100644
index 000000000..50dbcaebc
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/samequantumd32.c
@@ -0,0 +1,56 @@
+/* Returns true if x and y have the same exponent
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME samequantum
+
+#include <dfpmacro.h>
+
+_Bool
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x;
+ decNumber dn_y;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) && ___decNumberIsNaN(&dn_y))
+ return true;
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return false;
+ if(___decNumberIsInfinite(&dn_x) && ___decNumberIsInfinite(&dn_y))
+ return true;
+ if(___decNumberIsInfinite(&dn_x) || ___decNumberIsInfinite(&dn_y))
+ return false;
+
+ return (dn_x.exponent + dn_x.digits == dn_y.exponent + dn_y.digits);
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/scalblnd32.c b/libc/dfp/sysdeps/ieee754r/d32/scalblnd32.c
new file mode 100644
index 000000000..11c05a081
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/scalblnd32.c
@@ -0,0 +1,83 @@
+/* Returns x * FLT_RADIX^y without computing the right side directly
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#define FUNCTION_NAME scalbln
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, long y)
+{
+ decContext context;
+ DEC_TYPE result;
+ decNumber dn_x;
+ long long int sum=0LL;
+ uint32_t temp2 = 0;
+ /* Otherwise this may pass a bad residue to decFinalize which can result in
+ * rounding error. */
+ int32_t temp = 0;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+ if (___decNumberIsInfinite (&dn_x) || ___decNumberIsZero (&dn_x) || y==0L)
+ return x;
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ sum = dn_x.exponent + y;
+ if(sum >= 1000000000LL || sum <= -2000000000LL
+ || y >= 1000000000L || y <= -2000000000L)
+ ; /** definite overflow */
+ else
+ dn_x.exponent = sum;
+
+ ___decFinalize(&dn_x, &context, &temp, &temp2);
+
+ FUNC_CONVERT_FROM_DN(&dn_x, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, long y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/scalbnd32.c b/libc/dfp/sysdeps/ieee754r/d32/scalbnd32.c
new file mode 100644
index 000000000..f23a5a5f2
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/scalbnd32.c
@@ -0,0 +1,84 @@
+/* Returns x * FLT_RADIX^y without computing the right side directly
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#define FUNCTION_NAME scalbn
+
+#include <dfpmacro.h>
+
+#include <stdio.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x, int y)
+{
+ decContext context;
+ DEC_TYPE result;
+ decNumber dn_x;
+ long int sum = 0L;
+ uint32_t temp2 = 0;
+ /* Otherwise this may pass a bad residue to decFinalize which can result in
+ * rounding error. */
+ int32_t temp =0;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+ if (___decNumberIsInfinite (&dn_x) || ___decNumberIsZero (&dn_x) || y==0L)
+ return x;
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ sum = dn_x.exponent + y;
+ if(sum >= 1000000000L || sum <= -2000000000LL)
+ ; /** definite overflow */
+ else
+ dn_x.exponent = sum;
+
+ ___decFinalize(&dn_x, &context, &temp, &temp2);
+
+ FUNC_CONVERT_FROM_DN(&dn_x, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x, int y)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x, y);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/signbitd32.c b/libc/dfp/sysdeps/ieee754r/d32/signbitd32.c
new file mode 100644
index 000000000..4f4d8fba0
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/signbitd32.c
@@ -0,0 +1,46 @@
+/* Returns non-zero if _Decimal32 is negative
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME signbit
+
+#include <dfpmacro.h>
+
+int
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+
+ return ___decNumberIsNegative(&dn_x);
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/sind32.c b/libc/dfp/sysdeps/ieee754r/d32/sind32.c
new file mode 100644
index 000000000..9db1b2195
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/sind32.c
@@ -0,0 +1,73 @@
+/* Calculate the sin(x) for a _Decimal32 format x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME sin
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsZero (&dn_x))
+ return x+x;
+ if (___decNumberIsInfinite (&dn_x))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberSin (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (FUNC_D(isinf) (x))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/sinhd32.c b/libc/dfp/sysdeps/ieee754r/d32/sinhd32.c
new file mode 100644
index 000000000..f1e9e70ad
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/sinhd32.c
@@ -0,0 +1,76 @@
+/* Calculate the hyperbolic sin (sinh) for a _Decimal32 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME sinh
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsZero (&dn_x)
+ || ___decNumberIsInfinite (&dn_x) )
+ return x+x;
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberSinh (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if(_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ {
+ DFP_ERRNO (ERANGE);
+ return (z > DFP_CONSTANT(0.0) ? DFP_HUGE_VAL : -DFP_HUGE_VAL );
+ }
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/sqrtd32.c b/libc/dfp/sysdeps/ieee754r/d32/sqrtd32.c
new file mode 100644
index 000000000..7792e9d6c
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/sqrtd32.c
@@ -0,0 +1,79 @@
+/* Returns the square root of a _Decimal32 type argument
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME sqrt
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x))
+ return x+x;
+ if (___decNumberIsZero (&dn_x))
+ return x;
+ if (___decNumberIsNegative (&dn_x))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ if (___decNumberIsInfinite (&dn_x))
+ return x;
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ ___decNumberSquareRoot(&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (x < DFP_CONSTANT(0.0))
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/tand32.c b/libc/dfp/sysdeps/ieee754r/d32/tand32.c
new file mode 100644
index 000000000..a713a9b76
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/tand32.c
@@ -0,0 +1,78 @@
+/* Calculate the tan(x) for _Decimal32 format x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME tan
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsZero (&dn_x))
+ return x+x;
+ if (___decNumberIsInfinite (&dn_x))
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberTan (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ if (context.status & DEC_Overflow)
+ DFP_EXCEPT (FE_OVERFLOW);
+
+ return result;
+}
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (FUNC_D(isinf) (x))
+ DFP_ERRNO (EDOM);
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/tanhd32.c b/libc/dfp/sysdeps/ieee754r/d32/tanhd32.c
new file mode 100644
index 000000000..351c6bab2
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/tanhd32.c
@@ -0,0 +1,60 @@
+/* Calculate the hyperbolic tan (tanh) for a _Decimal32 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#include <decNumberMath.h>
+
+#define FUNCTION_NAME tanh
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN (&x, &dn_x);
+ if (___decNumberIsNaN (&dn_x) || ___decNumberIsZero (&dn_x))
+ return x+x;
+ if (___decNumberIsInfinite (&dn_x))
+ return ___decNumberIsNegative (&dn_x) ? DFP_CONSTANT(-1.0)
+ : DFP_CONSTANT(1.0);
+
+ ___decContextDefault (&context, DEFAULT_CONTEXT);
+ ___decNumberTanh (&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/tgammad32.c b/libc/dfp/sysdeps/ieee754r/d32/tgammad32.c
new file mode 100644
index 000000000..3e723d298
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/tgammad32.c
@@ -0,0 +1,80 @@
+/* Returns the result of integral[0->inf, t**(x-1) * e**(-t) dt]
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+#include <errno.h>
+
+#define FUNCTION_NAME tgamma
+
+#include <dfpmacro.h>
+
+extern DEC_TYPE
+FUNC_D (__lgamma_r) (DEC_TYPE, int *);
+extern int
+FUNC_D (__builtin_signbit) (DEC_TYPE);
+
+
+DEC_TYPE
+IEEE_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE result, gamma;
+ int local_signgam;
+
+ if (x == DFP_CONSTANT(0.0)) /* Pole error if x== +-0 */
+ {
+ DFP_EXCEPT (FE_DIVBYZERO);
+ return FUNC_D (__builtin_signbit) (x) ? -DFP_HUGE_VAL : DFP_HUGE_VAL;
+ }
+ if (x < DFP_CONSTANT(0.0) && (!FUNC_D (isinf) (x) && FUNC_D (rint) (x) == x) )
+ {
+ DFP_EXCEPT (FE_INVALID);
+ return DFP_NAN;
+ }
+
+ gamma = FUNC_D(__lgamma_r) (x,&local_signgam);
+ result = local_signgam * FUNC_D(exp) (gamma);
+
+ return result;
+}
+
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE z = IEEE_FUNCTION_NAME (x);
+#ifndef _IEEE_LIBDFP
+ if (_LIB_VERSION == _IEEE_) return z;
+ if (!FUNC_D(__finite) (z) && FUNC_D(__finite) (x))
+ DFP_ERRNO (ERANGE);
+ if (x < DFP_CONSTANT(0.0) && (FUNC_D (isinf) (x) && FUNC_D (rint) (x) == x) )
+ DFP_ERRNO (EDOM);
+#endif
+ return z;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d32/truncd32.c b/libc/dfp/sysdeps/ieee754r/d32/truncd32.c
new file mode 100644
index 000000000..eb49df96e
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d32/truncd32.c
@@ -0,0 +1,55 @@
+/* Round a _Decimal32 type to the nearest but <= argument
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECIMAL_SIZE
+# define _DECIMAL_SIZE 32
+ /* needed to pick up DECNUMDIGITS before including decNumber.h */
+# include <decimal32.h>
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME trunc
+
+#include <dfpmacro.h>
+
+DEC_TYPE
+INTERNAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ decContext context;
+ decNumber dn_result;
+ DEC_TYPE result;
+ decNumber dn_x;
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+ context.round = DEC_ROUND_DOWN;
+ ___decNumberToIntegralValue(&dn_result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
+
+ return result;
+}
+
+weak_alias (INTERNAL_FUNCTION_NAME, EXTERNAL_FUNCTION_NAME)
diff --git a/libc/dfp/sysdeps/ieee754r/d64/acosd64.c b/libc/dfp/sysdeps/ieee754r/d64/acosd64.c
new file mode 100644
index 000000000..aa8f80669
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/acosd64.c
@@ -0,0 +1,25 @@
+/* Calculates the arccos(x)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/acosd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/acoshd64.c b/libc/dfp/sysdeps/ieee754r/d64/acoshd64.c
new file mode 100644
index 000000000..18d204db7
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/acoshd64.c
@@ -0,0 +1,25 @@
+/* Calculates the arc that has the given tangent for a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/acoshd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/asind64.c b/libc/dfp/sysdeps/ieee754r/d64/asind64.c
new file mode 100644
index 000000000..f5d94b0b4
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/asind64.c
@@ -0,0 +1,25 @@
+/* Calculates the arccos(x)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/asind32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/asinhd64.c b/libc/dfp/sysdeps/ieee754r/d64/asinhd64.c
new file mode 100644
index 000000000..cce5ee498
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/asinhd64.c
@@ -0,0 +1,25 @@
+/* Calculates <description goes here> for a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/asinhd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/atan2d64.c b/libc/dfp/sysdeps/ieee754r/d64/atan2d64.c
new file mode 100644
index 000000000..91d48040f
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/atan2d64.c
@@ -0,0 +1,25 @@
+/* Calculates the arc that has the given tangent for a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/atan2d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/atand64.c b/libc/dfp/sysdeps/ieee754r/d64/atand64.c
new file mode 100644
index 000000000..c429a9c77
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/atand64.c
@@ -0,0 +1,25 @@
+/* Calculates the arc that has the given tangent for a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/atand32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/atanhd64.c b/libc/dfp/sysdeps/ieee754r/d64/atanhd64.c
new file mode 100644
index 000000000..05b3a3944
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/atanhd64.c
@@ -0,0 +1,25 @@
+/* Calculates the hyperbolic arc tangent (atanh) for a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/atanhd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/cbrtd64.c b/libc/dfp/sysdeps/ieee754r/d64/cbrtd64.c
new file mode 100644
index 000000000..0b046cf02
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/cbrtd64.c
@@ -0,0 +1,25 @@
+/* Calculates the cube root function of _Decimal64 type x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/cbrtd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/ceild64.c b/libc/dfp/sysdeps/ieee754r/d64/ceild64.c
new file mode 100644
index 000000000..7aeaae598
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/ceild64.c
@@ -0,0 +1,25 @@
+/* Ceiling function for _Decimal64 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/ceild32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/copysignd64.c b/libc/dfp/sysdeps/ieee754r/d64/copysignd64.c
new file mode 100644
index 000000000..c30baacee
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/copysignd64.c
@@ -0,0 +1,25 @@
+/* Copies the sign from the second argument to the first
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/copysignd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/cosd64.c b/libc/dfp/sysdeps/ieee754r/d64/cosd64.c
new file mode 100644
index 000000000..45317710d
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/cosd64.c
@@ -0,0 +1,25 @@
+/* Calculate the cos(x) for a _Decimal64 format x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/cosd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/coshd64.c b/libc/dfp/sysdeps/ieee754r/d64/coshd64.c
new file mode 100644
index 000000000..7b0e26a88
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/coshd64.c
@@ -0,0 +1,25 @@
+/* Calculate the hyperbolic cos (cosh) for _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/coshd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/erfd64.c b/libc/dfp/sysdeps/ieee754r/d64/erfd64.c
new file mode 100644
index 000000000..f18647182
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/erfd64.c
@@ -0,0 +1,25 @@
+/* Returns the error function of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/erfd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/exp2d64.c b/libc/dfp/sysdeps/ieee754r/d64/exp2d64.c
new file mode 100644
index 000000000..f9255725a
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/exp2d64.c
@@ -0,0 +1,25 @@
+/* Returns the value of 2 raised to the power of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/exp2d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/expd64.c b/libc/dfp/sysdeps/ieee754r/d64/expd64.c
new file mode 100644
index 000000000..4aff01087
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/expd64.c
@@ -0,0 +1,25 @@
+/* Calculate e^x, where x is the given _Decimal64 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/expd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/expm1d64.c b/libc/dfp/sysdeps/ieee754r/d64/expm1d64.c
new file mode 100644
index 000000000..99132f5df
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/expm1d64.c
@@ -0,0 +1,25 @@
+/* Returns a value equivelent to exp(x) - 1
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/expm1d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/fabsd64.c b/libc/dfp/sysdeps/ieee754r/d64/fabsd64.c
new file mode 100644
index 000000000..1b5d7ac82
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/fabsd64.c
@@ -0,0 +1,25 @@
+/* Calculate the absolute value for a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/fabsd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/fdimd64.c b/libc/dfp/sysdeps/ieee754r/d64/fdimd64.c
new file mode 100644
index 000000000..3bf922208
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/fdimd64.c
@@ -0,0 +1,25 @@
+/* Returns the positive difference between the _Decimal64 type arguments
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/fdimd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/finited64.c b/libc/dfp/sysdeps/ieee754r/d64/finited64.c
new file mode 100644
index 000000000..846d147e7
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/finited64.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if the _Decimal64 is non-infinite
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/finited32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/floord64.c b/libc/dfp/sysdeps/ieee754r/d64/floord64.c
new file mode 100644
index 000000000..bbd85cee1
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/floord64.c
@@ -0,0 +1,25 @@
+/* Floor function for _Decimal64 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/floord32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/fmad64.c b/libc/dfp/sysdeps/ieee754r/d64/fmad64.c
new file mode 100644
index 000000000..eb4db8848
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/fmad64.c
@@ -0,0 +1,25 @@
+/* Floating point multiply and add (x * y + z)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/fmad32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/fmaxd64.c b/libc/dfp/sysdeps/ieee754r/d64/fmaxd64.c
new file mode 100644
index 000000000..fa6a56e10
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/fmaxd64.c
@@ -0,0 +1,25 @@
+/* Determine the maximum of two _Decimal64 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/fmaxd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/fmind64.c b/libc/dfp/sysdeps/ieee754r/d64/fmind64.c
new file mode 100644
index 000000000..ffc538b01
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/fmind64.c
@@ -0,0 +1,25 @@
+/* Determine the minimum of two _Decimal64 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/fmind32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/fmodd64.c b/libc/dfp/sysdeps/ieee754r/d64/fmodd64.c
new file mode 100644
index 000000000..184524bd2
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/fmodd64.c
@@ -0,0 +1,25 @@
+/* Returns the remainder of a floating point division
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/fmodd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/fpclassifyd64.c b/libc/dfp/sysdeps/ieee754r/d64/fpclassifyd64.c
new file mode 100644
index 000000000..73357765e
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/fpclassifyd64.c
@@ -0,0 +1,25 @@
+/* Returns the type of floating point number from a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/fpclassifyd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/frexpd64.c b/libc/dfp/sysdeps/ieee754r/d64/frexpd64.c
new file mode 100644
index 000000000..db4c6a23c
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/frexpd64.c
@@ -0,0 +1,25 @@
+/* Break floating point number into normalized fraction and integral power of two
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/frexpd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/hypotd64.c b/libc/dfp/sysdeps/ieee754r/d64/hypotd64.c
new file mode 100644
index 000000000..4caad0223
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/hypotd64.c
@@ -0,0 +1,25 @@
+/* Returns sqrt(x*x+y*y)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/hypotd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/ilogbd64.c b/libc/dfp/sysdeps/ieee754r/d64/ilogbd64.c
new file mode 100644
index 000000000..3f81856f8
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/ilogbd64.c
@@ -0,0 +1,26 @@
+/* Returns the unbiased exponent of the passed _Decimal64 value as an int
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+#define DFP_DEBUG(arg) printf("%Df\n", arg)
+
+#include "../d32/ilogbd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/isgreaterd64.c b/libc/dfp/sysdeps/ieee754r/d64/isgreaterd64.c
new file mode 100644
index 000000000..6a4eed4c1
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/isgreaterd64.c
@@ -0,0 +1,25 @@
+/* Implements > for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/isgreaterd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/isgreaterequald64.c b/libc/dfp/sysdeps/ieee754r/d64/isgreaterequald64.c
new file mode 100644
index 000000000..4138c8988
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/isgreaterequald64.c
@@ -0,0 +1,25 @@
+/* Implements >= for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/isgreaterequald32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/isinfd64.c b/libc/dfp/sysdeps/ieee754r/d64/isinfd64.c
new file mode 100644
index 000000000..f9fd851da
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/isinfd64.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if the _Decimal64 is infinite
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/isinfd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/islessd64.c b/libc/dfp/sysdeps/ieee754r/d64/islessd64.c
new file mode 100644
index 000000000..8bca27e24
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/islessd64.c
@@ -0,0 +1,25 @@
+/* Implements < for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/islessd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/islessequald64.c b/libc/dfp/sysdeps/ieee754r/d64/islessequald64.c
new file mode 100644
index 000000000..47c322a91
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/islessequald64.c
@@ -0,0 +1,25 @@
+/* Implements <= for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/islessequald32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/islessgreaterd64.c b/libc/dfp/sysdeps/ieee754r/d64/islessgreaterd64.c
new file mode 100644
index 000000000..d4bdc7ae8
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/islessgreaterd64.c
@@ -0,0 +1,25 @@
+/* Implements <> for _Decimal
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/islessgreaterd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/isnand64.c b/libc/dfp/sysdeps/ieee754r/d64/isnand64.c
new file mode 100644
index 000000000..928c0694c
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/isnand64.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if the _Decimal64 is nan
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/isnand32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/isnormald64.c b/libc/dfp/sysdeps/ieee754r/d64/isnormald64.c
new file mode 100644
index 000000000..81031c829
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/isnormald64.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if the _Decimal64 is normalized
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/isnormald32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/isunorderedd64.c b/libc/dfp/sysdeps/ieee754r/d64/isunorderedd64.c
new file mode 100644
index 000000000..afd09e7a3
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/isunorderedd64.c
@@ -0,0 +1,25 @@
+/* Returns true if either _Decimal64 is NaN
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/isunorderedd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/ldexpd64.c b/libc/dfp/sysdeps/ieee754r/d64/ldexpd64.c
new file mode 100644
index 000000000..9d2cc77fd
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/ldexpd64.c
@@ -0,0 +1,25 @@
+/* Returns the _Decimal64 value * 2^ the integral value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/ldexpd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/lgammad64.c b/libc/dfp/sysdeps/ieee754r/d64/lgammad64.c
new file mode 100644
index 000000000..bca874612
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/lgammad64.c
@@ -0,0 +1,25 @@
+/* Returns the natural logarithm of the absolute value of the Gamma function of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/lgammad32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/llrintd64.c b/libc/dfp/sysdeps/ieee754r/d64/llrintd64.c
new file mode 100644
index 000000000..f0608ce4d
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/llrintd64.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest (long long int) integer
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/llrintd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/llroundd64.c b/libc/dfp/sysdeps/ieee754r/d64/llroundd64.c
new file mode 100644
index 000000000..737dbfde9
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/llroundd64.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest long long int value, ignoring rounding mode
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/llroundd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/log10d64.c b/libc/dfp/sysdeps/ieee754r/d64/log10d64.c
new file mode 100644
index 000000000..15dbada85
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/log10d64.c
@@ -0,0 +1,25 @@
+/* Calculate the Log (base 10) of a given _Decimal64 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/log10d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/log1pd64.c b/libc/dfp/sysdeps/ieee754r/d64/log1pd64.c
new file mode 100644
index 000000000..2a98b09b9
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/log1pd64.c
@@ -0,0 +1,25 @@
+/* Calculate the Natural Log of a given a _Decimal64 value + 1
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/log1pd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/log2d64.c b/libc/dfp/sysdeps/ieee754r/d64/log2d64.c
new file mode 100644
index 000000000..da75c69a3
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/log2d64.c
@@ -0,0 +1,25 @@
+/* Returns the base 2 logarithmic function of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/log2d32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/logbd64.c b/libc/dfp/sysdeps/ieee754r/d64/logbd64.c
new file mode 100644
index 000000000..a468d9525
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/logbd64.c
@@ -0,0 +1,25 @@
+/* Returns the unbiased exponent of the passed _Decimal64 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/logbd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/logd64.c b/libc/dfp/sysdeps/ieee754r/d64/logd64.c
new file mode 100644
index 000000000..84ecb337f
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/logd64.c
@@ -0,0 +1,25 @@
+/* Calculate the Natural Log of a given a _Decimal64 value
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/logd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/lrintd64.c b/libc/dfp/sysdeps/ieee754r/d64/lrintd64.c
new file mode 100644
index 000000000..4eb8f10e2
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/lrintd64.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest (long int) integer
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/lrintd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/lroundd64.c b/libc/dfp/sysdeps/ieee754r/d64/lroundd64.c
new file mode 100644
index 000000000..e510fb095
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/lroundd64.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest long int value, ignoring rounding mode.
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/lroundd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/modfd64.c b/libc/dfp/sysdeps/ieee754r/d64/modfd64.c
new file mode 100644
index 000000000..0063bcd65
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/modfd64.c
@@ -0,0 +1,25 @@
+/* Breaks the argument into integral and fractional parts for a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/modfd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/nand64.c b/libc/dfp/sysdeps/ieee754r/d64/nand64.c
new file mode 100644
index 000000000..5ab8b3a5d
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/nand64.c
@@ -0,0 +1,25 @@
+/* Returns a reprentation of NaN in the _Decimal64 format
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/nand32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/nearbyintd64.c b/libc/dfp/sysdeps/ieee754r/d64/nearbyintd64.c
new file mode 100644
index 000000000..9c5a3f477
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/nearbyintd64.c
@@ -0,0 +1,26 @@
+/* Round to nearest integer _Decimal64 form
+
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+#include "../d32/nearbyintd32.c"
+
diff --git a/libc/dfp/sysdeps/ieee754r/d64/nextafterd64.c b/libc/dfp/sysdeps/ieee754r/d64/nextafterd64.c
new file mode 100644
index 000000000..35e636122
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/nextafterd64.c
@@ -0,0 +1,25 @@
+/* Returns the next representable neighbor of x in the direction of y
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/nextafterd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/nexttowardd64.c b/libc/dfp/sysdeps/ieee754r/d64/nexttowardd64.c
new file mode 100644
index 000000000..9f2b61300
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/nexttowardd64.c
@@ -0,0 +1,29 @@
+/* Returns the next representable neighbor of x in the direction of y
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+
+/* Always include this since we need a _Decimal128 converted to a decNumber */
+#include <decimal128.h>
+#include <dfptypeconv128.h>
+#include <decimal64.h>
+
+#include "../d32/nexttowardd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/powd64.c b/libc/dfp/sysdeps/ieee754r/d64/powd64.c
new file mode 100644
index 000000000..0c1dd8e67
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/powd64.c
@@ -0,0 +1,25 @@
+/* Calculate x^y, where x and y are _Decimal64 types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/powd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/quantized64.c b/libc/dfp/sysdeps/ieee754r/d64/quantized64.c
new file mode 100644
index 000000000..fde5c96de
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/quantized64.c
@@ -0,0 +1,25 @@
+/* Set the exponent of x to the exp of y, trying to preserve the value of x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/quantized32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/remainderd64.c b/libc/dfp/sysdeps/ieee754r/d64/remainderd64.c
new file mode 100644
index 000000000..664c8bace
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/remainderd64.c
@@ -0,0 +1,25 @@
+/* Returns the result of x - ((int-round_even)(x/y)) * y
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/remainderd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/rintd64.c b/libc/dfp/sysdeps/ieee754r/d64/rintd64.c
new file mode 100644
index 000000000..7a931e382
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/rintd64.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest integer
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/rintd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/roundd64.c b/libc/dfp/sysdeps/ieee754r/d64/roundd64.c
new file mode 100644
index 000000000..5dad0a95b
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/roundd64.c
@@ -0,0 +1,25 @@
+/* Rounds to the nearest integer value, ignores rounding mode
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/roundd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/samequantumd64.c b/libc/dfp/sysdeps/ieee754r/d64/samequantumd64.c
new file mode 100644
index 000000000..a9e696908
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/samequantumd64.c
@@ -0,0 +1,25 @@
+/* Returns true if x and y have the same exponent
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/samequantumd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/scalblnd64.c b/libc/dfp/sysdeps/ieee754r/d64/scalblnd64.c
new file mode 100644
index 000000000..27e6d4421
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/scalblnd64.c
@@ -0,0 +1,25 @@
+/* Returns x * FLT_RADIX^y without computing the right side directly
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/scalblnd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/scalbnd64.c b/libc/dfp/sysdeps/ieee754r/d64/scalbnd64.c
new file mode 100644
index 000000000..c25041808
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/scalbnd64.c
@@ -0,0 +1,25 @@
+/* Returns x * FLT_RADIX^y without computing the right side directly
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/scalbnd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/signbitd64.c b/libc/dfp/sysdeps/ieee754r/d64/signbitd64.c
new file mode 100644
index 000000000..cca2f7272
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/signbitd64.c
@@ -0,0 +1,25 @@
+/* Returns non-zero if _Decimal64 is negative
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/signbitd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/sind64.c b/libc/dfp/sysdeps/ieee754r/d64/sind64.c
new file mode 100644
index 000000000..51eea4214
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/sind64.c
@@ -0,0 +1,25 @@
+/* Calculate the sin(x) for a _Decimal64 format x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/sind32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/sinhd64.c b/libc/dfp/sysdeps/ieee754r/d64/sinhd64.c
new file mode 100644
index 000000000..374586111
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/sinhd64.c
@@ -0,0 +1,25 @@
+/* Calculate the hyperbolic sin (sinh) for a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/sinhd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/sqrtd64.c b/libc/dfp/sysdeps/ieee754r/d64/sqrtd64.c
new file mode 100644
index 000000000..9f7d1686f
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/sqrtd64.c
@@ -0,0 +1,25 @@
+/* Returns the square root of a _Decimal64 type argument
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/sqrtd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/tand64.c b/libc/dfp/sysdeps/ieee754r/d64/tand64.c
new file mode 100644
index 000000000..75a3235d6
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/tand64.c
@@ -0,0 +1,25 @@
+/* Calculate the tan(x) for _Decimal64 format x
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/tand32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/tanhd64.c b/libc/dfp/sysdeps/ieee754r/d64/tanhd64.c
new file mode 100644
index 000000000..337421aaf
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/tanhd64.c
@@ -0,0 +1,25 @@
+/* Calculate the hyperbolic tan (tanh) for a _Decimal64 type
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/tanhd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/tgammad64.c b/libc/dfp/sysdeps/ieee754r/d64/tgammad64.c
new file mode 100644
index 000000000..cc66db72c
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/tgammad64.c
@@ -0,0 +1,25 @@
+/* Returns the result of integral[0->inf, t**(x-1) * e**(-t) dt]
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/tgammad32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/d64/truncd64.c b/libc/dfp/sysdeps/ieee754r/d64/truncd64.c
new file mode 100644
index 000000000..f874d3c3d
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/d64/truncd64.c
@@ -0,0 +1,25 @@
+/* Round a _Decimal64 type to the nearest but <= argument
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joseph Kerian <jkerian@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define _DECIMAL_SIZE 64
+#include <decimal64.h>
+
+#include "../d32/truncd32.c"
diff --git a/libc/dfp/sysdeps/ieee754r/dfpmacro.h b/libc/dfp/sysdeps/ieee754r/dfpmacro.h
new file mode 100644
index 000000000..19a782598
--- /dev/null
+++ b/libc/dfp/sysdeps/ieee754r/dfpmacro.h
@@ -0,0 +1,149 @@
+/* Macros that are used as a set of wrappers for function utilities
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ Contributed by Joseph Kerian <jkerian@us.ibm.com>
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* When this file is #include'd, _DECIMAL_SIZE and FUNCTION_NAME
+ * _DECIMAL_SIZE : 32, 64, 128 - Used for type definition
+ * FUNCTION_NAME : fabs, ceil - Does not include _DECIMAL_SIZE suffix
+ * should already be #define'd */
+
+/* There is a subtle bug that can occur if headers are not included in the
+ * right order in d32's *.c files. The order needs to be:
+ * #include <decimalX.h>
+ * #include <decNumber.h> + decContext.h + decWhatever.h
+ * #include "dfpmacro.h"
+ *
+ * The reason for this is that decNumber sets some type dependent sizes
+ * according to values set in decimalX.h. dfptypeconv.h (included below)
+ * includes all three of the decimalX.h headers
+ */
+
+/* Necessary to pull in inlined feraiseexcept */
+#ifndef __OPTIMIZE__
+# define __OPTIMIZE__ 1
+#endif
+#include <fenv.h>
+
+#if !defined( _DECIMAL_SIZE ) || !defined (FUNCTION_NAME)
+#error Including dfpmacro without defining _DECIMAL_SIZE and FUNCTION_NAME is invalid
+#endif
+
+#if _DECIMAL_SIZE == 128
+ #include <dfptypeconv128.h>
+#elif _DECIMAL_SIZE == 64
+ #include <dfptypeconv64.h>
+#else
+ #include <dfptypeconv32.h>
+#endif
+
+/* If _IEEE_LIBDFP is defined, errno will not be set when errors occur in
+ * math functions */
+#ifdef _IEEE_LIBM
+# define _IEEE_LIBDFP
+#endif
+
+/* Data type to use for the generic function implementations */
+#define DEC_TYPE PASTE(_Decimal,_DECIMAL_SIZE)
+
+/* Use these "functions" for variable preperation */
+/* They use functions provided in decimal32/64/128.c and dfptypeconv.c */
+#define FUNC_CONVERT_TO_DN(dec,dn) \
+ __DECIMAL_TO_DECNUMBER(dec,dn,_DECIMAL_SIZE)
+
+#define __DECIMAL_TO_DECNUMBER(dec,dn,SIZE) \
+do { \
+ PASTE(decimal,SIZE) decimal; \
+ PASTE(___host_to_ieee_,SIZE) ((dec), &decimal); \
+ PASTE(PASTE(___decimal,SIZE),ToNumber) (&decimal,(dn)); \
+}while (0)
+
+#define FUNC_CONVERT_FROM_DN(dn,dec,context) \
+do { \
+ PASTE(decimal,_DECIMAL_SIZE) decimal; \
+ PASTE(PASTE(___decimal,_DECIMAL_SIZE),FromNumber) \
+ (&decimal, (dn), (context)); \
+ PASTE(PASTE(___ieee_,_DECIMAL_SIZE),_to_host) (&decimal, (dec));\
+}while(0)
+
+#define IEEE_DECIMAL_TO_STRING(host, str) \
+do { \
+ PASTE(decimal, _DECIMAL_SIZE) decimal; \
+ PASTE(___host_to_ieee_,_DECIMAL_SIZE)(host, &decimal); \
+ PASTE(___decimal, PASTE(_DECIMAL_SIZE,ToString)) \
+ (&decimal, str); \
+}while(0)
+
+#define IEEE_DECIMAL_TO_ENG_STRING(host, str) \
+do { \
+ PASTE(decimal, _DECIMAL_SIZE) decimal; \
+ PASTE(___host_to_ieee_,_DECIMAL_SIZE)(host, &decimal); \
+ PASTE(___decimal, PASTE(_DECIMAL_SIZE,ToEngString)) \
+ (&decimal, str); \
+}while(0)
+
+#define DEFAULT_CONTEXT PASTE(DEC_INIT_DECIMAL,_DECIMAL_SIZE)
+
+/* Use this as function internal and external names */
+#define EXTERNAL_FUNCTION_NAME FUNC_D(FUNCTION_NAME)
+#define INTERNAL_FUNCTION_NAME PASTE(__,EXTERNAL_FUNCTION_NAME)
+/* For functions that have both errno wrappers and exception throwing
+ * implementations, this version is the exception throwing version, while
+ * the INTERNAL_FUNCTION_NAME will be the errno wrapper */
+#define IEEE_FUNCTION_NAME PASTE(__ieee743r_,EXTERNAL_FUNCTION_NAME)
+
+/* Use this if you need to refer to the type appropriate function
+ * elswhere. For example FUNC_D (fabs) (x) may be needed in asin
+ * FUNC_D(fabs) (x) will resolve to fabsd32 (x) in the 32 bit version */
+#define FUNC_D(x) PASTE(x,PASTE(d,_DECIMAL_SIZE))
+
+
+/* These can simply be called, and will check if it's appropriate
+ * to throw the exception/errno before doing so */
+/* If the compiler/glibc supports math_errhandling, we'll use it
+ * in the future */
+#define DFP_MATH_ERRHANDLING MATH_ERREXCEPT
+
+#define DFP_ERRNO(the_errno) __set_errno(the_errno)
+#define DFP_EXCEPT(the_exception) \
+ do { \
+ if((DFP_MATH_ERRHANDLING & MATH_ERREXCEPT) > 0) \
+ feraiseexcept( (the_exception) ); \
+ } while(0)
+
+
+/* Useful for generating constants */
+#if _DECIMAL_SIZE == 32
+#define DEC_SUFFIX DF
+#elif _DECIMAL_SIZE == 64
+#define DEC_SUFFIX DD
+#elif _DECIMAL_SIZE == 128
+#define DEC_SUFFIX DL
+#endif
+#define DFP_CONSTANT(x) PASTE(x,DEC_SUFFIX)
+#define DFP_MIN PASTE(DEC,PASTE(_DECIMAL_SIZE,_MIN))
+#define DFP_EPSILON PASTE(DEC,PASTE(_DECIMAL_SIZE,_EPSILON))
+/* Some useful (falsely generic) constants */
+#define DFP_HUGE_VAL PASTE(HUGE_VAL_D,_DECIMAL_SIZE)
+#define DFP_NAN (DEC_TYPE)DEC_NAN
+
+/* Ideally these shouldn't need to be used elsewhere outside of this file */
+#define PASTE(x,y) PASTE2(x,y)
+#define PASTE2(x,y) x##y
+
+
diff --git a/libc/dfp/sysdeps/powerpc/decode-decimal.c b/libc/dfp/sysdeps/powerpc/decode-decimal.c
new file mode 100644
index 000000000..1a0607f44
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/decode-decimal.c
@@ -0,0 +1,215 @@
+/* Functions to print the DPD declets for use with printf %Z
+ Copyright (C) 2006, 2007 IBM Corporation.
+
+ Author(s): Steve Munroe <sjmunroe@us.ibm.com>
+ Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#include <float.h>
+#include <math.h>
+#include <fenv.h>
+#include <string.h>
+
+#include <decode-decimal.h>
+#include "dpd-private.h"
+
+#undef DEBUG_PRINT
+#define DEBUG_PRINT 0
+char * __decoded32 (_Decimal32 a, char * str)
+{
+ union ieee754r_Decimal32 d;
+ struct ieee754r_c_field c_f;
+ int exp;
+ char sign;
+ char lmd;
+ const char *cc0;
+ const char *cc1;
+ char * after_exp = NULL;
+
+ d.sd = a;
+ if (d.ieee.negative)
+ sign = '-';
+ else
+ sign = '+';
+
+ c_f = c_decoder[d.ieee.c];
+ exp = c_f.lm_exp << DECIMAL32_BEC_bits;
+ exp += d.ieee.bec;
+ exp -= DECIMAL32_Bias;
+ lmd = '0' + c_f.lmd;
+
+ cc0 = &dpd_to_char[d.ieee.cc0][0];
+ cc1 = &dpd_to_char[d.ieee.cc1][0];
+
+ str[0] = sign;
+ str[1] = lmd;
+ str[2] = ',';
+ __dfp_cpydeclet(&str[3], cc0);
+ str[6] = ',';
+ __dfp_cpydeclet(&str[7], cc1);
+ str[10] = 'E';
+ after_exp = __dfp_exptostr(&str[11], exp);
+ if (after_exp != NULL)
+ *after_exp = '\0';
+
+ return str;
+}
+#if defined NOT_IN_libc
+ weak_alias (__decoded32, decoded32)
+#endif
+libc_hidden_def(__decoded32)
+
+char * __decoded64 ( _Decimal64 a, char * str )
+{
+ union ieee754r_Decimal64 d;
+ struct ieee754r_c_field c_f;
+ int exp, i;
+ char sign;
+ char lmd;
+ const char *cc0;
+ const char *cc1;
+ const char *cc2;
+ const char *cc3;
+ const char *cc4;
+ char * after_exp = NULL;
+
+ d.dd = a;
+ if (d.ieee.negative)
+ sign = '-';
+ else
+ sign = '+';
+
+ c_f = c_decoder[d.ieee.c];
+ exp = c_f.lm_exp << DECIMAL64_BEC_bits;
+ exp += d.ieee.bec;
+ exp -= DECIMAL64_Bias;
+ lmd = '0' + c_f.lmd;
+
+ cc0 = &dpd_to_char[d.ieee.cc0][0];
+ /* Packed fields crossing a word boundary require special handling. */
+ i = d.ieee.cc1H8 << 2;
+ i = i + d.ieee.cc1L2;
+ cc1 = &dpd_to_char[i][0];
+ cc2 = &dpd_to_char[d.ieee.cc2][0];
+ cc3 = &dpd_to_char[d.ieee.cc3][0];
+ cc4 = &dpd_to_char[d.ieee.cc4][0];
+
+ str[0] = sign;
+ str[1] = lmd;
+ str[2] = ',';
+ __dfp_cpydeclet(&str[3], cc0);
+ str[6] = ',';
+ __dfp_cpydeclet(&str[7], cc1);
+ str[10] = ',';
+ __dfp_cpydeclet(&str[11], cc2);
+ str[14] = ',';
+ __dfp_cpydeclet(&str[15], cc3);
+ str[18] = ',';
+ __dfp_cpydeclet(&str[19], cc4);
+ str[22] = 'E';
+ after_exp = __dfp_exptostr(&str[23], exp);
+ if (after_exp != NULL)
+ *after_exp = '\0';
+
+ return str;
+}
+#if defined NOT_IN_libc
+ weak_alias (__decoded64, decoded64)
+#endif
+libc_hidden_def(__decoded64)
+
+char * __decoded128 ( _Decimal128 a, char * str )
+{
+ union ieee754r_Decimal128 d;
+ struct ieee754r_c_field c_f;
+ int exp;/*, i; */
+ char sign;
+ char lmd;
+ const char *cc0;
+ const char *cc1;
+ const char *cc2;
+ const char *cc3;
+ const char *cc4;
+ const char *cc5;
+ const char *cc6;
+ const char *cc7;
+ const char *cc8;
+ const char *cc9;
+ const char *cc10;
+ char * after_exp = NULL;
+
+ d.td = a;
+ if (d.ieee.negative)
+ sign = '-';
+ else
+ sign = '+';
+
+ c_f = c_decoder[d.ieee.c];
+ exp = c_f.lm_exp << DECIMAL128_BEC_bits;
+ exp += d.ieee.bec;
+ exp -= DECIMAL128_Bias;
+ lmd = '0' + c_f.lmd;
+
+ cc0 = &dpd_to_char[d.ieee.cc0][0];
+ /* Packed fields crossing a word boundary require special handling. */
+ cc1 = &dpd_to_char[((d.ieee.cc1H4<<6) + d.ieee.cc1L6)][0];
+ cc2 = &dpd_to_char[d.ieee.cc2][0];
+ cc3 = &dpd_to_char[d.ieee.cc3][0];
+ cc4 = &dpd_to_char[((d.ieee.cc4H6<<4) + d.ieee.cc4L4)][0];
+ cc5 = &dpd_to_char[d.ieee.cc5][0];
+ cc6 = &dpd_to_char[d.ieee.cc6][0];
+ cc7 = &dpd_to_char[((d.ieee.cc7H8<<2) + d.ieee.cc7L2)][0];
+ cc8 = &dpd_to_char[d.ieee.cc8][0];
+ cc9 = &dpd_to_char[d.ieee.cc9][0];
+ cc10 = &dpd_to_char[d.ieee.cc10][0];
+
+ str[0] = sign;
+ str[1] = lmd;
+ str[2] = ',';
+ __dfp_cpydeclet(&str[3], cc0);
+ str[6] = ',';
+ __dfp_cpydeclet(&str[7], cc1);
+ str[10] = ',';
+ __dfp_cpydeclet(&str[11], cc2);
+ str[14] = ',';
+ __dfp_cpydeclet(&str[15], cc3);
+ str[18] = ',';
+ __dfp_cpydeclet(&str[19], cc4);
+ str[22] = ',';
+ __dfp_cpydeclet(&str[23], cc5);
+ str[26] = ',';
+ __dfp_cpydeclet(&str[27], cc6);
+ str[30] = ',';
+ __dfp_cpydeclet(&str[31], cc7);
+ str[34] = ',';
+ __dfp_cpydeclet(&str[35], cc8);
+ str[38] = ',';
+ __dfp_cpydeclet(&str[39], cc9);
+ str[42] = ',';
+ __dfp_cpydeclet(&str[43], cc10);
+ str[46] = 'E';
+ after_exp = __dfp_exptostr(&str[47], exp);
+ if (after_exp != NULL)
+ *after_exp = '\0';
+
+ return str;
+}
+#if defined NOT_IN_libc
+ weak_alias (__decoded128, decoded128)
+#endif
+libc_hidden_def(__decoded128)
diff --git a/libc/dfp/sysdeps/powerpc/dfpu/decroundtls.c b/libc/dfp/sysdeps/powerpc/dfpu/decroundtls.c
new file mode 100644
index 000000000..e33baa88c
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/dfpu/decroundtls.c
@@ -0,0 +1,25 @@
+/* Decimal Float Rounding Mode placeholder file for Power6[x].
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#include <decroundtls.h>
+
+/* Empty file to satisfy dfp/Makefile when building Power6[x] which stores the
+ * decimal rounding mode in the extended FPSCR. */
diff --git a/libc/dfp/sysdeps/powerpc/dfpu/decroundtls.h b/libc/dfp/sysdeps/powerpc/dfpu/decroundtls.h
new file mode 100644
index 000000000..e9c41f4cc
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/dfpu/decroundtls.h
@@ -0,0 +1,27 @@
+/* Decimal Float Rounding Mode accessor function prototype
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DECROUNDTLS_
+#define _DECROUNDTLS_
+/* No-op on power6[x], which have the decimal rounding mode in the extended
+ * FPSCR. */
+#define __decrm_location
+#endif /* _DECROUNDTLS_ */
diff --git a/libc/dfp/sysdeps/powerpc/dfpu/fe_decround.c b/libc/dfp/sysdeps/powerpc/dfpu/fe_decround.c
new file mode 100644
index 000000000..1a0467fab
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/dfpu/fe_decround.c
@@ -0,0 +1,124 @@
+/* Decimal Float fe_dec_getround and fe_dec_setround definitions.
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+ Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#include <bits/libc-tsd.h>
+#include <fenv.h>
+#include <dfpfenv_private.h>
+
+int __fe_dec_setround(int rounding_direction)
+{
+ /* The rounding modes are as follows:
+ *
+ * C Rounding Mode: (DRN) Hardware Description
+ * DecNumber Rounding Mode Equivalent
+ *
+ * FE_DEC_TONEAREST: (000) Round to nearest, ties to even.
+ * DEC_ROUND_HALF_EVEN
+ *
+ * FE_DEC_TOWARDZERO: (001) Round toward zero.
+ * DEC_ROUND_DOWN
+ *
+ * FE_DEC_UPWARD: (010) Round toward +Infinity
+ * DEC_ROUND_CEILING
+ *
+ * FE_DEC_DOWNWARD: (011) Round toward -Infinity
+ * DEC_ROUND_FLOOR
+ *
+ * FE_DEC_TONEARESTFROMZERO: (100) Round to nearest, ties away from zero
+ * DEC_ROUND_HALF_UP
+ *
+ * 5: (101) Round to nearest, ties toward zero
+ * DEC_ROUND_HALF_DOWN
+ *
+ * 6: (110) Round away from zero
+ * DEC_ROUND_UP
+ *
+ * 7: (111) Round for prepare for shorter precision
+ * Not supported by decNumber. */
+
+ /* High order bits 29-31 contain DFP Rounding control (DRN) and bit 28 is
+ * reserved for future rounding control. The new Power6[x] form of the mtfsfi
+ * instruction can be used against these four bits to set the rounding mode.
+ * Then new form of the mtfsfi instruction for Power6[x] adds the 'W' parameter:
+
+ mtfsfi BF,U,W
+ BF: Field [0-7: Bits 28-31 are field 7 of the high order word]
+ U: Bit Pattern [Bit 28 is reserved, use 0000-0111]
+ W: Word [Implicit '0' for bits 32:63 {low order word.}]
+ ['1' indicates the bits 0:31 {high order word}.] */
+
+ switch(rounding_direction)
+ {
+ case FE_DEC_TONEAREST:
+ asm ("mtfsfi 7, 0, 1\n");
+ break;
+ case FE_DEC_TOWARDZERO:
+ asm ("mtfsfi 7, 1, 1\n");
+ break;
+ case FE_DEC_UPWARD:
+ asm ("mtfsfi 7, 2, 1\n");
+ break;
+ case FE_DEC_DOWNWARD:
+ asm ("mtfsfi 7, 3, 1\n");
+ break;
+ case FE_DEC_TONEARESTFROMZERO:
+ asm ("mtfsfi 7, 4, 1\n");
+ break;
+ case 5: /* Allow covert setting of this rounding mode. */
+ asm ("mtfsfi 7, 5, 1\n");
+ break;
+ case 6: /* Allow covert setting of this rounding mode. */
+ asm ("mtfsfi 7, 6, 1\n");
+ break;
+ case 7: /* Allow covert setting of this rounding mode. */
+ asm ("mtfsfi 7, 7, 1\n");
+ break;
+ default:
+ return 1;
+ }
+ return 0;
+}
+strong_alias(__fe_dec_setround, fe_dec_setround)
+
+int __fe_dec_getround(void)
+{
+ union {
+ double as_double;
+ struct { unsigned int dummy: 29, drn:3; };
+ } fpscr;
+
+ /* On Power6, read the fpscr into a double union using mffs
+ instruction, then convert the DRN rounding mode to DEC spec. */
+ asm ("mffs %0\n" : "=f" (fpscr.as_double) : );
+ switch (fpscr.drn) {
+ case 0: return FE_DEC_TONEAREST;
+ case 1: return FE_DEC_TOWARDZERO;
+ case 2: return FE_DEC_UPWARD;
+ case 3: return FE_DEC_DOWNWARD;
+ case 4: return FE_DEC_TONEARESTFROMZERO;
+ case 5: return 5;
+ case 6: return 6;
+ case 7: return 7;
+ default: return FE_DEC_TONEAREST; /* Default */
+ }
+}
+strong_alias(__fe_dec_getround, fe_dec_getround)
diff --git a/libc/dfp/sysdeps/powerpc/dpd-private.h b/libc/dfp/sysdeps/powerpc/dpd-private.h
new file mode 100644
index 000000000..3b079e69c
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/dpd-private.h
@@ -0,0 +1,933 @@
+/* Data types for DPD format output.
+
+ Copyright (C) 2006, 2007 IBM Corporation.
+ Author(s): Steve Munroe <sjmunroe@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#ifndef _DPD_PRIVATE_H
+#define _DPD_PRIVATE_H 1
+
+/* copy the declet in the 'declet' param to the string in the 'str' param. */
+static inline void __dfp_cpydeclet(char * str, const char * declet)
+{
+ str[0] = declet[0];
+ str[1] = declet[1];
+ str[2] = declet[2];
+}
+
+/* Basically itoa */
+static inline char* __dfp_exptostr(char *str, int val)
+{
+ int digit;
+ if (val < 0)
+ {
+ *str++ = '-';
+ val = -val;
+ } else {
+ *str++ = '+';
+ }
+
+ if (val > 999)
+ {
+ digit = val / 1000;
+ val %= 1000;
+ *str++ = '0' + digit;
+ digit = val / 100;
+ val %= 100;
+ *str++ = '0' + digit;
+ digit = val / 10;
+ val %= 10;
+ *str++ = '0' + digit;
+ } else if (val > 99)
+ {
+ digit = val / 100;
+ val %= 100;
+ *str++ = '0' + digit;
+ digit = val / 10;
+ val %= 10;
+ *str++ = '0' + digit;
+ } else if (val > 9)
+ {
+ digit = val / 10;
+ val %= 10;
+ *str++ = '0' + digit;
+ }
+ *str++ = '0' + val;
+
+ return str;
+}
+
+union ieee754r_Decimal32
+ {
+ _Decimal32 sd;
+ unsigned int si;
+
+ /* This is the IEEE754r single-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int c:5;
+ unsigned int bec:6;
+ unsigned int cc0:10;
+ unsigned int cc1:10;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int cc1:10;
+ unsigned int cc0:10;
+ unsigned int bec:6;
+ unsigned int c:5;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int c:5;
+ unsigned int signaling_nan:1;
+ unsigned int bec:5;
+ unsigned int cc0:10;
+ unsigned int cc1:10;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int cc1:10;
+ unsigned int cc0:10;
+ unsigned int bec:5;
+ unsigned int signaling_nan:1;
+ unsigned int c:5;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee_nan;
+ };
+
+#define DECIMAL32_Bias 101 /* bias for the exponent */
+#define DECIMAL32_BEC_bits 6 /* Bits in BEC */
+#define DECIMAL32_CC_bits 20 /* Bits in CC */
+
+union ieee754r_Decimal64
+ {
+ _Decimal64 dd;
+ unsigned int di[2];
+
+ /* This is the IEEE754r _Decimal64 format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int c:5;
+ unsigned int bec:8;
+ unsigned int cc0:10;
+ unsigned int cc1H8:8;
+ unsigned int cc1L2:2;
+ unsigned int cc2:10;
+ unsigned int cc3:10;
+ unsigned int cc4:10;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int cc4:10;
+ unsigned int cc3:10;
+ unsigned int cc2:10;
+ unsigned int cc1L2:2;
+ unsigned int cc1H8:8;
+ unsigned int cc0:10;
+ unsigned int bec:8;
+ unsigned int c:5;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int c:5;
+ unsigned int signaling_nan:1;
+ unsigned int bec:7;
+ unsigned int cc0:10;
+ unsigned int cc1H8:8;
+ unsigned int cc1L2:2;
+ unsigned int cc2:10;
+ unsigned int cc3:10;
+ unsigned int cc4:10;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int cc4:10;
+ unsigned int cc3:10;
+ unsigned int cc2:10;
+ unsigned int cc1L2:2;
+ unsigned int cc1H8:8;
+ unsigned int cc0:10;
+ unsigned int bec:7;
+ unsigned int signaling_nan:1;
+ unsigned int c:5;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee_nan;
+ };
+
+#define DECIMAL64_Bias 398 /* bias for the exponent */
+#define DECIMAL64_BEC_bits 8 /* Bits in BEC */
+#define DECIMAL64_CC_bits 50 /* Bits in CC */
+
+union ieee754r_Decimal128
+ {
+ _Decimal128 td;
+ unsigned int ti[4];
+
+ /* This is the IEEE754r _Decimal128 format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int c:5;
+ unsigned int bec:12;
+ unsigned int cc0:10;
+ unsigned int cc1H4:4;
+ unsigned int cc1L6:6;
+ unsigned int cc2:10;
+ unsigned int cc3:10;
+ unsigned int cc4H6:6;
+ unsigned int cc4L4:4;
+ unsigned int cc5:10;
+ unsigned int cc6:10;
+ unsigned int cc7H8:8;
+ unsigned int cc7L2:2;
+ unsigned int cc8:10;
+ unsigned int cc9:10;
+ unsigned int cc10:10;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int cc10:10;
+ unsigned int cc9:10;
+ unsigned int cc8:10;
+ unsigned int cc7L2:2;
+ unsigned int cc7H8:8;
+ unsigned int cc6:10;
+ unsigned int cc5:10;
+ unsigned int cc4L4:4;
+ unsigned int cc4H6:6;
+ unsigned int cc3:10;
+ unsigned int cc2:10;
+ unsigned int cc1L6:6;
+ unsigned int cc1H4:4;
+ unsigned int cc0:10;
+ unsigned int bec:12;
+ unsigned int c:5;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int c:5;
+ unsigned int signaling_nan:1;
+ unsigned int bec:11;
+ unsigned int cc0:10;
+ unsigned int cc1H4:4;
+ unsigned int cc1L6:6;
+ unsigned int cc2:10;
+ unsigned int cc3:10;
+ unsigned int cc4H6:6;
+ unsigned int cc4L4:4;
+ unsigned int cc5:10;
+ unsigned int cc6:10;
+ unsigned int cc7H8:8;
+ unsigned int cc7L2:2;
+ unsigned int cc8:10;
+ unsigned int cc9:10;
+ unsigned int cc10:10;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int cc10:10;
+ unsigned int cc9:10;
+ unsigned int cc8:10;
+ unsigned int cc7L2:2;
+ unsigned int cc7H8:8;
+ unsigned int cc6:10;
+ unsigned int cc5:10;
+ unsigned int cc4L4:4;
+ unsigned int cc4H6:6;
+ unsigned int cc3:10;
+ unsigned int cc2:10;
+ unsigned int cc1L6:6;
+ unsigned int cc1H4:4;
+ unsigned int cc0:10;
+ unsigned int bec:11;
+ unsigned int signaling_nan:1;
+ unsigned int c:5;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee_nan;
+ };
+
+#define DECIMAL128_Bias 6176 /* bias for the exponent */
+#define DECIMAL128_BEC_bits 12 /* Bits in BEC */
+#define DECIMAL128_CC_bits 110 /* Bits in CC */
+
+struct ieee754r_c_field
+ {
+ unsigned int is_nan:1;
+ unsigned int is_inf:1;
+ unsigned int lm_exp:2;
+ unsigned int lmd:4;
+ };
+
+const struct ieee754r_c_field c_decoder[32] = {
+ {0, 0, 0, 0}, {0, 0, 0, 1}, {0, 0, 0, 2}, {0, 0, 0, 3}, /* 00000-00011 */
+ {0, 0, 0, 4}, {0, 0, 0, 5}, {0, 0, 0, 6}, {0, 0, 0, 7}, /* 00100-00111 */
+ {0, 0, 1, 0}, {0, 0, 1, 1}, {0, 0, 1, 2}, {0, 0, 1, 3}, /* 01000-01011 */
+ {0, 0, 1, 4}, {0, 0, 1, 5}, {0, 0, 1, 6}, {0, 0, 1, 7}, /* 01100-01111 */
+ {0, 0, 2, 0}, {0, 0, 2, 1}, {0, 0, 2, 2}, {0, 0, 2, 3}, /* 10000-10011 */
+ {0, 0, 2, 4}, {0, 0, 2, 5}, {0, 0, 2, 5}, {0, 0, 2, 7}, /* 10100-10111 */
+ {0, 0, 0, 8}, {0, 0, 0, 9}, {0, 0, 1, 8}, {0, 0, 1, 9}, /* 11000-11011 */
+ {0, 0, 2, 8}, {0, 0, 2, 9}, {0, 1, 0, 0}, {1, 0, 0, 0} /* 11100-11111 */
+ };
+
+/* Table to encode the "left most" 2 bits of the biased exponent and the
+ "Left Most Digit" into the "C"ombination field. Indexed by [lmd,lm2bits]. */
+const unsigned char lm2lmd_to_c[10][3] = {
+ {0x00, 0x08, 0x10},
+ {0x01, 0x09, 0x11},
+ {0x02, 0x0a, 0x12},
+ {0x03, 0x0b, 0x13},
+ {0x04, 0x0c, 0x14},
+ {0x05, 0x0d, 0x15},
+ {0x06, 0x0e, 0x16},
+ {0x07, 0x0f, 0x17},
+ {0x18, 0x1a, 0x1c},
+ {0x19, 0x1b, 0x1d}};
+
+/* Table to convert 3 Densely Packed Decimal digits (10-bits) into
+ 3 ASCII digits (24-bits, 3 bytes). */
+const char dpd_to_char[1024][4] = {
+ "000", "001", "002", "003", "004", "005", "006", "007", /* 000-007 */
+ "008", "009", "080", "081", "800", "801", "880", "881", /* 008-00f */
+ "010", "011", "012", "013", "014", "015", "016", "017", /* 010-017 */
+ "018", "019", "090", "091", "810", "811", "890", "891", /* 018-01f */
+ "020", "021", "022", "023", "024", "025", "026", "027", /* 020-027 */
+ "028", "029", "082", "083", "820", "821", "808", "809", /* 028-02f */
+ "030", "031", "032", "033", "034", "035", "036", "037", /* 030-037 */
+ "038", "039", "092", "093", "830", "831", "818", "819", /* 038-03f */
+
+ "040", "041", "042", "043", "044", "045", "046", "047", /* 040-047 */
+ "048", "049", "084", "085", "840", "841", "088", "089", /* 048-04f */
+ "050", "051", "052", "053", "054", "055", "056", "057", /* 050-057 */
+ "058", "059", "094", "095", "850", "851", "098", "099", /* 058-05f */
+ "060", "061", "062", "063", "064", "065", "066", "067", /* 060-067 */
+ "068", "069", "086", "087", "860", "861", "888", "889", /* 068-06f */
+ "070", "071", "072", "073", "074", "075", "076", "077", /* 070-077 */
+ "078", "079", "096", "097", "870", "871", "898", "899", /* 078-07f */
+
+ "100", "101", "102", "103", "104", "105", "106", "107", /* 080-087 */
+ "108", "109", "180", "181", "900", "901", "980", "981", /* 088-08f */
+ "110", "111", "112", "113", "114", "115", "116", "117", /* 090-097 */
+ "118", "119", "190", "191", "910", "911", "990", "991", /* 098-09f */
+ "120", "121", "122", "123", "124", "125", "126", "127", /* 0a0-0a7 */
+ "128", "129", "182", "183", "920", "921", "908", "909", /* 0a8-0af */
+ "130", "131", "132", "133", "134", "135", "136", "137", /* 0b0-0b7 */
+ "138", "139", "192", "193", "930", "931", "918", "919", /* 0b8-0bf */
+
+ "140", "141", "142", "143", "144", "145", "146", "147", /* 0c0-0c7 */
+ "148", "149", "184", "185", "940", "941", "188", "189", /* 0c8-0cf */
+ "150", "151", "152", "153", "154", "155", "156", "157", /* 0d0-0d7 */
+ "158", "159", "194", "195", "950", "951", "198", "199", /* 0d8-0df */
+ "160", "161", "162", "163", "164", "165", "166", "167", /* 0e0-0e7 */
+ "168", "169", "186", "187", "960", "961", "988", "989", /* 0e8-0ef */
+ "170", "171", "172", "173", "174", "175", "176", "177", /* 0f0-0f7 */
+ "178", "179", "196", "197", "970", "971", "998", "999", /* 0f8-0ff */
+
+ "200", "201", "202", "203", "204", "205", "206", "207", /* 100-107 */
+ "208", "209", "280", "281", "802", "803", "882", "883", /* 108-10f */
+ "210", "211", "212", "213", "214", "215", "216", "217", /* 110-117 */
+ "218", "219", "290", "291", "812", "813", "892", "893", /* 118-11f */
+ "220", "221", "222", "223", "224", "225", "226", "227", /* 120-127 */
+ "228", "229", "282", "283", "822", "823", "828", "829", /* 128-12f */
+ "230", "231", "232", "233", "234", "235", "236", "237", /* 130-137 */
+ "238", "239", "292", "293", "832", "833", "838", "839", /* 138-13f */
+
+ "240", "241", "242", "243", "244", "245", "246", "247", /* 140-147 */
+ "248", "249", "284", "285", "842", "843", "288", "289", /* 148-14f */
+ "250", "251", "252", "253", "254", "255", "256", "257", /* 150-157 */
+ "258", "259", "294", "295", "852", "853", "298", "299", /* 158-15f */
+ "260", "261", "262", "263", "264", "265", "266", "267", /* 160-167 */
+ "268", "269", "286", "287", "862", "863", "888", "889", /* 168-16f */
+ "270", "271", "272", "273", "274", "275", "276", "277", /* 170-177 */
+ "278", "279", "296", "297", "872", "873", "898", "899", /* 178-17f */
+
+ "300", "301", "302", "303", "304", "305", "306", "307", /* 180-187 */
+ "308", "309", "380", "381", "902", "903", "982", "983", /* 188-18f */
+ "310", "311", "312", "313", "314", "315", "316", "317", /* 190-197 */
+ "318", "319", "390", "391", "912", "913", "992", "993", /* 198-19f */
+ "320", "321", "322", "323", "324", "325", "326", "327", /* 1a0-1a7 */
+ "328", "329", "382", "383", "922", "923", "928", "929", /* 1a8-1af */
+ "330", "331", "332", "333", "334", "335", "336", "337", /* 1b0-1b7 */
+ "338", "339", "392", "393", "932", "933", "938", "939", /* 1b8-1bf */
+
+ "340", "341", "342", "343", "344", "345", "346", "347", /* 1c0-1c7 */
+ "348", "349", "384", "385", "942", "943", "388", "389", /* 1c8-1cf */
+ "350", "351", "352", "353", "354", "355", "356", "357", /* 1d0-1d7 */
+ "358", "359", "394", "395", "952", "953", "398", "399", /* 1d8-1df */
+ "360", "361", "362", "363", "364", "365", "366", "367", /* 1e0-1e7 */
+ "368", "369", "386", "387", "962", "963", "988", "989", /* 1e8-1ef */
+ "370", "371", "372", "373", "374", "375", "376", "377", /* 1f0-1f7 */
+ "378", "379", "396", "397", "972", "973", "998", "999", /* 1f8-1ff */
+
+ "400", "401", "402", "403", "404", "405", "406", "407", /* 200-207 */
+ "408", "409", "480", "481", "804", "805", "884", "885", /* 208-20f */
+ "410", "411", "412", "413", "414", "415", "416", "417", /* 210-217 */
+ "418", "419", "490", "491", "814", "815", "894", "895", /* 218-21f */
+ "420", "421", "422", "423", "424", "425", "426", "427", /* 220-227 */
+ "428", "429", "482", "483", "824", "825", "848", "849", /* 228-22f */
+ "430", "431", "432", "433", "434", "435", "436", "437", /* 230-237 */
+ "438", "439", "492", "493", "834", "835", "858", "859", /* 238-23f */
+
+ "440", "441", "442", "443", "444", "445", "446", "447", /* 240-247 */
+ "448", "449", "484", "485", "844", "845", "488", "489", /* 248-24f */
+ "450", "451", "452", "453", "454", "455", "456", "457", /* 250-257 */
+ "458", "459", "494", "495", "854", "855", "498", "499", /* 258-25f */
+ "460", "461", "462", "463", "464", "465", "466", "467", /* 260-267 */
+ "468", "469", "486", "487", "864", "865", "888", "889", /* 268-26f */
+ "470", "471", "472", "473", "474", "475", "476", "477", /* 270-277 */
+ "478", "479", "496", "497", "874", "875", "898", "899", /* 278-27f */
+
+ "500", "501", "502", "503", "504", "505", "506", "507", /* 280-287 */
+ "508", "509", "580", "581", "904", "905", "984", "985", /* 288-28f */
+ "510", "511", "512", "513", "514", "515", "516", "517", /* 290-297 */
+ "518", "519", "590", "591", "914", "915", "994", "995", /* 298-29f */
+ "520", "521", "522", "523", "524", "525", "526", "527", /* 2a0-2a7 */
+ "528", "529", "582", "583", "924", "925", "948", "949", /* 2a8-2af */
+ "530", "531", "532", "533", "534", "535", "536", "537", /* 2b0-2b7 */
+ "538", "539", "592", "593", "934", "935", "958", "959", /* 2b8-2bf */
+
+ "540", "541", "542", "543", "544", "545", "546", "547", /* 2c0-2c7 */
+ "548", "549", "584", "585", "944", "945", "588", "589", /* 2c8-2cf */
+ "550", "551", "552", "553", "554", "555", "556", "557", /* 2d0-2d7 */
+ "558", "559", "594", "595", "954", "955", "598", "599", /* 2d8-2df */
+ "560", "561", "562", "563", "564", "565", "566", "567", /* 2e0-2e7 */
+ "568", "569", "586", "587", "964", "965", "988", "989", /* 2e8-2ef */
+ "570", "571", "572", "573", "574", "575", "576", "577", /* 2f0-2f7 */
+ "578", "579", "596", "597", "974", "975", "998", "999", /* 2f8-2ff */
+
+ "600", "601", "602", "603", "604", "605", "606", "607", /* 300-307 */
+ "608", "609", "680", "681", "806", "807", "886", "887", /* 308-30f */
+ "610", "611", "612", "613", "614", "615", "616", "617", /* 310-317 */
+ "618", "619", "690", "691", "816", "817", "896", "897", /* 318-31f */
+ "620", "621", "622", "623", "624", "625", "626", "627", /* 320-327 */
+ "628", "629", "682", "683", "826", "827", "868", "869", /* 328-32f */
+ "630", "631", "632", "633", "634", "635", "636", "637", /* 330-337 */
+ "638", "639", "692", "693", "836", "837", "878", "879", /* 338-33f */
+
+ "640", "641", "642", "643", "644", "645", "646", "647", /* 340-347 */
+ "648", "649", "684", "685", "846", "847", "688", "689", /* 348-34f */
+ "650", "651", "652", "653", "654", "655", "656", "657", /* 350-357 */
+ "658", "659", "694", "695", "856", "857", "698", "699", /* 358-35f */
+ "660", "661", "662", "663", "664", "665", "666", "667", /* 360-367 */
+ "668", "669", "686", "687", "866", "867", "888", "889", /* 368-36f */
+ "670", "671", "672", "673", "674", "675", "676", "677", /* 370-377 */
+ "678", "679", "696", "697", "876", "877", "898", "899", /* 378-37f */
+
+ "700", "701", "702", "703", "704", "705", "706", "707", /* 380-387 */
+ "708", "709", "780", "781", "906", "907", "986", "987", /* 388-38f */
+ "710", "711", "712", "713", "714", "715", "716", "717", /* 390-397 */
+ "718", "719", "790", "791", "916", "917", "996", "997", /* 398-39f */
+ "720", "721", "722", "723", "724", "725", "726", "727", /* 3a0-3a7 */
+ "728", "729", "782", "783", "926", "927", "968", "969", /* 3a8-3af */
+ "730", "731", "732", "733", "734", "735", "736", "737", /* 3b0-3b7 */
+ "738", "739", "792", "793", "936", "937", "978", "979", /* 3b8-3bf */
+
+ "740", "741", "742", "743", "744", "745", "746", "747", /* 3c0-3c7 */
+ "748", "749", "784", "785", "946", "947", "788", "789", /* 3c8-3cf */
+ "750", "751", "752", "753", "754", "755", "756", "757", /* 3d0-3d7 */
+ "758", "759", "794", "795", "956", "957", "798", "799", /* 3d8-3df */
+ "760", "761", "762", "763", "764", "765", "766", "767", /* 3e0-3e7 */
+ "768", "769", "786", "787", "966", "967", "988", "989", /* 3e8-3ef */
+ "770", "771", "772", "773", "974", "775", "776", "777", /* 3f0-3f7 */
+ "778", "779", "796", "797", "976", "977", "998", "999" /* 3f8-3ff */
+ };
+
+/* Table to convert 3 Densely Packed Decimal digits (10-bits) into
+ 3 Binary coded Decimal digits (12-bits). */
+const short int dpd_to_bcd[1024] = {
+ 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, /* 000-007 */
+ 0x008, 0x009, 0x080, 0x081, 0x800, 0x801, 0x880, 0x881, /* 008-00f */
+ 0x010, 0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, /* 010-017 */
+ 0x018, 0x019, 0x090, 0x091, 0x810, 0x811, 0x890, 0x891, /* 018-01f */
+ 0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x027, /* 020-027 */
+ 0x028, 0x029, 0x082, 0x083, 0x820, 0x821, 0x808, 0x809, /* 028-02f */
+ 0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, /* 030-037 */
+ 0x038, 0x039, 0x092, 0x093, 0x830, 0x831, 0x818, 0x819, /* 038-03f */
+
+ 0x040, 0x041, 0x042, 0x043, 0x044, 0x045, 0x046, 0x047, /* 040-047 */
+ 0x048, 0x049, 0x084, 0x085, 0x840, 0x841, 0x088, 0x089, /* 048-04f */
+ 0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, 0x057, /* 050-057 */
+ 0x058, 0x059, 0x094, 0x095, 0x850, 0x851, 0x098, 0x099, /* 058-05f */
+ 0x060, 0x061, 0x062, 0x063, 0x064, 0x065, 0x066, 0x067, /* 060-067 */
+ 0x068, 0x069, 0x086, 0x087, 0x860, 0x861, 0x888, 0x889, /* 068-06f */
+ 0x070, 0x071, 0x072, 0x073, 0x074, 0x075, 0x076, 0x077, /* 070-077 */
+ 0x078, 0x079, 0x096, 0x097, 0x870, 0x871, 0x898, 0x899, /* 078-07f */
+
+ 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, /* 080-087 */
+ 0x108, 0x109, 0x180, 0x181, 0x900, 0x901, 0x980, 0x981, /* 088-08f */
+ 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, /* 090-097 */
+ 0x118, 0x119, 0x190, 0x191, 0x910, 0x911, 0x990, 0x991, /* 098-09f */
+ 0x120, 0x121, 0x122, 0x123, 0x124, 0x125, 0x126, 0x127, /* 0a0-0a7 */
+ 0x128, 0x129, 0x182, 0x183, 0x920, 0x921, 0x908, 0x909, /* 0a8-0af */
+ 0x130, 0x131, 0x132, 0x133, 0x134, 0x135, 0x136, 0x137, /* 0b0-0b7 */
+ 0x138, 0x139, 0x192, 0x193, 0x930, 0x931, 0x918, 0x919, /* 0b8-0bf */
+
+ 0x140, 0x141, 0x142, 0x143, 0x144, 0x145, 0x146, 0x147, /* 0c0-0c7 */
+ 0x148, 0x149, 0x184, 0x185, 0x940, 0x941, 0x188, 0x189, /* 0c8-0cf */
+ 0x150, 0x151, 0x152, 0x153, 0x154, 0x155, 0x156, 0x157, /* 0d0-0d7 */
+ 0x158, 0x159, 0x194, 0x195, 0x950, 0x951, 0x198, 0x199, /* 0d8-0df */
+ 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167, /* 0e0-0e7 */
+ 0x168, 0x169, 0x186, 0x187, 0x960, 0x961, 0x988, 0x989, /* 0e8-0ef */
+ 0x170, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0x177, /* 0f0-0f7 */
+ 0x178, 0x179, 0x196, 0x197, 0x970, 0x971, 0x998, 0x999, /* 0f8-0ff */
+
+ 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x206, 0x207, /* 100-107 */
+ 0x208, 0x209, 0x280, 0x281, 0x802, 0x803, 0x882, 0x883, /* 108-10f */
+ 0x210, 0x211, 0x212, 0x213, 0x214, 0x215, 0x216, 0x217, /* 110-117 */
+ 0x218, 0x219, 0x290, 0x291, 0x812, 0x813, 0x892, 0x893, /* 118-11f */
+ 0x220, 0x221, 0x222, 0x223, 0x224, 0x225, 0x226, 0x227, /* 120-127 */
+ 0x228, 0x229, 0x282, 0x283, 0x822, 0x823, 0x828, 0x829, /* 128-12f */
+ 0x230, 0x231, 0x232, 0x233, 0x234, 0x235, 0x236, 0x237, /* 130-137 */
+ 0x238, 0x239, 0x292, 0x293, 0x832, 0x833, 0x838, 0x839, /* 138-13f */
+
+ 0x240, 0x241, 0x242, 0x243, 0x244, 0x245, 0x246, 0x247, /* 140-147 */
+ 0x248, 0x249, 0x284, 0x285, 0x842, 0x843, 0x288, 0x289, /* 148-14f */
+ 0x250, 0x251, 0x252, 0x253, 0x254, 0x255, 0x256, 0x257, /* 150-157 */
+ 0x258, 0x259, 0x294, 0x295, 0x852, 0x853, 0x298, 0x299, /* 158-15f */
+ 0x260, 0x261, 0x262, 0x263, 0x264, 0x265, 0x266, 0x267, /* 160-167 */
+ 0x268, 0x269, 0x286, 0x287, 0x862, 0x863, 0x888, 0x889, /* 168-16f */
+ 0x270, 0x271, 0x272, 0x273, 0x274, 0x275, 0x276, 0x277, /* 170-177 */
+ 0x278, 0x279, 0x296, 0x297, 0x872, 0x873, 0x898, 0x899, /* 178-17f */
+
+ 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, 0x307, /* 180-187 */
+ 0x308, 0x309, 0x380, 0x381, 0x902, 0x903, 0x982, 0x983, /* 188-18f */
+ 0x310, 0x311, 0x312, 0x313, 0x314, 0x315, 0x316, 0x317, /* 190-197 */
+ 0x318, 0x319, 0x390, 0x391, 0x912, 0x913, 0x992, 0x993, /* 198-19f */
+ 0x320, 0x321, 0x322, 0x323, 0x324, 0x325, 0x326, 0x327, /* 1a0-1a7 */
+ 0x328, 0x329, 0x382, 0x383, 0x922, 0x923, 0x928, 0x929, /* 1a8-1af */
+ 0x330, 0x331, 0x332, 0x333, 0x334, 0x335, 0x336, 0x337, /* 1b0-1b7 */
+ 0x338, 0x339, 0x392, 0x393, 0x932, 0x933, 0x938, 0x939, /* 1b8-1bf */
+
+ 0x340, 0x341, 0x342, 0x343, 0x344, 0x345, 0x346, 0x347, /* 1c0-1c7 */
+ 0x348, 0x349, 0x384, 0x385, 0x942, 0x943, 0x388, 0x389, /* 1c8-1cf */
+ 0x350, 0x351, 0x352, 0x353, 0x354, 0x355, 0x356, 0x357, /* 1d0-1d7 */
+ 0x358, 0x359, 0x394, 0x395, 0x952, 0x953, 0x398, 0x399, /* 1d8-1df */
+ 0x360, 0x361, 0x362, 0x363, 0x364, 0x365, 0x366, 0x367, /* 1e0-1e7 */
+ 0x368, 0x369, 0x386, 0x387, 0x962, 0x963, 0x988, 0x989, /* 1e8-1ef */
+ 0x370, 0x371, 0x372, 0x373, 0x374, 0x375, 0x376, 0x377, /* 1f0-1f7 */
+ 0x378, 0x379, 0x396, 0x397, 0x972, 0x973, 0x998, 0x999, /* 1f8-1ff */
+
+ 0x400, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, /* 200-207 */
+ 0x408, 0x409, 0x480, 0x481, 0x804, 0x805, 0x884, 0x885, /* 208-20f */
+ 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, /* 210-217 */
+ 0x418, 0x419, 0x490, 0x491, 0x814, 0x815, 0x894, 0x895, /* 218-21f */
+ 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, /* 220-227 */
+ 0x428, 0x429, 0x482, 0x483, 0x824, 0x825, 0x848, 0x849, /* 228-22f */
+ 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, /* 230-237 */
+ 0x438, 0x439, 0x492, 0x493, 0x834, 0x835, 0x858, 0x859, /* 238-23f */
+
+ 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, /* 240-247 */
+ 0x448, 0x449, 0x484, 0x485, 0x844, 0x845, 0x488, 0x489, /* 248-24f */
+ 0x450, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, /* 250-257 */
+ 0x458, 0x459, 0x494, 0x495, 0x854, 0x855, 0x498, 0x499, /* 258-25f */
+ 0x460, 0x461, 0x462, 0x463, 0x464, 0x465, 0x466, 0x467, /* 260-267 */
+ 0x468, 0x469, 0x486, 0x487, 0x864, 0x865, 0x888, 0x889, /* 268-26f */
+ 0x470, 0x471, 0x472, 0x473, 0x474, 0x475, 0x476, 0x477, /* 270-277 */
+ 0x478, 0x479, 0x496, 0x497, 0x874, 0x875, 0x898, 0x899, /* 278-27f */
+
+ 0x500, 0x501, 0x502, 0x503, 0x504, 0x505, 0x506, 0x507, /* 280-287 */
+ 0x508, 0x509, 0x580, 0x581, 0x904, 0x905, 0x984, 0x985, /* 288-28f */
+ 0x510, 0x511, 0x512, 0x513, 0x514, 0x515, 0x516, 0x517, /* 290-297 */
+ 0x518, 0x519, 0x590, 0x591, 0x914, 0x915, 0x994, 0x995, /* 298-29f */
+ 0x520, 0x521, 0x522, 0x523, 0x524, 0x525, 0x526, 0x527, /* 2a0-2a7 */
+ 0x528, 0x529, 0x582, 0x583, 0x924, 0x925, 0x948, 0x949, /* 2a8-2af */
+ 0x530, 0x531, 0x532, 0x533, 0x534, 0x535, 0x536, 0x537, /* 2b0-2b7 */
+ 0x538, 0x539, 0x592, 0x593, 0x934, 0x935, 0x958, 0x959, /* 2b8-2bf */
+
+ 0x540, 0x541, 0x542, 0x543, 0x544, 0x545, 0x546, 0x547, /* 2c0-2c7 */
+ 0x548, 0x549, 0x584, 0x585, 0x944, 0x945, 0x588, 0x589, /* 2c8-2cf */
+ 0x550, 0x551, 0x552, 0x553, 0x554, 0x555, 0x556, 0x557, /* 2d0-2d7 */
+ 0x558, 0x559, 0x594, 0x595, 0x954, 0x955, 0x598, 0x599, /* 2d8-2df */
+ 0x560, 0x561, 0x562, 0x563, 0x564, 0x565, 0x566, 0x567, /* 2e0-2e7 */
+ 0x568, 0x569, 0x586, 0x587, 0x964, 0x965, 0x988, 0x989, /* 2e8-2ef */
+ 0x570, 0x571, 0x572, 0x573, 0x574, 0x575, 0x576, 0x577, /* 2f0-2f7 */
+ 0x578, 0x579, 0x596, 0x597, 0x974, 0x975, 0x998, 0x999, /* 2f8-2ff */
+
+ 0x600, 0x601, 0x602, 0x603, 0x604, 0x605, 0x606, 0x607, /* 300-307 */
+ 0x608, 0x609, 0x680, 0x681, 0x806, 0x807, 0x886, 0x887, /* 308-30f */
+ 0x610, 0x611, 0x612, 0x613, 0x614, 0x615, 0x616, 0x617, /* 310-317 */
+ 0x618, 0x619, 0x690, 0x691, 0x816, 0x817, 0x896, 0x897, /* 318-31f */
+ 0x620, 0x621, 0x622, 0x623, 0x624, 0x625, 0x626, 0x627, /* 320-327 */
+ 0x628, 0x629, 0x682, 0x683, 0x826, 0x827, 0x868, 0x869, /* 328-32f */
+ 0x630, 0x631, 0x632, 0x633, 0x634, 0x635, 0x636, 0x637, /* 330-337 */
+ 0x638, 0x639, 0x692, 0x693, 0x836, 0x837, 0x878, 0x879, /* 338-33f */
+
+ 0x640, 0x641, 0x642, 0x643, 0x644, 0x645, 0x646, 0x647, /* 340-347 */
+ 0x648, 0x649, 0x684, 0x685, 0x846, 0x847, 0x688, 0x689, /* 348-34f */
+ 0x650, 0x651, 0x652, 0x653, 0x654, 0x655, 0x656, 0x657, /* 350-357 */
+ 0x658, 0x659, 0x694, 0x695, 0x856, 0x857, 0x698, 0x699, /* 358-35f */
+ 0x660, 0x661, 0x662, 0x663, 0x664, 0x665, 0x666, 0x667, /* 360-367 */
+ 0x668, 0x669, 0x686, 0x687, 0x866, 0x867, 0x888, 0x889, /* 368-36f */
+ 0x670, 0x671, 0x672, 0x673, 0x674, 0x675, 0x676, 0x677, /* 370-377 */
+ 0x678, 0x679, 0x696, 0x697, 0x876, 0x877, 0x898, 0x899, /* 378-37f */
+
+ 0x700, 0x701, 0x702, 0x703, 0x704, 0x705, 0x706, 0x707, /* 380-387 */
+ 0x708, 0x709, 0x780, 0x781, 0x906, 0x907, 0x986, 0x987, /* 388-38f */
+ 0x710, 0x711, 0x712, 0x713, 0x714, 0x715, 0x716, 0x717, /* 390-397 */
+ 0x718, 0x719, 0x790, 0x791, 0x916, 0x917, 0x996, 0x997, /* 398-39f */
+ 0x720, 0x721, 0x722, 0x723, 0x724, 0x725, 0x726, 0x727, /* 3a0-3a7 */
+ 0x728, 0x729, 0x782, 0x783, 0x926, 0x927, 0x968, 0x969, /* 3a8-3af */
+ 0x730, 0x731, 0x732, 0x733, 0x734, 0x735, 0x736, 0x737, /* 3b0-3b7 */
+ 0x738, 0x739, 0x792, 0x793, 0x936, 0x937, 0x978, 0x979, /* 3b8-3bf */
+
+ 0x740, 0x741, 0x742, 0x743, 0x744, 0x745, 0x746, 0x747, /* 3c0-3c7 */
+ 0x748, 0x749, 0x784, 0x785, 0x946, 0x947, 0x788, 0x789, /* 3c8-3cf */
+ 0x750, 0x751, 0x752, 0x753, 0x754, 0x755, 0x756, 0x757, /* 3d0-3d7 */
+ 0x758, 0x759, 0x794, 0x795, 0x956, 0x957, 0x798, 0x799, /* 3d8-3df */
+ 0x760, 0x761, 0x762, 0x763, 0x764, 0x765, 0x766, 0x767, /* 3e0-3e7 */
+ 0x768, 0x769, 0x786, 0x787, 0x966, 0x967, 0x988, 0x989, /* 3e8-3ef */
+ 0x770, 0x771, 0x772, 0x773, 0x974, 0x775, 0x776, 0x777, /* 3f0-3f7 */
+ 0x778, 0x779, 0x796, 0x797, 0x976, 0x977, 0x998, 0x999 /* 3f8-3ff */
+ };
+
+/* Table to convert 3 Binary Coded Decimal digits (12-bits) into
+ 3 Densely Packed Decimal digits (10-bits). */
+const short int bcd_to_dpd[2464] = {
+ 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, /* 000-007 */
+ 0x008, 0x009, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 008-00f */
+ 0x010, 0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, /* 010-017 */
+ 0x018, 0x019, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 018-01f */
+ 0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x027, /* 020-027 */
+ 0x028, 0x029, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 028-02f */
+ 0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, /* 030-037 */
+ 0x038, 0x039, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 038-03f */
+ 0x040, 0x041, 0x042, 0x043, 0x044, 0x045, 0x046, 0x047, /* 040-047 */
+ 0x048, 0x049, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 048-04f */
+ 0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, 0x057, /* 050-057 */
+ 0x058, 0x059, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 058-05f */
+ 0x060, 0x061, 0x062, 0x063, 0x064, 0x065, 0x066, 0x067, /* 060-067 */
+ 0x068, 0x069, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 068-06f */
+ 0x070, 0x071, 0x072, 0x073, 0x074, 0x075, 0x076, 0x077, /* 070-077 */
+ 0x078, 0x079, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 078-07f */
+ 0x00a, 0x00b, 0x02a, 0x02b, 0x04a, 0x04b, 0x06a, 0x06b, /* 080-087 */
+ 0x04e, 0x04f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 088-08f */
+ 0x01a, 0x01b, 0x03a, 0x03b, 0x05a, 0x05b, 0x07a, 0x07b, /* 090-097 */
+ 0x05e, 0x05f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 098-09f */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0a0-0a7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0a8-0af */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0b0-0b7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0b8-0bf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0c0-0c7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0c8-0cf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0d0-0d7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0d8-0df */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0e0-0e7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0e8-0ef */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0f0-0f7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 0f8-0ff */
+ 0x080, 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087, /* 100-107 */
+ 0x088, 0x089, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 108-10f */
+ 0x090, 0x091, 0x092, 0x093, 0x094, 0x095, 0x096, 0x097, /* 110-117 */
+ 0x098, 0x099, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 118-11f */
+ 0x0a0, 0x0a1, 0x0a2, 0x0a3, 0x0a4, 0x0a5, 0x0a6, 0x0a7, /* 120-127 */
+ 0x0a8, 0x0a9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 128-12f */
+ 0x0b0, 0x0b1, 0x0b2, 0x0b3, 0x0b4, 0x0b5, 0x0b6, 0x0b7, /* 130-137 */
+ 0x0b8, 0x0b9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 138-13f */
+ 0x0c0, 0x0c1, 0x0c2, 0x0c3, 0x0c4, 0x0c5, 0x0c6, 0x0c7, /* 140-147 */
+ 0x0c8, 0x0c9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 148-14f */
+ 0x0d0, 0x0d1, 0x0d2, 0x0d3, 0x0d4, 0x0d5, 0x0d6, 0x0d7, /* 150-157 */
+ 0x0d8, 0x0d9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 158-15f */
+ 0x0e0, 0x0e1, 0x0e2, 0x0e3, 0x0e4, 0x0e5, 0x0e6, 0x0e7, /* 160-167 */
+ 0x0e8, 0x0e9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 168-16f */
+ 0x0f0, 0x0f1, 0x0f2, 0x0f3, 0x0f4, 0x0f5, 0x0f6, 0x0f7, /* 170-177 */
+ 0x0f8, 0x0f9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 178-17f */
+ 0x08a, 0x08b, 0x0aa, 0x0ab, 0x0ca, 0x0cb, 0x0ea, 0x0eb, /* 180-187 */
+ 0x0ce, 0x0cf, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 188-18f */
+ 0x09a, 0x09b, 0x0ba, 0x0bb, 0x0da, 0x0db, 0x0fa, 0x0fb, /* 190-197 */
+ 0x0de, 0x0df, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 198-19f */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1a0-1a7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1a8-1af */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1b0-1b7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1b8-1bf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1c0-1c7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1c8-1cf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1d0-1d7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1d8-1df */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1e0-1e7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1e8-1ef */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1f0-1f7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 1f8-1ff */
+ 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, /* 200-207 */
+ 0x108, 0x109, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 208-20f */
+ 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, /* 210-217 */
+ 0x118, 0x119, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 218-21f */
+ 0x120, 0x121, 0x122, 0x123, 0x124, 0x125, 0x126, 0x127, /* 220-227 */
+ 0x128, 0x129, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 228-22f */
+ 0x130, 0x131, 0x132, 0x133, 0x134, 0x135, 0x136, 0x137, /* 230-237 */
+ 0x138, 0x139, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 238-23f */
+ 0x140, 0x141, 0x142, 0x143, 0x144, 0x145, 0x146, 0x147, /* 240-247 */
+ 0x148, 0x149, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 248-24f */
+ 0x150, 0x151, 0x152, 0x153, 0x154, 0x155, 0x156, 0x157, /* 250-257 */
+ 0x158, 0x159, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 258-25f */
+ 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167, /* 260-267 */
+ 0x168, 0x169, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 268-26f */
+ 0x170, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0x177, /* 270-277 */
+ 0x178, 0x179, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 278-27f */
+ 0x10a, 0x10b, 0x12a, 0x12b, 0x14a, 0x14b, 0x16a, 0x16b, /* 280-287 */
+ 0x14e, 0x14f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 288-28f */
+ 0x11a, 0x11b, 0x13a, 0x13b, 0x15a, 0x15b, 0x17a, 0x17b, /* 290-297 */
+ 0x15e, 0x15f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 298-29f */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2a0-2a7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2a8-2af */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2b0-2b7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2b8-2bf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2c0-2c7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2c8-2cf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2d0-2d7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2d8-2df */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2e0-2e7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2e8-2ef */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2f0-2f7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 2f8-2ff */
+ 0x180, 0x181, 0x182, 0x183, 0x184, 0x185, 0x186, 0x187, /* 300-307 */
+ 0x188, 0x189, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 308-30f */
+ 0x190, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196, 0x197, /* 310-317 */
+ 0x198, 0x199, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 318-31f */
+ 0x1a0, 0x1a1, 0x1a2, 0x1a3, 0x1a4, 0x1a5, 0x1a6, 0x1a7, /* 320-327 */
+ 0x1a8, 0x1a9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 328-32f */
+ 0x1b0, 0x1b1, 0x1b2, 0x1b3, 0x1b4, 0x1b5, 0x1b6, 0x1b7, /* 330-337 */
+ 0x1b8, 0x1b9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 338-33f */
+ 0x1c0, 0x1c1, 0x1c2, 0x1c3, 0x1c4, 0x1c5, 0x1c6, 0x1c7, /* 340-347 */
+ 0x1c8, 0x1c9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 348-34f */
+ 0x1d0, 0x1d1, 0x1d2, 0x1d3, 0x1d4, 0x1d5, 0x1d6, 0x1d7, /* 350-357 */
+ 0x1d8, 0x1d9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 358-35f */
+ 0x1e0, 0x1e1, 0x1e2, 0x1e3, 0x1e4, 0x1e5, 0x1e6, 0x1e7, /* 360-367 */
+ 0x1e8, 0x1e9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 368-36f */
+ 0x1f0, 0x1f1, 0x1f2, 0x1f3, 0x1f4, 0x1f5, 0x1f6, 0x1f7, /* 370-377 */
+ 0x1f8, 0x1f9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 378-37f */
+ 0x18a, 0x18b, 0x1aa, 0x1ab, 0x1ca, 0x1cb, 0x1ea, 0x1eb, /* 380-387 */
+ 0x1ce, 0x1cf, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 388-38f */
+ 0x19a, 0x19b, 0x1ba, 0x1bb, 0x1da, 0x1db, 0x1fa, 0x1fb, /* 390-397 */
+ 0x1de, 0x1df, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 398-39f */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3a0-3a7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3a8-3af */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3b0-3b7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3b8-3bf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3c0-3c7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3c8-3cf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3d0-3d7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3d8-3df */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3e0-3e7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3e8-3ef */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3f0-3f7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 3f8-3ff */
+ 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x206, 0x207, /* 400-407 */
+ 0x208, 0x209, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 408-40f */
+ 0x210, 0x211, 0x212, 0x213, 0x214, 0x215, 0x216, 0x217, /* 410-417 */
+ 0x218, 0x219, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 418-41f */
+ 0x220, 0x221, 0x222, 0x223, 0x224, 0x225, 0x226, 0x227, /* 420-427 */
+ 0x228, 0x229, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 428-42f */
+ 0x230, 0x231, 0x232, 0x233, 0x234, 0x235, 0x236, 0x237, /* 430-437 */
+ 0x238, 0x239, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 438-43f */
+ 0x240, 0x241, 0x242, 0x243, 0x244, 0x245, 0x246, 0x247, /* 440-447 */
+ 0x248, 0x249, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 448-44f */
+ 0x250, 0x251, 0x252, 0x253, 0x254, 0x255, 0x256, 0x257, /* 450-457 */
+ 0x258, 0x259, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 458-45f */
+ 0x260, 0x261, 0x262, 0x263, 0x264, 0x265, 0x266, 0x267, /* 460-467 */
+ 0x268, 0x269, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 468-46f */
+ 0x270, 0x271, 0x272, 0x273, 0x274, 0x275, 0x276, 0x277, /* 470-477 */
+ 0x278, 0x279, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 478-47f */
+ 0x20a, 0x20b, 0x22a, 0x22b, 0x24a, 0x24b, 0x26a, 0x26b, /* 480-487 */
+ 0x24e, 0x24f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 488-48f */
+ 0x21a, 0x21b, 0x23a, 0x23b, 0x25a, 0x25b, 0x27a, 0x27b, /* 490-497 */
+ 0x25e, 0x25f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 498-49f */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4a0-4a7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4a8-4af */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4b0-4b7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4b8-4bf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4c0-4c7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4c8-4cf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4d0-4d7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4d8-4df */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4e0-4e7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4e8-4ef */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4f0-4f7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 4f8-4ff */
+ 0x280, 0x281, 0x282, 0x283, 0x284, 0x285, 0x286, 0x287, /* 500-507 */
+ 0x288, 0x289, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 508-50f */
+ 0x290, 0x291, 0x292, 0x293, 0x294, 0x295, 0x296, 0x297, /* 510-517 */
+ 0x298, 0x299, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 518-51f */
+ 0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x2a4, 0x2a5, 0x2a6, 0x2a7, /* 520-527 */
+ 0x2a8, 0x2a9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 528-52f */
+ 0x2b0, 0x2b1, 0x2b2, 0x2b3, 0x2b4, 0x2b5, 0x2b6, 0x2b7, /* 530-537 */
+ 0x2b8, 0x2b9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 538-53f */
+ 0x2c0, 0x2c1, 0x2c2, 0x2c3, 0x2c4, 0x2c5, 0x2c6, 0x2c7, /* 540-547 */
+ 0x2c8, 0x2c9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 548-54f */
+ 0x2d0, 0x2d1, 0x2d2, 0x2d3, 0x2d4, 0x2d5, 0x2d6, 0x2d7, /* 550-557 */
+ 0x2d8, 0x2d9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 558-55f */
+ 0x2e0, 0x2e1, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e6, 0x2e7, /* 560-567 */
+ 0x2e8, 0x2e9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 568-56f */
+ 0x2f0, 0x2f1, 0x2f2, 0x2f3, 0x2f4, 0x2f5, 0x2f6, 0x2f7, /* 570-577 */
+ 0x2f8, 0x2f9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 578-57f */
+ 0x28a, 0x28b, 0x2aa, 0x2ab, 0x2ca, 0x2cb, 0x2ea, 0x2eb, /* 580-587 */
+ 0x2ce, 0x2cf, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 588-58f */
+ 0x29a, 0x29b, 0x2ba, 0x2bb, 0x2da, 0x2db, 0x2fa, 0x2fb, /* 590-597 */
+ 0x2de, 0x2df, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 598-59f */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5a0-5a7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5a8-5af */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5b0-5b7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5b8-5bf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5c0-5c7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5c8-5cf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5d0-5d7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5d8-5df */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5e0-5e7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5e8-5ef */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5f0-5f7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 5f8-5ff */
+ 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, 0x307, /* 600-607 */
+ 0x308, 0x309, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 608-60f */
+ 0x310, 0x311, 0x312, 0x313, 0x314, 0x315, 0x316, 0x317, /* 610-617 */
+ 0x318, 0x319, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 618-61f */
+ 0x320, 0x321, 0x322, 0x323, 0x324, 0x325, 0x326, 0x327, /* 620-627 */
+ 0x328, 0x329, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 628-62f */
+ 0x330, 0x331, 0x332, 0x333, 0x334, 0x335, 0x336, 0x337, /* 630-637 */
+ 0x338, 0x339, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 638-63f */
+ 0x340, 0x341, 0x342, 0x343, 0x344, 0x345, 0x346, 0x347, /* 640-647 */
+ 0x348, 0x349, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 648-64f */
+ 0x350, 0x351, 0x352, 0x353, 0x354, 0x355, 0x356, 0x357, /* 650-657 */
+ 0x358, 0x359, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 658-65f */
+ 0x360, 0x361, 0x362, 0x363, 0x364, 0x365, 0x366, 0x367, /* 660-667 */
+ 0x368, 0x369, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 668-66f */
+ 0x370, 0x371, 0x372, 0x373, 0x374, 0x375, 0x376, 0x377, /* 670-677 */
+ 0x378, 0x379, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 678-67f */
+ 0x30a, 0x30b, 0x32a, 0x32b, 0x34a, 0x34b, 0x36a, 0x36b, /* 680-687 */
+ 0x34e, 0x34f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 688-68f */
+ 0x31a, 0x31b, 0x33a, 0x33b, 0x35a, 0x35b, 0x37a, 0x37b, /* 690-697 */
+ 0x35e, 0x35f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 698-69f */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6a0-6a7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6a8-6af */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6b0-6b7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6b8-6bf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6c0-6c7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6c8-6cf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6d0-6d7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6d8-6df */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6e0-6e7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6e8-6ef */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6f0-6f7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 6f8-6ff */
+ 0x380, 0x381, 0x382, 0x383, 0x384, 0x385, 0x386, 0x387, /* 700-707 */
+ 0x388, 0x389, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 708-70f */
+ 0x390, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, /* 710-717 */
+ 0x398, 0x399, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 718-71f */
+ 0x3a0, 0x3a1, 0x3a2, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, /* 720-727 */
+ 0x3a8, 0x3a9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 728-72f */
+ 0x3b0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7, /* 730-737 */
+ 0x3b8, 0x3b9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 738-73f */
+ 0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7, /* 740-747 */
+ 0x3c8, 0x3c9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 748-74f */
+ 0x3d0, 0x3d1, 0x3d2, 0x3d3, 0x3d4, 0x3d5, 0x3d6, 0x3d7, /* 750-757 */
+ 0x3d8, 0x3d9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 758-75f */
+ 0x3e0, 0x3e1, 0x3e2, 0x3e3, 0x3e4, 0x3e5, 0x3e6, 0x3e7, /* 760-767 */
+ 0x3e8, 0x3e9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 768-76f */
+ 0x3f0, 0x3f1, 0x3f2, 0x3f3, 0x000, 0x3f5, 0x3f6, 0x3f7, /* 770-777 */
+ 0x3f8, 0x3f9, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 778-77f */
+ 0x38a, 0x38b, 0x3aa, 0x3ab, 0x3ca, 0x3cb, 0x3ea, 0x3eb, /* 780-787 */
+ 0x3ce, 0x3cf, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 788-78f */
+ 0x39a, 0x39b, 0x3ba, 0x3bb, 0x3da, 0x3db, 0x3fa, 0x3fb, /* 790-797 */
+ 0x3de, 0x3df, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 798-79f */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7a0-7a7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7a8-7af */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7b0-7b7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7b8-7bf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7c0-7c7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7c8-7cf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7d0-7d7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7d8-7df */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7e0-7e7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7e8-7ef */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7f0-7f7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 7f8-7ff */
+ 0x00c, 0x00d, 0x10c, 0x10d, 0x20c, 0x20d, 0x30c, 0x30d, /* 800-807 */
+ 0x02e, 0x02f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 808-80f */
+ 0x01c, 0x01d, 0x11c, 0x11d, 0x21c, 0x21d, 0x31c, 0x31d, /* 810-817 */
+ 0x03e, 0x03f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 818-81f */
+ 0x02c, 0x02d, 0x12c, 0x12d, 0x22c, 0x22d, 0x32c, 0x32d, /* 820-827 */
+ 0x12e, 0x12f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 828-82f */
+ 0x03c, 0x03d, 0x13c, 0x13d, 0x23c, 0x23d, 0x33c, 0x33d, /* 830-837 */
+ 0x13e, 0x13f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 838-83f */
+ 0x04c, 0x04d, 0x14c, 0x14d, 0x24c, 0x24d, 0x34c, 0x34d, /* 840-847 */
+ 0x22e, 0x22f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 848-84f */
+ 0x05c, 0x05d, 0x15c, 0x15d, 0x25c, 0x25d, 0x35c, 0x35d, /* 850-857 */
+ 0x23e, 0x23f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 858-85f */
+ 0x06c, 0x06d, 0x16c, 0x16d, 0x26c, 0x26d, 0x36c, 0x36d, /* 860-867 */
+ 0x32e, 0x32f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 868-86f */
+ 0x07c, 0x07d, 0x17c, 0x17d, 0x27c, 0x27d, 0x37c, 0x37d, /* 870-877 */
+ 0x33e, 0x33f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 878-87f */
+ 0x00e, 0x00f, 0x10e, 0x10f, 0x20e, 0x20f, 0x30e, 0x30f, /* 880-887 */
+ 0x06e, 0x06f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 888-88f */
+ 0x01e, 0x01f, 0x11e, 0x11f, 0x21e, 0x21f, 0x31e, 0x31f, /* 890-897 */
+ 0x07e, 0x07f, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 898-89f */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8a0-8a7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8a8-8af */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8b0-8b7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8b8-8bf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8c0-8c7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8c8-8cf */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8d0-8d7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8d8-8df */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8e0-8e7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8e8-8ef */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8f0-8f7 */
+ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 8f8-8ff */
+ 0x08c, 0x08d, 0x18c, 0x18d, 0x28c, 0x28d, 0x38c, 0x38d, /* 900-907 */
+ 0x0ae, 0x0af, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 908-90f */
+ 0x09c, 0x09d, 0x19c, 0x19d, 0x29c, 0x29d, 0x39c, 0x39d, /* 910-917 */
+ 0x0be, 0x0bf, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 918-91f */
+ 0x0ac, 0x0ad, 0x1ac, 0x1ad, 0x2ac, 0x2ad, 0x3ac, 0x3ad, /* 920-927 */
+ 0x1ae, 0x1af, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 928-92f */
+ 0x0bc, 0x0bd, 0x1bc, 0x1bd, 0x2bc, 0x2bd, 0x3bc, 0x3bd, /* 930-937 */
+ 0x1be, 0x1bf, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 938-93f */
+ 0x0cc, 0x0cd, 0x1cc, 0x1cd, 0x2cc, 0x2cd, 0x3cc, 0x3cd, /* 940-947 */
+ 0x2ae, 0x2af, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 948-94f */
+ 0x0dc, 0x0dd, 0x1dc, 0x1dd, 0x2dc, 0x2dd, 0x3dc, 0x3dd, /* 950-957 */
+ 0x2be, 0x2bf, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 958-95f */
+ 0x0ec, 0x0ed, 0x1ec, 0x1ed, 0x2ec, 0x2ed, 0x3ec, 0x3ed, /* 960-967 */
+ 0x3ae, 0x3af, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 968-96f */
+ 0x0fc, 0x0fd, 0x1fc, 0x1fd, 0x3f4, 0x2fd, 0x3fc, 0x3fd, /* 970-977 */
+ 0x3be, 0x3bf, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 978-97f */
+ 0x08e, 0x08f, 0x18e, 0x18f, 0x28e, 0x28f, 0x38e, 0x38f, /* 980-987 */
+ 0x0ee, 0x0ef, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 988-98f */
+ 0x09e, 0x09f, 0x19e, 0x19f, 0x29e, 0x29f, 0x39e, 0x39f, /* 990-997 */
+ 0x0fe, 0x0ff, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 998-99f */
+
+};
+
+
+#endif /* _DPD_PRIVATE */
diff --git a/libc/dfp/sysdeps/powerpc/fpu/bits/fenvinline.h b/libc/dfp/sysdeps/powerpc/fpu/bits/fenvinline.h
new file mode 100644
index 000000000..30abeae1b
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/fpu/bits/fenvinline.h
@@ -0,0 +1,63 @@
+/* Inline floating-point environment handling functions for powerpc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2006
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if defined __GNUC__ && !defined _SOFT_FLOAT && !defined __NO_MATH_INLINES
+
+/* NOT USED IN LIBDFP */
+/* Inline definition for fegetround. */
+/*# define fegetround() \
+ (__extension__ ({ int __fegetround_result; \
+ __asm__ __volatile__ \
+ ("mcrfs 7,7 ; mfcr %0" \
+ : "=r"(__fegetround_result) : : "cr7"); \
+ __fegetround_result & 3; }))
+ */
+
+/* The weird 'i#*X' constraints on the following suppress a gcc
+ warning when __excepts is not a constant. Otherwise, they mean the
+ same as just plain 'i'. */
+
+/* Inline definition for feraiseexcept. */
+# define feraiseexcept(__excepts) \
+ ((__builtin_constant_p (__excepts) \
+ && ((__excepts) & ((__excepts)-1)) == 0 \
+ && (__excepts) != FE_INVALID) \
+ ? ((__excepts) != 0 \
+ ? (__extension__ ({ __asm__ __volatile__ \
+ ("mtfsb1 %s0" \
+ : : "i#*X"(__builtin_ffs (__excepts))); \
+ 0; })) \
+ : 0) \
+ : (feraiseexcept) (__excepts))
+
+/* Inline definition for feclearexcept. */
+# define feclearexcept(__excepts) \
+ ((__builtin_constant_p (__excepts) \
+ && ((__excepts) & ((__excepts)-1)) == 0 \
+ && (__excepts) != FE_INVALID) \
+ ? ((__excepts) != 0 \
+ ? (__extension__ ({ __asm__ __volatile__ \
+ ("mtfsb0 %s0" \
+ : : "i#*X"(__builtin_ffs (__excepts))); \
+ 0; })) \
+ : 0) \
+ : (feclearexcept) (__excepts))
+
+#endif /* __GNUC__ && !_SOFT_FLOAT */
diff --git a/libc/dfp/sysdeps/powerpc/nofpu/bits/fenvinline.h b/libc/dfp/sysdeps/powerpc/nofpu/bits/fenvinline.h
new file mode 100644
index 000000000..06cf9d49a
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/nofpu/bits/fenvinline.h
@@ -0,0 +1,39 @@
+/* Raise given exceptions (soft-float edition).
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if !defined feraiseexcept
+
+#include "soft-fp.h"
+#include "soft-supp.h"
+#include <signal.h>
+#include <bp-sym.h>
+
+#define feraiseexcept (x) \
+{ \
+ __sim_exceptions |= x; \
+ if (x == 0 || __sim_disabled_exceptions & x) \
+ /* Ignore exception. */ \
+ ; \
+ else \
+ raise (SIGFPE); \
+ return 0; \
+}
+
+#endif /* feraiseexcept */
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Makefile b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Makefile
new file mode 100644
index 000000000..f5214307f
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Makefile
@@ -0,0 +1,25 @@
+# Makefile fragment for POWER6 with FPU.
+
+ifeq ($(subdir),dfp)
+libdfp-routines += addsd3 adddd3 addtd3 \
+ subsd3 subdd3 subtd3 \
+ mulsd3 muldd3 multd3 \
+ divsd3 divdd3 divtd3 \
+ extendsddd2 extendsdtd2 extendddtd2 \
+ trunctdsd2 truncddsd2 trunctdsd2 \
+ unordsd2 unorddd2 unordtd2 \
+ eqsd2 eqdd2 eqtd2 \
+ nesd2 nedd2 netd2 \
+ gesd2 gedd2 getd2 \
+ gtsd2 gtdd2 gttd2 \
+ ltsd2 ltdd2 lttd2 \
+ lesd2 ledd2 letd2 \
+ fixsdsi fixddsi fixtdsi \
+ fixsddi fixdddi fixtddi \
+ fixunssdsi fixunsddsi fixunstdsi \
+ fixunssddi fixunsdddi fixunstddi \
+ floatsisd floatsidd floatsitd \
+ floatdisd floatdidd floatditd \
+ floatunssisd floatunssidd floatunssitd \
+ floatunsdisd floatunsdidd floatunsditd
+endif
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions
new file mode 100644
index 000000000..d4470bd43
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/Versions
@@ -0,0 +1,21 @@
+libdfp {
+ GLIBC_2.5 {
+ __addsd3; __adddd3; __addtd3;
+ __subsd3; __subdd3; __subtd3;
+ __mulsd3; __muldd3; __multd3;
+ __divsd3; __divdd3; __divtd3;
+ __extendsddd2; __extendsdtd2; __extendddtd2;
+ __trunctdsd2; __truncddsd2; __trunctddd2;
+ __unordsd2; __unorddd2; __unordtd2;
+ __eqsd2; __eqdd2; __eqtd2; __nesd2; __nedd2; __netd2;
+ __gesd2; __gedd2; __getd2; __gtsd2; __gtdd2; __gttd2;
+ __ltsd2; __ltdd2; __lttd2; __lesd2; __ledd2; __letd2;
+ __fixsdsi; __fixddsi; __fixtdsi; __fixsddi; __fixdddi; __fixtddi;
+ __fixunssdsi; __fixunsddsi; __fixunstdsi;
+ __fixunssddi; __fixunsdddi; __fixunstddi;
+ __floatsisd; __floatsidd; __floatsitd;
+ __floatdisd; __floatdidd; __floatditd;
+ __floatunssisd; __floatunssidd; __floatunssitd;
+ __floatunsdisd; __floatunsdidd; __floatunsditd;
+ }
+}
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/adddd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/adddd3.S
new file mode 100644
index 000000000..c1006c75f
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/adddd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 64-bit add. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __adddd3 (__decimal64 x, __decimal64 y) */
+ENTRY (__adddd3)
+ dadd fp1,fp1,fp2
+ blr
+ END (__adddd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/addsd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/addsd3.S
new file mode 100644
index 000000000..709348b2b
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/addsd3.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 32-bit add. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __addsd3 (__decimal32 x, __decimal32 y) */
+ENTRY (__addsd3)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dadd fp1,fp1,fp2
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__addsd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/addtd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/addtd3.S
new file mode 100644
index 000000000..04baa7e72
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/addtd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 128-bit add. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __addtd3 (__decimal128 x, __decimal128 y) */
+ENTRY (__addtd3)
+ daddq fp2,fp2,fp4
+ blr
+ END (__addtd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divdd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divdd3.S
new file mode 100644
index 000000000..80a0b8409
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divdd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 64-bit divide. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __divdd3 (__decimal64 x, __decimal64 y) */
+ENTRY (__divdd3)
+ ddiv fp1,fp1,fp2
+ blr
+ END (__divdd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divsd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divsd3.S
new file mode 100644
index 000000000..775f22734
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divsd3.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 32-bit divide. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __divsd3 (__decimal32 x, __decimal32 y) */
+ENTRY (__divsd3)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ ddiv fp1,fp1,fp2
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__divsd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divtd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divtd3.S
new file mode 100644
index 000000000..92aa3af32
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/divtd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 128-bit divide. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __divtd3 (__decimal128 x, __decimal128 y) */
+ENTRY (__divtd3)
+ ddivq fp2,fp2,fp4
+ blr
+ END (__divtd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqdd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqdd2.S
new file mode 100644
index 000000000..29059c7b0
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqdd2.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 64-bit compare equal. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __eqdd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__eqdd2)
+ dcmpu cr0,fp1,fp2 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__eqdd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqsd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqsd2.S
new file mode 100644
index 000000000..fe4d71a87
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqsd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 32-bit compare equal. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __eqsd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__eqsd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__eqsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqtd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqtd2.S
new file mode 100644
index 000000000..46b167c13
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/eqtd2.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point 128-bit compare equal.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __eqtd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__eqtd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__eqtd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendddtd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendddtd2.S
new file mode 100644
index 000000000..e8ff0b684
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendddtd2.S
@@ -0,0 +1,29 @@
+/* Decimal Floating Point extend 64-bit to 128-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __extendddtd2 (__decimal64 x) */
+ENTRY (__extendddtd2)
+ dctqpq fp2,fp1 /* Convert x to __decimal128. */
+ blr
+ END (__extendddtd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendsddd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendsddd2.S
new file mode 100644
index 000000000..d219b97b6
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendsddd2.S
@@ -0,0 +1,29 @@
+/* Decimal Floating Point extend 32-bit to 64-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __extendsddd2 (__decimal32 x) */
+ENTRY (__extendsddd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ blr
+ END (__extendsddd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendsdtd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendsdtd2.S
new file mode 100644
index 000000000..c6e4bad9d
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/extendsdtd2.S
@@ -0,0 +1,30 @@
+/* Decimal Floating Point extend 32-bit to 128-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __extendsdtd2 (__decimal32 x) */
+ENTRY (__extendsdtd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctqpq fp2,fp1 /* Convert x to __decimal128. */
+ blr
+ END (__extendsdtd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixdddi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixdddi.S
new file mode 100644
index 000000000..ad2d935b6
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixdddi.S
@@ -0,0 +1,36 @@
+/* Decimal Floating Point convert 64-bit to long. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* long __fixdddi (__decimal64 x) */
+ENTRY (__fixdddi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r3,8(r1)
+ lwz r4,12(r1)
+ addi r1,r1,16
+ blr
+ END (__fixdddi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixddsi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixddsi.S
new file mode 100644
index 000000000..fa54a248a
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixddsi.S
@@ -0,0 +1,56 @@
+/* Decimal Floating Point convert 64-bit to int.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __fixddsi (__decimal64 x) */
+ENTRY (__fixddsi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r0,8(r1)
+ lwz r3,12(r1)
+/* The return is an int, but we have long long, so we need to force overflow
+ if there are any significant bits in the high word or overflow (incorrect
+ sign) from the low word. */
+ cmpwi cr0,r0,0
+ cmpwi cr6,r3,0
+ cmpwi cr7,r0,-1
+ blt cr0,L(negative)
+ bne cr0,L(posoverflow)
+ bge cr6,L(done)
+L(posoverflow):
+ lis r3,0x7fff /* return max positive int. */
+ ori r3,r3,0xffff
+ b L(done)
+L(negative):
+ bne cr7,L(negoverflow)
+ blt cr6,L(done)
+L(negoverflow):
+ lis r3,0x8000 /* return max negative int. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__fixddsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsddi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsddi.S
new file mode 100644
index 000000000..8f6b54a11
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsddi.S
@@ -0,0 +1,37 @@
+/* Decimal Floating Point convert 32-bit to long. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* long __fixsddi (__decimal32 x) */
+ENTRY (__fixsddi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r3,8(r1)
+ lwz r4,12(r1)
+ addi r1,r1,16
+ blr
+ END (__fixsddi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsdsi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsdsi.S
new file mode 100644
index 000000000..9db001b69
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixsdsi.S
@@ -0,0 +1,57 @@
+/* Decimal Floating Point convert 32-bit to int.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __fixsdsi (__decimal32 x) */
+ENTRY (__fixsdsi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r0,8(r1)
+ lwz r3,12(r1)
+/* The return is an int, but we have long long, so we need to force overflow
+ if there are any significant bits in the high word or overflow (incorrect
+ sign) from the low word. */
+ cmpwi cr0,r0,0
+ cmpwi cr6,r3,0
+ cmpwi cr7,r0,-1
+ blt cr0,L(negative)
+ bne cr0,L(posoverflow)
+ bge cr6,L(done)
+L(posoverflow):
+ lis r3,0x7fff /* return max positive int. */
+ ori r3,r3,0xffff
+ b L(done)
+L(negative):
+ bne cr7,L(negoverflow)
+ blt cr6,L(done)
+L(negoverflow):
+ lis r3,0x8000 /* return max negative int. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__fixsdsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtddi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtddi.S
new file mode 100644
index 000000000..6851a3867
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtddi.S
@@ -0,0 +1,36 @@
+/* Decimal Floating Point convert 128-bit to long. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* long __fixtddi (__decimal128 x) */
+ENTRY (__fixtddi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ drintnq. 0,fp2,fp2,1 /* Preround to toward zero. */
+ dctfixq fp0,fp2 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r3,8(r1)
+ lwz r4,12(r1)
+ addi r1,r1,16
+ blr
+ END (__fixtddi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtdsi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtdsi.S
new file mode 100644
index 000000000..6a761595c
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixtdsi.S
@@ -0,0 +1,56 @@
+/* Decimal Floating Point convert 128-bit to int.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __fixtdsi (__decimal28 x) */
+ENTRY (__fixtdsi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ drintnq. 0,fp2,fp2,1 /* Preround to toward zero. */
+ dctfixq fp0,fp2 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r0,8(r1)
+ lwz r3,12(r1)
+/* The return is an int, but we have long long, so we need to force overflow
+ if there are any significant bits in the high word or overflow (incorrect
+ sign) from the low word. */
+ cmpwi cr0,r0,0
+ cmpwi cr6,r3,0
+ cmpwi cr7,r0,-1
+ blt cr0,L(negative)
+ bne cr0,L(posoverflow)
+ bge cr6,L(done)
+L(posoverflow):
+ lis r3,0x7fff /* return max positive int. */
+ ori r3,r3,0xffff
+ b L(done)
+L(negative):
+ bne cr7,L(negoverflow)
+ blt cr6,L(done)
+L(negoverflow):
+ lis r3,0x8000 /* return max negative int. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__fixtdsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsdddi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsdddi.S
new file mode 100644
index 000000000..1a8e95d75
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsdddi.S
@@ -0,0 +1,89 @@
+/* Decimal Floating Point convert 64-bit to unsigned long. P6 PPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 3
+.LC1: /* 9223372036854775808.0DD */
+ .long 0x6e45237c
+ .long 0x836973f6
+.LC2: /* 18446744073709551616.0DD */
+ .long 0x264a4cdd
+ .long 0x2077c2dd
+ .section ".text"
+
+ .machine "power6"
+/* unsigned long __fixunsdddi (__decimal64 x) */
+ENTRY (__fixunsdddi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC1-1b@ha
+ addi r9,r9,.LC1-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC1@got(10)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+ lfd fp10,0(r9)
+ lfd fp11,.LC2-.LC1(r9)
+#else
+ lis r9,.LC1@ha
+ lis r10,.LC2@ha
+ lfd fp10,.LC1@l(r9)
+ lfd fp11,.LC2@l(r10)
+#endif
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dcmpu cr0,fp1,fp10 /* check if > 2**63-1 */
+ blt cr1,L(negative)
+ blt cr0,L(poslong)
+/* The return is an unsigned long, but "DFP convert to fixed" takes
+ signed long, so we need to pre-adjust (-18446744073709551616.0DD)
+ to get the final (signed) conversion result to be the correct
+ unsigned result. */
+ dsub fp1,fp1,fp11
+ dcmpu cr0,fp1,fp10 /* if x still > 2**63-1 */
+ li r3,-1 /* return max_unsigned_long */
+ blt cr0,L(done) /* else */
+L(poslong):
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r3,8(r1)
+ lwz r4,12(r1)
+ addi r1,r1,16
+ blr
+L(negative):
+ li r3,0 /* return 0 for negative floats. */
+L(done):
+ mr r4,r3
+ addi r1,r1,16
+ blr
+ END (__fixunsdddi)
+
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsddsi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsddsi.S
new file mode 100644
index 000000000..ae0e7f284
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunsddsi.S
@@ -0,0 +1,51 @@
+/* Decimal Floating Point convert 64-bit to unsigned int.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __fixunsddsi (__decimal64 x) */
+ENTRY (__fixunsddsi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r0,8(r1)
+ lwz r3,12(r1)
+/* The return is an int, but we have long long, so we need to force overflow
+ if there are any significant bits in the high word or overflow (incorrect
+ sign) from the low word. */
+ cmpwi cr0,r0,0
+ cmpwi cr6,r3,0
+ blt cr0,L(negative)
+ bne cr0,L(posoverflow)
+ bge cr6,L(done)
+L(posoverflow):
+ li r3,-1 /* return max unsigned int. */
+ b L(done)
+L(negative):
+ lis r3,0 /* return 0 for negative floats. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__fixunsddsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssddi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssddi.S
new file mode 100644
index 000000000..9df1c40f3
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssddi.S
@@ -0,0 +1,90 @@
+/* Decimal Floating Point convert 64-bit to unsigned long. P6 PPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 3
+.LC1: /* 9223372036854775808.0DD */
+ .long 0x6e45237c
+ .long 0x836973f6
+.LC2: /* 18446744073709551616.0DD */
+ .long 0x264a4cdd
+ .long 0x2077c2dd
+ .section ".text"
+
+ .machine "power6"
+/* unsigned long __fixunssddi (__decimal32 x) */
+ENTRY (__fixunssddi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC1-1b@ha
+ addi r9,r9,.LC1-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC1@got(10)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+ lfd fp10,0(r9)
+ lfd fp11,.LC2-.LC1(r9)
+#else
+ lis r9,.LC1@ha
+ lis r10,.LC2@ha
+ lfd fp10,.LC1@l(r9)
+ lfd fp11,.LC2@l(r10)
+#endif
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dcmpu cr0,fp1,fp10 /* check if > 2**63-1 */
+ blt cr1,L(negative)
+ blt cr0,L(poslong)
+/* The return is an unsigned long, but "DFP convert to fixed" takes
+ signed long, so we need to pre-adjust (-18446744073709551616.0DD)
+ to get the final (signed) conversion result to be the correct
+ unsigned result. */
+ dsub fp1,fp1,fp11
+ dcmpu cr0,fp1,fp10 /* if x still > 2**63-1 */
+ li r3,-1 /* return max_unsigned_long */
+ blt cr0,L(done) /* else */
+L(poslong):
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r3,8(r1)
+ lwz r4,12(r1)
+ addi r1,r1,16
+ blr
+L(negative):
+ li r3,0 /* return 0 for negative floats. */
+L(done):
+ mr r4,r3
+ addi r1,r1,16
+ blr
+ END (__fixunssddi)
+
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssdsi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssdsi.S
new file mode 100644
index 000000000..482ff593a
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunssdsi.S
@@ -0,0 +1,52 @@
+/* Decimal Floating Point convert 32-bit to unsigned int.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __fixunssdsi (__decimal32 x) */
+ENTRY (__fixunssdsi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r0,8(r1)
+ lwz r3,12(r1)
+/* The return is an int, but we have long long, so we need to force overflow
+ if there are any significant bits in the high word or overflow (incorrect
+ sign) from the low word. */
+ cmpwi cr0,r0,0
+ cmpwi cr6,r3,0
+ blt cr0,L(negative)
+ bne cr0,L(posoverflow)
+ bge cr6,L(done)
+L(posoverflow):
+ li r3,-1 /* return max unsigned int. */
+ b L(done)
+L(negative):
+ lis r3,0 /* return 0 for negative floats. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__fixunssdsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstddi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstddi.S
new file mode 100644
index 000000000..2716f825d
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstddi.S
@@ -0,0 +1,99 @@
+/* Decimal Floating Point convert 128-bit to unsigned long.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section .rodata.cst8,"aM",@progbits,8
+ .align 3
+.LC1: /* 9223372036854775808.0DL */
+ .long 0x2207c000
+ .long 0x00000003
+ .long 0xa4cfa07a
+ .long 0x2c7f600a
+.LC2: /* 18446744073709551616.0DL */
+ .long 0x2207c000
+ .long 0x0000000c
+ .long 0xa99e40ed
+ .long 0xc5ba58e0
+ .section ".text"
+
+ .machine "power6"
+/* unsigned long __fixunstddi (__decimal128 x) */
+ENTRY (__fixunstddi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+#ifdef SHARED
+ mflr r11
+ cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r9
+ addis r9,r9,.LC1-1b@ha
+ addi r9,r9,.LC1-1b@l
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r10
+ lwz r9,.LC1@got(10)
+# endif
+ mtlr r11
+ cfi_same_value (lr)
+ lfd fp10,0(r9)
+ lfd fp11,8(r9)
+ lfd fp8,.LC2-.LC1(r9)
+ lfd fp9,.LC2-.LC1+8(r9)
+#else
+ lis r9,.LC1@ha
+ lis r10,.LC2@ha
+ addi r9,r9,.LC1@l
+ addi r10,r10,.LC2@l
+ lfd fp10,0(r9)
+ lfd fp11,8(r9)
+ lfd fp8,0(r10)
+ lfd fp9,8(r10)
+#endif
+ drintnq. 0,fp2,fp2,1 /* Preround to toward zero. */
+ dcmpuq cr0,fp2,fp10 /* check if > 2**63-1 */
+ blt cr1,L(negative)
+ blt cr0,L(poslong)
+/* The return is an unsigned long, but "DFP convert to fixed" takes
+ signed long, so we need to pre-adjust (-18446744073709551616.0DD)
+ to get the final (signed) conversion result to be the correct
+ unsigned result. */
+ dsubq fp2,fp2,fp8
+ dcmpuq cr0,fp2,fp10 /* if x still > 2**63-1 */
+ li r3,-1 /* return max_unsigned_long */
+ blt cr0,L(done) /* else */
+L(poslong):
+ dctfixq fp0,fp2 /* Convert x to integer. */
+ stfd fp0,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r3,8(r1)
+ lwz r4,12(r1)
+ addi r1,r1,16
+ blr
+L(negative):
+ li r3,0 /* return 0 for negative floats. */
+L(done):
+ mr r4,r3
+ addi r1,r1,16
+ blr
+ END (__fixunstddi)
+
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstdsi.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstdsi.S
new file mode 100644
index 000000000..4a7a08b8e
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/fixunstdsi.S
@@ -0,0 +1,52 @@
+/* Decimal Floating Point convert 128-bit to unsigned int.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __fixunstdsi (__decimal128 x) */
+ENTRY (__fixunstdsi)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ drintnq. 0,fp2,fp2,1 /* Preround to toward zero. */
+ dctfixq fp0,fp2 /* Convert x to integer. */
+ stfd fp1,8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lwz r0,8(r1)
+ lwz r3,12(r1)
+/* The return is an int, but we have long long, so we need to force overflow
+ if there are any significant bits in the high word or overflow (incorrect
+ sign) from the low word. */
+ cmpwi cr0,r0,0
+ cmpwi cr6,r3,0
+ blt cr0,L(negative)
+ bne cr0,L(posoverflow)
+ bge cr6,L(done)
+L(posoverflow):
+ li r3,-1 /* return max unsigned int. */
+ b L(done)
+L(negative):
+ lis r3,0 /* return 0 for negative floats. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__fixunsddsi)
+
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdidd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdidd.S
new file mode 100644
index 000000000..531658240
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdidd.S
@@ -0,0 +1,42 @@
+/* Convert int to Decimal Floating Point 64-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __floatdidd (int x) */
+ENTRY (__floatdidd)
+ cmpwi cr6,r3,0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,-1 /* extend negative. */
+ blt cr6,L(negative)
+ li r0,0 /* extend positive. */
+L(negative):
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatdidd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdisd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdisd.S
new file mode 100644
index 000000000..1e20d12f4
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatdisd.S
@@ -0,0 +1,43 @@
+/* Convert int to Decimal Floating Point 32-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __floatdisd (int x) */
+ENTRY (__floatdisd)
+ cmpwi cr6,r3,0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,-1 /* extend negative. */
+ blt cr6,L(negative)
+ li r0,0 /* extend positive. */
+L(negative):
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatdisd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatditd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatditd.S
new file mode 100644
index 000000000..53aca3da4
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatditd.S
@@ -0,0 +1,42 @@
+/* Convert int to Decimal Floating Point 128-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __floatditd (int x) */
+ENTRY (__floatditd)
+ cmpwi cr6,r3,0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,-1 /* extend negative. */
+ blt cr6,L(negative)
+ li r0,0 /* extend positive. */
+L(negative):
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffixq fp2,fp0 /* Convert x to decimal float. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatditd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsidd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsidd.S
new file mode 100644
index 000000000..aaf9072c6
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsidd.S
@@ -0,0 +1,42 @@
+/* Convert int to Decimal Floating Point 64-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __floatsidd (int x) */
+ENTRY (__floatsidd)
+ cmpwi cr6,r3,0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,-1 /* extend negative. */
+ blt cr6,L(negative)
+ li r0,0 /* extend positive. */
+L(negative):
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatsidd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsisd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsisd.S
new file mode 100644
index 000000000..a1e0bf8a3
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsisd.S
@@ -0,0 +1,43 @@
+/* Convert int to Decimal Floating Point 32-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __floatsisd (int x) */
+ENTRY (__floatsisd)
+ cmpwi cr6,r3,0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,-1 /* extend negative. */
+ blt cr6,L(negative)
+ li r0,0 /* extend positive. */
+L(negative):
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatsisd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsitd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsitd.S
new file mode 100644
index 000000000..af80a038d
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatsitd.S
@@ -0,0 +1,42 @@
+/* Convert int to Decimal Floating Point 128-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __floatsitd (int x) */
+ENTRY (__floatsitd)
+ cmpwi cr6,r3,0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,-1 /* extend negative. */
+ blt cr6,L(negative)
+ li r0,0 /* extend positive. */
+L(negative):
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffixq fp2,fp0 /* Convert x to decimal float. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatsitd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdidd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdidd.S
new file mode 100644
index 000000000..b04cddedd
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdidd.S
@@ -0,0 +1,38 @@
+/* Convert unsigned int to Decimal Floating Point 64-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __floatunsdidd (unsigned int x) */
+ENTRY (__floatunsdidd)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,0 /* extend unsigned. */
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal floatuns. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatunsdidd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdisd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdisd.S
new file mode 100644
index 000000000..d45ffd6f5
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsdisd.S
@@ -0,0 +1,39 @@
+/* Convert unsigned int to Decimal Floating Point 32-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __floatunsdisd (unsigned int x) */
+ENTRY (__floatunsdisd)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,0 /* extend unsigned. */
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal floatuns. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatunsdisd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsditd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsditd.S
new file mode 100644
index 000000000..fa9cec773
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunsditd.S
@@ -0,0 +1,38 @@
+/* Convert unsigned int to Decimal Floating Point 128-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __floatunsditd (unsigned int x) */
+ENTRY (__floatunsditd)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,0 /* extend unsigned. */
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffixq fp2,fp0 /* Convert x to decimal floatuns. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatunsditd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssidd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssidd.S
new file mode 100644
index 000000000..18ffae148
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssidd.S
@@ -0,0 +1,38 @@
+/* Convert unsigned int to Decimal Floating Point 64-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __floatunssidd (unsigned int x) */
+ENTRY (__floatunssidd)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,0 /* extend unsigned. */
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal floatuns. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatunssidd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssisd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssisd.S
new file mode 100644
index 000000000..595954b35
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssisd.S
@@ -0,0 +1,39 @@
+/* Convert unsigned int to Decimal Floating Point 32-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __floatunssisd (unsigned int x) */
+ENTRY (__floatunssisd)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,0 /* extend unsigned. */
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal floatuns. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatunssisd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssitd.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssitd.S
new file mode 100644
index 000000000..68ad89855
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/floatunssitd.S
@@ -0,0 +1,38 @@
+/* Convert unsigned int to Decimal Floating Point 128-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __floatunssitd (unsigned int x) */
+ENTRY (__floatunssitd)
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset (16)
+ li r0,0 /* extend unsigned. */
+ stw r0,8(r1)
+ stw r3,12(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,8(r1)
+ dcffixq fp2,fp0 /* Convert x to decimal floatuns. */
+L(done):
+ addi r1,r1,16
+ blr
+ END (__floatunssitd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gedd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gedd2.S
new file mode 100644
index 000000000..598ea6226
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gedd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 64-bit compare >=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gedd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__gedd2)
+ dcmpu cr0,fp1,fp2 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gedd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gesd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gesd2.S
new file mode 100644
index 000000000..f86fed05c
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gesd2.S
@@ -0,0 +1,35 @@
+/* Decimal Floating Point 32-bit compare >=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gesd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__gesd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gesd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/getd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/getd2.S
new file mode 100644
index 000000000..aeba48405
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/getd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 128-bit compare >=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __getd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__getd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__getd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtdd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtdd2.S
new file mode 100644
index 000000000..1383569b7
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtdd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 64-bit compare >=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gtdd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__gtdd2)
+ dcmpu cr0,fp1,fp2 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gtdd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtsd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtsd2.S
new file mode 100644
index 000000000..896224c79
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gtsd2.S
@@ -0,0 +1,35 @@
+/* Decimal Floating Point 32-bit compare >=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gtsd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__gtsd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gtsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gttd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gttd2.S
new file mode 100644
index 000000000..783575798
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/gttd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 128-bit compare >=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gttd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__gttd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gttd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ledd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ledd2.S
new file mode 100644
index 000000000..b6c1a9fa1
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ledd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 64-bit compare <. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __ledd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__ledd2)
+ dcmpu cr0,fp1,fp2 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__ledd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/lesd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/lesd2.S
new file mode 100644
index 000000000..eb2e2ac70
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/lesd2.S
@@ -0,0 +1,35 @@
+/* Decimal Floating Point 32-bit compare <. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __lesd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__lesd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__lesd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/letd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/letd2.S
new file mode 100644
index 000000000..72df3765c
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/letd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 128-bit compare >=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __letd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__letd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__letd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltdd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltdd2.S
new file mode 100644
index 000000000..eeb3bf48e
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltdd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 64-bit compare <. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __ltdd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__ltdd2)
+ dcmpu cr0,fp1,fp2 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__ltdd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltsd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltsd2.S
new file mode 100644
index 000000000..f84f512eb
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/ltsd2.S
@@ -0,0 +1,35 @@
+/* Decimal Floating Point 32-bit compare <. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __ltsd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__ltsd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__ltsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/lttd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/lttd2.S
new file mode 100644
index 000000000..837935925
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/lttd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 128-bit compare >=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __lttd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__lttd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__lttd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/muldd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/muldd3.S
new file mode 100644
index 000000000..01eda0397
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/muldd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 64-bit multiply. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __muldd3 (__decimal64 x, __decimal64 y) */
+ENTRY (__muldd3)
+ dmul fp1,fp1,fp2
+ blr
+ END (__muldd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/mulsd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/mulsd3.S
new file mode 100644
index 000000000..b80b954b4
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/mulsd3.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 32-bit multiply. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __mulsd3 (__decimal32 x, __decimal32 y) */
+ENTRY (__mulsd3)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dmul fp1,fp1,fp2
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__mulsd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/multd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/multd3.S
new file mode 100644
index 000000000..0e54e521b
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/multd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 128-bit multiply. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __multd3 (__decimal128 x, __decimal128 y) */
+ENTRY (__multd3)
+ dmulq fp2,fp2,fp4
+ blr
+ END (__multd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/nedd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/nedd2.S
new file mode 100644
index 000000000..589c4418d
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/nedd2.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point 64-bit compare !=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __nedd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__nedd2)
+ dcmpu cr0,fp1,fp2 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ bunlr cr0
+ li r3, 1 /* return 1 */
+ blr
+ END (__nedd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/nesd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/nesd2.S
new file mode 100644
index 000000000..f18581416
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/nesd2.S
@@ -0,0 +1,34 @@
+/* Decimal Floating Point 32-bit compare !=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __nesd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__nesd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ bunlr cr0
+ li r3, 1 /* return 1 */
+ blr
+ END (__nesd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/netd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/netd2.S
new file mode 100644
index 000000000..9b961875d
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/netd2.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point 128-bit compare !=. P6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __netd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__netd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ bunlr cr0
+ li r3, 1 /* return 1 */
+ blr
+ END (__netd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subdd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subdd3.S
new file mode 100644
index 000000000..b16dd3c22
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subdd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 64-bit substract. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __subdd3 (__decimal64 x, __decimal64 y) */
+ENTRY (__subdd3)
+ dsub fp1,fp1,fp2
+ blr
+ END (__subdd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subsd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subsd3.S
new file mode 100644
index 000000000..281695cd8
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subsd3.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 32-bit subtract. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __subsd3 (__decimal32 x, __decimal32 y) */
+ENTRY (__subsd3)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dsub fp1,fp1,fp2
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__subsd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subtd3.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subtd3.S
new file mode 100644
index 000000000..87ca173c1
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/subtd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 128-bit subtract. POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __subtd3 (__decimal128 x, __decimal128 y) */
+ENTRY (__subtd3)
+ dsubq fp2,fp2,fp4
+ blr
+ END (__subtd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/truncddsd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/truncddsd2.S
new file mode 100644
index 000000000..ed9bd69a6
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/truncddsd2.S
@@ -0,0 +1,29 @@
+/* Decimal Floating Point truncate 64-bit to 32-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __truncddsd2 (__decimal64 x) */
+ENTRY (__truncddsd2)
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__truncddsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctddd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctddd2.S
new file mode 100644
index 000000000..d4867aaf9
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctddd2.S
@@ -0,0 +1,29 @@
+/* Decimal Floating Point truncate 128-bit to 64-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __trunctddd2 (__decimal128 x) */
+ENTRY (__trunctddd2)
+ drdpq fp1,fp2 /* Round result to __decimal64. */
+ blr
+ END (__trunctddd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctdsd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctdsd2.S
new file mode 100644
index 000000000..4edbf2cd0
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/trunctdsd2.S
@@ -0,0 +1,30 @@
+/* Decimal Floating Point truncate 128-bit to 32-bit.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __trunctdsd2 (__decimal128 x) */
+ENTRY (__trunctdsd2)
+ drdpq fp1,fp2 /* Round result to __decimal64. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__trunctdsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unorddd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unorddd2.S
new file mode 100644
index 000000000..2f06b1bc0
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unorddd2.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point 64-bit unordered compare.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __unorddd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__unorddd2)
+ dcmpu cr0,fp1,fp2 /* if (!unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ bnulr+ cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__unorddd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unordsd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unordsd2.S
new file mode 100644
index 000000000..2348e3793
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unordsd2.S
@@ -0,0 +1,34 @@
+/* Decimal Floating Point 32-bit unordered compare.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __unordsd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__unordsd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if (!unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ bnulr+ cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__unordsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unordtd2.S b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unordtd2.S
new file mode 100644
index 000000000..82f59ae2d
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/unordtd2.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point 128-bit unordered compare.
+ POWER6 PowerPC32 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __unordtd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__unordtd2)
+ dcmpuq cr0,fp2,fp4 /* if (!unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ bnulr+ cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__unordtd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc32/power6x/fpu/Implies b/libc/dfp/sysdeps/powerpc/powerpc32/power6x/fpu/Implies
new file mode 100644
index 000000000..d53ce2573
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc32/power6x/fpu/Implies
@@ -0,0 +1 @@
+powerpc/powerpc32/power6/fpu
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Makefile b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Makefile
new file mode 100644
index 000000000..f5214307f
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Makefile
@@ -0,0 +1,25 @@
+# Makefile fragment for POWER6 with FPU.
+
+ifeq ($(subdir),dfp)
+libdfp-routines += addsd3 adddd3 addtd3 \
+ subsd3 subdd3 subtd3 \
+ mulsd3 muldd3 multd3 \
+ divsd3 divdd3 divtd3 \
+ extendsddd2 extendsdtd2 extendddtd2 \
+ trunctdsd2 truncddsd2 trunctdsd2 \
+ unordsd2 unorddd2 unordtd2 \
+ eqsd2 eqdd2 eqtd2 \
+ nesd2 nedd2 netd2 \
+ gesd2 gedd2 getd2 \
+ gtsd2 gtdd2 gttd2 \
+ ltsd2 ltdd2 lttd2 \
+ lesd2 ledd2 letd2 \
+ fixsdsi fixddsi fixtdsi \
+ fixsddi fixdddi fixtddi \
+ fixunssdsi fixunsddsi fixunstdsi \
+ fixunssddi fixunsdddi fixunstddi \
+ floatsisd floatsidd floatsitd \
+ floatdisd floatdidd floatditd \
+ floatunssisd floatunssidd floatunssitd \
+ floatunsdisd floatunsdidd floatunsditd
+endif
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions
new file mode 100644
index 000000000..d4470bd43
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/Versions
@@ -0,0 +1,21 @@
+libdfp {
+ GLIBC_2.5 {
+ __addsd3; __adddd3; __addtd3;
+ __subsd3; __subdd3; __subtd3;
+ __mulsd3; __muldd3; __multd3;
+ __divsd3; __divdd3; __divtd3;
+ __extendsddd2; __extendsdtd2; __extendddtd2;
+ __trunctdsd2; __truncddsd2; __trunctddd2;
+ __unordsd2; __unorddd2; __unordtd2;
+ __eqsd2; __eqdd2; __eqtd2; __nesd2; __nedd2; __netd2;
+ __gesd2; __gedd2; __getd2; __gtsd2; __gtdd2; __gttd2;
+ __ltsd2; __ltdd2; __lttd2; __lesd2; __ledd2; __letd2;
+ __fixsdsi; __fixddsi; __fixtdsi; __fixsddi; __fixdddi; __fixtddi;
+ __fixunssdsi; __fixunsddsi; __fixunstdsi;
+ __fixunssddi; __fixunsdddi; __fixunstddi;
+ __floatsisd; __floatsidd; __floatsitd;
+ __floatdisd; __floatdidd; __floatditd;
+ __floatunssisd; __floatunssidd; __floatunssitd;
+ __floatunsdisd; __floatunsdidd; __floatunsditd;
+ }
+}
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/adddd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/adddd3.S
new file mode 100644
index 000000000..b2f7fe524
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/adddd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 64-bit add. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __adddd3 (__decimal64 x, __decimal64 y) */
+ENTRY (__adddd3)
+ dadd fp1,fp1,fp2
+ blr
+ END (__adddd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/addsd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/addsd3.S
new file mode 100644
index 000000000..e6f1b3e32
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/addsd3.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 32-bit add. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __addsd3 (__decimal32 x, __decimal32 y) */
+ENTRY (__addsd3)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dadd fp1,fp1,fp2
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__addsd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/addtd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/addtd3.S
new file mode 100644
index 000000000..162503dd4
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/addtd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 128-bit add. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __addtd3 (__decimal128 x, __decimal128 y) */
+ENTRY (__addtd3)
+ daddq fp2,fp2,fp4
+ blr
+ END (__addtd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divdd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divdd3.S
new file mode 100644
index 000000000..05cc0ccde
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divdd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 64-bit divide. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __divdd3 (__decimal64 x, __decimal64 y) */
+ENTRY (__divdd3)
+ ddiv fp1,fp1,fp2
+ blr
+ END (__divdd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divsd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divsd3.S
new file mode 100644
index 000000000..c8ab54064
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divsd3.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 32-bit divide. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __divsd3 (__decimal32 x, __decimal32 y) */
+ENTRY (__divsd3)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ ddiv fp1,fp1,fp2
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__divsd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divtd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divtd3.S
new file mode 100644
index 000000000..1353715dd
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/divtd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 128-bit divide. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __divtd3 (__decimal128 x, __decimal128 y) */
+ENTRY (__divtd3)
+ ddivq fp2,fp2,fp4
+ blr
+ END (__divtd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqdd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqdd2.S
new file mode 100644
index 000000000..d186af852
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqdd2.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 64-bit compare equal. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __eqdd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__eqdd2)
+ dcmpu cr0,fp1,fp2 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__eqdd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqsd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqsd2.S
new file mode 100644
index 000000000..fafd918ad
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqsd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 32-bit compare equal. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __eqsd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__eqsd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__eqsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqtd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqtd2.S
new file mode 100644
index 000000000..c43b68d89
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/eqtd2.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 128-bit compare equal. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __eqtd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__eqtd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__eqtd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendddtd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendddtd2.S
new file mode 100644
index 000000000..1137048b9
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendddtd2.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point extend 64-bit to 128-bit. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __extendddtd2 (__decimal64 x) */
+ENTRY (__extendddtd2)
+ dctqpq fp2,fp1 /* Convert x to __decimal128. */
+ blr
+ END (__extendddtd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendsddd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendsddd2.S
new file mode 100644
index 000000000..2b44c8517
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendsddd2.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point extend 32-bit to 64-bit. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __extendsddd2 (__decimal32 x) */
+ENTRY (__extendsddd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ blr
+ END (__extendsddd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendsdtd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendsdtd2.S
new file mode 100644
index 000000000..22c19f880
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/extendsdtd2.S
@@ -0,0 +1,29 @@
+/* Decimal Floating Point extend 32-bit to 128-bit. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __extendsdtd2 (__decimal32 x) */
+ENTRY (__extendsdtd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctqpq fp2,fp1 /* Convert x to __decimal128. */
+ blr
+ END (__extendsdtd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixdddi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixdddi.S
new file mode 100644
index 000000000..7c293a7fe
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixdddi.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point convert 64-bit to long. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* long __fixdddi (__decimal64 x) */
+ENTRY (__fixdddi)
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ ld r3,-8(r1)
+ blr
+ END (__fixdddi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixddsi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixddsi.S
new file mode 100644
index 000000000..87fb780a5
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixddsi.S
@@ -0,0 +1,51 @@
+/* Decimal Floating Point convert 64-bit to int. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __fixddsi (__decimal64 x) */
+ENTRY (__fixddsi)
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ oris r4,0,0x8000 /* 0x0000000080000000 */
+ lis r5,0x8000 /* 0xffffffff80000000 */
+ ld r3,-8(r1)
+/* The return is an int, but we have long long, so we need to force overflow
+ if there are any significant bits in the high word or overflow (incorrect
+ sign) from the low word. */
+
+ cmpd cr0,r3,r4
+ cmpd cr7,r3,r5
+ cmpdi cr6,r3,0
+ blt cr1,L(negative)
+ bltlr cr0
+L(posoverflow):
+ addi r3,r4,-1 /* return max positive int. */
+ blr
+L(negative): /* If (result >= min negative int */
+ bgelr cr7 /* return result */
+L(negoverflow): /* else */
+ mr r3,r5 /* return min negative int. */
+ blr
+ END (__fixddsi)
+
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsddi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsddi.S
new file mode 100644
index 000000000..0f36cd5a8
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsddi.S
@@ -0,0 +1,34 @@
+/* Decimal Floating Point convert 32-bit to long. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* long __fixsddi (__decimal32 x) */
+ENTRY (__fixsddi)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ ld r3,-8(r1)
+ blr
+ END (__fixsddi)
+
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsdsi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsdsi.S
new file mode 100644
index 000000000..73cbf2a5c
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixsdsi.S
@@ -0,0 +1,51 @@
+/* Decimal Floating Point convert 32-bit to int. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __fixsdsi (__decimal32 x) */
+ENTRY (__fixsdsi)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ oris r4,0,0x8000 /* 0x0000000080000000 */
+ lis r5,0x8000 /* 0xffffffff80000000 */
+ ld r3,-8(r1)
+/* The return is an int, but we have long long, so we need to force overflow
+ if there are any significant bits in the high word or overflow (incorrect
+ sign) from the low word. */
+
+ cmpd cr0,r3,r4
+ cmpd cr7,r3,r5
+ cmpdi cr6,r3,0
+ blt cr1,L(negative)
+ bltlr cr0
+L(posoverflow):
+ addi r3,r4,-1 /* return max positive int. */
+ blr
+L(negative): /* If (result >= min negative int */
+ bgelr cr7 /* return result */
+L(negoverflow): /* else */
+ mr r3,r5 /* return min negative int. */
+ blr
+ END (__fixsdsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtddi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtddi.S
new file mode 100644
index 000000000..e493e69bc
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtddi.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point convert 128-bit to long. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* long __fixtddi (__decimal28 x) */
+ENTRY (__fixtddi)
+ drintnq. 0,fp2,fp2,1 /* Preround to toward zero. */
+ dctfixq fp0,fp2 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ ld r3,-8(r1)
+ blr
+ END (__fixtddi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtdsi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtdsi.S
new file mode 100644
index 000000000..c4d14eda4
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixtdsi.S
@@ -0,0 +1,50 @@
+/* Decimal Floating Point convert 128-bit to int. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __fixtdsi (__decimal28 x) */
+ENTRY (__fixtdsi)
+ drintnq. 0,fp2,fp2,1 /* Preround to toward zero. */
+ dctfixq fp0,fp2 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ oris r4,0,0x8000 /* 0x0000000080000000 */
+ lis r5,0x8000 /* 0xffffffff80000000 */
+ ld r3,-8(r1)
+/* The return is an int, but we have long long, so we need to force overflow
+ if there are any significant bits in the high word or overflow (incorrect
+ sign) from the low word. */
+
+ cmpd cr0,r3,r4
+ cmpd cr7,r3,r5
+ cmpdi cr6,r3,0
+ blt cr1,L(negative)
+ bltlr cr0
+L(posoverflow):
+ addi r3,r4,-1 /* return max positive int. */
+ blr
+L(negative): /* If (result >= min negative int */
+ bgelr cr7 /* return result */
+L(negoverflow): /* else */
+ mr r3,r5 /* return min negative int. */
+ blr
+ END (__fixtdsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsdddi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsdddi.S
new file mode 100644
index 000000000..8e7736d16
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsdddi.S
@@ -0,0 +1,57 @@
+/* Decimal Floating Point convert 64-bit to unsigned long. P6 PPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC1: /* 9223372036854775808.0DD */
+ .tc FD_6e45237c_836973f6[TC],0x6e45237c836973f6
+.LC2: /* 18446744073709551616.0DD */
+ .tc FD_264a4cdd_2077c2dd[TC],0x264a4cdd2077c2dd
+ .section ".text"
+
+ .machine "power6"
+/* unsigned long __fixunsdddi (__decimal64 x) */
+ENTRY (__fixunsdddi)
+ lfd fp10,.LC1@toc(2)
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dcmpu cr0,fp1,fp10 /* check if > 2**63-1 */
+ blt cr1,L(negative)
+ lfd fp11,.LC2@toc(2)
+ blt cr0,L(poslong)
+/* The return is an unsigned long, but "DFP convert to fixed" takes
+ signed long, so we need to pre-adjust (-18446744073709551616.0DD)
+ to get the final (signed) conversion result to be the correct
+ unsigned result. */
+ dsub fp1,fp1,fp11
+ dcmpu cr0,fp1,fp10 /* if x still > 2**63-1 */
+ li r3,-1 /* return max_unsigned_long */
+ bgelr cr0 /* else */
+L(poslong):
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ ld r3,-8(r1)
+ blr
+L(negative):
+ li r3,0 /* return 0 for negative floats. */
+ blr
+ END (__fixunsdddi)
+
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsddsi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsddsi.S
new file mode 100644
index 000000000..47209a79a
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunsddsi.S
@@ -0,0 +1,45 @@
+/* Decimal Floating Point convert 64-bit to unsigned int. P6 PPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* unsigned int __fixunsddsi (__decimal64 x) */
+ENTRY (__fixunsddsi)
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ oris r4,0,0xffff /* 0x00000000ffff0000 */
+ ori r4,r4,0xffff /* 0x00000000ffffffff */
+ ld r3,-8(r1)
+/* The return is an unsigned int, but we have long long, so we need to force
+ overflow if there are any significant bits in the high word or return
+ zero if negative. */
+ cmpld cr6,r3,r4
+ blt cr1,L(negative)
+ blelr cr6
+L(posoverflow):
+ mr r3,r4 /* return max unsigned int. */
+ blr
+L(negative):
+ li r3,0 /* return 0 for negative floats. */
+ blr
+ END (__fixunsddsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssddi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssddi.S
new file mode 100644
index 000000000..eeeb13c40
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssddi.S
@@ -0,0 +1,59 @@
+/* Decimal Floating Point convert 32-bit to unsigned long.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC1: /* 9223372036854775808.0DD */
+ .tc FD_6e45237c_836973f6[TC],0x6e45237c836973f6
+.LC2: /* 18446744073709551616.0DD */
+ .tc FD_264a4cdd_2077c2dd[TC],0x264a4cdd2077c2dd
+ .section ".text"
+
+ .machine "power6"
+/* unsigned long __fixunssddi (__decimal32 x) */
+ENTRY (__fixunssddi)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ lfd fp10,.LC1@toc(2)
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dcmpu cr0,fp1,fp10 /* check if > 2**63-1 */
+ blt cr1,L(negative)
+ lfd fp11,.LC1@toc(2)
+ blt cr0,L(poslong)
+/* The return is an unsigned long, but "DFP convert to fixed" takes
+ signed long, so we need to pre-adjust (-18446744073709551616.0DD)
+ to get the final (signed) conversion result to be the correct
+ unsigned result. */
+ dsub fp1,fp1,fp11
+ dcmpu cr0,fp1,fp10 /* if x still > 2**63-1 */
+ li r3,-1 /* return max_unsigned_long */
+ bgelr cr0 /* else */
+L(poslong):
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ ld r3,-8(r1)
+ blr
+L(negative):
+ li r3,0 /* return 0 for negative floats. */
+ blr
+ END (__fixunssddi)
+
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssdsi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssdsi.S
new file mode 100644
index 000000000..a4a4d5134
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunssdsi.S
@@ -0,0 +1,47 @@
+/* Decimal Floating Point convert 32-bit to unsigned int.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* unsigned int __fixunssdsi (__decimal32 x) */
+ENTRY (__fixunssdsi)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ drintn. 0,fp1,fp1,1 /* Preround to toward zero. */
+ dctfix fp0,fp1 /* Convert x to integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ oris r4,0,0xffff /* 0x00000000ffff0000 */
+ ori r4,r4,0xffff /* 0x00000000ffffffff */
+ ld r3,-8(r1)
+/* The return is an unsigned int, but we have long long, so we need to force
+ overflow if there are any significant bits in the high word or return
+ zero if negative. */
+ cmpld cr6,r3,r4
+ blt cr1,L(negative)
+ blelr cr6
+L(posoverflow):
+ mr r3,r4 /* return max unsigned int. */
+ blr
+L(negative):
+ li r3,0 /* return 0 for negative floats. */
+ blr
+ END (__fixunssdsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstddi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstddi.S
new file mode 100644
index 000000000..d27b29e33
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstddi.S
@@ -0,0 +1,60 @@
+/* Decimal Floating Point convert 128-bit to unsigned long.
+ POWER6 PPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC1: /* 9223372036854775808.0DD */
+ .tc FT_2207c000_3_a4cfa07a_2c7f600a[TC],0x2207c00000000003,0xa4cfa07a2c7f600a
+.LC2: /* 18446744073709551616.0DD */
+ .tc FT_2207c000_c_a99e40ed_c5ba58e0[TC],0x2207c0000000000c,0xa99e40edc5ba58e0
+ .section ".text"
+
+ .machine "power6"
+/* unsigned long __fixunstddi (__decimal128 x) */
+ENTRY (__fixunstddi)
+ lfd fp10,.LC1@toc(2)
+ lfd fp11,.LC1@toc+8(2)
+ drintnq. 0,fp2,fp2,1 /* Preround to toward zero. */
+ dcmpuq cr0,fp2,fp10 /* check if > 2**63-1 */
+ blt cr1,L(negative)
+ lfd fp8,.LC2@toc(2)
+ lfd fp9,.LC2@toc+8(2)
+ blt cr0,L(poslong)
+/* The return is an unsigned long, but "DFP convert to fixed" takes
+ signed long, so we need to pre-adjust (-18446744073709551616.0DD)
+ to get the final (signed) conversion result to be the correct
+ unsigned result. */
+ dsubq fp2,fp2,fp8
+ dcmpuq cr0,fp2,fp10 /* if x still > 2**63-1 */
+ li r3,-1 /* return max_unsigned_long */
+ bgelr cr0 /* else */
+L(poslong):
+ dctfixq fp0,fp2 /* Convert x to long integer. */
+ stfd fp0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ ld r3,-8(r1)
+ blr
+L(negative):
+ li r3,0 /* return 0 for negative floats. */
+ blr
+ END (__fixunstddi)
+
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstdsi.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstdsi.S
new file mode 100644
index 000000000..61daefa9e
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/fixunstdsi.S
@@ -0,0 +1,46 @@
+/* Decimal Floating Point convert 128-bit to unsigned int.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* unsigned int __fixunstdsi (__decimal128 x) */
+ENTRY (__fixunstdsi)
+ drintnq. 0,fp2,fp2,1 /* Preround to toward zero. */
+ dctfixq fp0,fp2 /* Convert x to integer. */
+ stfd fp1,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ oris r4,0,0xffff /* 0x00000000ffff0000 */
+ ori r4,r4,0xffff /* 0x00000000ffffffff */
+ ld r3,-8(r1)
+/* The return is an unsigned int, but we have long long, so we need to force
+ overflow if there are any significant bits in the high word or return
+ zero if negative. */
+ cmpld cr6,r3,r4
+ blt cr1,L(negative)
+ blelr cr6
+L(posoverflow):
+ mr r3,r4 /* return max unsigned int. */
+ blr
+L(negative):
+ li r3,0 /* return 0 for negative floats. */
+ blr
+ END (__fixunstdsi)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdidd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdidd.S
new file mode 100644
index 000000000..bc926299a
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdidd.S
@@ -0,0 +1,31 @@
+/* Convert long to Decimal Floating Point 64-bit. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __floatdidd (long x) */
+ENTRY (__floatdidd)
+ std r3,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+ blr
+ END (__floatdidd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdisd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdisd.S
new file mode 100644
index 000000000..77cf5d51c
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatdisd.S
@@ -0,0 +1,32 @@
+/* Convert long to Decimal Floating Point 32-bit. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __floatdisd (long x) */
+ENTRY (__floatdisd)
+ std r0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__floatdisd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatditd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatditd.S
new file mode 100644
index 000000000..3877b5cb0
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatditd.S
@@ -0,0 +1,31 @@
+/* Convert long to Decimal Floating Point 128-bit. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __floatditd (long x) */
+ENTRY (__floatditd)
+ std r0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ dcffixq fp2,fp0 /* Convert x to decimal float. */
+ blr
+ END (__floatditd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsidd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsidd.S
new file mode 100644
index 000000000..2861bfb8e
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsidd.S
@@ -0,0 +1,31 @@
+/* Convert int to Decimal Floating Point 64-bit. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __floatsidd (int x) */
+ENTRY (__floatsidd)
+ std r3,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+ blr
+ END (__floatsidd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsisd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsisd.S
new file mode 100644
index 000000000..a439ba14d
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsisd.S
@@ -0,0 +1,32 @@
+/* Convert int to Decimal Floating Point 32-bit. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __floatsisd (int x) */
+ENTRY (__floatsisd)
+ std r3,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__floatsisd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsitd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsitd.S
new file mode 100644
index 000000000..f8d2a1db9
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatsitd.S
@@ -0,0 +1,31 @@
+/* Convert int to Decimal Floating Point 128-bit. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __floatsitd (int x) */
+ENTRY (__floatsitd)
+ std r3,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ dcffixq fp2,fp0 /* Convert x to decimal float. */
+ blr
+ END (__floatsitd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdidd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdidd.S
new file mode 100644
index 000000000..f34f2ac4a
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdidd.S
@@ -0,0 +1,50 @@
+/* Convert unsigned long to Decimal Floating Point 64-bit.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC1: /* 9223372036854775808.0DD */
+ .tc FD_6e45237c_836973f6[TC],0x6e45237c836973f6
+ .section ".text"
+
+ .machine "power6"
+/* __decimal64 __floatunsdidd (unsigned long x) */
+ENTRY (__floatunsdidd)
+ cmpdi cr0,r3,0
+ std r3,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ blt cr0,L(negative)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+ blr
+/* we need to do more here. The function converts a unsigned long, but
+ the dcffix instruction provides a signed conversion. So we force
+ the binary to be positive by clearing the sign bit before we convert
+ to decimal. Then we add 9223372036854775808.0DD to the result of the
+ dcffix. This gives the decimal equivalent to the full 64-bit value. */
+L(negative):
+ fabs fp0,fp0
+ lfd fp10,.LC1@toc(2)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+ dadd fp1,fp1,fp10
+ blr
+ END (__floatunsdidd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdisd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdisd.S
new file mode 100644
index 000000000..c4a349b9b
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsdisd.S
@@ -0,0 +1,52 @@
+/* Convert unsigned long to Decimal Floating Point 32-bit.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC1: /* 9223372036854775808.0DD */
+ .tc FD_6e45237c_836973f6[TC],0x6e45237c836973f6
+ .section ".text"
+
+ .machine "power6"
+/* __decimal32 __floatunsdisd (unsigned long x) */
+ENTRY (__floatunsdisd)
+ cmpdi cr0,r3,0
+ std r3,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ blt cr0,L(negative)
+ dcffix fp1,fp0 /* Convert x to decimal floatuns. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+/* we need to do more here. The function converts a unsigned long, but
+ the dcffix instruction provides a signed conversion. So we force
+ the binary to be positive by clearing the sign bit before we convert
+ to decimal. Then we add 9223372036854775808.0DD to the result of the
+ dcffix. This gives the decimal equivalent to the full 64-bit value. */
+L(negative):
+ fabs fp0,fp0
+ lfd fp10,.LC1@toc(2)
+ dcffix fp1,fp0 /* Convert x to decimal float. */
+ dadd fp1,fp1,fp10
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__floatunsdisd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsditd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsditd.S
new file mode 100644
index 000000000..d815623a4
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunsditd.S
@@ -0,0 +1,51 @@
+/* Convert unsigned long to Decimal Floating Point 128-bit.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .section ".toc","aw"
+.LC1: /* 9223372036854775808.0DD */
+ .tc FT_2207c000_3_a4cfa07a_2c7f600a[TC],0x2207c00000000003,0xa4cfa07a2c7f600a
+ .section ".text"
+
+ .machine "power6"
+/* __decimal128 __floatunsditd (unsigned long x) */
+ENTRY (__floatunsditd)
+ cmpdi cr0,r3,0
+ std r3,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ blt cr0,L(negative)
+ dcffixq fp2,fp0 /* Convert x to decimal floatuns. */
+ blr
+/* we need to do more here. The function converts a unsigned long, but
+ the dcffix instruction provides a signed conversion. So we force
+ the binary to be positive by clearing the sign bit before we convert
+ to decimal. Then we add 9223372036854775808.0DD to the result of the
+ dcffixq. This gives the decimal equivalent to the full 64-bit value. */
+L(negative):
+ fabs fp0,fp0
+ lfd fp10,.LC1@toc(2)
+ lfd fp11,.LC1@toc+8(2)
+ dcffixq fp2,fp0 /* Convert x to decimal float. */
+ daddq fp2,fp2,fp10
+ blr
+ END (__floatunsditd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssidd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssidd.S
new file mode 100644
index 000000000..94abec2fd
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssidd.S
@@ -0,0 +1,33 @@
+/* Convert unsigned int to Decimal Floating Point 64-bit.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __floatunssidd (unsigned int x) */
+ENTRY (__floatunssidd)
+ clrldi r0,r3,32 /* extend unsigned. */
+ std r0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal floatuns. */
+ blr
+ END (__floatunssidd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssisd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssisd.S
new file mode 100644
index 000000000..f969c31dc
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssisd.S
@@ -0,0 +1,34 @@
+/* Convert unsigned int to Decimal Floating Point 32-bit.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __floatunssisd (unsigned int x) */
+ENTRY (__floatunssisd)
+ clrldi r0,r3,32 /* extend unsigned. */
+ std r0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ dcffix fp1,fp0 /* Convert x to decimal floatuns. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__floatunssisd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssitd.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssitd.S
new file mode 100644
index 000000000..b31e30952
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/floatunssitd.S
@@ -0,0 +1,33 @@
+/* Convert unsigned int to Decimal Floating Point 128-bit.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __floatunssitd (unsigned int x) */
+ENTRY (__floatunssitd)
+ clrldi r0,r3,32 /* extend unsigned. */
+ std r0,-8(r1)
+ ori r1,r1,0 /* Special group ending nop. */
+ lfd fp0,-8(r1)
+ dcffixq fp2,fp0 /* Convert x to decimal floatuns. */
+ blr
+ END (__floatunssitd)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gedd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gedd2.S
new file mode 100644
index 000000000..4f1e0f399
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gedd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 64-bit compare >=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gedd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__gedd2)
+ dcmpu cr0,fp1,fp2 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gedd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gesd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gesd2.S
new file mode 100644
index 000000000..fc90fe997
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gesd2.S
@@ -0,0 +1,35 @@
+/* Decimal Floating Point 32-bit compare >=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gesd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__gesd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gesd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/getd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/getd2.S
new file mode 100644
index 000000000..6b6943841
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/getd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 128-bit compare >=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __getd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__getd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__getd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtdd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtdd2.S
new file mode 100644
index 000000000..2025a4cd1
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtdd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 64-bit compare >=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gtdd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__gtdd2)
+ dcmpu cr0,fp1,fp2 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gtdd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtsd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtsd2.S
new file mode 100644
index 000000000..19acec272
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gtsd2.S
@@ -0,0 +1,35 @@
+/* Decimal Floating Point 32-bit compare >=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gtsd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__gtsd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gtsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gttd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gttd2.S
new file mode 100644
index 000000000..f440a1ead
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/gttd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 128-bit compare >=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __gttd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__gttd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x > y) && !unordered(x,y)) */
+ li r3, 1 /* return 1 */
+ bgtlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, -1 /* return -1 */
+ blr
+ END (__gttd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ledd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ledd2.S
new file mode 100644
index 000000000..3f7d8f861
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ledd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 64-bit compare <. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __ledd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__ledd2)
+ dcmpu cr0,fp1,fp2 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__ledd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/lesd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/lesd2.S
new file mode 100644
index 000000000..1f61b8b89
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/lesd2.S
@@ -0,0 +1,35 @@
+/* Decimal Floating Point 32-bit compare <. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __lesd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__lesd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__lesd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/letd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/letd2.S
new file mode 100644
index 000000000..f7706893f
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/letd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 128-bit compare >=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __letd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__letd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__letd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltdd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltdd2.S
new file mode 100644
index 000000000..8503053c7
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltdd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 64-bit compare <. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __ltdd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__ltdd2)
+ dcmpu cr0,fp1,fp2 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__ltdd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltsd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltsd2.S
new file mode 100644
index 000000000..c99c8fac0
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/ltsd2.S
@@ -0,0 +1,35 @@
+/* Decimal Floating Point 32-bit compare <. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __ltsd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__ltsd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__ltsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/lttd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/lttd2.S
new file mode 100644
index 000000000..1d6c8eb91
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/lttd2.S
@@ -0,0 +1,33 @@
+/* Decimal Floating Point 128-bit compare >=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __lttd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__lttd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x < y) && !unordered(x,y)) */
+ li r3, -1 /* return -1 */
+ bltlr cr0 /* else if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__lttd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/muldd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/muldd3.S
new file mode 100644
index 000000000..dff978315
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/muldd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 64-bit multiply. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __muldd3 (__decimal64 x, __decimal64 y) */
+ENTRY (__muldd3)
+ dmul fp1,fp1,fp2
+ blr
+ END (__muldd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/mulsd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/mulsd3.S
new file mode 100644
index 000000000..e28c1c8ad
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/mulsd3.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 32-bit multiply. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __mulsd3 (__decimal32 x, __decimal32 y) */
+ENTRY (__mulsd3)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dmul fp1,fp1,fp2
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__mulsd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/multd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/multd3.S
new file mode 100644
index 000000000..61391a284
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/multd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 128-bit multiply. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __multd3 (__decimal128 x, __decimal128 y) */
+ENTRY (__multd3)
+ dmulq fp2,fp2,fp4
+ blr
+ END (__multd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/nedd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/nedd2.S
new file mode 100644
index 000000000..640f44745
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/nedd2.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point 64-bit compare !=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __nedd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__nedd2)
+ dcmpu cr0,fp1,fp2 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ bunlr cr0
+ li r3, 1 /* return 1 */
+ blr
+ END (__nedd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/nesd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/nesd2.S
new file mode 100644
index 000000000..e55766e71
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/nesd2.S
@@ -0,0 +1,34 @@
+/* Decimal Floating Point 32-bit compare !=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __nesd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__nesd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ bunlr cr0
+ li r3, 1 /* return 1 */
+ blr
+ END (__nesd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/netd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/netd2.S
new file mode 100644
index 000000000..601953def
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/netd2.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point 128-bit compare !=. P6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __netd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__netd2)
+ dcmpuq cr0,fp2,fp4 /* if ((x == y) && !unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ beqlr cr0 /* else */
+ bunlr cr0
+ li r3, 1 /* return 1 */
+ blr
+ END (__netd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subdd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subdd3.S
new file mode 100644
index 000000000..4a37eaa8a
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subdd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 64-bit substract. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __subdd3 (__decimal64 x, __decimal64 y) */
+ENTRY (__subdd3)
+ dsub fp1,fp1,fp2
+ blr
+ END (__subdd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subsd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subsd3.S
new file mode 100644
index 000000000..a699aa4f7
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subsd3.S
@@ -0,0 +1,31 @@
+/* Decimal Floating Point 32-bit subtract. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __subsd3 (__decimal32 x, __decimal32 y) */
+ENTRY (__subsd3)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dsub fp1,fp1,fp2
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__subsd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subtd3.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subtd3.S
new file mode 100644
index 000000000..badc27ba9
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/subtd3.S
@@ -0,0 +1,28 @@
+/* Decimal Floating Point 128-bit subtract. POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal128 __subtd3 (__decimal128 x, __decimal128 y) */
+ENTRY (__subtd3)
+ dsubq fp2,fp2,fp4
+ blr
+ END (__subtd3)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/truncddsd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/truncddsd2.S
new file mode 100644
index 000000000..902e76a9e
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/truncddsd2.S
@@ -0,0 +1,29 @@
+/* Decimal Floating Point truncate 64-bit to 32-bit.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __truncddsd2 (__decimal64 x) */
+ENTRY (__truncddsd2)
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__truncddsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctddd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctddd2.S
new file mode 100644
index 000000000..89db226df
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctddd2.S
@@ -0,0 +1,29 @@
+/* Decimal Floating Point truncate 128-bit to 64-bit.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal64 __trunctddd2 (__decimal128 x) */
+ENTRY (__trunctddd2)
+ drdpq fp1,fp2 /* Round result to __decimal64. */
+ blr
+ END (__trunctddd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctdsd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctdsd2.S
new file mode 100644
index 000000000..cc2ba781e
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/trunctdsd2.S
@@ -0,0 +1,30 @@
+/* Decimal Floating Point truncate 128-bit to 32-bit.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* __decimal32 __trunctdsd2 (__decimal128 x) */
+ENTRY (__trunctdsd2)
+ drdpq fp1,fp2 /* Round result to __decimal64. */
+ drsp fp1,fp1 /* Round result to __decimal32. */
+ blr
+ END (__trunctdsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unorddd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unorddd2.S
new file mode 100644
index 000000000..073c7ab03
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unorddd2.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point 64-bit unordered compare.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __unorddd2 (__decimal64 x, __decimal64 y) */
+ENTRY (__unorddd2)
+ dcmpu cr0,fp1,fp2 /* if (!unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ bnulr+ cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__unorddd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unordsd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unordsd2.S
new file mode 100644
index 000000000..066dba009
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unordsd2.S
@@ -0,0 +1,34 @@
+/* Decimal Floating Point 32-bit unordered compare.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __unordsd2 (__decimal32 x, __decimal32 y) */
+ENTRY (__unordsd2)
+ dctdp fp1,fp1 /* Convert x to __decimal64. */
+ dctdp fp2,fp2 /* Convert y to __decimal64. */
+ dcmpu cr0,fp1,fp2 /* if (!unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ bnulr+ cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__unordsd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unordtd2.S b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unordtd2.S
new file mode 100644
index 000000000..0b15a660c
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6/fpu/unordtd2.S
@@ -0,0 +1,32 @@
+/* Decimal Floating Point 128-bit unordered compare.
+ POWER6 PowerPC64 version.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ MA 02110-1301 USA */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+ .machine "power6"
+/* int __unordtd2 (__decimal128 x, __decimal128 y) */
+ENTRY (__unordtd2)
+ dcmpuq cr0,fp2,fp4 /* if (!unordered(x,y)) */
+ li r3, 0 /* return 0 */
+ bnulr+ cr0 /* else */
+ li r3, 1 /* return 1 */
+ blr
+ END (__unordtd2)
diff --git a/libc/dfp/sysdeps/powerpc/powerpc64/power6x/fpu/Implies b/libc/dfp/sysdeps/powerpc/powerpc64/power6x/fpu/Implies
new file mode 100644
index 000000000..30fa17646
--- /dev/null
+++ b/libc/dfp/sysdeps/powerpc/powerpc64/power6x/fpu/Implies
@@ -0,0 +1 @@
+powerpc/powerpc64/power6/fpu
diff --git a/libc/dfp/sysdeps/soft-dfp/Makefile b/libc/dfp/sysdeps/soft-dfp/Makefile
new file mode 100644
index 000000000..ce76304f1
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/Makefile
@@ -0,0 +1,34 @@
+# Makefile fragment for soft-dfp.
+
+ifeq ($(subdir),dfp)
+sysdep-CFLAGS += -DWORDS_BIG_ENDIAN=1 -DLONG_DOUBLE_TYPE_SIZE=128 -DBITS_PER_UNIT=8 -Wall
+libdfp-routines += \
+ addsd3 adddd3 addtd3 \
+ subsd3 subdd3 subtd3 \
+ mulsd3 muldd3 multd3 \
+ divsd3 divdd3 divtd3 \
+ eqsd2 eqdd2 eqtd2 \
+ nesd2 nedd2 netd2 \
+ ltsd2 ltdd2 lttd2 \
+ gtsd2 gtdd2 gttd2 \
+ lesd2 ledd2 letd2 \
+ gesd2 gedd2 getd2 \
+ unordsd2 unorddd2 unordtd2 \
+ extendsddd2 extendsdtd2 extendddtd2 \
+ extendsfsd extendsddf extendsdtf \
+ extendsfdd extenddfdd extendddtf \
+ extendsftd extenddftd extendtftd \
+ trunctdsd2 truncddsd2 trunctddd2 \
+ truncsdsf truncdfsd trunctfsd \
+ truncddsf truncdddf trunctfdd \
+ trunctdsf trunctddf trunctdtf \
+ fixsdsi fixddsi fixtdsi \
+ fixsddi fixdddi fixtddi \
+ fixunssdsi fixunsddsi fixunstdsi \
+ fixunssddi fixunsdddi fixunstddi \
+ floatsisd floatsidd floatsitd \
+ floatdisd floatdidd floatditd \
+ floatunssisd floatunssidd floatunssitd \
+ floatunsdisd floatunsdidd floatunsditd \
+ decpowof2 binpowof10 classify
+endif
diff --git a/libc/dfp/sysdeps/soft-dfp/Versions b/libc/dfp/sysdeps/soft-dfp/Versions
new file mode 100644
index 000000000..fa6f9e9b6
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/Versions
@@ -0,0 +1,35 @@
+libdfp {
+ GLIBC_2.5 {
+ __addsd3; __adddd3; __addtd3;
+ __subsd3; __subdd3; __subtd3;
+ __mulsd3; __muldd3; __multd3;
+ __divsd3; __divdd3; __divtd3;
+ __eqsd2; __eqdd2; __eqtd2;
+ __nesd2; __nedd2; __netd2;
+ __ltsd2; __ltdd2; __lttd2;
+ __gtsd2; __gtdd2; __gttd2;
+ __lesd2; __ledd2; __letd2;
+ __gesd2; __gedd2; __getd2;
+ __unordsd2; __unorddd2; __unordtd2;
+ __extendsddd2; __extendsdtd2; __extendddtd2;
+ __extendsfsd; __extendsddf; __extendsdtf;
+ __extendsfdd; __extenddfdd; __extendddtf;
+ __extendsftd; __extenddftd; __extendtftd;
+ __trunctdsd2; __truncddsd2; __trunctddd2;
+ __truncsdsf; __truncdfsd; __trunctfsd;
+ __truncddsf; __truncdddf; __trunctfdd;
+ __trunctdsf; __trunctddf; __trunctdtf;
+ __fixsdsi; __fixddsi; __fixtdsi;
+ __fixsddi; __fixdddi; __fixtddi;
+ __fixunssdsi; __fixunsddsi; __fixunstdsi;
+ __fixunssddi; __fixunsdddi; __fixunstddi;
+ __floatsisd; __floatsidd; __floatsitd;
+ __floatdisd; __floatdidd; __floatditd;
+ __floatunssisd; __floatunssidd; __floatunssitd;
+ __floatunsdisd; __floatunsdidd; __floatunsditd;
+ __dfp_classify_sd; __dfp_classify_dd; __dfp_classify_td;
+ __dfp_frexp_sd; __dfp_frexp_dd; __dfp_frexp_td;
+ __dfp_trunc_sd; __dfp_trunc_dd; __dfp_trunc_td;
+ __dfp_classify_sf; __dfp_classify_df; __dfp_classify_tf;
+ }
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/adddd3.c b/libc/dfp/sysdeps/soft-dfp/adddd3.c
new file mode 100644
index 000000000..f8eaebc0a
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/adddd3.c
@@ -0,0 +1,27 @@
+/* _Decimal64 addition for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __adddd3
+#include <decimal64.h>
+
+#include "addsd3.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/addsd3.c b/libc/dfp/sysdeps/soft-dfp/addsd3.c
new file mode 100644
index 000000000..ad17fde26
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/addsd3.c
@@ -0,0 +1,68 @@
+/* _Decimal32 addition for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __addsd3
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME add
+
+#include <dfpmacro.h>
+DEC_TYPE
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE result;
+ decNumber dn_x, dn_y, dn_result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ ___decNumberAdd(&dn_result, &dn_x, &dn_y, &context);
+
+ if (context.status != 0)
+ {
+ int ieee_flags = 0;
+ if (context.status & DEC_IEEE_854_Division_by_zero)
+ ieee_flags |= FE_DIVBYZERO;
+ if (context.status & DEC_IEEE_854_Inexact)
+ ieee_flags |= FE_INEXACT;
+ if (context.status & DEC_IEEE_854_Invalid_operation)
+ ieee_flags |= FE_INVALID;
+ if (context.status & DEC_IEEE_854_Overflow)
+ ieee_flags |= FE_OVERFLOW;
+ if (context.status & DEC_IEEE_854_Underflow)
+ ieee_flags |= FE_UNDERFLOW;
+ if (ieee_flags != 0)
+ feraiseexcept (ieee_flags);
+ }
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ return result;
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/addtd3.c b/libc/dfp/sysdeps/soft-dfp/addtd3.c
new file mode 100644
index 000000000..7ee2dea3b
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/addtd3.c
@@ -0,0 +1,27 @@
+/* _Decimal128 addition for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __addtd3
+#include <decimal128.h>
+
+#include "addsd3.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/binpowof10.c b/libc/dfp/sysdeps/soft-dfp/binpowof10.c
new file mode 100644
index 000000000..31c690c8d
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/binpowof10.c
@@ -0,0 +1,335 @@
+/* Table to ease conversion of exponants from decimal to binary format
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Steve Munroe <sjmunroe@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+const long double binpowof10 [] =
+ {
+ 1e+00L, /* 10**0 */
+ 1e+01L, /* 10**1 */
+ 1e+02L, /* 10**2 */
+ 1e+03L, /* 10**3 */
+ 1e+04L, /* 10**4 */
+ 1e+05L, /* 10**5 */
+ 1e+06L, /* 10**6 */
+ 1e+07L, /* 10**7 */
+ 1e+08L, /* 10**8 */
+ 1e+09L, /* 10**9 */
+ 1e+10L, /* 10**10 */
+ 1e+11L, /* 10**11 */
+ 1e+12L, /* 10**12 */
+ 1e+13L, /* 10**13 */
+ 1e+14L, /* 10**14 */
+ 1e+15L, /* 10**15 */
+ 1e+16L, /* 10**16 */
+ 1e+17L, /* 10**17 */
+ 1e+18L, /* 10**18 */
+ 1e+19L, /* 10**19 */
+ 1e+20L, /* 10**20 */
+ 1e+21L, /* 10**21 */
+ 1e+22L, /* 10**22 */
+ 1e+23L, /* 10**23 */
+ 1e+24L, /* 10**24 */
+ 1e+25L, /* 10**25 */
+ 1e+26L, /* 10**26 */
+ 1e+27L, /* 10**27 */
+ 1e+28L, /* 10**28 */
+ 1e+29L, /* 10**29 */
+ 1e+30L, /* 10**30 */
+ 1e+31L, /* 10**31 */
+ 1e+32L, /* 10**32 */
+ 1e+33L, /* 10**33 */
+ 1e+34L, /* 10**34 */
+ 1e+35L, /* 10**35 */
+ 1e+36L, /* 10**36 */
+ 1e+37L, /* 10**37 */
+ 1e+38L, /* 10**38 */
+ 1e+39L, /* 10**39 */
+ 1e+40L, /* 10**40 */
+ 1e+41L, /* 10**41 */
+ 1e+42L, /* 10**42 */
+ 1e+43L, /* 10**43 */
+ 1e+44L, /* 10**44 */
+ 1e+45L, /* 10**45 */
+ 1e+46L, /* 10**46 */
+ 1e+47L, /* 10**47 */
+ 1e+48L, /* 10**48 */
+ 1e+49L, /* 10**49 */
+ 1e+50L, /* 10**50 */
+ 1e+51L, /* 10**51 */
+ 1e+52L, /* 10**52 */
+ 1e+53L, /* 10**53 */
+ 1e+54L, /* 10**54 */
+ 1e+55L, /* 10**55 */
+ 1e+56L, /* 10**56 */
+ 1e+57L, /* 10**57 */
+ 1e+58L, /* 10**58 */
+ 1e+59L, /* 10**59 */
+ 1e+60L, /* 10**60 */
+ 1e+61L, /* 10**61 */
+ 1e+62L, /* 10**62 */
+ 1e+63L, /* 10**63 */
+ 1e+64L, /* 10**64 */
+ 1e+65L, /* 10**65 */
+ 1e+66L, /* 10**66 */
+ 1e+67L, /* 10**67 */
+ 1e+68L, /* 10**68 */
+ 1e+69L, /* 10**69 */
+ 1e+70L, /* 10**70 */
+ 1e+71L, /* 10**71 */
+ 1e+72L, /* 10**72 */
+ 1e+73L, /* 10**73 */
+ 1e+74L, /* 10**74 */
+ 1e+75L, /* 10**75 */
+ 1e+76L, /* 10**76 */
+ 1e+77L, /* 10**77 */
+ 1e+78L, /* 10**78 */
+ 1e+79L, /* 10**79 */
+ 1e+80L, /* 10**80 */
+ 1e+81L, /* 10**81 */
+ 1e+82L, /* 10**82 */
+ 1e+83L, /* 10**83 */
+ 1e+84L, /* 10**84 */
+ 1e+85L, /* 10**85 */
+ 1e+86L, /* 10**86 */
+ 1e+87L, /* 10**87 */
+ 1e+88L, /* 10**88 */
+ 1e+89L, /* 10**89 */
+ 1e+90L, /* 10**90 */
+ 1e+91L, /* 10**91 */
+ 1e+92L, /* 10**92 */
+ 1e+93L, /* 10**93 */
+ 1e+94L, /* 10**94 */
+ 1e+95L, /* 10**95 */
+ 1e+96L, /* 10**96 */
+ 1e+97L, /* 10**97 */
+ 1e+98L, /* 10**98 */
+ 1e+99L, /* 10**99 */
+ 1e+100L, /* 10**100 */
+ 1e+101L, /* 10**101 */
+ 1e+102L, /* 10**102 */
+ 1e+103L, /* 10**103 */
+ 1e+104L, /* 10**104 */
+ 1e+105L, /* 10**105 */
+ 1e+106L, /* 10**106 */
+ 1e+107L, /* 10**107 */
+ 1e+108L, /* 10**108 */
+ 1e+109L, /* 10**109 */
+ 1e+110L, /* 10**110 */
+ 1e+111L, /* 10**111 */
+ 1e+112L, /* 10**112 */
+ 1e+113L, /* 10**113 */
+ 1e+114L, /* 10**114 */
+ 1e+115L, /* 10**115 */
+ 1e+116L, /* 10**116 */
+ 1e+117L, /* 10**117 */
+ 1e+118L, /* 10**118 */
+ 1e+119L, /* 10**119 */
+ 1e+120L, /* 10**120 */
+ 1e+121L, /* 10**121 */
+ 1e+122L, /* 10**122 */
+ 1e+123L, /* 10**123 */
+ 1e+124L, /* 10**124 */
+ 1e+125L, /* 10**125 */
+ 1e+126L, /* 10**126 */
+ 1e+127L, /* 10**127 */
+ 1e+128L, /* 10**128 */
+ 1e+129L, /* 10**129 */
+ 1e+130L, /* 10**130 */
+ 1e+131L, /* 10**131 */
+ 1e+132L, /* 10**132 */
+ 1e+133L, /* 10**133 */
+ 1e+134L, /* 10**134 */
+ 1e+135L, /* 10**135 */
+ 1e+136L, /* 10**136 */
+ 1e+137L, /* 10**137 */
+ 1e+138L, /* 10**138 */
+ 1e+139L, /* 10**139 */
+ 1e+140L, /* 10**140 */
+ 1e+141L, /* 10**141 */
+ 1e+142L, /* 10**142 */
+ 1e+143L, /* 10**143 */
+ 1e+144L, /* 10**144 */
+ 1e+145L, /* 10**145 */
+ 1e+146L, /* 10**146 */
+ 1e+147L, /* 10**147 */
+ 1e+148L, /* 10**148 */
+ 1e+149L, /* 10**149 */
+ 1e+150L, /* 10**150 */
+ 1e+151L, /* 10**151 */
+ 1e+152L, /* 10**152 */
+ 1e+153L, /* 10**153 */
+ 1e+154L, /* 10**154 */
+ 1e+155L, /* 10**155 */
+ 1e+156L, /* 10**156 */
+ 1e+157L, /* 10**157 */
+ 1e+158L, /* 10**158 */
+ 1e+159L, /* 10**159 */
+ 1e+160L, /* 10**160 */
+ 1e+161L, /* 10**161 */
+ 1e+162L, /* 10**162 */
+ 1e+163L, /* 10**163 */
+ 1e+164L, /* 10**164 */
+ 1e+165L, /* 10**165 */
+ 1e+166L, /* 10**166 */
+ 1e+167L, /* 10**167 */
+ 1e+168L, /* 10**168 */
+ 1e+169L, /* 10**169 */
+ 1e+170L, /* 10**170 */
+ 1e+171L, /* 10**171 */
+ 1e+172L, /* 10**172 */
+ 1e+173L, /* 10**173 */
+ 1e+174L, /* 10**174 */
+ 1e+175L, /* 10**175 */
+ 1e+176L, /* 10**176 */
+ 1e+177L, /* 10**177 */
+ 1e+178L, /* 10**178 */
+ 1e+179L, /* 10**179 */
+ 1e+180L, /* 10**180 */
+ 1e+181L, /* 10**181 */
+ 1e+182L, /* 10**182 */
+ 1e+183L, /* 10**183 */
+ 1e+184L, /* 10**184 */
+ 1e+185L, /* 10**185 */
+ 1e+186L, /* 10**186 */
+ 1e+187L, /* 10**187 */
+ 1e+188L, /* 10**188 */
+ 1e+189L, /* 10**189 */
+ 1e+190L, /* 10**190 */
+ 1e+191L, /* 10**191 */
+ 1e+192L, /* 10**192 */
+ 1e+193L, /* 10**193 */
+ 1e+194L, /* 10**194 */
+ 1e+195L, /* 10**195 */
+ 1e+196L, /* 10**196 */
+ 1e+197L, /* 10**197 */
+ 1e+198L, /* 10**198 */
+ 1e+199L, /* 10**199 */
+ 1e+200L, /* 10**200 */
+ 1e+201L, /* 10**201 */
+ 1e+202L, /* 10**202 */
+ 1e+203L, /* 10**203 */
+ 1e+204L, /* 10**204 */
+ 1e+205L, /* 10**205 */
+ 1e+206L, /* 10**206 */
+ 1e+207L, /* 10**207 */
+ 1e+208L, /* 10**208 */
+ 1e+209L, /* 10**209 */
+ 1e+210L, /* 10**210 */
+ 1e+211L, /* 10**211 */
+ 1e+212L, /* 10**212 */
+ 1e+213L, /* 10**213 */
+ 1e+214L, /* 10**214 */
+ 1e+215L, /* 10**215 */
+ 1e+216L, /* 10**216 */
+ 1e+217L, /* 10**217 */
+ 1e+218L, /* 10**218 */
+ 1e+219L, /* 10**219 */
+ 1e+220L, /* 10**220 */
+ 1e+221L, /* 10**221 */
+ 1e+222L, /* 10**222 */
+ 1e+223L, /* 10**223 */
+ 1e+224L, /* 10**224 */
+ 1e+225L, /* 10**225 */
+ 1e+226L, /* 10**226 */
+ 1e+227L, /* 10**227 */
+ 1e+228L, /* 10**228 */
+ 1e+229L, /* 10**229 */
+ 1e+230L, /* 10**230 */
+ 1e+231L, /* 10**231 */
+ 1e+232L, /* 10**232 */
+ 1e+233L, /* 10**233 */
+ 1e+234L, /* 10**234 */
+ 1e+235L, /* 10**235 */
+ 1e+236L, /* 10**236 */
+ 1e+237L, /* 10**237 */
+ 1e+238L, /* 10**238 */
+ 1e+239L, /* 10**239 */
+ 1e+240L, /* 10**240 */
+ 1e+241L, /* 10**241 */
+ 1e+242L, /* 10**242 */
+ 1e+243L, /* 10**243 */
+ 1e+244L, /* 10**244 */
+ 1e+245L, /* 10**245 */
+ 1e+246L, /* 10**246 */
+ 1e+247L, /* 10**247 */
+ 1e+248L, /* 10**248 */
+ 1e+249L, /* 10**249 */
+ 1e+250L, /* 10**250 */
+ 1e+251L, /* 10**251 */
+ 1e+252L, /* 10**252 */
+ 1e+253L, /* 10**253 */
+ 1e+254L, /* 10**254 */
+ 1e+255L, /* 10**255 */
+ 1e+256L, /* 10**256 */
+ 1e+257L, /* 10**257 */
+ 1e+258L, /* 10**258 */
+ 1e+259L, /* 10**259 */
+ 1e+260L, /* 10**260 */
+ 1e+261L, /* 10**261 */
+ 1e+262L, /* 10**262 */
+ 1e+263L, /* 10**263 */
+ 1e+264L, /* 10**264 */
+ 1e+265L, /* 10**265 */
+ 1e+266L, /* 10**266 */
+ 1e+267L, /* 10**267 */
+ 1e+268L, /* 10**268 */
+ 1e+269L, /* 10**269 */
+ 1e+270L, /* 10**270 */
+ 1e+271L, /* 10**271 */
+ 1e+272L, /* 10**272 */
+ 1e+273L, /* 10**273 */
+ 1e+274L, /* 10**274 */
+ 1e+275L, /* 10**275 */
+ 1e+276L, /* 10**276 */
+ 1e+277L, /* 10**277 */
+ 1e+278L, /* 10**278 */
+ 1e+279L, /* 10**279 */
+ 1e+280L, /* 10**280 */
+ 1e+281L, /* 10**281 */
+ 1e+282L, /* 10**282 */
+ 1e+283L, /* 10**283 */
+ 1e+284L, /* 10**284 */
+ 1e+285L, /* 10**285 */
+ 1e+286L, /* 10**286 */
+ 1e+287L, /* 10**287 */
+ 1e+288L, /* 10**288 */
+ 1e+289L, /* 10**289 */
+ 1e+290L, /* 10**290 */
+ 1e+291L, /* 10**291 */
+ 1e+292L, /* 10**292 */
+ 1e+293L, /* 10**293 */
+ 1e+294L, /* 10**294 */
+ 1e+295L, /* 10**295 */
+ 1e+296L, /* 10**296 */
+ 1e+297L, /* 10**297 */
+ 1e+298L, /* 10**298 */
+ 1e+299L, /* 10**299 */
+ 1e+300L, /* 10**300 */
+ 1e+301L, /* 10**301 */
+ 1e+302L, /* 10**302 */
+ 1e+303L, /* 10**303 */
+ 1e+304L, /* 10**304 */
+ 1e+305L, /* 10**305 */
+ 1e+306L, /* 10**306 */
+ 1e+307L, /* 10**307 */
+ 1e+308L, /* 10**308 */
+ 1e+309L};/* 10**309 */
+
+weak_alias(binpowof10, __dfp_binpowof10)
diff --git a/libc/dfp/sysdeps/soft-dfp/classify.c b/libc/dfp/sysdeps/soft-dfp/classify.c
new file mode 100644
index 000000000..d6339048d
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/classify.c
@@ -0,0 +1,75 @@
+/* Classification functions for binary floating point types
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#include <math.h>
+
+int __dfp_classify_sf (float a)
+{
+ union {
+ float x;
+ struct {
+ unsigned int sign:1;
+ unsigned int exp:8;
+ unsigned int sig:23;
+ } e;
+ } u;
+ u.x = a;
+ if (__builtin_expect (a == 0.0f, 0))
+ return FP_ZERO;
+
+ if (__builtin_expect (u.e.exp == 0xff, 0))
+ {
+ if (u.e.sig == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+ return FP_NORMAL;
+}
+
+
+
+
+int __dfp_classify_df (double a)
+{
+ union {
+ double x;
+ struct {
+ unsigned int sign:1;
+ unsigned int exp:11;
+ unsigned int sig0:20;
+ unsigned int sig1:32;
+ } e;
+ } u;
+ u.x = a;
+ if (__builtin_expect (a == 0.0, 0))
+ return FP_ZERO;
+
+ if (__builtin_expect (u.e.exp == 0x7ff, 0))
+ {
+ if (u.e.sig0 == 0 && u.e.sig1 == 0)
+ return FP_INFINITE;
+ else
+ return FP_NAN;
+ }
+ return FP_NORMAL;
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/convert.c b/libc/dfp/sysdeps/soft-dfp/convert.c
new file mode 100644
index 000000000..6967364ac
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/convert.c
@@ -0,0 +1,444 @@
+/* Handle conversion from binary integers, floats and decimal types
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mapround.h"
+
+#include "convert.h"
+
+#if defined DECIMAL_TO_BINARY && SRC==32 && DEST==128
+extern double __extendsddf (_Decimal32);
+extern _Decimal32 __truncdfsd (double);
+#elif defined DECIMAL_TO_BINARY && SRC==64 && DEST==128
+extern double __truncdddf (_Decimal64);
+extern _Decimal64 __extenddfdd (double);
+#elif defined DECIMAL_TO_BINARY && SRC==128 && DEST==128
+extern double __trunctddf(_Decimal128);
+extern _Decimal128 __extenddftd(double);
+#endif
+
+#if defined BINARY_TO_DECIMAL && SRC==128 && DEST==32
+extern _Decimal32 __truncdfsd(double);
+#elif defined BINARY_TO_DECIMAL && SRC==128 && DEST==64
+extern _Decimal64 __extenddfdd(double);
+#elif defined BINARY_TO_DECIMAL && SRC==128 && DEST==128
+extern _Decimal128 __extenddftd(double);
+#endif
+
+#define BUFMAX 128
+
+
+DEST_TYPE
+FUNCTION_NAME (SRC_TYPE a)
+{
+#if defined DECIMAL_TO_DECIMAL
+ DEST_TYPE result;
+ decNumber d;
+ decContext context;
+ IEEE_SRC_TYPE e;
+ IEEE_DEST_TYPE r;
+
+ ___decContextDefault(&context, CONTEXT_INIT);
+ context.round = __dn_getround();
+
+ PASTE(___host_to_ieee_,SRC) ((&a), &e);
+ PASTE(___decimal,PASTE(SRC,ToNumber))(&e, &d);
+ /* PASTE(___decimal,PASTE(SRC,ToNumber))(&a, &d); */
+ /* PASTE(___decimal,PASTE(DEST,FromNumber))(&result, &d, &context); */
+ PASTE(___decimal,PASTE(DEST,FromNumber))(&r, &d, &context);
+ PASTE(PASTE(___ieee_,DEST),_to_host) (&r, (&result));
+
+ if (context.status != 0) {
+ int dec_flags = context.status & (DEC_IEEE_854_Inexact|DEC_IEEE_854_Invalid_operation);
+ DFP_HANDLE_EXCEPTIONS(DFP_IEEE_FLAGS(dec_flags));
+ }
+
+ return result;
+#elif defined DECIMAL_TO_INTEGER
+ /* decNumber's decimal* types have the same format as C's _Decimal*
+ types, but they have different calling conventions. */
+
+ /* TODO: Decimal float to integer conversions should raise FE_INVALID
+ if the result value does not fit into the result type. */
+
+ char buf[BUFMAX];
+ char *pos;
+ decNumber qval, n1, n2;
+ decContext context;
+ IEEE_SRC_TYPE e;
+
+ /* Use a large context to avoid losing precision. */
+ ___decContextDefault (&context, DEC_INIT_DECIMAL128);
+ /* Need non-default rounding mode here. */
+ context.round = DEC_ROUND_DOWN;
+
+ PASTE(___host_to_ieee_,SRC) ((&a), &e);
+ PASTE(___decimal,PASTE(SRC,ToNumber))(&e, &n1);
+ /* PASTE(___decimal,PASTE(SRC,ToNumber))(&a, &n1); */
+
+ /* Rescale if the exponent is less than zero. */
+ ___decNumberToIntegralValue (&n2, &n1, &context);
+ /* Get a value to use for the quantize call. */
+ ___decNumberFromString (&qval, (char *) "1.0", &context);
+ /* Force the exponent to zero. */
+ ___decNumberQuantize (&n1, &n2, &qval, &context);
+ /* Get a string, which at this point will not include an exponent. */
+ ___decNumberToString (&n1, buf);
+ /* Ignore the fractional part. */
+ pos = strchr (buf, '.');
+ if (pos)
+ *pos = 0;
+ /* Use a C library function to convert to the integral type. */
+ return STR_TO_INT (buf, NULL, 10);
+#elif defined INTEGER_TO_DECIMAL
+ DEST_TYPE f;
+ char buf[BUFMAX];
+ decContext context;
+ IEEE_DEST_TYPE e;
+
+ ___decContextDefault (&context, CONTEXT_INIT);
+ context.round = DEC_ROUND_HALF_EVEN;
+
+ /* Use a C library function to get a floating point string. */
+ sprintf (buf, INT_FMT ".0", CAST_FOR_FMT(a));
+ /* Convert from the floating point string to a decimal* type. */
+ /* PASTE(___decimal,PASTE(DEST,FromString))(&f, buf, &context); */
+ PASTE(___decimal,PASTE(DEST,FromString))(&e, buf, &context);
+ PASTE(PASTE(___ieee_,DEST),_to_host) (&e, (&f));
+
+ if (context.status != 0) {
+ int dec_flags = context.status &
+ (DEC_IEEE_854_Inexact|DEC_IEEE_854_Invalid_operation|DEC_IEEE_854_Overflow);
+ DFP_HANDLE_EXCEPTIONS(DFP_IEEE_FLAGS(dec_flags));
+ }
+
+ return f;
+#else
+
+ DEST_TYPE result = DEST_LITERAL(0.);
+
+ switch (CLASSIFY (a)) {
+ case FP_ZERO:
+ result = SIGNBIT(a) ? DEST_LITERAL(-0.) : DEST_LITERAL(0.);
+ break;
+ case FP_INFINITE:
+ result = SIGNBIT(a) ? -DEST_INFINITY : DEST_INFINITY;
+ break;
+ case FP_NAN:
+ result = DEST_NAN;
+ break;
+ default: {
+
+#if defined DECIMAL_TO_BINARY && SRC==32 && DEST==128
+// extendsdtf
+ double df_part1, df_part2;
+ _Decimal32 sd_part1, sd_part2;
+
+ df_part1 = a; /* TD -> DF */
+ sd_part1 = df_part1; /* DF -> SD (not exact) */
+ sd_part2 = a - sd_part1; /* SD */
+ df_part2 = sd_part2; /* SD -> DF (trunc) */
+ result = df_part1;
+ result += df_part2;
+
+#elif defined DECIMAL_TO_BINARY && SRC==64 && DEST==128
+// extendddtf
+ double df_part1, df_part2;
+ _Decimal64 dd_part1, dd_part2;
+
+ df_part1 = a; /* TD -> DF */
+ dd_part1 = df_part1; /* DF -> DD. */
+ dd_part2 = a - dd_part1; /* DD. */
+ df_part2 = dd_part2; /* DD -> DF. */
+ result = df_part1;
+ result += df_part2;
+ /* Clear inexact exception raised by DFP arithmetic. */
+ if (DFP_EXCEPTIONS_ENABLED
+ && DFP_TEST_EXCEPTIONS (FE_OVERFLOW|FE_UNDERFLOW) == 0)
+ DFP_CLEAR_EXCEPTIONS (FE_INEXACT);
+
+#elif defined DECIMAL_TO_BINARY && SRC==128 && DEST==128
+// trunctdtf
+ double df_part1, df_part2;
+ _Decimal128 td_part1, td_part2;
+
+ df_part1 = a; /* TD -> DF */
+ td_part1 = df_part1; /* DF -> TD. */
+ td_part2 = a - td_part1; /* TD. */
+ df_part2 = td_part2; /* TD -> DF. */
+ result = df_part1;
+ result += df_part2;
+ /* Clear inexact exception raised by DFP arithmetic. */
+ if (DFP_EXCEPTIONS_ENABLED
+ && DFP_TEST_EXCEPTIONS (FE_OVERFLOW|FE_UNDERFLOW) == 0)
+ DFP_CLEAR_EXCEPTIONS (FE_INEXACT);
+
+#elif defined BINARY_TO_DECIMAL && SRC==128 && (DEST==32 || DEST==64 || DEST==128)
+// trunctfsd, trunctfdd, extendtftd
+ DEST_TYPE temp;
+ union {
+ SRC_TYPE ld;
+ double d[2];
+ } ldd;
+
+ ldd.ld = a;
+ temp = ldd.d[0];
+ result = temp;
+ temp = ldd.d[1];
+ result += temp;
+ /* Clear inexact exception raised by DFP arithmetic. */
+ if (DFP_EXCEPTIONS_ENABLED
+ && DFP_TEST_EXCEPTIONS (FE_OVERFLOW|FE_UNDERFLOW) == 0)
+ DFP_CLEAR_EXCEPTIONS (FE_INEXACT);
+
+#elif defined BINARY_TO_DECIMAL && SRC==64 && (DEST==32 || DEST==64 || DEST==128)
+// truncdfsd, extenddfdd, extenddftd
+/* DEST_TYPE temp; */
+ _Decimal128 temp; /* Needs to be big enough so that temp = mant doesn't round. */
+ double a_norm;
+ long long mant;
+ int exp, sexp;
+
+ a_norm = FREXPDF (a, &exp);
+ mant = a_norm * 9007199254740992.0; /* 53 bits of mantissa. */
+ sexp = exp - 53; /* Exponent adjusted for mantissa. */
+ temp = mant; /* DI -> TD. */
+ if (sexp > 0)
+ temp *= DECPOWOF2[sexp];
+ else if (sexp < 0)
+ temp /= DECPOWOF2[-sexp];
+ result = (DEST_TYPE)temp; /* Cast to the resultant type. */
+ /* Clear inexact exception raised by DFP arithmetic. */
+ if (DFP_EXCEPTIONS_ENABLED
+ && DFP_TEST_EXCEPTIONS (FE_OVERFLOW|FE_UNDERFLOW) == 0)
+ DFP_CLEAR_EXCEPTIONS (FE_INEXACT);
+
+#elif defined BINARY_TO_DECIMAL && SRC==32 && (DEST==32 || DEST==64 || DEST==128)
+// extendsfsd, extendsfdd, extendsftd
+#if DEST==32
+ _Decimal64 temp;
+#else
+ _Decimal128 temp;
+#endif
+ float a_norm;
+ long long mant;
+ int exp, sexp;
+
+ a_norm = FREXPSF (a, &exp);
+ mant = a_norm * 16777216.0; /* 24 bits of mantissa. */
+ sexp = exp - 24; /* Exponent adjusted for mantissa. */
+ temp = mant;
+ if (sexp > 0)
+ temp *= DECPOWOF2[sexp];
+ else if (sexp < 0)
+ temp /= DECPOWOF2[-sexp];
+ result = temp;
+ /* Clear inexact exception raised by DFP arithmetic. */
+ if (DFP_EXCEPTIONS_ENABLED
+ && DFP_TEST_EXCEPTIONS (FE_OVERFLOW|FE_UNDERFLOW) == 0)
+ DFP_CLEAR_EXCEPTIONS (FE_INEXACT);
+
+#elif defined DECIMAL_TO_BINARY && SRC==64 && DEST==64
+// truncdddf
+ long double temp;
+ SRC_TYPE a_norm;
+ SRC_TYPE a_half;
+ long long mant;
+ int exp, sexp;
+
+ a_norm = FREXPD64 (a, &exp);
+
+ /* Avoid going beyond the bounds of the table, which would also
+ mean an overflow or underflow. */
+ if (exp > BINPOWOF10_LIMIT) /* Obvious overflow. */
+ {
+ if (DFP_EXCEPTIONS_ENABLED)
+ DFP_HANDLE_EXCEPTIONS (FE_OVERFLOW|FE_INEXACT);
+ return SIGNBIT(a) ? -INFINITY : INFINITY;
+ }
+ else if (exp < -BINPOWOF10_LIMIT) /* Obvious underflow. */
+ {
+ if (DFP_EXCEPTIONS_ENABLED)
+ DFP_HANDLE_EXCEPTIONS (FE_UNDERFLOW|FE_INEXACT);
+ return SIGNBIT(a) ? -0.0 : 0.0;
+ }
+
+ mant = a_norm * 1.E+16DD; /* 16 digits of mantissa. */
+ sexp = exp - 16; /* Exponent adjusted for mantissa. */
+ temp = mant; /* mantissa as TF */
+ if (sexp > 0)
+ result = temp * BINPOWOF10[sexp];
+ else if (sexp < 0)
+ {
+ /* Avoid going beyond the bounds of the exponent table for
+ negative exponents. */
+ if (sexp < -BINPOWOF10_LIMIT)
+ {
+ temp /= BINPOWOF10[BINPOWOF10_LIMIT];
+ sexp += BINPOWOF10_LIMIT;
+ }
+ result = temp / BINPOWOF10[-sexp];
+ }
+ else
+ result = temp;
+ /* Clear inexact exception raised by DFP arithmetic. */
+ if (DFP_EXCEPTIONS_ENABLED
+ && DFP_TEST_EXCEPTIONS (FE_OVERFLOW|FE_UNDERFLOW) == 0)
+ DFP_CLEAR_EXCEPTIONS (FE_INEXACT);
+
+#elif defined DECIMAL_TO_BINARY && SRC==64 && DEST==32
+// truncddsf
+ double temp;
+ _Decimal64 a_norm;
+ long long mant;
+ int exp, sexp;
+
+ a_norm = FREXPD64 (a, &exp);
+
+ /* Check for values that would overflow the exponent table, which
+ would be obvious overflow and underflow. */
+ if (exp > 39) /* Obvious overflow. */
+ {
+ if (DFP_EXCEPTIONS_ENABLED)
+ DFP_HANDLE_EXCEPTIONS (FE_OVERFLOW|FE_INEXACT);
+ return SIGNBIT(a) ? -INFINITY : INFINITY;
+ }
+ else if (exp < -39) /* Obvious underflow. */
+ {
+ if (DFP_EXCEPTIONS_ENABLED)
+ DFP_HANDLE_EXCEPTIONS (FE_UNDERFLOW|FE_INEXACT);
+ return SIGNBIT(a) ? -0.0 : 0.0;
+ }
+
+ mant = a_norm * 1.E+16DD; /* 16 digits of mantissa. */
+ sexp = exp - 16; /* Exponent adjusted for mantissa. */
+ temp = mant;
+ if (sexp > 0)
+ temp *= BINPOWOF10[sexp];
+ else if (sexp < 0)
+ temp /= BINPOWOF10[-sexp];
+ result = temp;
+
+#elif defined DECIMAL_TO_BINARY && SRC==128 && DEST==64
+// trunctddf
+ long double temp; /* Need at least 16 decimal digits of accuracy. */
+ SRC_TYPE a_norm;
+ SRC_TYPE a_half;
+ long long mant;
+ int exp, sexp;
+
+ a_norm = FREXPD128 (a, &exp);
+ /* Avoid going beyond the bounds of the exponent table. */
+ if (exp > BINPOWOF10_LIMIT) /* Obvious overflow. */
+ {
+ if (DFP_EXCEPTIONS_ENABLED)
+ DFP_HANDLE_EXCEPTIONS (FE_OVERFLOW|FE_INEXACT);
+ return SIGNBIT(a) ? -INFINITY : INFINITY;
+ }
+ else if (exp < -BINPOWOF10_LIMIT) /* Obvious underflow. */
+ {
+ if (DFP_EXCEPTIONS_ENABLED)
+ DFP_HANDLE_EXCEPTIONS (FE_UNDERFLOW|FE_INEXACT);
+ return SIGNBIT(a) ? -0.0 : 0.0;
+ }
+
+ mant = a_norm * 1.E+17DL; /* 17 digits of mantissa. */
+ sexp = exp - 17; /* Exponent adjusted for mantissa. */
+ temp = mant;
+ if (sexp > 0)
+ temp *= BINPOWOF10[sexp];
+ else if (sexp < 0)
+ {
+ /* Avoid going beyond the bounds of the exponent table for
+ negative exponents. */
+ if (sexp < -BINPOWOF10_LIMIT)
+ {
+ temp /= BINPOWOF10[BINPOWOF10_LIMIT];
+ sexp += BINPOWOF10_LIMIT;
+ }
+ temp /= BINPOWOF10[-sexp];
+ }
+ result = temp;
+ /* Clear inexact exception raised by DFP arithmetic. */
+ if (DFP_EXCEPTIONS_ENABLED
+ && DFP_TEST_EXCEPTIONS (FE_OVERFLOW|FE_UNDERFLOW) == 0)
+ DFP_CLEAR_EXCEPTIONS (FE_INEXACT);
+
+#elif defined DECIMAL_TO_BINARY && SRC==128 && DEST==32
+// trunctdsf
+ double temp;
+ SRC_TYPE a_norm;
+ SRC_TYPE a_half;
+ long long mant;
+ int exp, sexp;
+
+ a_norm = FREXPD128 (a, &exp);
+ /* Handle obvious overflow and underflow to avoid going beyond the
+ bounds of the exponent table. */
+ if (exp > 39) /* Obvious overflow. */
+ {
+ if (DFP_EXCEPTIONS_ENABLED)
+ DFP_HANDLE_EXCEPTIONS (FE_OVERFLOW|FE_INEXACT);
+ return SIGNBIT(a) ? -INFINITY : INFINITY;
+ }
+ else if (exp < -39) /* Obvious underflow. */
+ {
+ if (DFP_EXCEPTIONS_ENABLED)
+ DFP_HANDLE_EXCEPTIONS (FE_UNDERFLOW|FE_INEXACT);
+ return SIGNBIT(a) ? -0.0 : 0.0;
+ }
+
+ mant = a_norm * 1E+15DL; /* 15 digits of mantissa. */
+ sexp = exp - 15; /* Exponent adjusted for mantissa. */
+ temp = mant;
+ if (sexp > 0)
+ temp *= BINPOWOF10[sexp];
+ else if (sexp < 0)
+ temp /= BINPOWOF10[-sexp];
+ result = temp;
+
+#elif defined DECIMAL_TO_BINARY && SRC==32 && (DEST==32 || DEST==64)
+// truncsdsf, extendsddf
+ double temp;
+ SRC_TYPE a_norm;
+ long long mant;
+ int exp, sexp;
+
+ a_norm = FREXPD32 (a, &exp);
+ mant = a_norm * 1E+7DF; /* 7 digits of mantissa. */
+ sexp = exp - 7; /* Exponent adjusted for mantissa. */
+ temp = mant;
+ if (sexp > 0)
+ temp *= BINPOWOF10[sexp];
+ else if (sexp < 0)
+ temp /= BINPOWOF10[-sexp];
+ result = temp;
+
+#endif
+ break;
+ }
+ }
+ return result;
+#endif
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/convert.h b/libc/dfp/sysdeps/soft-dfp/convert.h
new file mode 100644
index 000000000..d11de6564
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/convert.h
@@ -0,0 +1,294 @@
+/* Handle conversion from binary integers, floats and decimal types
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+/* decimal source */
+#if defined DECIMAL_TO_INTEGER || defined DECIMAL_TO_BINARY || defined DECIMAL_TO_DECIMAL
+
+#if SRC==32
+#define SRC_TYPE _Decimal32
+#define IEEE_SRC_TYPE decimal32
+#define SRC_LITERAL(n) n##DF
+#define SRC_KIND sd
+#define SIGNBIT __signbitd32
+#define CLASSIFY __fpclassifyd32
+#endif
+
+#if SRC==64
+#define SRC_TYPE _Decimal64
+#define IEEE_SRC_TYPE decimal64
+#define SRC_LITERAL(n) n##DD
+#define SRC_KIND dd
+#define SIGNBIT __signbitd64
+#define CLASSIFY __fpclassifyd64
+#endif
+
+#if SRC==128
+#define SRC_TYPE _Decimal128
+#define IEEE_SRC_TYPE decimal128
+#define SRC_LITERAL(n) n##DL
+#define SRC_KIND td
+#define SIGNBIT __signbitd128
+#define CLASSIFY __fpclassifyd128
+#endif
+
+extern int SIGNBIT (SRC_TYPE);
+extern int CLASSIFY (SRC_TYPE);
+
+
+#define DECIMAL_SIZE SRC
+
+#endif //DECIMAL_TO_INTEGER || DECIMAL_TO_BINARY || DECIMAL_TO_DECIMAL
+
+
+/* float source */
+#if defined BINARY_TO_DECIMAL
+
+#if SRC==32
+#define SRC_TYPE float
+#define SRC_LITERAL(n) n##f
+#define SRC_KIND sf
+#define SIGNBIT __builtin_signbitf
+#define CLASSIFY __dfp_classify_sf
+#endif
+
+#if SRC==64
+#define SRC_TYPE double
+#define SRC_LITERAL(n) n##d
+#define SRC_KIND df
+#define SIGNBIT __builtin_signbit
+#define CLASSIFY __dfp_classify_df
+#endif
+
+#if SRC==128
+#define SRC_TYPE long double
+#define SRC_LITERAL(n) n##l
+#define SRC_KIND tf
+#define SIGNBIT __builtin_signbitl
+/* For IBM 128-bit long double we use the double version. */
+#define CLASSIFY __dfp_classify_df
+#endif
+
+extern int SIGNBIT (SRC_TYPE);
+extern int CLASSIFY (SRC_TYPE);
+
+
+#endif // BINARY_TO_DECIMAL
+
+
+/* integer source */
+#if defined INTEGER_TO_DECIMAL
+
+#if SRC==32
+#if defined UNSIGNED
+#define SRC_TYPE unsigned int
+#define INT_FMT "%u"
+#define CAST_FOR_FMT(A) (unsigned int)A
+#else
+#define SRC_TYPE int
+#define INT_FMT "%d"
+#define CAST_FOR_FMT(A) (int)A
+#endif
+#define SRC_LITERAL(n) n
+#define SRC_KIND si
+#endif
+
+#if SRC==64
+#if defined UNSIGNED
+#define SRC_TYPE unsigned long long
+#define INT_FMT "%llu"
+#define CAST_FOR_FMT(A) (unsigned long long)A
+#else
+#define SRC_TYPE long long
+#define INT_FMT "%lld"
+#define CAST_FOR_FMT(A) (long long)A
+#endif
+#define SRC_LITERAL(n) n
+#define SRC_KIND di
+#endif
+
+#endif // INTEGER_TO_DECIMAL
+
+
+
+/* decimal dest */
+#if defined DECIMAL_TO_DECIMAL || defined INTEGER_TO_DECIMAL || defined BINARY_TO_DECIMAL
+
+#if DEST==32
+#define DEST_TYPE _Decimal32
+#define IEEE_DEST_TYPE decimal32
+#define DEST_LITERAL(n) n##DF
+#define DEST_KIND sd
+#endif
+
+#if DEST==64
+#define DEST_TYPE _Decimal64
+#define IEEE_DEST_TYPE decimal64
+#define DEST_LITERAL(n) n##DD
+#define DEST_KIND dd
+#endif
+
+#if DEST==128
+#define DEST_TYPE _Decimal128
+#define IEEE_DEST_TYPE decimal128
+#define DEST_LITERAL(n) n##DL
+#define DEST_KIND td
+#endif
+
+#define DEST_INFINITY DEC_INFINITY
+#define DEST_NAN DEC_NAN
+
+#if defined DECIMAL_SIZE
+#if DECIMAL_SIZE < DEST
+#undef DECIMAL_SIZE
+#define DECIMAL_SIZE DEST
+#endif
+#endif
+
+#define CONTEXT_INIT PASTE(DEC_INIT_DECIMAL,DEST)
+
+#endif //DECIMAL_TO_DECIMAL || INTEGER_TO_DECIMAL || BINARY_TO_DECIMAL
+
+
+/* float dest */
+#if defined DECIMAL_TO_BINARY
+
+#if DEST==32
+#define DEST_TYPE float
+#define DEST_LITERAL(n) n##F
+#define DEST_KIND sf
+#endif
+
+#if DEST==64
+#define DEST_TYPE double
+#define DEST_LITERAL(n) n
+#define DEST_KIND df
+#endif
+
+#if DEST==128
+#define DEST_TYPE long double
+#define DEST_LITERAL(n) n##L
+#define DEST_KIND tf
+#endif
+
+#define DEST_INFINITY INFINITY
+#define DEST_NAN NAN
+
+
+#endif //DECIMAL_TO_BINARY
+
+
+/* integer dest */
+#if defined DECIMAL_TO_INTEGER
+
+#if DEST==32
+#if defined UNSIGNED
+#define DEST_TYPE unsigned int
+#define STR_TO_INT strtoul
+#else
+#define DEST_TYPE int
+#define STR_TO_INT strtol
+#endif
+#define DEST_LITERAL(n) n
+#define DEST_KIND si
+#endif
+
+#if DEST==64
+#if defined UNSIGNED
+#define DEST_TYPE unsigned long long
+#define STR_TO_INT strtoull
+#else
+#define DEST_TYPE long long
+#define STR_TO_INT strtoll
+#endif
+#define DEST_LITERAL(n) n
+#define DEST_KIND di
+#endif
+
+#endif //DECIMAL_TO_INTEGER
+
+
+extern long double binpowof10[];
+extern const _Decimal128 decpowof2[];
+
+#define BINPOWOF10 binpowof10
+#define BINPOWOF10_LIMIT 308
+#define DECPOWOF2 decpowof2
+
+#define FREXPSF __builtin_frexpf
+#define FREXPDF __builtin_frexp
+#define FREXPTF __builtin_frexpl
+#define FREXPD32 __frexpd32
+#define FREXPD64 __frexpd64
+#define FREXPD128 __frexpd128
+
+
+
+#define PASTE(a,b) PASTE2(a,b)
+#define PASTE2(x,y) x##y
+#define PASTE4(a,b,c,d) PASTE(PASTE(a,b),PASTE(c,d))
+#define PASTE5(a,b,c,d,e) PASTE(PASTE4(a,b,c,d),2)
+
+#if defined DECIMAL_TO_DECIMAL
+#define FUNCTION_NAME PASTE5(__,NAME,SRC_KIND,DEST_KIND,2)
+#else
+#define FUNCTION_NAME PASTE4(__,NAME,SRC_KIND,DEST_KIND)
+#endif
+
+#if (SRC == 128 && (defined DECIMAL_TO_DECIMAL || defined DECIMAL_TO_INTEGER)) || \
+ (DEST == 128 && (defined DECIMAL_TO_DECIMAL || defined INTEGER_TO_DECIMAL))
+#include "decimal128.h"
+#include <dfptypeconv128.h>
+#endif
+#if (SRC == 64 && (defined DECIMAL_TO_DECIMAL || defined DECIMAL_TO_INTEGER)) || \
+ (DEST == 64 && (defined DECIMAL_TO_DECIMAL || defined INTEGER_TO_DECIMAL))
+#include "decimal64.h"
+#include <dfptypeconv64.h>
+#endif
+#if (SRC == 32 && (defined DECIMAL_TO_DECIMAL || defined DECIMAL_TO_INTEGER)) || \
+ (DEST == 32 && (defined DECIMAL_TO_DECIMAL || defined INTEGER_TO_DECIMAL))
+#include "decimal32.h"
+#include <dfptypeconv32.h>
+#endif
+
+#define DFP_EXCEPTIONS_ENABLED 1
+
+#define DFP_IEEE_FLAGS(status) ( \
+ (((status) & DEC_IEEE_854_Division_by_zero) ? FE_DIVBYZERO : 0) | \
+ (((status) & DEC_IEEE_854_Inexact) ? FE_INEXACT : 0) | \
+ (((status) & DEC_IEEE_854_Invalid_operation) ? FE_INVALID : 0) | \
+ (((status) & DEC_IEEE_854_Overflow) ? FE_OVERFLOW : 0) | \
+ (((status) & DEC_IEEE_854_Underflow) ? FE_UNDERFLOW : 0))
+
+#include <fenv_libc.h>
+#define DFP_TEST_EXCEPTIONS(status) ({ \
+ fenv_union_t u; \
+ u.fenv = fegetenv_register(); \
+ u.l[1] & (status); \
+ })
+#define DFP_CLEAR_EXCEPTIONS(status) { \
+ fenv_union_t u; \
+ u.fenv = fegetenv_register(); \
+ u.l[1] &= ~status; \
+ fesetenv_register(u.fenv); \
+ }
+#define DFP_HANDLE_EXCEPTIONS(status) feraiseexcept(status)
+
diff --git a/libc/dfp/sysdeps/soft-dfp/decpowof2.c b/libc/dfp/sysdeps/soft-dfp/decpowof2.c
new file mode 100644
index 000000000..29a903e22
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/decpowof2.c
@@ -0,0 +1,1107 @@
+/* Table to ease conversion from binary to decimal formats
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Steve Munroe <sjmunroe@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* Table of decimal powers of 2 from 0 to 1076. Only positive powers of
+ * 2 are needed as negative exponents are handled via divide. Entries
+ * 1023-1076 are required to handle denormal doubles (-1022 - 54)
+*/
+const _Decimal128 decpowof2 [] = {
+ 1.0E+0DL, /* 2**0 */
+ 2.0E+0DL, /* 2**1 */
+ 4.0E+0DL, /* 2**2 */
+ 8.0E+0DL, /* 2**3 */
+ 1.6E+1DL, /* 2**4 */
+ 3.2E+1DL, /* 2**5 */
+ 6.4E+1DL, /* 2**6 */
+ 1.28E+2DL, /* 2**7 */
+ 2.56E+2DL, /* 2**8 */
+ 5.12E+2DL, /* 2**9 */
+ 1.024E+3DL, /* 2**10 */
+ 2.048E+3DL, /* 2**11 */
+ 4.096E+3DL, /* 2**12 */
+ 8.192E+3DL, /* 2**13 */
+ 1.6384E+4DL, /* 2**14 */
+ 3.2768E+4DL, /* 2**15 */
+ 6.5536E+4DL, /* 2**16 */
+ 1.31072E+5DL, /* 2**17 */
+ 2.62144E+5DL, /* 2**18 */
+ 5.24288E+5DL, /* 2**19 */
+ 1.048576E+6DL, /* 2**20 */
+ 2.097152E+6DL, /* 2**21 */
+ 4.194304E+6DL, /* 2**22 */
+ 8.388608E+6DL, /* 2**23 */
+ 1.6777216E+7DL, /* 2**24 */
+ 3.3554432E+7DL, /* 2**25 */
+ 6.7108864E+7DL, /* 2**26 */
+ 1.34217728E+8DL, /* 2**27 */
+ 2.68435456E+8DL, /* 2**28 */
+ 5.36870912E+8DL, /* 2**29 */
+ 1.073741824E+9DL, /* 2**30 */
+ 2.147483648E+9DL, /* 2**31 */
+ 4.294967296E+9DL, /* 2**32 */
+ 8.589934592E+9DL, /* 2**33 */
+ 1.7179869184E+10DL, /* 2**34 */
+ 3.4359738368E+10DL, /* 2**35 */
+ 6.8719476736E+10DL, /* 2**36 */
+ 1.37438953472E+11DL, /* 2**37 */
+ 2.74877906944E+11DL, /* 2**38 */
+ 5.49755813888E+11DL, /* 2**39 */
+ 1.099511627776E+12DL, /* 2**40 */
+ 2.199023255552E+12DL, /* 2**41 */
+ 4.398046511104E+12DL, /* 2**42 */
+ 8.796093022208E+12DL, /* 2**43 */
+ 1.7592186044416E+13DL, /* 2**44 */
+ 3.5184372088832E+13DL, /* 2**45 */
+ 7.0368744177664E+13DL, /* 2**46 */
+ 1.40737488355328E+14DL, /* 2**47 */
+ 2.81474976710656E+14DL, /* 2**48 */
+ 5.62949953421312E+14DL, /* 2**49 */
+ 1.125899906842624E+15DL, /* 2**50 */
+ 2.251799813685248E+15DL, /* 2**51 */
+ 4.503599627370496E+15DL, /* 2**52 */
+ 9.007199254740992E+15DL, /* 2**53 */
+ 1.8014398509481984E+16DL, /* 2**54 */
+ 3.6028797018963968E+16DL, /* 2**55 */
+ 7.2057594037927936E+16DL, /* 2**56 */
+ 1.44115188075855872E+17DL, /* 2**57 */
+ 2.88230376151711744E+17DL, /* 2**58 */
+ 5.76460752303423488E+17DL, /* 2**59 */
+ 1.152921504606846976E+18DL, /* 2**60 */
+ 2.305843009213693952E+18DL, /* 2**61 */
+ 4.611686018427387904E+18DL, /* 2**62 */
+ 9.223372036854775808E+18DL, /* 2**63 */
+ 1.8446744073709551616E+19DL, /* 2**64 */
+ 3.6893488147419103232E+19DL, /* 2**65 */
+ 7.3786976294838206464E+19DL, /* 2**66 */
+ 1.47573952589676412928E+20DL, /* 2**67 */
+ 2.95147905179352825856E+20DL, /* 2**68 */
+ 5.90295810358705651712E+20DL, /* 2**69 */
+ 1.180591620717411303424E+21DL, /* 2**70 */
+ 2.361183241434822606848E+21DL, /* 2**71 */
+ 4.722366482869645213696E+21DL, /* 2**72 */
+ 9.444732965739290427392E+21DL, /* 2**73 */
+ 1.8889465931478580854784E+22DL, /* 2**74 */
+ 3.7778931862957161709568E+22DL, /* 2**75 */
+ 7.5557863725914323419136E+22DL, /* 2**76 */
+ 1.51115727451828646838272E+23DL, /* 2**77 */
+ 3.02231454903657293676544E+23DL, /* 2**78 */
+ 6.04462909807314587353088E+23DL, /* 2**79 */
+ 1.208925819614629174706176E+24DL, /* 2**80 */
+ 2.417851639229258349412352E+24DL, /* 2**81 */
+ 4.835703278458516698824704E+24DL, /* 2**82 */
+ 9.671406556917033397649408E+24DL, /* 2**83 */
+ 1.9342813113834066795298816E+25DL, /* 2**84 */
+ 3.8685626227668133590597632E+25DL, /* 2**85 */
+ 7.7371252455336267181195264E+25DL, /* 2**86 */
+ 1.54742504910672534362390528E+26DL, /* 2**87 */
+ 3.09485009821345068724781056E+26DL, /* 2**88 */
+ 6.18970019642690137449562112E+26DL, /* 2**89 */
+ 1.237940039285380274899124224E+27DL, /* 2**90 */
+ 2.475880078570760549798248448E+27DL, /* 2**91 */
+ 4.951760157141521099596496896E+27DL, /* 2**92 */
+ 9.903520314283042199192993792E+27DL, /* 2**93 */
+ 1.9807040628566084398385987584E+28DL, /* 2**94 */
+ 3.9614081257132168796771975168E+28DL, /* 2**95 */
+ 7.9228162514264337593543950336E+28DL, /* 2**96 */
+ 1.58456325028528675187087900672E+29DL, /* 2**97 */
+ 3.16912650057057350374175801344E+29DL, /* 2**98 */
+ 6.33825300114114700748351602688E+29DL, /* 2**99 */
+ 1.267650600228229401496703205376E+30DL, /* 2**100 */
+ 2.535301200456458802993406410752E+30DL, /* 2**101 */
+ 5.070602400912917605986812821504E+30DL, /* 2**102 */
+ 1.0141204801825835211973625643008E+31DL, /* 2**103 */
+ 2.0282409603651670423947251286016E+31DL, /* 2**104 */
+ 4.0564819207303340847894502572032E+31DL, /* 2**105 */
+ 8.1129638414606681695789005144064E+31DL, /* 2**106 */
+ 1.62259276829213363391578010288128E+32DL, /* 2**107 */
+ 3.24518553658426726783156020576256E+32DL, /* 2**108 */
+ 6.49037107316853453566312041152512E+32DL, /* 2**109 */
+ 1.298074214633706907132624082305024E+33DL, /* 2**110 */
+ 2.596148429267413814265248164610048E+33DL, /* 2**111 */
+ 5.192296858534827628530496329220096E+33DL, /* 2**112 */
+ 1.038459371706965525706099265844019E+34DL, /* 2**113 */
+ 2.076918743413931051412198531688038E+34DL, /* 2**114 */
+ 4.153837486827862102824397063376077E+34DL, /* 2**115 */
+ 8.307674973655724205648794126752154E+34DL, /* 2**116 */
+ 1.661534994731144841129758825350431E+35DL, /* 2**117 */
+ 3.323069989462289682259517650700861E+35DL, /* 2**118 */
+ 6.646139978924579364519035301401723E+35DL, /* 2**119 */
+ 1.329227995784915872903807060280345E+36DL, /* 2**120 */
+ 2.658455991569831745807614120560689E+36DL, /* 2**121 */
+ 5.316911983139663491615228241121378E+36DL, /* 2**122 */
+ 1.063382396627932698323045648224276E+37DL, /* 2**123 */
+ 2.126764793255865396646091296448551E+37DL, /* 2**124 */
+ 4.253529586511730793292182592897103E+37DL, /* 2**125 */
+ 8.507059173023461586584365185794205E+37DL, /* 2**126 */
+ 1.701411834604692317316873037158841E+38DL, /* 2**127 */
+ 3.402823669209384634633746074317682E+38DL, /* 2**128 */
+ 6.805647338418769269267492148635364E+38DL, /* 2**129 */
+ 1.361129467683753853853498429727073E+39DL, /* 2**130 */
+ 2.722258935367507707706996859454146E+39DL, /* 2**131 */
+ 5.444517870735015415413993718908291E+39DL, /* 2**132 */
+ 1.088903574147003083082798743781658E+40DL, /* 2**133 */
+ 2.177807148294006166165597487563317E+40DL, /* 2**134 */
+ 4.355614296588012332331194975126633E+40DL, /* 2**135 */
+ 8.711228593176024664662389950253266E+40DL, /* 2**136 */
+ 1.742245718635204932932477990050653E+41DL, /* 2**137 */
+ 3.484491437270409865864955980101306E+41DL, /* 2**138 */
+ 6.968982874540819731729911960202613E+41DL, /* 2**139 */
+ 1.393796574908163946345982392040523E+42DL, /* 2**140 */
+ 2.787593149816327892691964784081045E+42DL, /* 2**141 */
+ 5.575186299632655785383929568162090E+42DL, /* 2**142 */
+ 1.115037259926531157076785913632418E+43DL, /* 2**143 */
+ 2.230074519853062314153571827264836E+43DL, /* 2**144 */
+ 4.460149039706124628307143654529672E+43DL, /* 2**145 */
+ 8.920298079412249256614287309059345E+43DL, /* 2**146 */
+ 1.784059615882449851322857461811869E+44DL, /* 2**147 */
+ 3.568119231764899702645714923623738E+44DL, /* 2**148 */
+ 7.136238463529799405291429847247476E+44DL, /* 2**149 */
+ 1.427247692705959881058285969449495E+45DL, /* 2**150 */
+ 2.854495385411919762116571938898990E+45DL, /* 2**151 */
+ 5.708990770823839524233143877797981E+45DL, /* 2**152 */
+ 1.141798154164767904846628775559596E+46DL, /* 2**153 */
+ 2.283596308329535809693257551119192E+46DL, /* 2**154 */
+ 4.567192616659071619386515102238384E+46DL, /* 2**155 */
+ 9.134385233318143238773030204476769E+46DL, /* 2**156 */
+ 1.826877046663628647754606040895354E+47DL, /* 2**157 */
+ 3.653754093327257295509212081790708E+47DL, /* 2**158 */
+ 7.307508186654514591018424163581415E+47DL, /* 2**159 */
+ 1.461501637330902918203684832716283E+48DL, /* 2**160 */
+ 2.923003274661805836407369665432566E+48DL, /* 2**161 */
+ 5.846006549323611672814739330865132E+48DL, /* 2**162 */
+ 1.169201309864722334562947866173026E+49DL, /* 2**163 */
+ 2.338402619729444669125895732346053E+49DL, /* 2**164 */
+ 4.676805239458889338251791464692106E+49DL, /* 2**165 */
+ 9.353610478917778676503582929384211E+49DL, /* 2**166 */
+ 1.870722095783555735300716585876842E+50DL, /* 2**167 */
+ 3.741444191567111470601433171753685E+50DL, /* 2**168 */
+ 7.482888383134222941202866343507369E+50DL, /* 2**169 */
+ 1.496577676626844588240573268701474E+51DL, /* 2**170 */
+ 2.993155353253689176481146537402948E+51DL, /* 2**171 */
+ 5.986310706507378352962293074805895E+51DL, /* 2**172 */
+ 1.197262141301475670592458614961179E+52DL, /* 2**173 */
+ 2.394524282602951341184917229922358E+52DL, /* 2**174 */
+ 4.789048565205902682369834459844716E+52DL, /* 2**175 */
+ 9.578097130411805364739668919689432E+52DL, /* 2**176 */
+ 1.915619426082361072947933783937886E+53DL, /* 2**177 */
+ 3.831238852164722145895867567875773E+53DL, /* 2**178 */
+ 7.662477704329444291791735135751546E+53DL, /* 2**179 */
+ 1.532495540865888858358347027150309E+54DL, /* 2**180 */
+ 3.064991081731777716716694054300618E+54DL, /* 2**181 */
+ 6.129982163463555433433388108601237E+54DL, /* 2**182 */
+ 1.225996432692711086686677621720247E+55DL, /* 2**183 */
+ 2.451992865385422173373355243440495E+55DL, /* 2**184 */
+ 4.903985730770844346746710486880989E+55DL, /* 2**185 */
+ 9.807971461541688693493420973761979E+55DL, /* 2**186 */
+ 1.961594292308337738698684194752396E+56DL, /* 2**187 */
+ 3.923188584616675477397368389504792E+56DL, /* 2**188 */
+ 7.846377169233350954794736779009583E+56DL, /* 2**189 */
+ 1.569275433846670190958947355801917E+57DL, /* 2**190 */
+ 3.138550867693340381917894711603833E+57DL, /* 2**191 */
+ 6.277101735386680763835789423207666E+57DL, /* 2**192 */
+ 1.255420347077336152767157884641533E+58DL, /* 2**193 */
+ 2.510840694154672305534315769283067E+58DL, /* 2**194 */
+ 5.021681388309344611068631538566133E+58DL, /* 2**195 */
+ 1.004336277661868922213726307713227E+59DL, /* 2**196 */
+ 2.008672555323737844427452615426453E+59DL, /* 2**197 */
+ 4.017345110647475688854905230852907E+59DL, /* 2**198 */
+ 8.034690221294951377709810461705813E+59DL, /* 2**199 */
+ 1.606938044258990275541962092341163E+60DL, /* 2**200 */
+ 3.213876088517980551083924184682325E+60DL, /* 2**201 */
+ 6.427752177035961102167848369364650E+60DL, /* 2**202 */
+ 1.285550435407192220433569673872930E+61DL, /* 2**203 */
+ 2.571100870814384440867139347745860E+61DL, /* 2**204 */
+ 5.142201741628768881734278695491720E+61DL, /* 2**205 */
+ 1.028440348325753776346855739098344E+62DL, /* 2**206 */
+ 2.056880696651507552693711478196688E+62DL, /* 2**207 */
+ 4.113761393303015105387422956393376E+62DL, /* 2**208 */
+ 8.227522786606030210774845912786753E+62DL, /* 2**209 */
+ 1.645504557321206042154969182557351E+63DL, /* 2**210 */
+ 3.291009114642412084309938365114701E+63DL, /* 2**211 */
+ 6.582018229284824168619876730229402E+63DL, /* 2**212 */
+ 1.316403645856964833723975346045880E+64DL, /* 2**213 */
+ 2.632807291713929667447950692091761E+64DL, /* 2**214 */
+ 5.265614583427859334895901384183522E+64DL, /* 2**215 */
+ 1.053122916685571866979180276836704E+65DL, /* 2**216 */
+ 2.106245833371143733958360553673409E+65DL, /* 2**217 */
+ 4.212491666742287467916721107346817E+65DL, /* 2**218 */
+ 8.424983333484574935833442214693635E+65DL, /* 2**219 */
+ 1.684996666696914987166688442938727E+66DL, /* 2**220 */
+ 3.369993333393829974333376885877454E+66DL, /* 2**221 */
+ 6.739986666787659948666753771754908E+66DL, /* 2**222 */
+ 1.347997333357531989733350754350982E+67DL, /* 2**223 */
+ 2.695994666715063979466701508701963E+67DL, /* 2**224 */
+ 5.391989333430127958933403017403926E+67DL, /* 2**225 */
+ 1.078397866686025591786680603480785E+68DL, /* 2**226 */
+ 2.156795733372051183573361206961570E+68DL, /* 2**227 */
+ 4.313591466744102367146722413923141E+68DL, /* 2**228 */
+ 8.627182933488204734293444827846282E+68DL, /* 2**229 */
+ 1.725436586697640946858688965569256E+69DL, /* 2**230 */
+ 3.450873173395281893717377931138513E+69DL, /* 2**231 */
+ 6.901746346790563787434755862277025E+69DL, /* 2**232 */
+ 1.380349269358112757486951172455405E+70DL, /* 2**233 */
+ 2.760698538716225514973902344910810E+70DL, /* 2**234 */
+ 5.521397077432451029947804689821620E+70DL, /* 2**235 */
+ 1.104279415486490205989560937964324E+71DL, /* 2**236 */
+ 2.208558830972980411979121875928648E+71DL, /* 2**237 */
+ 4.417117661945960823958243751857296E+71DL, /* 2**238 */
+ 8.834235323891921647916487503714593E+71DL, /* 2**239 */
+ 1.766847064778384329583297500742919E+72DL, /* 2**240 */
+ 3.533694129556768659166595001485837E+72DL, /* 2**241 */
+ 7.067388259113537318333190002971674E+72DL, /* 2**242 */
+ 1.413477651822707463666638000594335E+73DL, /* 2**243 */
+ 2.826955303645414927333276001188670E+73DL, /* 2**244 */
+ 5.653910607290829854666552002377339E+73DL, /* 2**245 */
+ 1.130782121458165970933310400475468E+74DL, /* 2**246 */
+ 2.261564242916331941866620800950936E+74DL, /* 2**247 */
+ 4.523128485832663883733241601901871E+74DL, /* 2**248 */
+ 9.046256971665327767466483203803743E+74DL, /* 2**249 */
+ 1.809251394333065553493296640760749E+75DL, /* 2**250 */
+ 3.618502788666131106986593281521497E+75DL, /* 2**251 */
+ 7.237005577332262213973186563042994E+75DL, /* 2**252 */
+ 1.447401115466452442794637312608599E+76DL, /* 2**253 */
+ 2.894802230932904885589274625217198E+76DL, /* 2**254 */
+ 5.789604461865809771178549250434395E+76DL, /* 2**255 */
+ 1.157920892373161954235709850086879E+77DL, /* 2**256 */
+ 2.315841784746323908471419700173758E+77DL, /* 2**257 */
+ 4.631683569492647816942839400347516E+77DL, /* 2**258 */
+ 9.263367138985295633885678800695033E+77DL, /* 2**259 */
+ 1.852673427797059126777135760139007E+78DL, /* 2**260 */
+ 3.705346855594118253554271520278013E+78DL, /* 2**261 */
+ 7.410693711188236507108543040556026E+78DL, /* 2**262 */
+ 1.482138742237647301421708608111205E+79DL, /* 2**263 */
+ 2.964277484475294602843417216222410E+79DL, /* 2**264 */
+ 5.928554968950589205686834432444821E+79DL, /* 2**265 */
+ 1.185710993790117841137366886488964E+80DL, /* 2**266 */
+ 2.371421987580235682274733772977928E+80DL, /* 2**267 */
+ 4.742843975160471364549467545955857E+80DL, /* 2**268 */
+ 9.485687950320942729098935091911713E+80DL, /* 2**269 */
+ 1.897137590064188545819787018382343E+81DL, /* 2**270 */
+ 3.794275180128377091639574036764685E+81DL, /* 2**271 */
+ 7.588550360256754183279148073529371E+81DL, /* 2**272 */
+ 1.517710072051350836655829614705874E+82DL, /* 2**273 */
+ 3.035420144102701673311659229411748E+82DL, /* 2**274 */
+ 6.070840288205403346623318458823497E+82DL, /* 2**275 */
+ 1.214168057641080669324663691764699E+83DL, /* 2**276 */
+ 2.428336115282161338649327383529399E+83DL, /* 2**277 */
+ 4.856672230564322677298654767058797E+83DL, /* 2**278 */
+ 9.713344461128645354597309534117595E+83DL, /* 2**279 */
+ 1.942668892225729070919461906823519E+84DL, /* 2**280 */
+ 3.885337784451458141838923813647038E+84DL, /* 2**281 */
+ 7.770675568902916283677847627294076E+84DL, /* 2**282 */
+ 1.554135113780583256735569525458815E+85DL, /* 2**283 */
+ 3.108270227561166513471139050917630E+85DL, /* 2**284 */
+ 6.216540455122333026942278101835261E+85DL, /* 2**285 */
+ 1.243308091024466605388455620367052E+86DL, /* 2**286 */
+ 2.486616182048933210776911240734104E+86DL, /* 2**287 */
+ 4.973232364097866421553822481468208E+86DL, /* 2**288 */
+ 9.946464728195732843107644962936417E+86DL, /* 2**289 */
+ 1.989292945639146568621528992587283E+87DL, /* 2**290 */
+ 3.978585891278293137243057985174567E+87DL, /* 2**291 */
+ 7.957171782556586274486115970349133E+87DL, /* 2**292 */
+ 1.591434356511317254897223194069827E+88DL, /* 2**293 */
+ 3.182868713022634509794446388139653E+88DL, /* 2**294 */
+ 6.365737426045269019588892776279307E+88DL, /* 2**295 */
+ 1.273147485209053803917778555255861E+89DL, /* 2**296 */
+ 2.546294970418107607835557110511723E+89DL, /* 2**297 */
+ 5.092589940836215215671114221023445E+89DL, /* 2**298 */
+ 1.018517988167243043134222844204689E+90DL, /* 2**299 */
+ 2.037035976334486086268445688409378E+90DL, /* 2**300 */
+ 4.074071952668972172536891376818756E+90DL, /* 2**301 */
+ 8.148143905337944345073782753637513E+90DL, /* 2**302 */
+ 1.629628781067588869014756550727503E+91DL, /* 2**303 */
+ 3.259257562135177738029513101455005E+91DL, /* 2**304 */
+ 6.518515124270355476059026202910010E+91DL, /* 2**305 */
+ 1.303703024854071095211805240582002E+92DL, /* 2**306 */
+ 2.607406049708142190423610481164004E+92DL, /* 2**307 */
+ 5.214812099416284380847220962328008E+92DL, /* 2**308 */
+ 1.042962419883256876169444192465602E+93DL, /* 2**309 */
+ 2.085924839766513752338888384931203E+93DL, /* 2**310 */
+ 4.171849679533027504677776769862406E+93DL, /* 2**311 */
+ 8.343699359066055009355553539724813E+93DL, /* 2**312 */
+ 1.668739871813211001871110707944963E+94DL, /* 2**313 */
+ 3.337479743626422003742221415889925E+94DL, /* 2**314 */
+ 6.674959487252844007484442831779850E+94DL, /* 2**315 */
+ 1.334991897450568801496888566355970E+95DL, /* 2**316 */
+ 2.669983794901137602993777132711940E+95DL, /* 2**317 */
+ 5.339967589802275205987554265423880E+95DL, /* 2**318 */
+ 1.067993517960455041197510853084776E+96DL, /* 2**319 */
+ 2.135987035920910082395021706169552E+96DL, /* 2**320 */
+ 4.271974071841820164790043412339104E+96DL, /* 2**321 */
+ 8.543948143683640329580086824678208E+96DL, /* 2**322 */
+ 1.708789628736728065916017364935642E+97DL, /* 2**323 */
+ 3.417579257473456131832034729871283E+97DL, /* 2**324 */
+ 6.835158514946912263664069459742567E+97DL, /* 2**325 */
+ 1.367031702989382452732813891948513E+98DL, /* 2**326 */
+ 2.734063405978764905465627783897027E+98DL, /* 2**327 */
+ 5.468126811957529810931255567794053E+98DL, /* 2**328 */
+ 1.093625362391505962186251113558811E+99DL, /* 2**329 */
+ 2.187250724783011924372502227117621E+99DL, /* 2**330 */
+ 4.374501449566023848745004454235243E+99DL, /* 2**331 */
+ 8.749002899132047697490008908470485E+99DL, /* 2**332 */
+ 1.749800579826409539498001781694097E+100DL, /* 2**333 */
+ 3.499601159652819078996003563388194E+100DL, /* 2**334 */
+ 6.999202319305638157992007126776388E+100DL, /* 2**335 */
+ 1.399840463861127631598401425355278E+101DL, /* 2**336 */
+ 2.799680927722255263196802850710555E+101DL, /* 2**337 */
+ 5.599361855444510526393605701421111E+101DL, /* 2**338 */
+ 1.119872371088902105278721140284222E+102DL, /* 2**339 */
+ 2.239744742177804210557442280568444E+102DL, /* 2**340 */
+ 4.479489484355608421114884561136889E+102DL, /* 2**341 */
+ 8.958978968711216842229769122273777E+102DL, /* 2**342 */
+ 1.791795793742243368445953824454755E+103DL, /* 2**343 */
+ 3.583591587484486736891907648909511E+103DL, /* 2**344 */
+ 7.167183174968973473783815297819022E+103DL, /* 2**345 */
+ 1.433436634993794694756763059563804E+104DL, /* 2**346 */
+ 2.866873269987589389513526119127609E+104DL, /* 2**347 */
+ 5.733746539975178779027052238255217E+104DL, /* 2**348 */
+ 1.146749307995035755805410447651043E+105DL, /* 2**349 */
+ 2.293498615990071511610820895302087E+105DL, /* 2**350 */
+ 4.586997231980143023221641790604174E+105DL, /* 2**351 */
+ 9.173994463960286046443283581208348E+105DL, /* 2**352 */
+ 1.834798892792057209288656716241670E+106DL, /* 2**353 */
+ 3.669597785584114418577313432483339E+106DL, /* 2**354 */
+ 7.339195571168228837154626864966678E+106DL, /* 2**355 */
+ 1.467839114233645767430925372993336E+107DL, /* 2**356 */
+ 2.935678228467291534861850745986671E+107DL, /* 2**357 */
+ 5.871356456934583069723701491973343E+107DL, /* 2**358 */
+ 1.174271291386916613944740298394669E+108DL, /* 2**359 */
+ 2.348542582773833227889480596789337E+108DL, /* 2**360 */
+ 4.697085165547666455778961193578674E+108DL, /* 2**361 */
+ 9.394170331095332911557922387157348E+108DL, /* 2**362 */
+ 1.878834066219066582311584477431470E+109DL, /* 2**363 */
+ 3.757668132438133164623168954862939E+109DL, /* 2**364 */
+ 7.515336264876266329246337909725878E+109DL, /* 2**365 */
+ 1.503067252975253265849267581945176E+110DL, /* 2**366 */
+ 3.006134505950506531698535163890351E+110DL, /* 2**367 */
+ 6.012269011901013063397070327780703E+110DL, /* 2**368 */
+ 1.202453802380202612679414065556141E+111DL, /* 2**369 */
+ 2.404907604760405225358828131112281E+111DL, /* 2**370 */
+ 4.809815209520810450717656262224562E+111DL, /* 2**371 */
+ 9.619630419041620901435312524449124E+111DL, /* 2**372 */
+ 1.923926083808324180287062504889825E+112DL, /* 2**373 */
+ 3.847852167616648360574125009779650E+112DL, /* 2**374 */
+ 7.695704335233296721148250019559300E+112DL, /* 2**375 */
+ 1.539140867046659344229650003911860E+113DL, /* 2**376 */
+ 3.078281734093318688459300007823720E+113DL, /* 2**377 */
+ 6.156563468186637376918600015647440E+113DL, /* 2**378 */
+ 1.231312693637327475383720003129488E+114DL, /* 2**379 */
+ 2.462625387274654950767440006258976E+114DL, /* 2**380 */
+ 4.925250774549309901534880012517952E+114DL, /* 2**381 */
+ 9.850501549098619803069760025035903E+114DL, /* 2**382 */
+ 1.970100309819723960613952005007181E+115DL, /* 2**383 */
+ 3.940200619639447921227904010014361E+115DL, /* 2**384 */
+ 7.880401239278895842455808020028723E+115DL, /* 2**385 */
+ 1.576080247855779168491161604005745E+116DL, /* 2**386 */
+ 3.152160495711558336982323208011489E+116DL, /* 2**387 */
+ 6.304320991423116673964646416022978E+116DL, /* 2**388 */
+ 1.260864198284623334792929283204596E+117DL, /* 2**389 */
+ 2.521728396569246669585858566409191E+117DL, /* 2**390 */
+ 5.043456793138493339171717132818383E+117DL, /* 2**391 */
+ 1.008691358627698667834343426563677E+118DL, /* 2**392 */
+ 2.017382717255397335668686853127353E+118DL, /* 2**393 */
+ 4.034765434510794671337373706254706E+118DL, /* 2**394 */
+ 8.069530869021589342674747412509412E+118DL, /* 2**395 */
+ 1.613906173804317868534949482501882E+119DL, /* 2**396 */
+ 3.227812347608635737069898965003765E+119DL, /* 2**397 */
+ 6.455624695217271474139797930007530E+119DL, /* 2**398 */
+ 1.291124939043454294827959586001506E+120DL, /* 2**399 */
+ 2.582249878086908589655919172003012E+120DL, /* 2**400 */
+ 5.164499756173817179311838344006024E+120DL, /* 2**401 */
+ 1.032899951234763435862367668801205E+121DL, /* 2**402 */
+ 2.065799902469526871724735337602409E+121DL, /* 2**403 */
+ 4.131599804939053743449470675204819E+121DL, /* 2**404 */
+ 8.263199609878107486898941350409638E+121DL, /* 2**405 */
+ 1.652639921975621497379788270081928E+122DL, /* 2**406 */
+ 3.305279843951242994759576540163855E+122DL, /* 2**407 */
+ 6.610559687902485989519153080327710E+122DL, /* 2**408 */
+ 1.322111937580497197903830616065542E+123DL, /* 2**409 */
+ 2.644223875160994395807661232131084E+123DL, /* 2**410 */
+ 5.288447750321988791615322464262168E+123DL, /* 2**411 */
+ 1.057689550064397758323064492852434E+124DL, /* 2**412 */
+ 2.115379100128795516646128985704867E+124DL, /* 2**413 */
+ 4.230758200257591033292257971409735E+124DL, /* 2**414 */
+ 8.461516400515182066584515942819469E+124DL, /* 2**415 */
+ 1.692303280103036413316903188563894E+125DL, /* 2**416 */
+ 3.384606560206072826633806377127788E+125DL, /* 2**417 */
+ 6.769213120412145653267612754255575E+125DL, /* 2**418 */
+ 1.353842624082429130653522550851115E+126DL, /* 2**419 */
+ 2.707685248164858261307045101702230E+126DL, /* 2**420 */
+ 5.415370496329716522614090203404460E+126DL, /* 2**421 */
+ 1.083074099265943304522818040680892E+127DL, /* 2**422 */
+ 2.166148198531886609045636081361784E+127DL, /* 2**423 */
+ 4.332296397063773218091272162723568E+127DL, /* 2**424 */
+ 8.664592794127546436182544325447137E+127DL, /* 2**425 */
+ 1.732918558825509287236508865089427E+128DL, /* 2**426 */
+ 3.465837117651018574473017730178855E+128DL, /* 2**427 */
+ 6.931674235302037148946035460357709E+128DL, /* 2**428 */
+ 1.386334847060407429789207092071542E+129DL, /* 2**429 */
+ 2.772669694120814859578414184143084E+129DL, /* 2**430 */
+ 5.545339388241629719156828368286167E+129DL, /* 2**431 */
+ 1.109067877648325943831365673657233E+130DL, /* 2**432 */
+ 2.218135755296651887662731347314467E+130DL, /* 2**433 */
+ 4.436271510593303775325462694628934E+130DL, /* 2**434 */
+ 8.872543021186607550650925389257868E+130DL, /* 2**435 */
+ 1.774508604237321510130185077851574E+131DL, /* 2**436 */
+ 3.549017208474643020260370155703147E+131DL, /* 2**437 */
+ 7.098034416949286040520740311406294E+131DL, /* 2**438 */
+ 1.419606883389857208104148062281259E+132DL, /* 2**439 */
+ 2.839213766779714416208296124562518E+132DL, /* 2**440 */
+ 5.678427533559428832416592249125035E+132DL, /* 2**441 */
+ 1.135685506711885766483318449825007E+133DL, /* 2**442 */
+ 2.271371013423771532966636899650014E+133DL, /* 2**443 */
+ 4.542742026847543065933273799300028E+133DL, /* 2**444 */
+ 9.085484053695086131866547598600057E+133DL, /* 2**445 */
+ 1.817096810739017226373309519720011E+134DL, /* 2**446 */
+ 3.634193621478034452746619039440023E+134DL, /* 2**447 */
+ 7.268387242956068905493238078880045E+134DL, /* 2**448 */
+ 1.453677448591213781098647615776009E+135DL, /* 2**449 */
+ 2.907354897182427562197295231552018E+135DL, /* 2**450 */
+ 5.814709794364855124394590463104036E+135DL, /* 2**451 */
+ 1.162941958872971024878918092620807E+136DL, /* 2**452 */
+ 2.325883917745942049757836185241615E+136DL, /* 2**453 */
+ 4.651767835491884099515672370483229E+136DL, /* 2**454 */
+ 9.303535670983768199031344740966458E+136DL, /* 2**455 */
+ 1.860707134196753639806268948193292E+137DL, /* 2**456 */
+ 3.721414268393507279612537896386583E+137DL, /* 2**457 */
+ 7.442828536787014559225075792773166E+137DL, /* 2**458 */
+ 1.488565707357402911845015158554633E+138DL, /* 2**459 */
+ 2.977131414714805823690030317109267E+138DL, /* 2**460 */
+ 5.954262829429611647380060634218533E+138DL, /* 2**461 */
+ 1.190852565885922329476012126843707E+139DL, /* 2**462 */
+ 2.381705131771844658952024253687413E+139DL, /* 2**463 */
+ 4.763410263543689317904048507374827E+139DL, /* 2**464 */
+ 9.526820527087378635808097014749653E+139DL, /* 2**465 */
+ 1.905364105417475727161619402949931E+140DL, /* 2**466 */
+ 3.810728210834951454323238805899861E+140DL, /* 2**467 */
+ 7.621456421669902908646477611799722E+140DL, /* 2**468 */
+ 1.524291284333980581729295522359944E+141DL, /* 2**469 */
+ 3.048582568667961163458591044719889E+141DL, /* 2**470 */
+ 6.097165137335922326917182089439778E+141DL, /* 2**471 */
+ 1.219433027467184465383436417887956E+142DL, /* 2**472 */
+ 2.438866054934368930766872835775911E+142DL, /* 2**473 */
+ 4.877732109868737861533745671551822E+142DL, /* 2**474 */
+ 9.755464219737475723067491343103645E+142DL, /* 2**475 */
+ 1.951092843947495144613498268620729E+143DL, /* 2**476 */
+ 3.902185687894990289226996537241458E+143DL, /* 2**477 */
+ 7.804371375789980578453993074482916E+143DL, /* 2**478 */
+ 1.560874275157996115690798614896583E+144DL, /* 2**479 */
+ 3.121748550315992231381597229793166E+144DL, /* 2**480 */
+ 6.243497100631984462763194459586333E+144DL, /* 2**481 */
+ 1.248699420126396892552638891917267E+145DL, /* 2**482 */
+ 2.497398840252793785105277783834533E+145DL, /* 2**483 */
+ 4.994797680505587570210555567669066E+145DL, /* 2**484 */
+ 9.989595361011175140421111135338132E+145DL, /* 2**485 */
+ 1.997919072202235028084222227067626E+146DL, /* 2**486 */
+ 3.995838144404470056168444454135253E+146DL, /* 2**487 */
+ 7.991676288808940112336888908270506E+146DL, /* 2**488 */
+ 1.598335257761788022467377781654101E+147DL, /* 2**489 */
+ 3.196670515523576044934755563308202E+147DL, /* 2**490 */
+ 6.393341031047152089869511126616405E+147DL, /* 2**491 */
+ 1.278668206209430417973902225323281E+148DL, /* 2**492 */
+ 2.557336412418860835947804450646562E+148DL, /* 2**493 */
+ 5.114672824837721671895608901293124E+148DL, /* 2**494 */
+ 1.022934564967544334379121780258625E+149DL, /* 2**495 */
+ 2.045869129935088668758243560517249E+149DL, /* 2**496 */
+ 4.091738259870177337516487121034499E+149DL, /* 2**497 */
+ 8.183476519740354675032974242068998E+149DL, /* 2**498 */
+ 1.636695303948070935006594848413800E+150DL, /* 2**499 */
+ 3.273390607896141870013189696827599E+150DL, /* 2**500 */
+ 6.546781215792283740026379393655198E+150DL, /* 2**501 */
+ 1.309356243158456748005275878731040E+151DL, /* 2**502 */
+ 2.618712486316913496010551757462079E+151DL, /* 2**503 */
+ 5.237424972633826992021103514924159E+151DL, /* 2**504 */
+ 1.047484994526765398404220702984832E+152DL, /* 2**505 */
+ 2.094969989053530796808441405969663E+152DL, /* 2**506 */
+ 4.189939978107061593616882811939327E+152DL, /* 2**507 */
+ 8.379879956214123187233765623878654E+152DL, /* 2**508 */
+ 1.675975991242824637446753124775731E+153DL, /* 2**509 */
+ 3.351951982485649274893506249551462E+153DL, /* 2**510 */
+ 6.703903964971298549787012499102923E+153DL, /* 2**511 */
+ 1.340780792994259709957402499820585E+154DL, /* 2**512 */
+ 2.681561585988519419914804999641169E+154DL, /* 2**513 */
+ 5.363123171977038839829609999282338E+154DL, /* 2**514 */
+ 1.072624634395407767965921999856468E+155DL, /* 2**515 */
+ 2.145249268790815535931843999712935E+155DL, /* 2**516 */
+ 4.290498537581631071863687999425871E+155DL, /* 2**517 */
+ 8.580997075163262143727375998851742E+155DL, /* 2**518 */
+ 1.716199415032652428745475199770348E+156DL, /* 2**519 */
+ 3.432398830065304857490950399540697E+156DL, /* 2**520 */
+ 6.864797660130609714981900799081393E+156DL, /* 2**521 */
+ 1.372959532026121942996380159816279E+157DL, /* 2**522 */
+ 2.745919064052243885992760319632557E+157DL, /* 2**523 */
+ 5.491838128104487771985520639265115E+157DL, /* 2**524 */
+ 1.098367625620897554397104127853023E+158DL, /* 2**525 */
+ 2.196735251241795108794208255706046E+158DL, /* 2**526 */
+ 4.393470502483590217588416511412092E+158DL, /* 2**527 */
+ 8.786941004967180435176833022824183E+158DL, /* 2**528 */
+ 1.757388200993436087035366604564837E+159DL, /* 2**529 */
+ 3.514776401986872174070733209129673E+159DL, /* 2**530 */
+ 7.029552803973744348141466418259347E+159DL, /* 2**531 */
+ 1.405910560794748869628293283651869E+160DL, /* 2**532 */
+ 2.811821121589497739256586567303739E+160DL, /* 2**533 */
+ 5.623642243178995478513173134607477E+160DL, /* 2**534 */
+ 1.124728448635799095702634626921495E+161DL, /* 2**535 */
+ 2.249456897271598191405269253842991E+161DL, /* 2**536 */
+ 4.498913794543196382810538507685982E+161DL, /* 2**537 */
+ 8.997827589086392765621077015371964E+161DL, /* 2**538 */
+ 1.799565517817278553124215403074393E+162DL, /* 2**539 */
+ 3.599131035634557106248430806148785E+162DL, /* 2**540 */
+ 7.198262071269114212496861612297571E+162DL, /* 2**541 */
+ 1.439652414253822842499372322459514E+163DL, /* 2**542 */
+ 2.879304828507645684998744644919028E+163DL, /* 2**543 */
+ 5.758609657015291369997489289838057E+163DL, /* 2**544 */
+ 1.151721931403058273999497857967611E+164DL, /* 2**545 */
+ 2.303443862806116547998995715935223E+164DL, /* 2**546 */
+ 4.606887725612233095997991431870445E+164DL, /* 2**547 */
+ 9.213775451224466191995982863740891E+164DL, /* 2**548 */
+ 1.842755090244893238399196572748178E+165DL, /* 2**549 */
+ 3.685510180489786476798393145496356E+165DL, /* 2**550 */
+ 7.371020360979572953596786290992713E+165DL, /* 2**551 */
+ 1.474204072195914590719357258198543E+166DL, /* 2**552 */
+ 2.948408144391829181438714516397085E+166DL, /* 2**553 */
+ 5.896816288783658362877429032794170E+166DL, /* 2**554 */
+ 1.179363257756731672575485806558834E+167DL, /* 2**555 */
+ 2.358726515513463345150971613117668E+167DL, /* 2**556 */
+ 4.717453031026926690301943226235336E+167DL, /* 2**557 */
+ 9.434906062053853380603886452470672E+167DL, /* 2**558 */
+ 1.886981212410770676120777290494134E+168DL, /* 2**559 */
+ 3.773962424821541352241554580988269E+168DL, /* 2**560 */
+ 7.547924849643082704483109161976538E+168DL, /* 2**561 */
+ 1.509584969928616540896621832395308E+169DL, /* 2**562 */
+ 3.019169939857233081793243664790615E+169DL, /* 2**563 */
+ 6.038339879714466163586487329581230E+169DL, /* 2**564 */
+ 1.207667975942893232717297465916246E+170DL, /* 2**565 */
+ 2.415335951885786465434594931832492E+170DL, /* 2**566 */
+ 4.830671903771572930869189863664984E+170DL, /* 2**567 */
+ 9.661343807543145861738379727329968E+170DL, /* 2**568 */
+ 1.932268761508629172347675945465994E+171DL, /* 2**569 */
+ 3.864537523017258344695351890931987E+171DL, /* 2**570 */
+ 7.729075046034516689390703781863975E+171DL, /* 2**571 */
+ 1.545815009206903337878140756372795E+172DL, /* 2**572 */
+ 3.091630018413806675756281512745590E+172DL, /* 2**573 */
+ 6.183260036827613351512563025491180E+172DL, /* 2**574 */
+ 1.236652007365522670302512605098236E+173DL, /* 2**575 */
+ 2.473304014731045340605025210196472E+173DL, /* 2**576 */
+ 4.946608029462090681210050420392944E+173DL, /* 2**577 */
+ 9.893216058924181362420100840785888E+173DL, /* 2**578 */
+ 1.978643211784836272484020168157178E+174DL, /* 2**579 */
+ 3.957286423569672544968040336314355E+174DL, /* 2**580 */
+ 7.914572847139345089936080672628710E+174DL, /* 2**581 */
+ 1.582914569427869017987216134525742E+175DL, /* 2**582 */
+ 3.165829138855738035974432269051484E+175DL, /* 2**583 */
+ 6.331658277711476071948864538102968E+175DL, /* 2**584 */
+ 1.266331655542295214389772907620594E+176DL, /* 2**585 */
+ 2.532663311084590428779545815241187E+176DL, /* 2**586 */
+ 5.065326622169180857559091630482374E+176DL, /* 2**587 */
+ 1.013065324433836171511818326096475E+177DL, /* 2**588 */
+ 2.026130648867672343023636652192950E+177DL, /* 2**589 */
+ 4.052261297735344686047273304385900E+177DL, /* 2**590 */
+ 8.104522595470689372094546608771799E+177DL, /* 2**591 */
+ 1.620904519094137874418909321754360E+178DL, /* 2**592 */
+ 3.241809038188275748837818643508720E+178DL, /* 2**593 */
+ 6.483618076376551497675637287017439E+178DL, /* 2**594 */
+ 1.296723615275310299535127457403488E+179DL, /* 2**595 */
+ 2.593447230550620599070254914806976E+179DL, /* 2**596 */
+ 5.186894461101241198140509829613951E+179DL, /* 2**597 */
+ 1.037378892220248239628101965922790E+180DL, /* 2**598 */
+ 2.074757784440496479256203931845581E+180DL, /* 2**599 */
+ 4.149515568880992958512407863691161E+180DL, /* 2**600 */
+ 8.299031137761985917024815727382322E+180DL, /* 2**601 */
+ 1.659806227552397183404963145476464E+181DL, /* 2**602 */
+ 3.319612455104794366809926290952929E+181DL, /* 2**603 */
+ 6.639224910209588733619852581905858E+181DL, /* 2**604 */
+ 1.327844982041917746723970516381172E+182DL, /* 2**605 */
+ 2.655689964083835493447941032762343E+182DL, /* 2**606 */
+ 5.311379928167670986895882065524686E+182DL, /* 2**607 */
+ 1.062275985633534197379176413104937E+183DL, /* 2**608 */
+ 2.124551971267068394758352826209875E+183DL, /* 2**609 */
+ 4.249103942534136789516705652419749E+183DL, /* 2**610 */
+ 8.498207885068273579033411304839498E+183DL, /* 2**611 */
+ 1.699641577013654715806682260967900E+184DL, /* 2**612 */
+ 3.399283154027309431613364521935799E+184DL, /* 2**613 */
+ 6.798566308054618863226729043871598E+184DL, /* 2**614 */
+ 1.359713261610923772645345808774320E+185DL, /* 2**615 */
+ 2.719426523221847545290691617548639E+185DL, /* 2**616 */
+ 5.438853046443695090581383235097279E+185DL, /* 2**617 */
+ 1.087770609288739018116276647019456E+186DL, /* 2**618 */
+ 2.175541218577478036232553294038911E+186DL, /* 2**619 */
+ 4.351082437154956072465106588077823E+186DL, /* 2**620 */
+ 8.702164874309912144930213176155646E+186DL, /* 2**621 */
+ 1.740432974861982428986042635231129E+187DL, /* 2**622 */
+ 3.480865949723964857972085270462258E+187DL, /* 2**623 */
+ 6.961731899447929715944170540924517E+187DL, /* 2**624 */
+ 1.392346379889585943188834108184903E+188DL, /* 2**625 */
+ 2.784692759779171886377668216369807E+188DL, /* 2**626 */
+ 5.569385519558343772755336432739613E+188DL, /* 2**627 */
+ 1.113877103911668754551067286547923E+189DL, /* 2**628 */
+ 2.227754207823337509102134573095845E+189DL, /* 2**629 */
+ 4.455508415646675018204269146191691E+189DL, /* 2**630 */
+ 8.911016831293350036408538292383381E+189DL, /* 2**631 */
+ 1.782203366258670007281707658476676E+190DL, /* 2**632 */
+ 3.564406732517340014563415316953353E+190DL, /* 2**633 */
+ 7.128813465034680029126830633906705E+190DL, /* 2**634 */
+ 1.425762693006936005825366126781341E+191DL, /* 2**635 */
+ 2.851525386013872011650732253562682E+191DL, /* 2**636 */
+ 5.703050772027744023301464507125364E+191DL, /* 2**637 */
+ 1.140610154405548804660292901425073E+192DL, /* 2**638 */
+ 2.281220308811097609320585802850146E+192DL, /* 2**639 */
+ 4.562440617622195218641171605700291E+192DL, /* 2**640 */
+ 9.124881235244390437282343211400583E+192DL, /* 2**641 */
+ 1.824976247048878087456468642280117E+193DL, /* 2**642 */
+ 3.649952494097756174912937284560233E+193DL, /* 2**643 */
+ 7.299904988195512349825874569120466E+193DL, /* 2**644 */
+ 1.459980997639102469965174913824093E+194DL, /* 2**645 */
+ 2.919961995278204939930349827648186E+194DL, /* 2**646 */
+ 5.839923990556409879860699655296373E+194DL, /* 2**647 */
+ 1.167984798111281975972139931059275E+195DL, /* 2**648 */
+ 2.335969596222563951944279862118549E+195DL, /* 2**649 */
+ 4.671939192445127903888559724237098E+195DL, /* 2**650 */
+ 9.343878384890255807777119448474197E+195DL, /* 2**651 */
+ 1.868775676978051161555423889694839E+196DL, /* 2**652 */
+ 3.737551353956102323110847779389679E+196DL, /* 2**653 */
+ 7.475102707912204646221695558779357E+196DL, /* 2**654 */
+ 1.495020541582440929244339111755871E+197DL, /* 2**655 */
+ 2.990041083164881858488678223511743E+197DL, /* 2**656 */
+ 5.980082166329763716977356447023486E+197DL, /* 2**657 */
+ 1.196016433265952743395471289404697E+198DL, /* 2**658 */
+ 2.392032866531905486790942578809394E+198DL, /* 2**659 */
+ 4.784065733063810973581885157618789E+198DL, /* 2**660 */
+ 9.568131466127621947163770315237577E+198DL, /* 2**661 */
+ 1.913626293225524389432754063047515E+199DL, /* 2**662 */
+ 3.827252586451048778865508126095031E+199DL, /* 2**663 */
+ 7.654505172902097557731016252190062E+199DL, /* 2**664 */
+ 1.530901034580419511546203250438012E+200DL, /* 2**665 */
+ 3.061802069160839023092406500876025E+200DL, /* 2**666 */
+ 6.123604138321678046184813001752050E+200DL, /* 2**667 */
+ 1.224720827664335609236962600350410E+201DL, /* 2**668 */
+ 2.449441655328671218473925200700820E+201DL, /* 2**669 */
+ 4.898883310657342436947850401401640E+201DL, /* 2**670 */
+ 9.797766621314684873895700802803279E+201DL, /* 2**671 */
+ 1.959553324262936974779140160560656E+202DL, /* 2**672 */
+ 3.919106648525873949558280321121312E+202DL, /* 2**673 */
+ 7.838213297051747899116560642242623E+202DL, /* 2**674 */
+ 1.567642659410349579823312128448525E+203DL, /* 2**675 */
+ 3.135285318820699159646624256897049E+203DL, /* 2**676 */
+ 6.270570637641398319293248513794099E+203DL, /* 2**677 */
+ 1.254114127528279663858649702758820E+204DL, /* 2**678 */
+ 2.508228255056559327717299405517639E+204DL, /* 2**679 */
+ 5.016456510113118655434598811035279E+204DL, /* 2**680 */
+ 1.003291302022623731086919762207056E+205DL, /* 2**681 */
+ 2.006582604045247462173839524414112E+205DL, /* 2**682 */
+ 4.013165208090494924347679048828223E+205DL, /* 2**683 */
+ 8.026330416180989848695358097656446E+205DL, /* 2**684 */
+ 1.605266083236197969739071619531289E+206DL, /* 2**685 */
+ 3.210532166472395939478143239062579E+206DL, /* 2**686 */
+ 6.421064332944791878956286478125157E+206DL, /* 2**687 */
+ 1.284212866588958375791257295625031E+207DL, /* 2**688 */
+ 2.568425733177916751582514591250063E+207DL, /* 2**689 */
+ 5.136851466355833503165029182500126E+207DL, /* 2**690 */
+ 1.027370293271166700633005836500025E+208DL, /* 2**691 */
+ 2.054740586542333401266011673000050E+208DL, /* 2**692 */
+ 4.109481173084666802532023346000101E+208DL, /* 2**693 */
+ 8.218962346169333605064046692000201E+208DL, /* 2**694 */
+ 1.643792469233866721012809338400040E+209DL, /* 2**695 */
+ 3.287584938467733442025618676800080E+209DL, /* 2**696 */
+ 6.575169876935466884051237353600161E+209DL, /* 2**697 */
+ 1.315033975387093376810247470720032E+210DL, /* 2**698 */
+ 2.630067950774186753620494941440064E+210DL, /* 2**699 */
+ 5.260135901548373507240989882880129E+210DL, /* 2**700 */
+ 1.052027180309674701448197976576026E+211DL, /* 2**701 */
+ 2.104054360619349402896395953152051E+211DL, /* 2**702 */
+ 4.208108721238698805792791906304103E+211DL, /* 2**703 */
+ 8.416217442477397611585583812608206E+211DL, /* 2**704 */
+ 1.683243488495479522317116762521641E+212DL, /* 2**705 */
+ 3.366486976990959044634233525043282E+212DL, /* 2**706 */
+ 6.732973953981918089268467050086565E+212DL, /* 2**707 */
+ 1.346594790796383617853693410017313E+213DL, /* 2**708 */
+ 2.693189581592767235707386820034626E+213DL, /* 2**709 */
+ 5.386379163185534471414773640069252E+213DL, /* 2**710 */
+ 1.077275832637106894282954728013850E+214DL, /* 2**711 */
+ 2.154551665274213788565909456027701E+214DL, /* 2**712 */
+ 4.309103330548427577131818912055401E+214DL, /* 2**713 */
+ 8.618206661096855154263637824110803E+214DL, /* 2**714 */
+ 1.723641332219371030852727564822161E+215DL, /* 2**715 */
+ 3.447282664438742061705455129644321E+215DL, /* 2**716 */
+ 6.894565328877484123410910259288642E+215DL, /* 2**717 */
+ 1.378913065775496824682182051857728E+216DL, /* 2**718 */
+ 2.757826131550993649364364103715457E+216DL, /* 2**719 */
+ 5.515652263101987298728728207430914E+216DL, /* 2**720 */
+ 1.103130452620397459745745641486183E+217DL, /* 2**721 */
+ 2.206260905240794919491491282972366E+217DL, /* 2**722 */
+ 4.412521810481589838982982565944731E+217DL, /* 2**723 */
+ 8.825043620963179677965965131889462E+217DL, /* 2**724 */
+ 1.765008724192635935593193026377892E+218DL, /* 2**725 */
+ 3.530017448385271871186386052755785E+218DL, /* 2**726 */
+ 7.060034896770543742372772105511570E+218DL, /* 2**727 */
+ 1.412006979354108748474554421102314E+219DL, /* 2**728 */
+ 2.824013958708217496949108842204628E+219DL, /* 2**729 */
+ 5.648027917416434993898217684409256E+219DL, /* 2**730 */
+ 1.129605583483286998779643536881851E+220DL, /* 2**731 */
+ 2.259211166966573997559287073763702E+220DL, /* 2**732 */
+ 4.518422333933147995118574147527405E+220DL, /* 2**733 */
+ 9.036844667866295990237148295054809E+220DL, /* 2**734 */
+ 1.807368933573259198047429659010962E+221DL, /* 2**735 */
+ 3.614737867146518396094859318021924E+221DL, /* 2**736 */
+ 7.229475734293036792189718636043847E+221DL, /* 2**737 */
+ 1.445895146858607358437943727208769E+222DL, /* 2**738 */
+ 2.891790293717214716875887454417539E+222DL, /* 2**739 */
+ 5.783580587434429433751774908835078E+222DL, /* 2**740 */
+ 1.156716117486885886750354981767016E+223DL, /* 2**741 */
+ 2.313432234973771773500709963534031E+223DL, /* 2**742 */
+ 4.626864469947543547001419927068062E+223DL, /* 2**743 */
+ 9.253728939895087094002839854136125E+223DL, /* 2**744 */
+ 1.850745787979017418800567970827225E+224DL, /* 2**745 */
+ 3.701491575958034837601135941654450E+224DL, /* 2**746 */
+ 7.402983151916069675202271883308900E+224DL, /* 2**747 */
+ 1.480596630383213935040454376661780E+225DL, /* 2**748 */
+ 2.961193260766427870080908753323560E+225DL, /* 2**749 */
+ 5.922386521532855740161817506647120E+225DL, /* 2**750 */
+ 1.184477304306571148032363501329424E+226DL, /* 2**751 */
+ 2.368954608613142296064727002658848E+226DL, /* 2**752 */
+ 4.737909217226284592129454005317696E+226DL, /* 2**753 */
+ 9.475818434452569184258908010635392E+226DL, /* 2**754 */
+ 1.895163686890513836851781602127078E+227DL, /* 2**755 */
+ 3.790327373781027673703563204254157E+227DL, /* 2**756 */
+ 7.580654747562055347407126408508313E+227DL, /* 2**757 */
+ 1.516130949512411069481425281701663E+228DL, /* 2**758 */
+ 3.032261899024822138962850563403325E+228DL, /* 2**759 */
+ 6.064523798049644277925701126806651E+228DL, /* 2**760 */
+ 1.212904759609928855585140225361330E+229DL, /* 2**761 */
+ 2.425809519219857711170280450722660E+229DL, /* 2**762 */
+ 4.851619038439715422340560901445320E+229DL, /* 2**763 */
+ 9.703238076879430844681121802890641E+229DL, /* 2**764 */
+ 1.940647615375886168936224360578128E+230DL, /* 2**765 */
+ 3.881295230751772337872448721156256E+230DL, /* 2**766 */
+ 7.762590461503544675744897442312513E+230DL, /* 2**767 */
+ 1.552518092300708935148979488462503E+231DL, /* 2**768 */
+ 3.105036184601417870297958976925005E+231DL, /* 2**769 */
+ 6.210072369202835740595917953850010E+231DL, /* 2**770 */
+ 1.242014473840567148119183590770002E+232DL, /* 2**771 */
+ 2.484028947681134296238367181540004E+232DL, /* 2**772 */
+ 4.968057895362268592476734363080008E+232DL, /* 2**773 */
+ 9.936115790724537184953468726160016E+232DL, /* 2**774 */
+ 1.987223158144907436990693745232003E+233DL, /* 2**775 */
+ 3.974446316289814873981387490464007E+233DL, /* 2**776 */
+ 7.948892632579629747962774980928013E+233DL, /* 2**777 */
+ 1.589778526515925949592554996185603E+234DL, /* 2**778 */
+ 3.179557053031851899185109992371205E+234DL, /* 2**779 */
+ 6.359114106063703798370219984742410E+234DL, /* 2**780 */
+ 1.271822821212740759674043996948482E+235DL, /* 2**781 */
+ 2.543645642425481519348087993896964E+235DL, /* 2**782 */
+ 5.087291284850963038696175987793928E+235DL, /* 2**783 */
+ 1.017458256970192607739235197558786E+236DL, /* 2**784 */
+ 2.034916513940385215478470395117571E+236DL, /* 2**785 */
+ 4.069833027880770430956940790235143E+236DL, /* 2**786 */
+ 8.139666055761540861913881580470285E+236DL, /* 2**787 */
+ 1.627933211152308172382776316094057E+237DL, /* 2**788 */
+ 3.255866422304616344765552632188114E+237DL, /* 2**789 */
+ 6.511732844609232689531105264376228E+237DL, /* 2**790 */
+ 1.302346568921846537906221052875246E+238DL, /* 2**791 */
+ 2.604693137843693075812442105750491E+238DL, /* 2**792 */
+ 5.209386275687386151624884211500983E+238DL, /* 2**793 */
+ 1.041877255137477230324976842300197E+239DL, /* 2**794 */
+ 2.083754510274954460649953684600393E+239DL, /* 2**795 */
+ 4.167509020549908921299907369200786E+239DL, /* 2**796 */
+ 8.335018041099817842599814738401572E+239DL, /* 2**797 */
+ 1.667003608219963568519962947680314E+240DL, /* 2**798 */
+ 3.334007216439927137039925895360629E+240DL, /* 2**799 */
+ 6.668014432879854274079851790721258E+240DL, /* 2**800 */
+ 1.333602886575970854815970358144252E+241DL, /* 2**801 */
+ 2.667205773151941709631940716288503E+241DL, /* 2**802 */
+ 5.334411546303883419263881432577006E+241DL, /* 2**803 */
+ 1.066882309260776683852776286515401E+242DL, /* 2**804 */
+ 2.133764618521553367705552573030802E+242DL, /* 2**805 */
+ 4.267529237043106735411105146061605E+242DL, /* 2**806 */
+ 8.535058474086213470822210292123210E+242DL, /* 2**807 */
+ 1.707011694817242694164442058424642E+243DL, /* 2**808 */
+ 3.414023389634485388328884116849284E+243DL, /* 2**809 */
+ 6.828046779268970776657768233698568E+243DL, /* 2**810 */
+ 1.365609355853794155331553646739714E+244DL, /* 2**811 */
+ 2.731218711707588310663107293479427E+244DL, /* 2**812 */
+ 5.462437423415176621326214586958854E+244DL, /* 2**813 */
+ 1.092487484683035324265242917391771E+245DL, /* 2**814 */
+ 2.184974969366070648530485834783542E+245DL, /* 2**815 */
+ 4.369949938732141297060971669567084E+245DL, /* 2**816 */
+ 8.739899877464282594121943339134167E+245DL, /* 2**817 */
+ 1.747979975492856518824388667826833E+246DL, /* 2**818 */
+ 3.495959950985713037648777335653667E+246DL, /* 2**819 */
+ 6.991919901971426075297554671307334E+246DL, /* 2**820 */
+ 1.398383980394285215059510934261467E+247DL, /* 2**821 */
+ 2.796767960788570430119021868522933E+247DL, /* 2**822 */
+ 5.593535921577140860238043737045867E+247DL, /* 2**823 */
+ 1.118707184315428172047608747409173E+248DL, /* 2**824 */
+ 2.237414368630856344095217494818347E+248DL, /* 2**825 */
+ 4.474828737261712688190434989636694E+248DL, /* 2**826 */
+ 8.949657474523425376380869979273387E+248DL, /* 2**827 */
+ 1.789931494904685075276173995854677E+249DL, /* 2**828 */
+ 3.579862989809370150552347991709355E+249DL, /* 2**829 */
+ 7.159725979618740301104695983418710E+249DL, /* 2**830 */
+ 1.431945195923748060220939196683742E+250DL, /* 2**831 */
+ 2.863890391847496120441878393367484E+250DL, /* 2**832 */
+ 5.727780783694992240883756786734968E+250DL, /* 2**833 */
+ 1.145556156738998448176751357346994E+251DL, /* 2**834 */
+ 2.291112313477996896353502714693987E+251DL, /* 2**835 */
+ 4.582224626955993792707005429387974E+251DL, /* 2**836 */
+ 9.164449253911987585414010858775948E+251DL, /* 2**837 */
+ 1.832889850782397517082802171755190E+252DL, /* 2**838 */
+ 3.665779701564795034165604343510379E+252DL, /* 2**839 */
+ 7.331559403129590068331208687020759E+252DL, /* 2**840 */
+ 1.466311880625918013666241737404152E+253DL, /* 2**841 */
+ 2.932623761251836027332483474808303E+253DL, /* 2**842 */
+ 5.865247522503672054664966949616607E+253DL, /* 2**843 */
+ 1.173049504500734410932993389923321E+254DL, /* 2**844 */
+ 2.346099009001468821865986779846643E+254DL, /* 2**845 */
+ 4.692198018002937643731973559693286E+254DL, /* 2**846 */
+ 9.384396036005875287463947119386571E+254DL, /* 2**847 */
+ 1.876879207201175057492789423877314E+255DL, /* 2**848 */
+ 3.753758414402350114985578847754628E+255DL, /* 2**849 */
+ 7.507516828804700229971157695509257E+255DL, /* 2**850 */
+ 1.501503365760940045994231539101851E+256DL, /* 2**851 */
+ 3.003006731521880091988463078203703E+256DL, /* 2**852 */
+ 6.006013463043760183976926156407405E+256DL, /* 2**853 */
+ 1.201202692608752036795385231281481E+257DL, /* 2**854 */
+ 2.402405385217504073590770462562962E+257DL, /* 2**855 */
+ 4.804810770435008147181540925125924E+257DL, /* 2**856 */
+ 9.609621540870016294363081850251849E+257DL, /* 2**857 */
+ 1.921924308174003258872616370050370E+258DL, /* 2**858 */
+ 3.843848616348006517745232740100740E+258DL, /* 2**859 */
+ 7.687697232696013035490465480201479E+258DL, /* 2**860 */
+ 1.537539446539202607098093096040296E+259DL, /* 2**861 */
+ 3.075078893078405214196186192080592E+259DL, /* 2**862 */
+ 6.150157786156810428392372384161183E+259DL, /* 2**863 */
+ 1.230031557231362085678474476832237E+260DL, /* 2**864 */
+ 2.460063114462724171356948953664473E+260DL, /* 2**865 */
+ 4.920126228925448342713897907328947E+260DL, /* 2**866 */
+ 9.840252457850896685427795814657893E+260DL, /* 2**867 */
+ 1.968050491570179337085559162931579E+261DL, /* 2**868 */
+ 3.936100983140358674171118325863157E+261DL, /* 2**869 */
+ 7.872201966280717348342236651726315E+261DL, /* 2**870 */
+ 1.574440393256143469668447330345263E+262DL, /* 2**871 */
+ 3.148880786512286939336894660690526E+262DL, /* 2**872 */
+ 6.297761573024573878673789321381052E+262DL, /* 2**873 */
+ 1.259552314604914775734757864276210E+263DL, /* 2**874 */
+ 2.519104629209829551469515728552421E+263DL, /* 2**875 */
+ 5.038209258419659102939031457104841E+263DL, /* 2**876 */
+ 1.007641851683931820587806291420968E+264DL, /* 2**877 */
+ 2.015283703367863641175612582841937E+264DL, /* 2**878 */
+ 4.030567406735727282351225165683873E+264DL, /* 2**879 */
+ 8.061134813471454564702450331367746E+264DL, /* 2**880 */
+ 1.612226962694290912940490066273549E+265DL, /* 2**881 */
+ 3.224453925388581825880980132547098E+265DL, /* 2**882 */
+ 6.448907850777163651761960265094197E+265DL, /* 2**883 */
+ 1.289781570155432730352392053018839E+266DL, /* 2**884 */
+ 2.579563140310865460704784106037679E+266DL, /* 2**885 */
+ 5.159126280621730921409568212075357E+266DL, /* 2**886 */
+ 1.031825256124346184281913642415071E+267DL, /* 2**887 */
+ 2.063650512248692368563827284830143E+267DL, /* 2**888 */
+ 4.127301024497384737127654569660286E+267DL, /* 2**889 */
+ 8.254602048994769474255309139320572E+267DL, /* 2**890 */
+ 1.650920409798953894851061827864114E+268DL, /* 2**891 */
+ 3.301840819597907789702123655728229E+268DL, /* 2**892 */
+ 6.603681639195815579404247311456458E+268DL, /* 2**893 */
+ 1.320736327839163115880849462291292E+269DL, /* 2**894 */
+ 2.641472655678326231761698924582583E+269DL, /* 2**895 */
+ 5.282945311356652463523397849165166E+269DL, /* 2**896 */
+ 1.056589062271330492704679569833033E+270DL, /* 2**897 */
+ 2.113178124542660985409359139666066E+270DL, /* 2**898 */
+ 4.226356249085321970818718279332133E+270DL, /* 2**899 */
+ 8.452712498170643941637436558664266E+270DL, /* 2**900 */
+ 1.690542499634128788327487311732853E+271DL, /* 2**901 */
+ 3.381084999268257576654974623465706E+271DL, /* 2**902 */
+ 6.762169998536515153309949246931413E+271DL, /* 2**903 */
+ 1.352433999707303030661989849386283E+272DL, /* 2**904 */
+ 2.704867999414606061323979698772565E+272DL, /* 2**905 */
+ 5.409735998829212122647959397545130E+272DL, /* 2**906 */
+ 1.081947199765842424529591879509026E+273DL, /* 2**907 */
+ 2.163894399531684849059183759018052E+273DL, /* 2**908 */
+ 4.327788799063369698118367518036104E+273DL, /* 2**909 */
+ 8.655577598126739396236735036072208E+273DL, /* 2**910 */
+ 1.731115519625347879247347007214442E+274DL, /* 2**911 */
+ 3.462231039250695758494694014428883E+274DL, /* 2**912 */
+ 6.924462078501391516989388028857766E+274DL, /* 2**913 */
+ 1.384892415700278303397877605771553E+275DL, /* 2**914 */
+ 2.769784831400556606795755211543107E+275DL, /* 2**915 */
+ 5.539569662801113213591510423086213E+275DL, /* 2**916 */
+ 1.107913932560222642718302084617243E+276DL, /* 2**917 */
+ 2.215827865120445285436604169234485E+276DL, /* 2**918 */
+ 4.431655730240890570873208338468971E+276DL, /* 2**919 */
+ 8.863311460481781141746416676937941E+276DL, /* 2**920 */
+ 1.772662292096356228349283335387588E+277DL, /* 2**921 */
+ 3.545324584192712456698566670775176E+277DL, /* 2**922 */
+ 7.090649168385424913397133341550353E+277DL, /* 2**923 */
+ 1.418129833677084982679426668310071E+278DL, /* 2**924 */
+ 2.836259667354169965358853336620141E+278DL, /* 2**925 */
+ 5.672519334708339930717706673240282E+278DL, /* 2**926 */
+ 1.134503866941667986143541334648056E+279DL, /* 2**927 */
+ 2.269007733883335972287082669296113E+279DL, /* 2**928 */
+ 4.538015467766671944574165338592226E+279DL, /* 2**929 */
+ 9.076030935533343889148330677184452E+279DL, /* 2**930 */
+ 1.815206187106668777829666135436890E+280DL, /* 2**931 */
+ 3.630412374213337555659332270873781E+280DL, /* 2**932 */
+ 7.260824748426675111318664541747561E+280DL, /* 2**933 */
+ 1.452164949685335022263732908349512E+281DL, /* 2**934 */
+ 2.904329899370670044527465816699025E+281DL, /* 2**935 */
+ 5.808659798741340089054931633398049E+281DL, /* 2**936 */
+ 1.161731959748268017810986326679610E+282DL, /* 2**937 */
+ 2.323463919496536035621972653359220E+282DL, /* 2**938 */
+ 4.646927838993072071243945306718439E+282DL, /* 2**939 */
+ 9.293855677986144142487890613436879E+282DL, /* 2**940 */
+ 1.858771135597228828497578122687376E+283DL, /* 2**941 */
+ 3.717542271194457656995156245374751E+283DL, /* 2**942 */
+ 7.435084542388915313990312490749503E+283DL, /* 2**943 */
+ 1.487016908477783062798062498149901E+284DL, /* 2**944 */
+ 2.974033816955566125596124996299801E+284DL, /* 2**945 */
+ 5.948067633911132251192249992599602E+284DL, /* 2**946 */
+ 1.189613526782226450238449998519920E+285DL, /* 2**947 */
+ 2.379227053564452900476899997039841E+285DL, /* 2**948 */
+ 4.758454107128905800953799994079682E+285DL, /* 2**949 */
+ 9.516908214257811601907599988159364E+285DL, /* 2**950 */
+ 1.903381642851562320381519997631873E+286DL, /* 2**951 */
+ 3.806763285703124640763039995263745E+286DL, /* 2**952 */
+ 7.613526571406249281526079990527491E+286DL, /* 2**953 */
+ 1.522705314281249856305215998105498E+287DL, /* 2**954 */
+ 3.045410628562499712610431996210996E+287DL, /* 2**955 */
+ 6.090821257124999425220863992421993E+287DL, /* 2**956 */
+ 1.218164251424999885044172798484399E+288DL, /* 2**957 */
+ 2.436328502849999770088345596968797E+288DL, /* 2**958 */
+ 4.872657005699999540176691193937594E+288DL, /* 2**959 */
+ 9.745314011399999080353382387875188E+288DL, /* 2**960 */
+ 1.949062802279999816070676477575038E+289DL, /* 2**961 */
+ 3.898125604559999632141352955150075E+289DL, /* 2**962 */
+ 7.796251209119999264282705910300151E+289DL, /* 2**963 */
+ 1.559250241823999852856541182060030E+290DL, /* 2**964 */
+ 3.118500483647999705713082364120060E+290DL, /* 2**965 */
+ 6.237000967295999411426164728240121E+290DL, /* 2**966 */
+ 1.247400193459199882285232945648024E+291DL, /* 2**967 */
+ 2.494800386918399764570465891296048E+291DL, /* 2**968 */
+ 4.989600773836799529140931782592096E+291DL, /* 2**969 */
+ 9.979201547673599058281863565184193E+291DL, /* 2**970 */
+ 1.995840309534719811656372713036839E+292DL, /* 2**971 */
+ 3.991680619069439623312745426073677E+292DL, /* 2**972 */
+ 7.983361238138879246625490852147354E+292DL, /* 2**973 */
+ 1.596672247627775849325098170429471E+293DL, /* 2**974 */
+ 3.193344495255551698650196340858942E+293DL, /* 2**975 */
+ 6.386688990511103397300392681717883E+293DL, /* 2**976 */
+ 1.277337798102220679460078536343577E+294DL, /* 2**977 */
+ 2.554675596204441358920157072687153E+294DL, /* 2**978 */
+ 5.109351192408882717840314145374307E+294DL, /* 2**979 */
+ 1.021870238481776543568062829074861E+295DL, /* 2**980 */
+ 2.043740476963553087136125658149723E+295DL, /* 2**981 */
+ 4.087480953927106174272251316299445E+295DL, /* 2**982 */
+ 8.174961907854212348544502632598891E+295DL, /* 2**983 */
+ 1.634992381570842469708900526519778E+296DL, /* 2**984 */
+ 3.269984763141684939417801053039556E+296DL, /* 2**985 */
+ 6.539969526283369878835602106079113E+296DL, /* 2**986 */
+ 1.307993905256673975767120421215823E+297DL, /* 2**987 */
+ 2.615987810513347951534240842431645E+297DL, /* 2**988 */
+ 5.231975621026695903068481684863290E+297DL, /* 2**989 */
+ 1.046395124205339180613696336972658E+298DL, /* 2**990 */
+ 2.092790248410678361227392673945316E+298DL, /* 2**991 */
+ 4.185580496821356722454785347890632E+298DL, /* 2**992 */
+ 8.371160993642713444909570695781264E+298DL, /* 2**993 */
+ 1.674232198728542688981914139156253E+299DL, /* 2**994 */
+ 3.348464397457085377963828278312506E+299DL, /* 2**995 */
+ 6.696928794914170755927656556625011E+299DL, /* 2**996 */
+ 1.339385758982834151185531311325002E+300DL, /* 2**997 */
+ 2.678771517965668302371062622650005E+300DL, /* 2**998 */
+ 5.357543035931336604742125245300009E+300DL, /* 2**999 */
+ 1.071508607186267320948425049060002E+301DL, /* 2**1000 */
+ 2.143017214372534641896850098120004E+301DL, /* 2**1001 */
+ 4.286034428745069283793700196240007E+301DL, /* 2**1002 */
+ 8.572068857490138567587400392480014E+301DL, /* 2**1003 */
+ 1.714413771498027713517480078496003E+302DL, /* 2**1004 */
+ 3.428827542996055427034960156992006E+302DL, /* 2**1005 */
+ 6.857655085992110854069920313984012E+302DL, /* 2**1006 */
+ 1.371531017198422170813984062796802E+303DL, /* 2**1007 */
+ 2.743062034396844341627968125593605E+303DL, /* 2**1008 */
+ 5.486124068793688683255936251187209E+303DL, /* 2**1009 */
+ 1.097224813758737736651187250237442E+304DL, /* 2**1010 */
+ 2.194449627517475473302374500474884E+304DL, /* 2**1011 */
+ 4.388899255034950946604749000949767E+304DL, /* 2**1012 */
+ 8.777798510069901893209498001899535E+304DL, /* 2**1013 */
+ 1.755559702013980378641899600379907E+305DL, /* 2**1014 */
+ 3.511119404027960757283799200759814E+305DL, /* 2**1015 */
+ 7.022238808055921514567598401519628E+305DL, /* 2**1016 */
+ 1.404447761611184302913519680303926E+306DL, /* 2**1017 */
+ 2.808895523222368605827039360607851E+306DL, /* 2**1018 */
+ 5.617791046444737211654078721215702E+306DL, /* 2**1019 */
+ 1.123558209288947442330815744243140E+307DL, /* 2**1020 */
+ 2.247116418577894884661631488486281E+307DL, /* 2**1021 */
+ 4.494232837155789769323262976972562E+307DL, /* 2**1022 */
+ 8.988465674311579538646525953945124E+307DL, /* 2**1023 */
+ 1.797693134862315907729305190789025E+308DL, /* 2**1024 */
+ 3.595386269724631815458610381578049E+308DL, /* 2**1025 */
+ 7.190772539449263630917220763156099E+308DL, /* 2**1026 */
+ 1.438154507889852726183444152631220E+309DL, /* 2**1027 */
+ 2.876309015779705452366888305262440E+309DL, /* 2**1028 */
+ 5.752618031559410904733776610524879E+309DL, /* 2**1029 */
+ 1.150523606311882180946755322104976E+310DL, /* 2**1030 */
+ 2.301047212623764361893510644209952E+310DL, /* 2**1031 */
+ 4.602094425247528723787021288419903E+310DL, /* 2**1032 */
+ 9.204188850495057447574042576839807E+310DL, /* 2**1033 */
+ 1.840837770099011489514808515367961E+311DL, /* 2**1034 */
+ 3.681675540198022979029617030735923E+311DL, /* 2**1035 */
+ 7.363351080396045958059234061471845E+311DL, /* 2**1036 */
+ 1.472670216079209191611846812294369E+312DL, /* 2**1037 */
+ 2.945340432158418383223693624588738E+312DL, /* 2**1038 */
+ 5.890680864316836766447387249177476E+312DL, /* 2**1039 */
+ 1.178136172863367353289477449835495E+313DL, /* 2**1040 */
+ 2.356272345726734706578954899670990E+313DL, /* 2**1041 */
+ 4.712544691453469413157909799341981E+313DL, /* 2**1042 */
+ 9.425089382906938826315819598683962E+313DL, /* 2**1043 */
+ 1.885017876581387765263163919736792E+314DL, /* 2**1044 */
+ 3.770035753162775530526327839473585E+314DL, /* 2**1045 */
+ 7.540071506325551061052655678947170E+314DL, /* 2**1046 */
+ 1.508014301265110212210531135789434E+315DL, /* 2**1047 */
+ 3.016028602530220424421062271578868E+315DL, /* 2**1048 */
+ 6.032057205060440848842124543157736E+315DL, /* 2**1049 */
+ 1.206411441012088169768424908631547E+316DL, /* 2**1050 */
+ 2.412822882024176339536849817263094E+316DL, /* 2**1051 */
+ 4.825645764048352679073699634526189E+316DL, /* 2**1052 */
+ 9.651291528096705358147399269052377E+316DL, /* 2**1053 */
+ 1.930258305619341071629479853810475E+317DL, /* 2**1054 */
+ 3.860516611238682143258959707620951E+317DL, /* 2**1055 */
+ 7.721033222477364286517919415241902E+317DL, /* 2**1056 */
+ 1.544206644495472857303583883048380E+318DL, /* 2**1057 */
+ 3.088413288990945714607167766096761E+318DL, /* 2**1058 */
+ 6.176826577981891429214335532193521E+318DL, /* 2**1059 */
+ 1.235365315596378285842867106438704E+319DL, /* 2**1060 */
+ 2.470730631192756571685734212877409E+319DL, /* 2**1061 */
+ 4.941461262385513143371468425754817E+319DL, /* 2**1062 */
+ 9.882922524771026286742936851509634E+319DL, /* 2**1063 */
+ 1.976584504954205257348587370301927E+320DL, /* 2**1064 */
+ 3.953169009908410514697174740603854E+320DL, /* 2**1065 */
+ 7.906338019816821029394349481207707E+320DL, /* 2**1066 */
+ 1.581267603963364205878869896241541E+321DL, /* 2**1067 */
+ 3.162535207926728411757739792483083E+321DL, /* 2**1068 */
+ 6.325070415853456823515479584966166E+321DL, /* 2**1069 */
+ 1.265014083170691364703095916993233E+322DL, /* 2**1070 */
+ 2.530028166341382729406191833986466E+322DL, /* 2**1071 */
+ 5.060056332682765458812383667972933E+322DL, /* 2**1072 */
+ 1.012011266536553091762476733594587E+323DL, /* 2**1073 */
+ 2.024022533073106183524953467189173E+323DL, /* 2**1074 */
+ 4.048045066146212367049906934378346E+323DL, /* 2**1075 */
+ 8.096090132292424734099813868756692E+323DL, /* 2**1076 */
+ 1.619218026458484946819962773751338E+324DL /* 2**1077 */
+};
+
+weak_alias(decpowof2, __dfp_decpowof2)
diff --git a/libc/dfp/sysdeps/soft-dfp/divdd3.c b/libc/dfp/sysdeps/soft-dfp/divdd3.c
new file mode 100644
index 000000000..c1fccba31
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/divdd3.c
@@ -0,0 +1,27 @@
+/* _Decimal64 division for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __divdd3
+#include <decimal64.h>
+
+#include "divsd3.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/divsd3.c b/libc/dfp/sysdeps/soft-dfp/divsd3.c
new file mode 100644
index 000000000..8c957a598
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/divsd3.c
@@ -0,0 +1,68 @@
+/* _Decimal32 division for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __divsd3
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME div
+
+#include <dfpmacro.h>
+DEC_TYPE
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE result;
+ decNumber dn_x, dn_y, dn_result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ ___decNumberDivide(&dn_result, &dn_x, &dn_y, &context);
+
+ if (context.status != 0)
+ {
+ int ieee_flags = 0;
+ if (context.status & DEC_IEEE_854_Division_by_zero)
+ ieee_flags |= FE_DIVBYZERO;
+ if (context.status & DEC_IEEE_854_Inexact)
+ ieee_flags |= FE_INEXACT;
+ if (context.status & DEC_IEEE_854_Invalid_operation)
+ ieee_flags |= FE_INVALID;
+ if (context.status & DEC_IEEE_854_Overflow)
+ ieee_flags |= FE_OVERFLOW;
+ if (context.status & DEC_IEEE_854_Underflow)
+ ieee_flags |= FE_UNDERFLOW;
+ if (ieee_flags != 0)
+ feraiseexcept (ieee_flags);
+ }
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ return result;
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/divtd3.c b/libc/dfp/sysdeps/soft-dfp/divtd3.c
new file mode 100644
index 000000000..a5202b889
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/divtd3.c
@@ -0,0 +1,27 @@
+/* _Decimal128 division for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __divtd3
+#include <decimal128.h>
+
+#include "divsd3.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/eqdd2.c b/libc/dfp/sysdeps/soft-dfp/eqdd2.c
new file mode 100644
index 000000000..807daf7cd
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/eqdd2.c
@@ -0,0 +1,27 @@
+/* _Decimal64 compare equality for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __eqdd2
+#include <decimal64.h>
+
+#include "eqsd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/eqsd2.c b/libc/dfp/sysdeps/soft-dfp/eqsd2.c
new file mode 100644
index 000000000..6b05e0044
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/eqsd2.c
@@ -0,0 +1,51 @@
+/* _Decimal32 compare equality for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __eqsd2
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME eq
+
+#include <dfpmacro.h>
+int
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x, dn_y, result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return 1;
+
+ ___decNumberCompare(&result, &dn_x, &dn_y, &context);
+ return !___decNumberIsZero(&result);
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/eqtd2.c b/libc/dfp/sysdeps/soft-dfp/eqtd2.c
new file mode 100644
index 000000000..91b11a8fd
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/eqtd2.c
@@ -0,0 +1,27 @@
+/* _Decimal128 compare equality for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __eqtd2
+#include <decimal128.h>
+
+#include "eqsd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extend.c b/libc/dfp/sysdeps/soft-dfp/extend.c
new file mode 100644
index 000000000..49f7ea88d
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extend.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary long double (dual 64bit) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 128
+#define DEST 128
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extend2.c b/libc/dfp/sysdeps/soft-dfp/extend2.c
new file mode 100644
index 000000000..7e4144628
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extend2.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_DECIMAL
+#define SRC 64
+#define DEST 128
+#define NAME extend2
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extend_d_f.c b/libc/dfp/sysdeps/soft-dfp/extend_d_f.c
new file mode 100644
index 000000000..5f2b7bc1f
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extend_d_f.c
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+#include "convert.h"
+
+extern double __truncdddf (_Decimal64);
+extern _Decimal64 __extenddfdd (double);
+
+DEST_TYPE
+__extendddxf (SRC_TYPE a)
+{
+ double df_part1, df_part2;
+ DEST_TYPE result;
+ SRC_TYPE dd_part1, dd_part2;
+
+ df_part1 = __truncdddf(a); //_D64 -> dbl
+ if(isnan(df_part1) || isinf(df_part1))
+ return df_part1; //inf or NaN
+ dd_part1 = __extenddfdd(df_part1); //dbl -> _D64 (exact?)
+ dd_part2 = a - dd_part1; //_D64
+ df_part2 = __truncdddf(dd_part2); //_D64 -> dbl (trunc)
+ result = df_part1;
+ result += df_part2;
+ return df_part1;
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/extendddtd2.c b/libc/dfp/sysdeps/soft-dfp/extendddtd2.c
new file mode 100644
index 000000000..ef540b34f
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendddtd2.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_DECIMAL
+#define SRC 64
+#define DEST 128
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extendddtf.c b/libc/dfp/sysdeps/soft-dfp/extendddtf.c
new file mode 100644
index 000000000..b535347d2
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendddtf.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to binary long double (128)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 64
+#define DEST 128
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extenddfdd.c b/libc/dfp/sysdeps/soft-dfp/extenddfdd.c
new file mode 100644
index 000000000..7dafb7286
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extenddfdd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary double (64) to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 64
+#define DEST 64
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extenddftd.c b/libc/dfp/sysdeps/soft-dfp/extenddftd.c
new file mode 100644
index 000000000..136e54a9e
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extenddftd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary double (64) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 64
+#define DEST 128
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extendsddd2.c b/libc/dfp/sysdeps/soft-dfp/extendsddd2.c
new file mode 100644
index 000000000..60cf6e312
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendsddd2.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal32 to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_DECIMAL
+#define SRC 32
+#define DEST 64
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extendsddf.c b/libc/dfp/sysdeps/soft-dfp/extendsddf.c
new file mode 100644
index 000000000..c3e229e7c
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendsddf.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal32 to binary double (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 32
+#define DEST 64
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extendsdtd2.c b/libc/dfp/sysdeps/soft-dfp/extendsdtd2.c
new file mode 100644
index 000000000..19e4b1ca9
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendsdtd2.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal32 to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_DECIMAL
+#define SRC 32
+#define DEST 128
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extendsdtf.c b/libc/dfp/sysdeps/soft-dfp/extendsdtf.c
new file mode 100644
index 000000000..5dedd65e0
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendsdtf.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal32 to binary long double (128)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 32
+#define DEST 128
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extendsfdd.c b/libc/dfp/sysdeps/soft-dfp/extendsfdd.c
new file mode 100644
index 000000000..c9aacdbb6
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendsfdd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary float (32) to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 32
+#define DEST 64
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extendsfsd.c b/libc/dfp/sysdeps/soft-dfp/extendsfsd.c
new file mode 100644
index 000000000..e9216c7b6
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendsfsd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary float (32) to Decimal32
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 32
+#define DEST 32
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extendsftd.c b/libc/dfp/sysdeps/soft-dfp/extendsftd.c
new file mode 100644
index 000000000..6ab33ad0a
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendsftd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary float (32) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 32
+#define DEST 128
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/extendtfdd.c b/libc/dfp/sysdeps/soft-dfp/extendtfdd.c
new file mode 100644
index 000000000..e61c510d7
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendtfdd.c
@@ -0,0 +1,55 @@
+/* Handle
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#include <math.h>
+
+extern _Decimal64 __extenddfdd(double);
+
+_Decimal64
+__extendtfdd (long double a)
+{
+ _Decimal64 result = 0.0DD;
+ _Decimal64 temp;
+ union {
+ long double ld;
+ double d[2];
+ }
+
+ switch (fpclassify (a)) {
+ case FP_ZERO:
+ result = signbit(a) ? -0.0DD : 0.0DD;
+ break;
+ case FP_INFINITY:
+ result = a>0.0 ? DEC_INFINITY : -DEC_INFINITY;
+ break;
+ case FP_NAN:
+ result = DEC_NAN;
+ break;
+ default:
+ ldd.ld = a;
+ temp = __extenddfdd (ldd.d[0]);
+ result = temp;
+ temp = __extenddfdd (ldd.d[1]);
+ result = result + temp;
+ }
+ return result;
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/extendtftd.c b/libc/dfp/sysdeps/soft-dfp/extendtftd.c
new file mode 100644
index 000000000..49f7ea88d
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/extendtftd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary long double (dual 64bit) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 128
+#define DEST 128
+#define NAME extend
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fix.c b/libc/dfp/sysdeps/soft-dfp/fix.c
new file mode 100644
index 000000000..7727cf549
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fix.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to binary long (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 128
+#define DEST 64
+#define NAME fix
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixdddi.c b/libc/dfp/sysdeps/soft-dfp/fixdddi.c
new file mode 100644
index 000000000..104ce89b4
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixdddi.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to binary long (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 64
+#define DEST 64
+#define NAME fix
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixddsi.c b/libc/dfp/sysdeps/soft-dfp/fixddsi.c
new file mode 100644
index 000000000..81d3e5ad1
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixddsi.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to binary integer (32)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 64
+#define DEST 32
+#define NAME fix
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixsddi.c b/libc/dfp/sysdeps/soft-dfp/fixsddi.c
new file mode 100644
index 000000000..1818acd79
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixsddi.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal32 to binary long (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 32
+#define DEST 64
+#define NAME fix
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixsdsi.c b/libc/dfp/sysdeps/soft-dfp/fixsdsi.c
new file mode 100644
index 000000000..5b532a54e
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixsdsi.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal32 to binary integer (32)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 32
+#define DEST 32
+#define NAME fix
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixtddi.c b/libc/dfp/sysdeps/soft-dfp/fixtddi.c
new file mode 100644
index 000000000..7727cf549
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixtddi.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to binary long (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 128
+#define DEST 64
+#define NAME fix
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixtdsi.c b/libc/dfp/sysdeps/soft-dfp/fixtdsi.c
new file mode 100644
index 000000000..25d941d53
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixtdsi.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to binary integer (32)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 128
+#define DEST 32
+#define NAME fix
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixuns.c b/libc/dfp/sysdeps/soft-dfp/fixuns.c
new file mode 100644
index 000000000..cd6b40749
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixuns.c
@@ -0,0 +1,29 @@
+/* Handle conversion from Decimal64 to binary unsigned long (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 128
+#define DEST 64
+#define NAME fixuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixunsdddi.c b/libc/dfp/sysdeps/soft-dfp/fixunsdddi.c
new file mode 100644
index 000000000..bb9dfaacd
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixunsdddi.c
@@ -0,0 +1,29 @@
+/* Handle conversion from Decimal64 to binary unsigned long (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 64
+#define DEST 64
+#define NAME fixuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixunsddsi.c b/libc/dfp/sysdeps/soft-dfp/fixunsddsi.c
new file mode 100644
index 000000000..27e60bdd6
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixunsddsi.c
@@ -0,0 +1,29 @@
+/* Handle conversion from Decimal64 to binary unsigned integer (32)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 64
+#define DEST 32
+#define NAME fixuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixunssddi.c b/libc/dfp/sysdeps/soft-dfp/fixunssddi.c
new file mode 100644
index 000000000..4418cc4b4
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixunssddi.c
@@ -0,0 +1,29 @@
+/* Handle conversion from Decimal32 to binary unsigned long (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 32
+#define DEST 64
+#define NAME fixuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixunssdsi.c b/libc/dfp/sysdeps/soft-dfp/fixunssdsi.c
new file mode 100644
index 000000000..59d2f4b06
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixunssdsi.c
@@ -0,0 +1,29 @@
+/* Handle conversion from Decimal32 to binary unsigned integer (32)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 32
+#define DEST 32
+#define NAME fixuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixunstddi.c b/libc/dfp/sysdeps/soft-dfp/fixunstddi.c
new file mode 100644
index 000000000..cd6b40749
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixunstddi.c
@@ -0,0 +1,29 @@
+/* Handle conversion from Decimal64 to binary unsigned long (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 128
+#define DEST 64
+#define NAME fixuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/fixunstdsi.c b/libc/dfp/sysdeps/soft-dfp/fixunstdsi.c
new file mode 100644
index 000000000..2b1a5eb81
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/fixunstdsi.c
@@ -0,0 +1,29 @@
+/* Handle conversion from Decimal64 to binary unsigned integer (32)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_INTEGER
+#define SRC 128
+#define DEST 32
+#define NAME fixuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/float.c b/libc/dfp/sysdeps/soft-dfp/float.c
new file mode 100644
index 000000000..1921b8c3a
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/float.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary long (64) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 64
+#define DEST 128
+#define NAME float
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatdidd.c b/libc/dfp/sysdeps/soft-dfp/floatdidd.c
new file mode 100644
index 000000000..bbb89edc5
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatdidd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary long (64) to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 64
+#define DEST 64
+#define NAME float
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatdisd.c b/libc/dfp/sysdeps/soft-dfp/floatdisd.c
new file mode 100644
index 000000000..e4b25f082
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatdisd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary long (64) to Decimal32
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 64
+#define DEST 32
+#define NAME float
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatditd.c b/libc/dfp/sysdeps/soft-dfp/floatditd.c
new file mode 100644
index 000000000..1921b8c3a
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatditd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary long (64) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 64
+#define DEST 128
+#define NAME float
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatsidd.c b/libc/dfp/sysdeps/soft-dfp/floatsidd.c
new file mode 100644
index 000000000..3e9bb6f56
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatsidd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary integer (32) to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 32
+#define DEST 64
+#define NAME float
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatsisd.c b/libc/dfp/sysdeps/soft-dfp/floatsisd.c
new file mode 100644
index 000000000..988c9ebd2
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatsisd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary integer (32) to Decimal32
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 32
+#define DEST 32
+#define NAME float
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatsitd.c b/libc/dfp/sysdeps/soft-dfp/floatsitd.c
new file mode 100644
index 000000000..2f8687f40
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatsitd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary integer (32) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 32
+#define DEST 128
+#define NAME float
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatuns.c b/libc/dfp/sysdeps/soft-dfp/floatuns.c
new file mode 100644
index 000000000..b544eab9e
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatuns.c
@@ -0,0 +1,29 @@
+/* Handle conversion from binary unsigned long (64) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 64
+#define DEST 128
+#define NAME floatuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatunsdidd.c b/libc/dfp/sysdeps/soft-dfp/floatunsdidd.c
new file mode 100644
index 000000000..aa9edce5d
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatunsdidd.c
@@ -0,0 +1,29 @@
+/* Handle conversion from binary unsigned long (64) to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 64
+#define DEST 64
+#define NAME floatuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatunsdisd.c b/libc/dfp/sysdeps/soft-dfp/floatunsdisd.c
new file mode 100644
index 000000000..8d92eabc1
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatunsdisd.c
@@ -0,0 +1,29 @@
+/* Handle conversion from binary unsigned long (64) to Decimal32
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 64
+#define DEST 32
+#define NAME floatuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatunsditd.c b/libc/dfp/sysdeps/soft-dfp/floatunsditd.c
new file mode 100644
index 000000000..b544eab9e
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatunsditd.c
@@ -0,0 +1,29 @@
+/* Handle conversion from binary unsigned long (64) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 64
+#define DEST 128
+#define NAME floatuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatunssidd.c b/libc/dfp/sysdeps/soft-dfp/floatunssidd.c
new file mode 100644
index 000000000..a7321fd4f
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatunssidd.c
@@ -0,0 +1,29 @@
+/* Handle conversion from binary unsigned integer (32) to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 32
+#define DEST 64
+#define NAME floatuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatunssisd.c b/libc/dfp/sysdeps/soft-dfp/floatunssisd.c
new file mode 100644
index 000000000..aded26e5b
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatunssisd.c
@@ -0,0 +1,29 @@
+/* Handle conversion from binary unsigned integer (32) to Decimal32
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 32
+#define DEST 32
+#define NAME floatuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/floatunssitd.c b/libc/dfp/sysdeps/soft-dfp/floatunssitd.c
new file mode 100644
index 000000000..dc7f0d767
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/floatunssitd.c
@@ -0,0 +1,29 @@
+/* Handle conversion from binary unsigned integer (32) to Decimal128
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define INTEGER_TO_DECIMAL
+#define SRC 32
+#define DEST 128
+#define NAME floatuns
+#define UNSIGNED
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/gedd2.c b/libc/dfp/sysdeps/soft-dfp/gedd2.c
new file mode 100644
index 000000000..670f86471
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/gedd2.c
@@ -0,0 +1,27 @@
+/* _Decimal64 compare greather-than or equal for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __gedd2
+#include <decimal64.h>
+
+#include "gesd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/gesd2.c b/libc/dfp/sysdeps/soft-dfp/gesd2.c
new file mode 100644
index 000000000..b5fd4ba69
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/gesd2.c
@@ -0,0 +1,51 @@
+/* _Decimal32 compare greather-than or equal for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __gesd2
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME ge
+
+#include <dfpmacro.h>
+int
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x, dn_y, result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return -1;
+
+ ___decNumberCompare(&result, &dn_x, &dn_y, &context);
+ return -___decNumberIsNegative(&result);
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/getd2.c b/libc/dfp/sysdeps/soft-dfp/getd2.c
new file mode 100644
index 000000000..a5ab3b17e
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/getd2.c
@@ -0,0 +1,27 @@
+/* _Decimal128 compare greather-than or equal for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __getd2
+#include <decimal128.h>
+
+#include "gesd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/gtdd2.c b/libc/dfp/sysdeps/soft-dfp/gtdd2.c
new file mode 100644
index 000000000..dcdf8c76b
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/gtdd2.c
@@ -0,0 +1,27 @@
+/* _Decimal64 compare greater-than for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __gtdd2
+#include <decimal64.h>
+
+#include "gtsd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/gtsd2.c b/libc/dfp/sysdeps/soft-dfp/gtsd2.c
new file mode 100644
index 000000000..d5a0eb702
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/gtsd2.c
@@ -0,0 +1,51 @@
+/* _Decimal32 compare greater-than for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __gtsd2
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME gt
+
+#include <dfpmacro.h>
+int
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x, dn_y, result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return -1;
+
+ ___decNumberCompare(&result, &dn_x, &dn_y, &context);
+ return !___decNumberIsNegative(&result) && !___decNumberIsZero(&result);
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/gttd2.c b/libc/dfp/sysdeps/soft-dfp/gttd2.c
new file mode 100644
index 000000000..bc7bad064
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/gttd2.c
@@ -0,0 +1,27 @@
+/* _Decimal128 compare greater-than for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __gttd2
+#include <decimal128.h>
+
+#include "gtsd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/ledd2.c b/libc/dfp/sysdeps/soft-dfp/ledd2.c
new file mode 100644
index 000000000..5e967e678
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/ledd2.c
@@ -0,0 +1,27 @@
+/* _Decimal64 compare less-than or equal for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __ledd2
+#include <decimal64.h>
+
+#include "lesd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/lesd2.c b/libc/dfp/sysdeps/soft-dfp/lesd2.c
new file mode 100644
index 000000000..99816568d
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/lesd2.c
@@ -0,0 +1,51 @@
+/* _Decimal32 compare less-than or equal for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __lesd2
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME le
+
+#include <dfpmacro.h>
+int
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x, dn_y, result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return 1;
+
+ ___decNumberCompare(&result, &dn_x, &dn_y, &context);
+ return !___decNumberIsNegative(&result) && !___decNumberIsZero(&result);
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/letd2.c b/libc/dfp/sysdeps/soft-dfp/letd2.c
new file mode 100644
index 000000000..fefc639f8
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/letd2.c
@@ -0,0 +1,27 @@
+/* _Decimal128 compare less-than or equal for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __letd2
+#include <decimal128.h>
+
+#include "lesd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/ltdd2.c b/libc/dfp/sysdeps/soft-dfp/ltdd2.c
new file mode 100644
index 000000000..827651c73
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/ltdd2.c
@@ -0,0 +1,27 @@
+/* _Decimal64 compare less-than for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __ltdd2
+#include <decimal64.h>
+
+#include "ltsd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/ltsd2.c b/libc/dfp/sysdeps/soft-dfp/ltsd2.c
new file mode 100644
index 000000000..aaa19bb52
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/ltsd2.c
@@ -0,0 +1,51 @@
+/* _Decimal32 compare less-than for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __ltsd2
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME lt
+
+#include <dfpmacro.h>
+int
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x, dn_y, result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return 1;
+
+ ___decNumberCompare(&result, &dn_x, &dn_y, &context);
+ return -___decNumberIsNegative(&result);
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/lttd2.c b/libc/dfp/sysdeps/soft-dfp/lttd2.c
new file mode 100644
index 000000000..2d48b3032
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/lttd2.c
@@ -0,0 +1,27 @@
+/* _Decimal128 compare less-than for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __lttd2
+#include <decimal128.h>
+
+#include "ltsd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/makecfiles.sh b/libc/dfp/sysdeps/soft-dfp/makecfiles.sh
new file mode 100644
index 000000000..da1c57e95
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/makecfiles.sh
@@ -0,0 +1,635 @@
+#!/bin/bash
+
+
+function header {
+ cat > ${1} << EOF
+/* $2
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+EOF
+
+
+}
+
+
+## unaryop file op
+function unaryop {
+
+cat >> ${1} << EOF
+DEC_TYPE
+ACTUAL_FUNCTION_NAME (DEC_TYPE x)
+{
+ DEC_TYPE result;
+ decNumber dn_x;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+
+ ___decNumber${2}(&result, &dn_x, &context);
+
+ FUNC_CONVERT_FROM_DN (&dn_x, &result, &context);
+ return result;
+}
+EOF
+}
+
+
+## binaryop file op
+function binaryop {
+
+cat >> ${1} << EOF
+DEC_TYPE
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE result;
+ decNumber dn_x, dn_y, dn_result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ ___decNumber${2}(&dn_result, &dn_x, &dn_y, &context);
+
+ if (context.status != 0)
+ {
+ int ieee_flags = 0;
+ if (context.status & DEC_IEEE_854_Division_by_zero)
+ ieee_flags |= FE_DIVBYZERO;
+ if (context.status & DEC_IEEE_854_Inexact)
+ ieee_flags |= FE_INEXACT;
+ if (context.status & DEC_IEEE_854_Invalid_operation)
+ ieee_flags |= FE_INVALID;
+ if (context.status & DEC_IEEE_854_Overflow)
+ ieee_flags |= FE_OVERFLOW;
+ if (context.status & DEC_IEEE_854_Underflow)
+ ieee_flags |= FE_UNDERFLOW;
+ if (ieee_flags != 0)
+ feraiseexcept (ieee_flags);
+ }
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ return result;
+}
+EOF
+}
+
+
+
+## compareop file op
+function compareop {
+
+case $2 in
+ eq) nanret=1;;
+ ne) nanret=1;;
+ ge) nanret=-1;;
+ lt) nanret=1;;
+ le) nanret=1;;
+ gt) nanret=-1;;
+esac
+
+
+cat >> ${1} << EOF
+int
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x, dn_y, result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return ${nanret};
+
+ ___decNumberCompare(&result, &dn_x, &dn_y, &context);
+EOF
+
+case $2 in
+ eq|ne) echo " return !___decNumberIsZero(&result);">> ${1};;
+ ge|lt) echo " return -___decNumberIsNegative(&result);">> ${1};;
+ le|gt) echo " return !___decNumberIsNegative(&result) && !___decNumberIsZero(&result);">> ${1};;
+esac
+echo "}" >> ${1}
+
+}
+
+
+## unord file op
+function unord {
+
+cat >> ${1} << EOF
+int
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x;
+ decNumber dn_y;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ return (___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y));
+}
+EOF
+}
+
+
+
+
+
+## generate name postfix description
+function generate {
+
+ name32=${1}sd${2}
+ name64=${1}dd${2}
+ name128=${1}td${2}
+
+ file32=${name32}.c
+ file64=${name64}.c
+ file128=${name128}.c
+ desc=$3
+
+ header $file32 "_Decimal32 $desc for soft-dfp"
+ header $file64 "_Decimal64 $desc for soft-dfp"
+ header $file128 "_Decimal128 $desc for soft-dfp"
+
+ cat >> ${file32} << EOF32
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __${name32}
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME ${1}
+
+#include <dfpmacro.h>
+EOF32
+
+
+
+case $1 in
+ add) binaryop ${file32} Add;;
+ sub) binaryop ${file32} Subtract;;
+ mul) binaryop ${file32} Multiply;;
+ div) binaryop ${file32} Divide;;
+ eq|ne|lt|gt|le|ge) compareop ${file32} $1;;
+ unord) unord ${file32};;
+
+
+esac
+
+
+
+
+
+ echo "#define _DECIMAL_SIZE 64" >> ${file64}
+ echo "#define ACTUAL_FUNCTION_NAME __${name64}" >> ${file64}
+ echo "#include <decimal64.h>" >> ${file64}
+ echo "" >> ${file64}
+ echo "#include \"${file32}\"" >> ${file64}
+
+ echo "#define _DECIMAL_SIZE 128" >> ${file128}
+ echo "#define ACTUAL_FUNCTION_NAME __${name128}" >> ${file128}
+ echo "#include <decimal128.h>" >> ${file128}
+ echo "" >> ${file128}
+ echo "#include \"${file32}\"" >> ${file128}
+
+
+}
+
+
+function convert {
+ op=$1
+ from=$2
+ to=$3
+ width=
+ destwidth=
+ desc=$4
+
+ case $from in
+ sd) width=32; action=DECIMAL;;
+ dd) width=64; action=DECIMAL;;
+ td) width=128; action=DECIMAL;;
+ sf) width=32; action=BINARY;;
+ df) width=64; action=BINARY;;
+ tf) width=128; action=BINARY;;
+ si) width=32; action=INTEGER;;
+ di) width=64; action=INTEGER;;
+ esac
+
+
+ case $to in
+ sd) destwidth=32; action=${action}_TO_DECIMAL;;
+ dd) destwidth=64; action=${action}_TO_DECIMAL;;
+ td) destwidth=128; action=${action}_TO_DECIMAL;;
+ sf) destwidth=32; action=${action}_TO_BINARY;;
+ df) destwidth=64; action=${action}_TO_BINARY;;
+ tf) destwidth=128; action=${action}_TO_BINARY;;
+ si) destwidth=32; action=${action}_TO_INTEGER;;
+ di) destwidth=64; action=${action}_TO_INTEGER;;
+ esac
+
+ name=${op}${from}${to}
+ if [ $action == DECIMAL_TO_DECIMAL ]
+ then
+ name=${name}2
+ fi
+ file=${name}.c
+
+echo $file
+
+ header $file "${desc}"
+ echo "#define ${action}" >> $file
+ echo "#define SRC ${width}" >> $file
+ echo "#define DEST ${destwidth}" >> $file
+ echo "#define NAME ${op}" >> $file
+ case ${op} in
+ fixuns|floatuns) echo "#define UNSIGNED" >> $file;;
+ esac
+ echo "" >> $file
+ echo "#include \"convert.c\"" >> $file
+
+}
+
+
+generate add 3 addition
+generate sub 3 subtraction
+generate mul 3 multiplication
+generate div 3 division
+
+generate eq 2 "compare equality"
+generate ne 2 "compare inequality"
+generate lt 2 "compare less-than"
+generate gt 2 "compare greater-than"
+generate le 2 "compare less-than or equal"
+generate ge 2 "compare greather-than or equal"
+generate unord 2 "compare unordered"
+
+
+convert extend sd dd "Handle conversion from Decimal32 to Decimal64"
+convert extend sd td "Handle conversion from Decimal32 to Decimal128"
+convert extend dd td "Handle conversion from Decimal64 to Decimal128"
+
+convert extend sf sd "Handle conversion from binary float (32) to Decimal32"
+convert extend sd df "Handle conversion from Decimal32 to binary double (64)"
+convert extend sd tf "Handle conversion from Decimal32 to binary long double (128)"
+convert extend sf dd "Handle conversion from binary float (32) to Decimal64"
+convert extend df dd "Handle conversion from binary double (64) to Decimal64"
+convert extend dd tf "Handle conversion from Decimal64 to binary long double (128)"
+convert extend sf td "Handle conversion from binary float (32) to Decimal128"
+convert extend df td "Handle conversion from binary double (64) to Decimal128"
+convert extend tf td "Handle conversion from binary long double (dual 64bit) to Decimal128"
+
+convert trunc dd sd "Handle conversion from Decimal64 to Decimal32"
+convert trunc td sd "Handle conversion from Decimal128 to Decimal32"
+convert trunc td dd "Handle conversion from Decimal128 to Decimal64"
+
+convert trunc sd sf "Handle conversion from Decimal32 to binary float (32)"
+convert trunc df sd "Handle conversion from binary double (64) to Decimal32"
+convert trunc tf sd "Handle conversion from binary long double (128) to Decimal32"
+convert trunc dd sf "Handle conversion from Decimal64 to binary float (32)"
+convert trunc dd df "Handle conversion from Decimal64 to binary double (64)"
+convert trunc tf dd "Handle conversion from binary long double (128) to Decimal64"
+convert trunc td sf "Handle conversion from Decimal128 to binary float (32)"
+convert trunc td df "Handle conversion from Decimal128 to binary double (64)"
+convert trunc td tf "Handle conversion from Decimal128 to binary long double (dual 64bit)"
+
+convert fix sd si "Handle conversion from Decimal32 to binary integer (32)"
+convert fix dd si "Handle conversion from Decimal64 to binary integer (32)"
+convert fix td si "Handle conversion from Decimal64 to binary integer (32)"
+convert fix sd di "Handle conversion from Decimal32 to binary long (64)"
+convert fix dd di "Handle conversion from Decimal64 to binary long (64)"
+convert fix td di "Handle conversion from Decimal64 to binary long (64)"
+
+convert fixuns sd si "Handle conversion from Decimal32 to binary unsigned integer (32)"
+convert fixuns dd si "Handle conversion from Decimal64 to binary unsigned integer (32)"
+convert fixuns td si "Handle conversion from Decimal64 to binary unsigned integer (32)"
+convert fixuns sd di "Handle conversion from Decimal32 to binary unsigned long (64)"
+convert fixuns dd di "Handle conversion from Decimal64 to binary unsigned long (64)"
+convert fixuns td di "Handle conversion from Decimal64 to binary unsigned long (64)"
+
+convert float si sd "Handle conversion from binary integer (32) to Decimal32"
+convert float si dd "Handle conversion from binary integer (32) to Decimal64"
+convert float si td "Handle conversion from binary integer (32) to Decimal128"
+convert float di sd "Handle conversion from binary long (64) to Decimal32"
+convert float di dd "Handle conversion from binary long (64) to Decimal64"
+convert float di td "Handle conversion from binary long (64) to Decimal128"
+
+convert floatuns si sd "Handle conversion from binary unsigned integer (32) to Decimal32"
+convert floatuns si dd "Handle conversion from binary unsigned integer (32) to Decimal64"
+convert floatuns si td "Handle conversion from binary unsigned integer (32) to Decimal128"
+convert floatuns di sd "Handle conversion from binary unsigned long (64) to Decimal32"
+convert floatuns di dd "Handle conversion from binary unsigned long (64) to Decimal64"
+convert floatuns di td "Handle conversion from binary unsigned long (64) to Decimal128"
+
+
+exit
+
+makefile=Makefile
+versions=Versions
+
+echo "libdfp {" > ${versions}
+echo " GLIBC_2.5 {" >> ${versions}
+
+echo "# Makefile fragment for soft-dfp." > ${makefile}
+echo "" >> ${makefile}
+echo "ifeq (\$(subdir),dfp)" >> ${makefile}
+echo "sysdep-CFLAGS += -DWORDS_BIT_ENDIAN=1 -DLONG_DOUBLE_TYPE_SIZE=128 -DBITS_PER_UNIT=8" >> ${makefile}
+
+echo "libdfp-routines += \\">> ${makefile}
+makeline=" "
+
+
+## arguments: file, description
+function header {
+
+}
+
+## arguments: file, operation, description
+function arith {
+
+ case $1 in
+ add)
+
+ header file
+
+
+
+}
+
+
+for ins in add sub mul div eq ne lt gt le ge unord
+ do
+ versionline=" ";
+ for a in 32 64 128; do
+ width=$a
+ case $width in
+ 32) postfix=sd ;;
+ 64) postfix=dd ;;
+ 128) postfix=td ;;
+ esac
+ case $ins in
+ add|sub|mul|div)
+ define=L_${ins}_${postfix}
+ file=${ins}${postfix}3
+ case $ins in
+ add) desc="addition";;
+ sub) desc="subtraction";;
+ mul) desc="multiplication";;
+ div) desc="division";;
+ esac
+ type=_Decimal${width}
+ ;;
+ eq|ne|lt|gt|le|ge|unord)
+ define=L_${ins}_${postfix}
+ file=${ins}${postfix}2
+ case $ins in
+ eq) desc="compare equality";;
+ ne) desc="compare inequality";;
+ lt) desc="compare less-than";;
+ gt) desc="compare greater-than";;
+ le) desc="compare less-than or equal";;
+ ge) desc="compare greater-than or equal";;
+ unord) desc="compare unordered";;
+ esac
+ ;;
+ extend) case $width in
+ 32) define=L_sd_to_dd; width=32; file=extendsddd2
+ desc="extension to {{{_Decimal64}}}";;
+ 64) define=L_sd_to_td; width=32; file=extendsdtd2
+ desc="extension to {{{_Decimal128}}}";;
+ 128) define=L_dd_to_td; width=64; file=extendddtd2
+ desc="extension to {{{_Decimal128}}}";;
+ esac
+ ;;
+ extend2) case $width in
+ 32) define=L_sf_to_sd; width=32; file=extendsfsd
+ desc="extension from float";;
+ 64) define=L_sd_to_df; width=32; file=extendsddf
+ desc="extension to double";;
+ 128) define=L_sd_to_tf; width=32; file=extendsdtf
+ desc="extension to long double";;
+ esac
+ ;;
+ extend3) case $width in
+ 32) define=L_sf_to_dd; width=64; file=extendsfdd
+ desc="extension from float";;
+ 64) define=L_df_to_dd; width=64; file=extenddfdd
+ desc="extension from double";;
+ 128) define=L_dd_to_tf; width=64; file=extendddtf
+ desc="extension to long double";;
+ esac
+ ;;
+ extend4) case $width in
+ 32) define=L_sf_to_td; width=128; file=extendsftd
+ desc="extension from float";;
+ 64) define=L_df_to_td; width=128; file=extenddftd
+ desc="extension from double";;
+ 128) define=L_tf_to_td; width=128; file=extendtftd
+ desc="extension from long double";;
+ esac
+ ;;
+
+ trunc) case $width in
+ 32) define=L_td_to_sd; width=128; file=trunctdsd2
+ desc="truncation to {{{_Decimal32}}}";;
+ 64) define=L_dd_to_sd; width=64; file=truncddsd2
+ desc="truncation to {{{_Decimal32}}}";;
+ 128) define=L_td_to_dd; width=128; file=trunctddd2
+ desc="truncation to {{{_Decimal64}}}";;
+ esac
+ ;;
+ trunc2) case $width in
+ 32) define=L_sd_to_sf; width=32; file=truncsdsf
+ desc="truncation to float";;
+ 64) define=L_df_to_sd; width=32; file=truncdfsd
+ desc="truncation from double";;
+ 128) define=L_tf_to_sd; width=32; file=trunctfsd
+ desc="truncation from long double";;
+ esac
+ ;;
+ trunc3) case $width in
+ 32) define=L_dd_to_sf; width=64; file=truncddsf
+ desc="truncation to float";;
+ 64) define=L_dd_to_df; width=64; file=truncdddf
+ desc="truncation to double";;
+ 128) define=L_tf_to_dd; width=64; file=trunctfdd
+ desc="truncation from long double";;
+ esac
+ ;;
+ trunc4) case $width in
+ 32) define=L_td_to_sf; width=128; file=trunctdsf
+ desc="truncation to float";;
+ 64) define=L_td_to_df; width=128; file=trunctddf
+ desc="truncation to double";;
+ 128) define=L_td_to_tf; width=128; file=trunctdtf
+ desc="truncation to long double";;
+ esac
+ ;;
+
+ fixsi) define=L_${postfix}_to_si; file=fix${postfix}si; desc="conversion to signed integer";;
+ fixdi) define=L_${postfix}_to_di; file=fix${postfix}di; desc="conversion to signed long";;
+ fixunssi) define=L_${postfix}_to_usi; file=fixuns${postfix}si; desc="conversion to unsigned integer";;
+ fixunsdi) define=L_${postfix}_to_udi; file=fixuns${postfix}di; desc="conversion to unsigned long";;
+ floatsi) define=L_si_to_${postfix}; file=float${postfix}si; desc="conversion from signed integer";;
+ floatdi) define=L_di_to_${postfix}; file=float${postfix}di; desc="conversion from signed long";;
+ floatunssi) define=L_usi_to_${postfix}; file=floatuns${postfix}si; desc="conversion from unsigned integer";;
+ floatunsdi) define=L_udi_to_${postfix}; file=floatuns${postfix}di; desc="conversion from unsigned long";;
+
+ dfp_classify) define=L_classify_${postfix}; file=dfp_classify_${postfix}; desc="dfp classify";;
+ dfp_frexp) define=L_frexp_${postfix}; file=dfp_frexp_${postfix}; desc="dfp frexp";;
+ dfp_trunc) define=L_trunc_${postfix}; file=dfp_trunc_${postfix}; desc="dfp trunc";;
+ dfp_classify_f) case $width in
+ 32) define=L_classify_sf; file=dfp_classify_sf; desc="dfp classify float";;
+ 64) define=L_classify_df; file=dfp_classify_df; desc="dfp classify double";;
+ 128) define=L_classify_tf; file=dfp_classify_tf; desc="dfp classify long double";;
+ esac
+ ;;
+ esac
+ versionline="${versionline} __${file};"
+# echo ${define} ${file}.c ${width}
+# echo "||{{{__${file}}}}||<#FFCC66 (>libgcc||Power6|| ||gcc/gcc/config/rs6000/dfp.md||{{{_Decimal${width}}}} ${desc}||"
+# echo "||{{{__${file}}}}||<#99CC99 (>libdfp||generic||missing||libc/dfp/sysdeps/soft-dfp/${file}.c||{{{_Decimal${width}}}} ${desc}||"
+# echo "||{{{__${file}}}}||<#99CC99 (>libdfp||Power6||completed||libc/dfp/sysdeps/powerpc/powerpc32/power6/fpu/${file}.S||{{{_Decimal${width}}}} ${desc}||"
+ echo "||{{{__${file}}}}||<#FFCC66 (>complete||<#99CC99 (>complete||<#99CC99 (>complete|| ||{{{_Decimal${width}}}} ${desc}||"
+
+ makeline="${makeline} ${file}"
+
+ cat > ${file}.c << EOF
+/* _Decimal${width} $desc for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+EOF
+
+ if [ ${width} == 32 ]; then
+ file32=${file}.c
+ cat > ${file32} << EOF32
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+#endif
+#include <errno.h>
+
+
+${type} ${file} (
+
+EOF32
+
+ elif [ ${width} == 64 ]; then
+ echo "#define _DECIMAL_SIZE 64" >> ${file}.c
+ echo "#include <decimal64.h>" >> ${file}.c
+ echo "" >> ${file}.c
+ echo "#include \"${file32}\"" >> ${file}.c
+
+ elif [ ${width} == 128 ]; then
+ echo "#define _DECIMAL_SIZE 128" >> ${file}.c
+ echo "#include <decimal128.h>" >> ${file}.c
+ echo "" >> ${file}.c
+ echo "#include \"${file32}\"" >> ${file}.c
+ fi
+
+
+
+
+ done
+ echo "${versionline}" >> ${versions}
+ echo "${makeline} \\" >> ${makefile}
+ makeline=" "
+
+done
+
+echo " }" >> ${versions}
+echo "}" >> ${versions}
+
+echo "endif" >> ${makefile}
+
+exit
+
+cat > ${file}.c << EOF
+/* Declare arithmetic operations using 32-bit decimal types
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define WIDTH 32
+
+#define L_addsub_sd
+#define L_mul_sd
+#define L_div_sd
+
+#define L_eq_sd
+#define L_ne_sd
+#define L_lt_sd
+#define L_gt_sd
+#define L_le_sd
+#define L_ge_sd
+
+#define DFP_EXCEPTIONS_ENABLED 1
+#define DFP_HANDLE_EXCEPTIONS feraiseexcept
+
+EOF
+
+
diff --git a/libc/dfp/sysdeps/soft-dfp/muldd3.c b/libc/dfp/sysdeps/soft-dfp/muldd3.c
new file mode 100644
index 000000000..966c0eccf
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/muldd3.c
@@ -0,0 +1,27 @@
+/* _Decimal64 multiplication for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __muldd3
+#include <decimal64.h>
+
+#include "mulsd3.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/mulsd3.c b/libc/dfp/sysdeps/soft-dfp/mulsd3.c
new file mode 100644
index 000000000..2b7364a21
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/mulsd3.c
@@ -0,0 +1,68 @@
+/* _Decimal32 multiplication for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __mulsd3
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME mul
+
+#include <dfpmacro.h>
+DEC_TYPE
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE result;
+ decNumber dn_x, dn_y, dn_result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ ___decNumberMultiply(&dn_result, &dn_x, &dn_y, &context);
+
+ if (context.status != 0)
+ {
+ int ieee_flags = 0;
+ if (context.status & DEC_IEEE_854_Division_by_zero)
+ ieee_flags |= FE_DIVBYZERO;
+ if (context.status & DEC_IEEE_854_Inexact)
+ ieee_flags |= FE_INEXACT;
+ if (context.status & DEC_IEEE_854_Invalid_operation)
+ ieee_flags |= FE_INVALID;
+ if (context.status & DEC_IEEE_854_Overflow)
+ ieee_flags |= FE_OVERFLOW;
+ if (context.status & DEC_IEEE_854_Underflow)
+ ieee_flags |= FE_UNDERFLOW;
+ if (ieee_flags != 0)
+ feraiseexcept (ieee_flags);
+ }
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ return result;
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/multd3.c b/libc/dfp/sysdeps/soft-dfp/multd3.c
new file mode 100644
index 000000000..b2089ac13
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/multd3.c
@@ -0,0 +1,27 @@
+/* _Decimal128 multiplication for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __multd3
+#include <decimal128.h>
+
+#include "mulsd3.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/nedd2.c b/libc/dfp/sysdeps/soft-dfp/nedd2.c
new file mode 100644
index 000000000..18c8c24e1
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/nedd2.c
@@ -0,0 +1,27 @@
+/* _Decimal64 compare inequality for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __nedd2
+#include <decimal64.h>
+
+#include "nesd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/nesd2.c b/libc/dfp/sysdeps/soft-dfp/nesd2.c
new file mode 100644
index 000000000..765c9fe81
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/nesd2.c
@@ -0,0 +1,51 @@
+/* _Decimal32 compare inequality for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __nesd2
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME ne
+
+#include <dfpmacro.h>
+int
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x, dn_y, result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ if(___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y))
+ return 1;
+
+ ___decNumberCompare(&result, &dn_x, &dn_y, &context);
+ return !___decNumberIsZero(&result);
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/netd2.c b/libc/dfp/sysdeps/soft-dfp/netd2.c
new file mode 100644
index 000000000..ad1410df6
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/netd2.c
@@ -0,0 +1,27 @@
+/* _Decimal128 compare inequality for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __netd2
+#include <decimal128.h>
+
+#include "nesd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/subdd3.c b/libc/dfp/sysdeps/soft-dfp/subdd3.c
new file mode 100644
index 000000000..18b405c35
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/subdd3.c
@@ -0,0 +1,27 @@
+/* _Decimal64 subtraction for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __subdd3
+#include <decimal64.h>
+
+#include "subsd3.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/subsd3.c b/libc/dfp/sysdeps/soft-dfp/subsd3.c
new file mode 100644
index 000000000..d1634c7bb
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/subsd3.c
@@ -0,0 +1,68 @@
+/* _Decimal32 subtraction for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __subsd3
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME sub
+
+#include <dfpmacro.h>
+DEC_TYPE
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ DEC_TYPE result;
+ decNumber dn_x, dn_y, dn_result;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ ___decNumberSubtract(&dn_result, &dn_x, &dn_y, &context);
+
+ if (context.status != 0)
+ {
+ int ieee_flags = 0;
+ if (context.status & DEC_IEEE_854_Division_by_zero)
+ ieee_flags |= FE_DIVBYZERO;
+ if (context.status & DEC_IEEE_854_Inexact)
+ ieee_flags |= FE_INEXACT;
+ if (context.status & DEC_IEEE_854_Invalid_operation)
+ ieee_flags |= FE_INVALID;
+ if (context.status & DEC_IEEE_854_Overflow)
+ ieee_flags |= FE_OVERFLOW;
+ if (context.status & DEC_IEEE_854_Underflow)
+ ieee_flags |= FE_UNDERFLOW;
+ if (ieee_flags != 0)
+ feraiseexcept (ieee_flags);
+ }
+
+ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
+ return result;
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/subtd3.c b/libc/dfp/sysdeps/soft-dfp/subtd3.c
new file mode 100644
index 000000000..4e9cb2bce
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/subtd3.c
@@ -0,0 +1,27 @@
+/* _Decimal128 subtraction for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __subtd3
+#include <decimal128.h>
+
+#include "subsd3.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/trunc.c b/libc/dfp/sysdeps/soft-dfp/trunc.c
new file mode 100644
index 000000000..3326a08fb
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/trunc.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal128 to binary long double (dual 64bit)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 128
+#define DEST 128
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/trunc2.c b/libc/dfp/sysdeps/soft-dfp/trunc2.c
new file mode 100644
index 000000000..534c410ba
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/trunc2.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal128 to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_DECIMAL
+#define SRC 128
+#define DEST 64
+#define NAME trunc2
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/truncdddf.c b/libc/dfp/sysdeps/soft-dfp/truncdddf.c
new file mode 100644
index 000000000..849734878
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/truncdddf.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to binary double (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 64
+#define DEST 64
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/truncddsd2.c b/libc/dfp/sysdeps/soft-dfp/truncddsd2.c
new file mode 100644
index 000000000..0f140fe90
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/truncddsd2.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to Decimal32
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_DECIMAL
+#define SRC 64
+#define DEST 32
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/truncddsf.c b/libc/dfp/sysdeps/soft-dfp/truncddsf.c
new file mode 100644
index 000000000..92905f862
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/truncddsf.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal64 to binary float (32)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 64
+#define DEST 32
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/truncdfsd.c b/libc/dfp/sysdeps/soft-dfp/truncdfsd.c
new file mode 100644
index 000000000..f91c7eae6
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/truncdfsd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary double (64) to Decimal32
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 64
+#define DEST 32
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/truncsdsf.c b/libc/dfp/sysdeps/soft-dfp/truncsdsf.c
new file mode 100644
index 000000000..63b06075e
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/truncsdsf.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal32 to binary float (32)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 32
+#define DEST 32
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/trunctddd2.c b/libc/dfp/sysdeps/soft-dfp/trunctddd2.c
new file mode 100644
index 000000000..d51b6cd29
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/trunctddd2.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal128 to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_DECIMAL
+#define SRC 128
+#define DEST 64
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/trunctddf.c b/libc/dfp/sysdeps/soft-dfp/trunctddf.c
new file mode 100644
index 000000000..2586a37e2
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/trunctddf.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal128 to binary double (64)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 128
+#define DEST 64
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/trunctdsd2.c b/libc/dfp/sysdeps/soft-dfp/trunctdsd2.c
new file mode 100644
index 000000000..f42036317
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/trunctdsd2.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal128 to Decimal32
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_DECIMAL
+#define SRC 128
+#define DEST 32
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/trunctdsf.c b/libc/dfp/sysdeps/soft-dfp/trunctdsf.c
new file mode 100644
index 000000000..6a07eb436
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/trunctdsf.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal128 to binary float (32)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 128
+#define DEST 32
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/trunctdtf.c b/libc/dfp/sysdeps/soft-dfp/trunctdtf.c
new file mode 100644
index 000000000..3326a08fb
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/trunctdtf.c
@@ -0,0 +1,28 @@
+/* Handle conversion from Decimal128 to binary long double (dual 64bit)
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define DECIMAL_TO_BINARY
+#define SRC 128
+#define DEST 128
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/trunctfdd.c b/libc/dfp/sysdeps/soft-dfp/trunctfdd.c
new file mode 100644
index 000000000..e9247d79c
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/trunctfdd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary long double (128) to Decimal64
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 128
+#define DEST 64
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/trunctfsd.c b/libc/dfp/sysdeps/soft-dfp/trunctfsd.c
new file mode 100644
index 000000000..6569bfb52
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/trunctfsd.c
@@ -0,0 +1,28 @@
+/* Handle conversion from binary long double (128) to Decimal32
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define BINARY_TO_DECIMAL
+#define SRC 128
+#define DEST 32
+#define NAME trunc
+
+#include "convert.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/unorddd2.c b/libc/dfp/sysdeps/soft-dfp/unorddd2.c
new file mode 100644
index 000000000..c65e992ed
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/unorddd2.c
@@ -0,0 +1,27 @@
+/* _Decimal64 compare unordered for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 64
+#define ACTUAL_FUNCTION_NAME __unorddd2
+#include <decimal64.h>
+
+#include "unordsd2.c"
diff --git a/libc/dfp/sysdeps/soft-dfp/unordsd2.c b/libc/dfp/sysdeps/soft-dfp/unordsd2.c
new file mode 100644
index 000000000..2cfa416ae
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/unordsd2.c
@@ -0,0 +1,48 @@
+/* _Decimal32 compare unordered for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#ifndef _DECIMAL_SIZE
+# include <decimal32.h>
+# define _DECIMAL_SIZE 32
+# define ACTUAL_FUNCTION_NAME __unordsd2
+#endif
+
+#include <decContext.h>
+#include <decNumber.h>
+#include <math.h>
+
+#define FUNCTION_NAME unord
+
+#include <dfpmacro.h>
+int
+ACTUAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
+{
+ decNumber dn_x;
+ decNumber dn_y;
+ decContext context;
+ ___decContextDefault(&context, DEFAULT_CONTEXT);
+
+ FUNC_CONVERT_TO_DN(&x, &dn_x);
+ FUNC_CONVERT_TO_DN(&y, &dn_y);
+
+ return (___decNumberIsNaN(&dn_x) || ___decNumberIsNaN(&dn_y));
+}
diff --git a/libc/dfp/sysdeps/soft-dfp/unordtd2.c b/libc/dfp/sysdeps/soft-dfp/unordtd2.c
new file mode 100644
index 000000000..e94983ac8
--- /dev/null
+++ b/libc/dfp/sysdeps/soft-dfp/unordtd2.c
@@ -0,0 +1,27 @@
+/* _Decimal128 compare unordered for soft-dfp
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+#define _DECIMAL_SIZE 128
+#define ACTUAL_FUNCTION_NAME __unordtd2
+#include <decimal128.h>
+
+#include "unordsd2.c"
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/Implies b/libc/dfp/sysdeps/unix/sysv/linux/Implies
new file mode 100644
index 000000000..3f29a33f7
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/Implies
@@ -0,0 +1,11 @@
+dfp
+dfp/math
+dfp/math/bits
+dfp/stdio-common
+dfp/stdlib
+dfp/wcsmbs
+ieee754r
+ieee754r/d32
+ieee754r/d64
+ieee754r/d128
+soft-dfp
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/fpu/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/fpu/Implies
new file mode 100644
index 000000000..09766422b
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/fpu/Implies
@@ -0,0 +1,2 @@
+powerpc/fpu
+
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/nofpu/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/nofpu/Implies
new file mode 100644
index 000000000..331706ca2
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/nofpu/Implies
@@ -0,0 +1,2 @@
+powerpc/nofpu
+
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/Implies
new file mode 100644
index 000000000..fc9d20b1f
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/Implies
@@ -0,0 +1 @@
+powerpc/dfpu
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/fpu/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/fpu/Implies
new file mode 100644
index 000000000..9fb457db9
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6/fpu/Implies
@@ -0,0 +1,3 @@
+# Make sure this comes before the powerpc/powerpc32/fpu that's
+# listed in unix/sysv/linux/powerpc/powerpc32/fpu/Implies.
+powerpc/powerpc32/power6/fpu
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/Implies
new file mode 100644
index 000000000..fc9d20b1f
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/Implies
@@ -0,0 +1 @@
+powerpc/dfpu
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/fpu/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/fpu/Implies
new file mode 100644
index 000000000..ffca13c0e
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc32/power6x/fpu/Implies
@@ -0,0 +1,4 @@
+# Make sure this comes before the powerpc/powerpc32/fpu that's
+# listed in unix/sysv/linux/powerpc/powerpc32/fpu/Implies.
+powerpc/powerpc32/power6x/fpu
+powerpc/powerpc32/power6/fpu
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies
new file mode 100644
index 000000000..fc9d20b1f
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies
@@ -0,0 +1 @@
+powerpc/dfpu
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/fpu/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/fpu/Implies
new file mode 100644
index 000000000..945114726
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/fpu/Implies
@@ -0,0 +1,3 @@
+# Make sure this comes before the powerpc/powerpc64/fpu that's
+# listed in unix/sysv/linux/powerpc/powerpc64/fpu/Implies.
+powerpc/powerpc64/power6/fpu
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies
new file mode 100644
index 000000000..fc9d20b1f
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies
@@ -0,0 +1 @@
+powerpc/dfpu
diff --git a/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/fpu/Implies b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/fpu/Implies
new file mode 100644
index 000000000..fd74b8341
--- /dev/null
+++ b/libc/dfp/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/fpu/Implies
@@ -0,0 +1,4 @@
+# Make sure this comes before the powerpc/powerpc64/fpu that's
+# listed in unix/sysv/linux/powerpc/powerpc64/fpu/Implies.
+powerpc/powerpc64/power6x/fpu
+powerpc/powerpc64/power6/fpu
diff --git a/libc/dfp/test-d128.c b/libc/dfp/test-d128.c
new file mode 100644
index 000000000..ec092bb59
--- /dev/null
+++ b/libc/dfp/test-d128.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define FUNC(function) function##d128
+#define FLOAT _Decimal128
+#define TEST_MSG "testing _Decimal128 (without inline functions)\n"
+
+/* Always use the DL floating suffix. The dfp library will handle proper
+ * truncation and rounding. */
+/*#define MATHCONST(x) x##dl NOT USED */
+#define _F(x) x##DL
+#define _L(x) x##DL
+#define _LC(x) x##dl /* Long Double constant suffix is the same */
+#define _C(x) x##dl /* as the normal constant suffix for DFP */
+#define _N(x) x##_DL /* special long name terms for decimal float. e.g. minus_zero_DL */
+
+/* vim regex to search/replace instances of x.xL with _L(x.x):
+ * :%s/\(-\=\d*\)\.\(\d\+[eE]\=-\=\d*\)L/_L(\1\.\2)/gc
+ */
+
+/* Define the rounding mode and rounding mode functions. */
+#define SETROUND(x) fe_dec_setround(x)
+#define GETROUND(x) fe_dec_getround(x)
+
+#define TONEAREST FE_DEC_TONEAREST
+#define TOWARDZERO FE_DEC_TOWARDZERO
+#define TONEARESTFROMZERO FE_DEC_TONEARESTFROMZERO
+#define DOWNWARD FE_DEC_DOWNWARD
+#define UPWARD FE_DEC_UPWARD
+
+#define CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat,C_Decimal128,C_Decimal64,C_Decimal32) C_Decimal128
+#define PRINTF_EXPR "DDe"
+/*#define PRINTF_XEXPR "Ha" We don't have hex printing yet. */
+#define PRINTF_XEXPR "DDe"
+#define PRINTF_NEXPR "DDf"
+#define TEST_DECIMAL 1
+
+#ifndef __NO_MATH_INLINES
+# define __NO_MATH_INLINES
+#endif
+
+/* Various constants (we must supply them precalculated for accuracy). */
+# define M_PI_6dl .52359877559829887307710723054658383DL
+# define M_E2dl 7.389056098930650227230427460575008DL
+# define M_E3dl 20.085536923187667740928529654581719DL
+# define M_2_SQRT_PIdl 3.5449077018110320545963349666822903DL /* 2 sqrt (M_PIdl) */
+# define M_SQRT_PIdl 1.7724538509055160272981674833411451DL /* sqrt (M_PIdl) */
+# define M_LOG_SQRT_PIdl 0.57236494292470008707171367567652933DL /* log(sqrt(M_PIdl)) */
+# define M_LOG_2_SQRT_PIdl 1.265512123484645396488945797134706DL /* log(2*sqrt(M_PIdl)) */
+# define M_PI_34dl (M_PIdl - M_PI_4dl) /* 3*pi/4 */
+# define M_PI_34_LOG10Edl (M_PIdl - M_PI_4dl) * M_LOG10Edl
+# define M_PI2_LOG10Edl M_PI_2dl * M_LOG10Edl
+# define M_PI4_LOG10Edl M_PI_4dl * M_LOG10Edl
+# define M_PI_LOG10Edl M_PIdl * M_LOG10Edl
+# define M_SQRT_2_2dl 0.70710678118654752440084436210484903DL /* sqrt (2) / 2 */
+
+#include "libdfp-test.c"
diff --git a/libc/dfp/test-d32.c b/libc/dfp/test-d32.c
new file mode 100644
index 000000000..f6a845f59
--- /dev/null
+++ b/libc/dfp/test-d32.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define FUNC(function) function##d32
+#define FLOAT _Decimal32
+#define TEST_MSG "testing _Decimal32 (without inline functions)\n"
+
+/* Always use the DL floating suffix. The dfp library will handle proper
+ * truncation and rounding. */
+/*#define MATHCONST(x) x##dl NOT USED */
+#define _F(x) x##DL
+#define _L(x) x##DL
+#define _LC(x) x##dl /* Long Double constant suffix is the same */
+#define _C(x) x##dl /* as the normal constant suffix for DFP */
+#define _N(x) x##_DL /* special long name terms for decimal float. e.g. minus_zero_DL */
+
+/* vim regex to search/replace instances of x.xL with _L(x.x):
+ * :%s/\(-\=\d*\)\.\(\d\+[eE]\=-\=\d*\)L/_L(\1\.\2)/gc
+ */
+
+/* Define the rounding mode and rounding mode functions. */
+#define SETROUND(x) fe_dec_setround(x)
+#define GETROUND(x) fe_dec_getround(x)
+
+#define TONEAREST FE_DEC_TONEAREST
+#define TOWARDZERO FE_DEC_TOWARDZERO
+#define TONEARESTFROMZERO FE_DEC_TONEARESTFROMZERO
+#define DOWNWARD FE_DEC_DOWNWARD
+#define UPWARD FE_DEC_UPWARD
+
+#define CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat,C_Decimal128,C_Decimal64,C_Decimal32) C_Decimal32
+#define PRINTF_EXPR "He"
+/*#define PRINTF_XEXPR "Ha" We don't have hex printing yet. */
+#define PRINTF_XEXPR "He"
+#define PRINTF_NEXPR "Hf"
+#define TEST_DECIMAL 1
+
+#ifndef __NO_MATH_INLINES
+# define __NO_MATH_INLINES
+#endif
+
+/* Various constants (we must supply them precalculated for accuracy). */
+# define M_PI_6dl .52359877559829887307710723054658383DL
+# define M_E2dl 7.389056098930650227230427460575008DL
+# define M_E3dl 20.085536923187667740928529654581719DL
+# define M_2_SQRT_PIdl 3.5449077018110320545963349666822903DL /* 2 sqrt (M_PIdl) */
+# define M_SQRT_PIdl 1.7724538509055160272981674833411451DL /* sqrt (M_PIdl) */
+# define M_LOG_SQRT_PIdl 0.57236494292470008707171367567652933DL /* log(sqrt(M_PIdl)) */
+# define M_LOG_2_SQRT_PIdl 1.265512123484645396488945797134706DL /* log(2*sqrt(M_PIdl)) */
+# define M_PI_34dl (M_PIdl - M_PI_4dl) /* 3*pi/4 */
+# define M_PI_34_LOG10Edl (M_PIdl - M_PI_4dl) * M_LOG10Edl
+# define M_PI2_LOG10Edl M_PI_2dl * M_LOG10Edl
+# define M_PI4_LOG10Edl M_PI_4dl * M_LOG10Edl
+# define M_PI_LOG10Edl M_PIdl * M_LOG10Edl
+# define M_SQRT_2_2dl 0.70710678118654752440084436210484903DL /* sqrt (2) / 2 */
+
+#include "libdfp-test.c"
diff --git a/libc/dfp/test-d64.c b/libc/dfp/test-d64.c
new file mode 100644
index 000000000..15cc3c5c6
--- /dev/null
+++ b/libc/dfp/test-d64.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 2006,2007 IBM Corporation.
+ Author(s): Ryan S. Arnold <rsa@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+#define FUNC(function) function##d64
+#define FLOAT _Decimal64
+#define TEST_MSG "testing _Decimal64 (without inline functions)\n"
+
+/* Always use the DL floating suffix. The dfp library will handle proper
+ * truncation and rounding. */
+/*#define MATHCONST(x) x##dl NOT USED */
+#define _F(x) x##DL
+#define _L(x) x##DL
+#define _LC(x) x##dl /* Long Double constant suffix is the same */
+#define _C(x) x##dl /* as the normal constant suffix for DFP */
+#define _N(x) x##_DL /* special long name terms for decimal float. e.g. minus_zero_DL */
+
+/* vim regex to search/replace instances of x.xL with _L(x.x):
+ * :%s/\(-\=\d*\)\.\(\d\+[eE]\=-\=\d*\)L/_L(\1\.\2)/gc
+ */
+
+/* Define the rounding mode and rounding mode functions. */
+#define SETROUND(x) fe_dec_setround(x)
+#define GETROUND(x) fe_dec_getround(x)
+
+#define TONEAREST FE_DEC_TONEAREST
+#define TOWARDZERO FE_DEC_TOWARDZERO
+#define TONEARESTFROMZERO FE_DEC_TONEARESTFROMZERO
+#define DOWNWARD FE_DEC_DOWNWARD
+#define UPWARD FE_DEC_UPWARD
+
+#define CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat,C_Decimal128,C_Decimal64,C_Decimal32) C_Decimal64
+#define PRINTF_EXPR "De"
+/*#define PRINTF_XEXPR "Ha" We don't have hex printing yet. */
+#define PRINTF_XEXPR "De"
+#define PRINTF_NEXPR "Df"
+#define TEST_DECIMAL 1
+
+#ifndef __NO_MATH_INLINES
+# define __NO_MATH_INLINES
+#endif
+
+/* Various constants (we must supply them precalculated for accuracy). */
+# define M_PI_6dl .52359877559829887307710723054658383DL
+# define M_E2dl 7.389056098930650227230427460575008DL
+# define M_E3dl 20.085536923187667740928529654581719DL
+# define M_2_SQRT_PIdl 3.5449077018110320545963349666822903DL /* 2 sqrt (M_PIdl) */
+# define M_SQRT_PIdl 1.7724538509055160272981674833411451DL /* sqrt (M_PIdl) */
+# define M_LOG_SQRT_PIdl 0.57236494292470008707171367567652933DL /* log(sqrt(M_PIdl)) */
+# define M_LOG_2_SQRT_PIdl 1.265512123484645396488945797134706DL /* log(2*sqrt(M_PIdl)) */
+# define M_PI_34dl (M_PIdl - M_PI_4dl) /* 3*pi/4 */
+# define M_PI_34_LOG10Edl (M_PIdl - M_PI_4dl) * M_LOG10Edl
+# define M_PI2_LOG10Edl M_PI_2dl * M_LOG10Edl
+# define M_PI4_LOG10Edl M_PI_4dl * M_LOG10Edl
+# define M_PI_LOG10Edl M_PIdl * M_LOG10Edl
+# define M_SQRT_2_2dl 0.70710678118654752440084436210484903DL /* sqrt (2) / 2 */
+
+#include "libdfp-test.c"
diff --git a/libc/dfp/test/CLEANME b/libc/dfp/test/CLEANME
new file mode 100644
index 000000000..45b3279be
--- /dev/null
+++ b/libc/dfp/test/CLEANME
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+for i in $( ls *.c);
+ do
+ if [ "$i" == "test-decimal.c" ]; then
+ continue;
+ fi
+ echo "rm `basename $i .c`"
+ echo "rm `basename $i .c`_64"
+ rm `basename $i .c`
+ rm "`basename $i .c`_64"
+ done
diff --git a/libc/dfp/test/README b/libc/dfp/test/README
new file mode 100644
index 000000000..3c2db0ece
--- /dev/null
+++ b/libc/dfp/test/README
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+if test -z "$1"; then
+ cc="/opt/at05/bin/gcc"
+ export PATH=/opt/at05/bin:$PATH
+else
+ cc=$1/gcc
+ export PATH=$1:$PATH
+fi
+
+#for i in $( ls *.c); do ${cc} -ldfp $i -o `basename $i .c`; done
+for i in $( ls *.c);
+ do
+ if [ "$i" == "test-decimal.c" ]; then
+ continue;
+ fi
+ echo "${cc} -ldfp -ldecnumber -std=gnu99 $i -o `basename $i .c`"
+ ${cc} -ldfp -ldecnumber -std=gnu99 $i -o `basename $i .c`;
+
+ echo "${cc} -m64 -ldfp -ldecnumber -std=gnu99 $i -o `basename $i .c`_64"
+ ${cc} -ldfp -m64 -ldecnumber -std=gnu99 $i -o `basename $i .c`_64;
+ done
diff --git a/libc/dfp/test/convert.c b/libc/dfp/test/convert.c
new file mode 100644
index 000000000..b3dd992ab
--- /dev/null
+++ b/libc/dfp/test/convert.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+
+typedef union {
+ _Decimal64 d;
+ long l[2];
+ } convert;
+
+int main() {
+
+
+ convert c;
+ convert d;
+ convert e;
+ convert f;
+// c.l[0] = 573833216L;
+// c.l[1] = 5120;
+
+ c.l[0] = 0x22340000;
+ c.l[1] = 0x00000050;
+
+
+ d.l[0] = 0x223c0000;
+ d.l[1] = 0x00000050;
+
+ e.l[0] = 0x22340000;
+ e.l[1] = 0x00001400;
+
+ f.l[0] = 0x223c0000;
+ f.l[1] = 0x00000051;
+
+ printf("0x%.8x%.8x = %De\n",c.l[0], c.l[1], c.d);
+ printf("0x%.8x%.8x = %De\n",d.l[0], d.l[1], d.d);
+ printf("0x%.8x%.8x = %De\n",e.l[0], e.l[1], e.d);
+ printf("0x%.8x%.8x = %De\n",f.l[0], f.l[1], f.d);
+
+ return 0;
+}
diff --git a/libc/dfp/test/test-decimal.c b/libc/dfp/test/test-decimal.c
new file mode 100644
index 000000000..3079d9d0c
--- /dev/null
+++ b/libc/dfp/test/test-decimal.c
@@ -0,0 +1,362 @@
+/* Test conversion from binary X to decimal X (note that many failures are
+ * expected, and have to be reviewed on a case-by-case basis)
+ Copyright (C) 2006 IBM Corporation.
+
+ Author(s): Joe Kerian jkerian@us.ibm.com
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+/* This mess of a test file created by Joseph Kerian 2006-12-13 */
+/* -std=gnu99 */
+//#define __STDC_WANT_DEC_FP__ 1
+// At the moment... these tests can be compiled by moving or linking this file
+// from the dfp/sysdeps/powerpc directory, and compiling it and all files in
+// that directory with something like the following
+// gcc -ldfp -std=gnu99 -D__STDC_WANT_DEC_FP__ *.c -o tests
+
+//You can test individual areas by commenting in or out the following #defines
+//Known errors:
+// _Decimal64 -> double: due to truncation of D64 input... cases near DBL_MAX
+// seem to fail.
+#define TEST_FROM_DECIMAL128
+#define TEST_FROM_DECIMAL64
+#define TEST_FROM_DECIMAL32
+#define TEST_FROM_FLOAT
+#define TEST_FROM_DOUBLE
+#define TEST_FROM_LONG_DOUBLE
+
+#define TEST_TO_DECIMAL128
+#define TEST_TO_DECIMAL64
+#define TEST_TO_DECIMAL32
+#define TEST_TO_FLOAT
+#define TEST_TO_DOUBLE
+#define TEST_TO_LONG_DOUBLE
+
+
+#include <stdio.h>
+#include <errno.h>
+#include <float.h>
+#include <math.h>
+
+#define PASTE(i,j) PASTE2(i,j)
+#define PASTE2(i,j) i##j
+#define STRINGIT(k) STRINGIT2(k)
+#define STRINGIT2(k) #k
+
+#define TEST(x) \
+do {\
+ if(PASTE(x,SRC_SUFFIX) <= SRC_MAXSRC) { \
+ sample = PASTE(x,DST_SUFFIX); \
+ s = PASTE(x,SRC_SUFFIX); \
+ d = FUNCTION (s); \
+ printf (STRINGIT(DST_TYPE) "("STRINGIT(DST_PRINTF)")%s <- " \
+ STRINGIT(SRC_TYPE)"("STRINGIT(SRC_PRINTF)") \n",d, \
+ ( PASTE(x,SRC_SUFFIX) > DST_MAXSRC )?"Overflow OK":" ",s); \
+ if(d != sample) { \
+ printf(STRINGIT(DST_TYPE)"("STRINGIT(DST_PRINTF)") Error: " \
+ STRINGIT(DST_PRINTF)"("STRINGIT(DST_PRINTF)")\n", \
+ sample, d-sample, NEXT_AFTER(d, sample)); \
+ printf("---------\n");\
+ }\
+ } else \
+ printf ("Skipping: "#x" is too big for "STRINGIT(SRC_TYPE)"\n"); \
+}while (0);
+#define storage \
+
+#define ALL_TESTS() do { \
+ SRC_TYPE s; \
+ DST_TYPE d; \
+ DST_TYPE sample; \
+ \
+ TEST(0.000000000000000000000000125); \
+ TEST(0.125); \
+ TEST(8388609.0); \
+ TEST(16777215.0); \
+ TEST(4503599627370496.0); \
+ TEST(4503599627370497.0); \
+ TEST(9223372036854775808.0); \
+ TEST(3.40282347e+38); \
+ TEST(3.40282348e+38); \
+ TEST(3.333333333333333333333333333333333333); \
+ TEST(-3.333333333333333333333333333333333333); \
+ TEST(256.0); \
+ TEST(9007199254740991.0); \
+ TEST(3.14159265358979323846264338327950288419716939937510); \
+ TEST(18446744073709551616.0); \
+ TEST(3.40282349e+38); \
+ TEST(1.7976931348623154e+308); \
+ TEST(1.7976931348623156e+308); \
+ TEST(1.7976931348623157e+308); /* DBL_MAX */ \
+ TEST(1.7976931348623158e+308); /* LDBL_MAX */ \
+ TEST(1.7976931348623159e+308); \
+}while (0)
+
+extern _Decimal32 __extendsfsd(float);
+extern _Decimal64 __extendsfdd(float);
+extern _Decimal128 __extendsftd(float);
+
+extern _Decimal32 __truncdfsd(double);
+extern _Decimal64 __extenddfdd(double);
+extern _Decimal128 __extenddftd (double);
+
+extern _Decimal32 __truncxfsd(long double);
+extern _Decimal64 __truncxfdd(long double);
+extern _Decimal128 __extendxftd (long double);
+
+extern float __extendsdsf(_Decimal32);
+extern float __truncddsf(_Decimal64);
+extern float __trunctdsf(_Decimal128);
+
+extern double __extendsddf(_Decimal32);
+extern double __truncdddf(_Decimal64);
+extern double __trunctddf(_Decimal128);
+
+extern long double __extendsdxf(_Decimal32);
+extern long double __extendddxf(_Decimal64);
+extern long double __trunctdxf(_Decimal128);
+
+int main (int argc, char *argv[])
+{
+#ifdef TEST_FROM_DECIMAL128
+/* FIRST: Test from _Decimal128 */
+#define SRC_TYPE _Decimal128
+#define SRC_PRINTF %.36DDe
+#define SRC_SUFFIX DL
+#define SRC_MAXSRC 9.999999999999999999999999999999999E+6144DL
+//To float
+#ifdef TEST_TO_FLOAT
+#define FUNCTION __trunctdsf
+#define DST_TYPE float
+#define DST_PRINTF %.20e
+#define DST_MAXSRC 3.402823466385288598117041834845169e+38DL
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterf
+ALL_TESTS();
+#endif
+//To double
+#ifdef TEST_TO_DOUBLE
+#define FUNCTION __trunctddf
+#define DST_TYPE double
+#define DST_PRINTF %.20e
+#define DST_MAXSRC 1.797693134862315708145274237317044e+308DL
+#define DST_SUFFIX
+#define NEXT_AFTER nextafter
+ALL_TESTS();
+#endif
+//To long double
+#ifdef TEST_TO_LONG_DOUBLE
+#define FUNCTION __trunctdxf
+#define DST_TYPE long double
+#define DST_PRINTF %.20Le
+#define DST_MAXSRC 1.797693134862315807937289714053012e+308DL
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterl
+ALL_TESTS();
+#endif
+#endif
+
+/* Second: Test from _Decimal64 */
+#ifdef TEST_FROM_DECIMAL64
+#define SRC_TYPE _Decimal64
+#define SRC_PRINTF %.21Df
+#define SRC_SUFFIX DD
+#define SRC_MAXSRC 9.9999999999999999E+384DD
+//To float
+#ifdef TEST_TO_FLOAT
+#define FUNCTION __truncddsf
+#define DST_TYPE float
+#define DST_PRINTF %.20e
+#define DST_MAXSRC 3.4028234663852886e+38DD
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterf
+ALL_TESTS();
+#endif
+//To double
+#ifdef TEST_TO_DOUBLE
+#define FUNCTION __truncdddf
+#define DST_TYPE double
+#define DST_PRINTF %.20e
+#define DST_MAXSRC 1.7976931348623157e+308DD
+#define DST_SUFFIX
+#define NEXT_AFTER nextafter
+ALL_TESTS();
+#endif
+//To long double
+#ifdef TEST_TO_LONG_DOUBLE
+#define FUNCTION __extendddxf
+#define DST_TYPE long double
+#define DST_PRINTF %.20Le
+#define DST_MAXSRC 1.7976931348623158e+308DD
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterl
+ALL_TESTS();
+#endif
+#endif
+/* Third: Test from _Decimal32 */
+#ifdef TEST_FROM_DECIMAL32
+#define SRC_TYPE _Decimal32
+#define SRC_PRINTF %.21Hf
+#define SRC_SUFFIX DD
+#define SRC_MAXSRC 9.9999999999999999E+384DF
+//To float
+#ifdef TEST_TO_FLOAT
+#define FUNCTION __extendsdsf
+#define DST_TYPE float
+#define DST_PRINTF %.20e
+#define DST_MAXSRC 3.4028234663852886e+38DF
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterf
+ALL_TESTS();
+#endif
+//To double
+#ifdef TEST_TO_DOUBLE
+#define FUNCTION __extendsddf
+#define DST_TYPE double
+#define DST_PRINTF %.20e
+#define DST_MAXSRC 1.7976931348623157e+308DF
+#define DST_SUFFIX
+#define NEXT_AFTER nextafter
+ALL_TESTS();
+#endif
+//To long double
+#ifdef TEST_TO_LONG_DOUBLE
+#define FUNCTION __extendsdxf
+#define DST_TYPE long double
+#define DST_PRINTF %.20Le
+#define DST_MAXSRC 1.7976931348623158e+308DF
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterl
+ALL_TESTS();
+#endif
+#endif
+
+#ifdef TEST_FROM_LONG_DOUBLE
+/* FOURTH: Test from long double */
+#define SRC_TYPE long double
+#define SRC_PRINTF %.36Le
+#define SRC_SUFFIX
+#define SRC_MAXSRC LDBL_MAX
+//To _Decimal32
+#ifdef TEST_TO_DECIMAL32
+#define FUNCTION __truncxfsd
+#define DST_TYPE _Decimal32
+#define DST_PRINTF %.9Hf
+#define DST_MAXSRC 9.999999e+96
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterd32
+ALL_TESTS();
+#endif
+//To _Decimal64
+#ifdef TEST_TO_DECIMAL64
+#define FUNCTION __truncxfdd
+#define DST_TYPE _Decimal64
+#define DST_PRINTF %.17Df
+#define DST_MAXSRC 9.999999999999999e+384
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterd64
+ALL_TESTS();
+#endif
+//To _Decimal128
+#ifdef TEST_TO_DECIMAL128
+#define FUNCTION __extendxftd
+#define DST_TYPE _Decimal128
+#define DST_PRINTF %.34DDf
+#define DST_MAXSRC 9.999999999999999999999999999999999e+6144
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterd128
+ALL_TESTS();
+#endif
+#endif
+
+#ifdef TEST_FROM_DOUBLE
+/* FIFTH: Test from double */
+#define SRC_TYPE double
+#define SRC_PRINTF %.36e
+#define SRC_SUFFIX
+#define SRC_MAXSRC DBL_MAX
+//To _Decimal32
+#ifdef TEST_TO_DECIMAL32
+#define FUNCTION __truncdfsd
+#define DST_TYPE _Decimal32
+#define DST_PRINTF %.9Hf
+#define DST_MAXSRC 9.999999e+96
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterd32
+ALL_TESTS();
+#endif
+//To _Decimal64
+#ifdef TEST_TO_DECIMAL64
+#define FUNCTION __extenddfdd
+#define DST_TYPE _Decimal64
+#define DST_PRINTF %.17Df
+#define DST_MAXSRC 9.999999999999999e+384
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterd64
+ALL_TESTS();
+#endif
+//To _Decimal128
+#ifdef TEST_TO_DECIMAL128
+#define FUNCTION __extenddftd
+#define DST_TYPE _Decimal128
+#define DST_PRINTF %.34DDf
+#define DST_MAXSRC 9.999999999999999999999999999999999e+6144
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterd128
+ALL_TESTS();
+#endif
+#endif
+
+#ifdef TEST_FROM_FLOAT
+/* SIXTH: Test from float */
+#define SRC_TYPE float
+#define SRC_PRINTF %.36e
+#define SRC_SUFFIX
+#define SRC_MAXSRC FLT_MAX
+//To _Decimal32
+#ifdef TEST_TO_DECIMAL32
+#define FUNCTION __extendsfsd
+#define DST_TYPE _Decimal32
+#define DST_PRINTF %.9Hf
+#define DST_MAXSRC 9.999999e+96
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterd32
+ALL_TESTS();
+#endif
+//To _Decimal64
+#ifdef TEST_TO_DECIMAL64
+#define FUNCTION __extendsfdd
+#define DST_TYPE _Decimal64
+#define DST_PRINTF %.17Df
+#define DST_MAXSRC 9.999999999999999e+384
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterd64
+ALL_TESTS();
+#endif
+//To _Decimal128
+#ifdef TEST_TO_DECIMAL128
+#define FUNCTION __extendsftd
+#define DST_TYPE _Decimal128
+#define DST_PRINTF %.34DDf
+#define DST_MAXSRC 9.999999999999999999999999999999999e+6144
+#define DST_SUFFIX
+#define NEXT_AFTER nextafterd128
+ALL_TESTS();
+#endif
+#endif
+//printf("\nFLT_MAX: %.32a\nDBL_MAX: %.32a\nLDBL_MAX:%.32La\n",FLT_MAX,DBL_MAX,LDBL_MAX);
+ return 0;
+}
diff --git a/libc/dfp/test/test_acos.c b/libc/dfp/test/test_acos.c
new file mode 100644
index 000000000..9beceb7fb
--- /dev/null
+++ b/libc/dfp/test/test_acos.c
@@ -0,0 +1,12 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+
+int main() {
+ TEST_f_f_all(acos, 0.722734247813415611178377352641333362, 0.75);
+}
+
diff --git a/libc/dfp/test/test_arctrig.c b/libc/dfp/test/test_arctrig.c
new file mode 100644
index 000000000..1ceeca461
--- /dev/null
+++ b/libc/dfp/test/test_arctrig.c
@@ -0,0 +1,48 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+#include <float.h>
+#include "test_math.h"
+
+//Functions that need testing:
+//_Decimal acos (_Decimal)
+//_Decimal asin (_Decimal)
+//the various fe_set/get functions also need testing, but seperately
+
+int main() {
+//_Decimal asin (_Decimal)
+ TEST_f_1_all(acos, DEC_NAN, DEC_INFINITY);
+ TEST_f_1_all(acos, DEC_NAN, -DEC_INFINITY);
+ TEST_f_1_all(acos, DEC_NAN, DEC_NAN);
+ TEST_f_1_all(acos, DEC_NAN, 1.125);
+ TEST_f_1_all(acos, DEC_NAN, -1.125);
+// TEST_f_f_all(acos, M_PI_2, 0.0);
+// TEST_f_f_all(acos, M_PI_2, -0.0);
+ TEST_f_f_all(acos, 0.0, 1.0);
+// TEST_f_f_all(acos, M_PI, -1.0);
+// TEST_f_f_all(acos, M_PI/3.0, 0.5);
+ TEST_f_f_all(acos, 0.722734247813415611178377352641333362, 0.75);
+ TEST_f_f_all(acos, 1.57079632679489659923132169163975144, 2E-17);
+ TEST_f_f_all(acos, 1.50825556499840522843072005474337068, 0.0625);
+
+//_Decimal asin (_Decimal)
+ TEST_f_1_all(asin, DEC_NAN, DEC_INFINITY);
+ TEST_f_1_all(asin, DEC_NAN, -DEC_INFINITY);
+ TEST_f_1_all(asin, DEC_NAN, DEC_NAN);
+ TEST_f_1_all(asin, DEC_NAN, 1.125);
+ TEST_f_1_all(asin, DEC_NAN, -1.125);
+ TEST_f_f_all(asin, 0.0, 0.0);
+ TEST_f_f_all(asin, -0.0, -0.0);
+// TEST_f_f_all(asin, M_PI_6, 0.5);
+// TEST_f_f_all(asin, -M_PI_6, -0.5);
+ TEST_f_f_all(asin, M_PI_2, 1.0);
+// TEST_f_f_all(asin, -M_PI_2, -1.0);
+ TEST_f_f_all(asin, 0.848062078981481008052944338998418080, 0.75);
+
+ if(isnan((_Decimal32)DEC_NAN)) printf("1 ");
+ else printf("0 ");
+ if(isnand32(DEC_NAN)) printf("1\n");
+ else printf("0\n");
+}
diff --git a/libc/dfp/test/test_assign.c b/libc/dfp/test/test_assign.c
new file mode 100644
index 000000000..57265087e
--- /dev/null
+++ b/libc/dfp/test/test_assign.c
@@ -0,0 +1,42 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+#include <stdint.h>
+#include <fenv.h>
+#include <stdio.h>
+
+#define PRINT_ARRAY(size,array) \
+for(i=0; i<size; i++) \
+ printf("%x ",array[i]);\
+printf("\n");
+
+int main() {
+ int i;
+ union {
+ _Decimal32 dec;
+ uint8_t bytes[4];
+ } d32;
+ union {
+ _Decimal64 dec;
+ uint8_t bytes[8];
+ } d64;
+ union {
+ _Decimal128 dec;
+ uint8_t bytes[16];
+ } d128;
+
+ d32.dec = 0.0DF;
+ d64.dec = 0.0DD;
+ d128.dec= 0.0DL;
+ PRINT_ARRAY(4,d32.bytes);
+ PRINT_ARRAY(8,d64.bytes);
+ PRINT_ARRAY(16,d128.bytes);
+ d32.dec = 0.000000DF;
+ d64.dec = 0.000000DD;
+ d128.dec= 0.000000DL;
+ PRINT_ARRAY(4,d32.bytes);
+ PRINT_ARRAY(8,d64.bytes);
+ PRINT_ARRAY(16,d128.bytes);
+}
+
diff --git a/libc/dfp/test/test_cbrt.c b/libc/dfp/test/test_cbrt.c
new file mode 100644
index 000000000..630590a0a
--- /dev/null
+++ b/libc/dfp/test/test_cbrt.c
@@ -0,0 +1,25 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "fenv.h"
+#include "test_math.h"
+
+int main() {
+ _Decimal128 d128,e128;
+
+ fe_dec_setround(FE_DEC_TOWARDZERO);
+ fesetround(FE_TOWARDZERO);
+ //TEST_f_1_all (cbrt, 0.997389022060725270579075195353955217, 0.9921875);
+ TEST_f_1_all (cbrt, 0.908560296416069829445605878163630251, 0.75);
+ //if(0.9085602964160698294456058781636302DL != 0.908560296416069829445605878163630251DL)
+ // printf("fail d128\n");
+
+ d128 = cbrtd128(0.75DL);
+ e128 = 0.908560296416069829445605878163630251DL;
+ printf("%DDf = cbrt(0.75DL)\n", d128);
+ printf("%DDf = 0.908560296416069829445605878163630251DL\n", e128);
+}
+
diff --git a/libc/dfp/test/test_ceil.c b/libc/dfp/test/test_ceil.c
new file mode 100644
index 000000000..1c483199d
--- /dev/null
+++ b/libc/dfp/test/test_ceil.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdint.h>
+#define __STDC_WANT_DEC_FP__ 1
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION ceil
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 d32;
+ _Decimal32 cd32;
+ _Decimal64 d64;
+ _Decimal64 cd64;
+ _Decimal128 d128;
+ _Decimal128 cd128;
+
+ d32 = -19.54DF;
+ cd32 = 0.0DF;
+
+ d64 = -19.54DD;
+ cd64 = 0.0DD;
+
+ d128 = -19.54DL;
+ cd128 = 0.0DL;
+
+ cd32 = FUNCTION_CALL(d32)(d32);
+ printf("%Hf = ceild32(%Hf)\n", cd32, d32);
+ d32 = 19.54DF;
+ cd32 = FUNCTION_CALL(d32)(d32);
+ printf("%Hf = ceild32(%Hf)\n", cd32, d32);
+
+ cd64 = FUNCTION_CALL(d64)(d64);
+ printf("%Df = ceild64(%Df)\n", cd64, d64);
+ d64 = 19.54DD;
+ cd64 = FUNCTION_CALL(d64)(d64);
+ printf("%Df = ceild64(%Df)\n", cd64, d64);
+
+ cd128 = FUNCTION_CALL(d128)(d128);
+ printf("%DDf = ceild128(%DDf)\n", cd128, d128);
+ d128 = 19.54DL;
+ cd128 = FUNCTION_CALL(d128)(d128);
+ printf("%DDf = ceild128(%DDf)\n", cd128, d128);
+}
diff --git a/libc/dfp/test/test_const.c b/libc/dfp/test/test_const.c
new file mode 100644
index 000000000..2d9836c7a
--- /dev/null
+++ b/libc/dfp/test/test_const.c
@@ -0,0 +1,45 @@
+/*#define __STDC_WANT_DEC_FP__ */
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+
+int main() {
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+
+ d32 = 2.7182818284590452353602874713526625DL;
+ printf ("M_EDF = %Hf\n", d32);
+
+ d64 = 2.7182818284590452353602874713526625DL;
+ printf ("M_EDF = %Df\n", d64);
+
+ d128 = 2.7182818284590452353602874713526625DL;
+ printf ("M_EDF = %DDf\n", d128);
+
+ d128 = 2.718281828459045235360287471352662DL;
+ printf ("M_EDF = %DDf\n", d128);
+
+ d128 = 2.7182818284590452353602874713526626DL;
+ printf ("M_EDF = %DDf\n", d128);
+
+ d32 = 0.0DL;
+
+ if (d32 == 0.0DL)
+ printf ("(d32 = 0.0DL) == 0.0DL\n");
+ else
+ printf ("Not\n");
+
+ d32 = 0.0;
+
+ printf ("(d32 = 0.0) == %Hf\n",d32);
+
+ d32 = 0.0DL;
+
+ printf ("d32 == %Hf\n",d32);
+
+ d32 = 1.0DL;
+
+ printf ("d32 == %Hf\n",d32);
+ return 0;
+}
diff --git a/libc/dfp/test/test_conversion.c b/libc/dfp/test/test_conversion.c
new file mode 100644
index 000000000..bc643cf7c
--- /dev/null
+++ b/libc/dfp/test/test_conversion.c
@@ -0,0 +1,70 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+
+extern char * decoded32 (_Decimal32, char*);
+extern char * decoded64 (_Decimal64, char*);
+extern char * decoded128 (_Decimal128, char*);
+
+static float f = 2.f;
+int main() {
+
+ _Decimal32 d32;
+ _Decimal64 d64;
+ float f32;
+ long double ld128;
+ _Complex long double cld;
+ double f64 = 0.0625;
+ char s32[32];
+ char s64[64];
+ char s128[128];
+ _Decimal128 c128;
+ _Decimal64 c64;
+ _Decimal32 c32;
+
+
+ cld = 2.0l * __extension__ 1i + 0.0625l;
+
+ f64 = cld;
+ c32 = f64;
+ printf("[%s]d32 = f64[%lf] = (double)cld\n", decoded32(c32,s32),f64);
+
+ printf("%Hf\n", c32);
+ printf("%s\n", decoded32(c32,s32));
+
+ f32 = cld;
+ d32 = f32;
+ printf("[%s]d32 = f32[%f] = (float)cld\n", decoded32(d32,s32),f32);
+
+ c128 = cld;
+ c32 = c128;
+ printf("[%s]d32 = d128[%DDf] = (_Decimal128)cld\n", decoded32(c32,s32), c128);
+
+ c64 = cld;
+ c32 = c64;
+ printf("[%s]d32 = d64[%Df] = (_Decimal64)cld\n", decoded32(c32,s32), c64);
+
+ d32 = cld;
+ printf("[%s]d32 = (_Decimal32)cld\n", decoded32(d32,s32));
+ ld128 = cld;
+ d32 = ld128;
+ printf("[%s]d32 = f128[%llf] = (long double)cld\n", decoded32(d32,s32),ld128);
+
+ d32 = f64;
+ printf("[%s]d32 = f64[%lf]\n", decoded32(d32,s32),f64);
+
+ d64 = cld;
+ printf("[%s]d64 = f128[%llf] = (long double)cld\n", decoded64(d64,s64), ld128);
+
+// DISP_HEXD32(d32,0.0625DF);
+// DISP_HEXD64(d64,0.0625DD);
+// DISP_HEXD128(d128,0.0625DL);
+
+// DISP_HEXD32(d32,(_Decimal32)cld);
+// DISP_HEXD64(d64,(_Decimal64)cld);
+ return -1;
+}
diff --git a/libc/dfp/test/test_convert.h b/libc/dfp/test/test_convert.h
new file mode 100644
index 000000000..c78a2017c
--- /dev/null
+++ b/libc/dfp/test/test_convert.h
@@ -0,0 +1,284 @@
+/* Handle conversion from binary integers, floats and decimal types
+ Copyright (C) 2007 IBM Corporation.
+
+ Author(s): Pete Eberlein <eberlein@us.ibm.com>
+
+ The Decimal Floating Point C Library is free software; you can
+ redistribute it and/or modify it under the terms of the GNU Lesser
+ General Public License version 2.1.
+
+ The Decimal Floating Point C Library 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 Lesser General Public License version 2.1 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License version 2.1 along with the Decimal Floating Point C Library;
+ if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA.
+
+ Please see dfp/COPYING.txt for more information. */
+
+
+/* decimal source */
+#if defined DECIMAL_TO_INTEGER || defined DECIMAL_TO_BINARY || defined DECIMAL_TO_DECIMAL
+
+#if SRC==32
+#define SRC_TYPE _Decimal32
+#define IEEE_SRC_TYPE decimal32
+#define SRC_LITERAL(n) n##DF
+#define SRC_KIND sd
+#define SIGNBIT __builtin_signbitd32
+#define CLASSIFY __fpclassifyd32
+#endif
+
+#if SRC==64
+#define SRC_TYPE _Decimal64
+#define IEEE_SRC_TYPE decimal64
+#define SRC_LITERAL(n) n##DD
+#define SRC_KIND dd
+#define SIGNBIT __builtin_signbitd64
+#define CLASSIFY __fpclassifyd64
+#endif
+
+#if SRC==128
+#define SRC_TYPE _Decimal128
+#define IEEE_SRC_TYPE decimal128
+#define SRC_LITERAL(n) n##DL
+#define SRC_KIND td
+#define SIGNBIT __builtin_signbitd128
+#define CLASSIFY __fpclassifyd128
+#endif
+
+#define DECIMAL_SIZE SRC
+
+#endif //DECIMAL_TO_INTEGER || DECIMAL_TO_BINARY || DECIMAL_TO_DECIMAL
+
+
+/* float source */
+#if defined BINARY_TO_DECIMAL
+
+#if SRC==32
+#define SRC_TYPE float
+#define SRC_LITERAL(n) n##f
+#define SRC_KIND sf
+#define SIGNBIT __builtin_signbitf
+#define CLASSIFY __dfp_classify_sf
+#endif
+
+#if SRC==64
+#define SRC_TYPE double
+#define SRC_LITERAL(n) n##d
+#define SRC_KIND df
+#define SIGNBIT __builtin_signbit
+#define CLASSIFY __dfp_classify_df
+#endif
+
+#if SRC==128
+#define SRC_TYPE long double
+#define SRC_LITERAL(n) n##l
+#define SRC_KIND tf
+#define SIGNBIT __builtin_signbitl
+/* For IBM 128-bit long double we use the double version. */
+#define CLASSIFY __dfp_classify_df
+#endif
+
+#endif // BINARY_TO_DECIMAL
+
+
+/* integer source */
+#if defined INTEGER_TO_DECIMAL
+
+#if SRC==32
+#if defined UNSIGNED
+#define SRC_TYPE unsigned int
+#define INT_FMT "%u"
+#define CAST_FOR_FMT(A) (unsigned int)A
+#else
+#define SRC_TYPE int
+#define INT_FMT "%d"
+#define CAST_FOR_FMT(A) (int)A
+#endif
+#define SRC_LITERAL(n) n
+#define SRC_KIND si
+#endif
+
+#if SRC==64
+#if defined UNSIGNED
+#define SRC_TYPE unsigned long long
+#define INT_FMT "%llu"
+#define CAST_FOR_FMT(A) (unsigned long long)A
+#else
+#define SRC_TYPE long long
+#define INT_FMT "%lld"
+#define CAST_FOR_FMT(A) (long long)A
+#endif
+#define SRC_LITERAL(n) n
+#define SRC_KIND di
+#endif
+
+#endif // INTEGER_TO_DECIMAL
+
+
+
+/* decimal dest */
+#if defined DECIMAL_TO_DECIMAL || defined INTEGER_TO_DECIMAL || defined BINARY_TO_DECIMAL
+
+#if DEST==32
+#define DEST_TYPE _Decimal32
+#define IEEE_DEST_TYPE decimal32
+#define DEST_LITERAL(n) n##DF
+#define DEST_KIND sd
+#endif
+
+#if DEST==64
+#define DEST_TYPE _Decimal64
+#define IEEE_DEST_TYPE decimal64
+#define DEST_LITERAL(n) n##DD
+#define DEST_KIND dd
+#endif
+
+#if DEST==128
+#define DEST_TYPE _Decimal128
+#define IEEE_DEST_TYPE decimal128
+#define DEST_LITERAL(n) n##DL
+#define DEST_KIND td
+#endif
+
+#define DEST_INFINITY DEC_INFINITY
+#define DEST_NAN DEC_NAN
+
+#if defined DECIMAL_SIZE
+#if DECIMAL_SIZE < DEST
+#undef DECIMAL_SIZE
+#define DECIMAL_SIZE DEST
+#endif
+#endif
+
+#define CONTEXT_INIT PASTE(DEC_INIT_DECIMAL,DEST)
+
+#endif //DECIMAL_TO_DECIMAL || INTEGER_TO_DECIMAL || BINARY_TO_DECIMAL
+
+
+/* float dest */
+#if defined DECIMAL_TO_BINARY
+
+#if DEST==32
+#define DEST_TYPE float
+#define DEST_LITERAL(n) n##F
+#define DEST_KIND sf
+#endif
+
+#if DEST==64
+#define DEST_TYPE double
+#define DEST_LITERAL(n) n
+#define DEST_KIND df
+#endif
+
+#if DEST==128
+#define DEST_TYPE long double
+#define DEST_LITERAL(n) n##L
+#define DEST_KIND tf
+#endif
+
+#define DEST_INFINITY INFINITY
+#define DEST_NAN NAN
+
+
+#endif //DECIMAL_TO_BINARY
+
+
+/* integer dest */
+#if defined DECIMAL_TO_INTEGER
+
+#if DEST==32
+#if defined UNSIGNED
+#define DEST_TYPE unsigned int
+#define STR_TO_INT strtoul
+#else
+#define DEST_TYPE int
+#define STR_TO_INT strtol
+#endif
+#define DEST_LITERAL(n) n
+#define DEST_KIND si
+#endif
+
+#if DEST==64
+#if defined UNSIGNED
+#define DEST_TYPE unsigned long long
+#define STR_TO_INT strtoull
+#else
+#define DEST_TYPE long long
+#define STR_TO_INT strtoll
+#endif
+#define DEST_LITERAL(n) n
+#define DEST_KIND di
+#endif
+
+#endif //DECIMAL_TO_INTEGER
+
+
+extern const _Decimal128 decpowof2[];
+
+#define BINPOWOF10 binpowof10
+#define BINPOWOF10_LIMIT 308
+#define DECPOWOF2 decpowof2
+
+#define FREXPSF __builtin_frexpf
+#define FREXPDF __builtin_frexp
+#define FREXPTF __builtin_frexpl
+#define FREXPD32 __frexpd32
+#define FREXPD64 __frexpd64
+#define FREXPD128 __frexpd128
+
+
+
+#define PASTE(a,b) PASTE2(a,b)
+#define PASTE2(x,y) x##y
+#define PASTE4(a,b,c,d) PASTE(PASTE(a,b),PASTE(c,d))
+#define PASTE5(a,b,c,d,e) PASTE(PASTE4(a,b,c,d),2)
+
+#if defined DECIMAL_TO_DECIMAL
+#define FUNCTION_NAME PASTE5(__,NAME,SRC_KIND,DEST_KIND,2)
+#else
+#define FUNCTION_NAME PASTE4(__,NAME,SRC_KIND,DEST_KIND)
+#endif
+
+#if (SRC == 128 && (defined DECIMAL_TO_DECIMAL || defined DECIMAL_TO_INTEGER)) || \
+ (DEST == 128 && (defined DECIMAL_TO_DECIMAL || defined INTEGER_TO_DECIMAL))
+#include "decimal128.h"
+#include <dfptypeconv128.h>
+#endif
+#if (SRC == 64 && (defined DECIMAL_TO_DECIMAL || defined DECIMAL_TO_INTEGER)) || \
+ (DEST == 64 && (defined DECIMAL_TO_DECIMAL || defined INTEGER_TO_DECIMAL))
+#include "decimal64.h"
+#include <dfptypeconv64.h>
+#endif
+#if (SRC == 32 && (defined DECIMAL_TO_DECIMAL || defined DECIMAL_TO_INTEGER)) || \
+ (DEST == 32 && (defined DECIMAL_TO_DECIMAL || defined INTEGER_TO_DECIMAL))
+#include "decimal32.h"
+#include <dfptypeconv32.h>
+#endif
+
+#define DFP_EXCEPTIONS_ENABLED 1
+
+#define DFP_IEEE_FLAGS(status) ( \
+ (((status) & DEC_IEEE_854_Division_by_zero) ? FE_DIVBYZERO : 0) | \
+ (((status) & DEC_IEEE_854_Inexact) ? FE_INEXACT : 0) | \
+ (((status) & DEC_IEEE_854_Invalid_operation) ? FE_INVALID : 0) | \
+ (((status) & DEC_IEEE_854_Overflow) ? FE_OVERFLOW : 0) | \
+ (((status) & DEC_IEEE_854_Underflow) ? FE_UNDERFLOW : 0))
+
+#include <fenv_libc.h>
+#define DFP_TEST_EXCEPTIONS(status) ({ \
+ fenv_union_t u; \
+ u.fenv = fegetenv_register(); \
+ u.l[1] & (status); \
+ })
+#define DFP_CLEAR_EXCEPTIONS(status) { \
+ fenv_union_t u; \
+ u.fenv = fegetenv_register(); \
+ u.l[1] &= ~status; \
+ fesetenv_register(u.fenv); \
+ }
+#define DFP_HANDLE_EXCEPTIONS(status) feraiseexcept(status)
diff --git a/libc/dfp/test/test_copysign.c b/libc/dfp/test/test_copysign.c
new file mode 100644
index 000000000..19251fea0
--- /dev/null
+++ b/libc/dfp/test/test_copysign.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdint.h>
+#define __STDC_WANT_DEC_FP__ 1
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION copysign
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 ad32;
+ _Decimal32 bd32;
+ _Decimal32 cd32;
+
+ _Decimal64 ad64;
+ _Decimal64 bd64;
+ _Decimal64 cd64;
+
+ _Decimal128 ad128;
+ _Decimal128 bd128;
+ _Decimal128 cd128;
+
+ ad32 = -1.20DF;
+ bd32 = 0.12DF;
+ cd32 = FUNCTION_CALL()(ad32,bd32);
+ printf("%Hf = copysign(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad32 = -1.20DF;
+ bd32 = -0.12DF;
+ cd32 = FUNCTION_CALL()(ad32,bd32);
+ printf("%Hf = copysign(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad64 = -1.20DD;
+ bd64 = 0.12DD;
+ cd64 = FUNCTION_CALL()(ad64,bd64);
+ printf("%Df = copysign(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad64 = -1.20DD;
+ bd64 = -0.12DD;
+ cd64 = FUNCTION_CALL()(ad64,bd64);
+ printf("%Df = copysign(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad128 = -1.20DL;
+ bd128 = -0.12DL;
+ cd128 = FUNCTION_CALL()(ad128,bd128);
+ printf("%DDf = copysign(%DDf,%DDf)\n", cd128, ad128, bd128);
+
+ ad128 = -1.20DL;
+ bd128 = -0.12DL;
+ cd128 = FUNCTION_CALL()(ad128,bd128);
+ printf("%DDf = copysign(%DDf,%DDf)\n", cd128, ad128, bd128);
+
+
+}
diff --git a/libc/dfp/test/test_decimal128.c b/libc/dfp/test/test_decimal128.c
new file mode 100644
index 000000000..7f0a92869
--- /dev/null
+++ b/libc/dfp/test/test_decimal128.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+void
+f (long r3, long r4, long r5, long r6,
+ long r7, long r8, long r9, long r10,
+ _Decimal64 f1, _Decimal64 f2, _Decimal64 f3, _Decimal64 f4,
+ _Decimal64 f5, _Decimal64 f6, _Decimal64 f7, _Decimal64 f8,
+ long onstack, ...)
+{
+ __builtin_va_list ap;
+ _Decimal128 ld;
+
+ __builtin_va_start (ap, onstack);
+
+ ld = __builtin_va_arg (ap, _Decimal128);
+ if (ld != 1.23DL) {
+ printf("%Hf,%Df,%DDf\n", ld,ld,ld);
+ __builtin_abort ();
+ }
+
+ __builtin_va_end (ap);
+}
+
+int
+main (void)
+{
+ f (1, 2, 3, 4, 5, 6, 7, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 99, 1.23DL);
+ return 0;
+}
diff --git a/libc/dfp/test/test_decode.c b/libc/dfp/test/test_decode.c
new file mode 100644
index 000000000..452b3d853
--- /dev/null
+++ b/libc/dfp/test/test_decode.c
@@ -0,0 +1,75 @@
+/* /opt/biarch/dfp/bin/gcc -g test_signbit.c -o signbit -ldfp */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#ifndef __STDC_WANT_DEC_FP
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+#include <float.h>
+#include <fenv.h>
+
+extern char * decoded32 (_Decimal32, char*);
+extern char * decoded64 (_Decimal64, char*);
+extern char * decoded128 (_Decimal128, char*);
+
+int main() {
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+ char s32[32];
+ char s64[64];
+ char s128[128];
+
+ float f32;
+ double f64;
+ long double f128;
+
+ int i32;
+ long i64;
+ long long i128;
+
+ f32 = 0.0;
+ f64 = 0.0;
+ f128 = 0.0;
+ i32 = 0;
+ i64 = 0;
+ i128 = 0;
+
+ d32 = 0.0DF;
+ d64 = 0.0DD;
+ d128 = 0.0DL;
+
+ memset(s32, 0x0, 32);
+ memset(s64, 0x0, 64);
+ memset(s128, 0x0, 128);
+
+ printf("%Hf.0DF: [%s]\n", d32, decoded32(d32,s32));
+ printf("%Df.0DD: [%s]\n", d64, decoded64(d64,s64));
+ printf("%DDf.0DL: [%s]\n", d128, decoded128(d128,s128));
+
+ d32 = i32;
+ memset(s32, 0x0, 32);
+ printf("(_Decimal32)%HfDF = (int)%d: [%s]\n", d32, i32, decoded32(d32,s32));
+
+ d32 = f32;
+ memset(s32, 0x0, 32);
+ printf("(_Decimal32)%Hf.0DF = (float)%f: [%s]\n", d32, f32, decoded32(d32,s32));
+
+ d64 = i64;
+ memset(s64, 0x0, 64);
+ printf("(_Decimal64)%DfDD = (long)%ld: [%s]\n", d64, i64, decoded64(d64,s64));
+
+ d64 = f64;
+ memset(s64, 0x0, 64);
+ printf("(_Decimal64)%Df.0DD = (double)%f: [%s]\n", d64, f64, decoded64(d64,s64));
+
+ d128 = i128;
+ memset(s128, 0x0, 128);
+ printf("(_Decimal128)%DDfDL = (long long)%lld: [%s]\n", d128, i128, decoded128(d128,s128));
+
+ d128 = f128;
+ memset(s128, 0x0, 128);
+ printf("(_Decimal128)%DDf.0DL = (long double)%Lf: [%s]\n", d128, f128, decoded128(d128,s128));
+}
diff --git a/libc/dfp/test/test_decode2.c b/libc/dfp/test/test_decode2.c
new file mode 100644
index 000000000..5f2cecadd
--- /dev/null
+++ b/libc/dfp/test/test_decode2.c
@@ -0,0 +1,55 @@
+/* /opt/biarch/dfp/bin/gcc -g test_signbit.c -o signbit -ldfp */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#ifndef __STDC_WANT_DEC_FP
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+#include <float.h>
+#include <fenv.h>
+
+extern char * decoded32 (_Decimal32, char*);
+extern char * decoded64 (_Decimal64, char*);
+extern char * decoded128 (_Decimal128, char*);
+
+int main() {
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+ char s32[32];
+ char s64[64];
+ char s128[128];
+ double f64;
+
+ d128 = 123.1215E4DL;
+ printf("(_Decimal128)%DDfDL = [%s]\n", d128, decoded128(d128,s128));
+
+ d128 = 123.12150E4DL;
+ printf("(_Decimal128)%DDfDL = [%s]\n", d128, decoded128(d128,s128));
+
+ d128 = 1231215.0DL;
+ printf("(_Decimal128)%DDfDL = [%s]\n", d128, decoded128(d128,s128));
+
+ f64 = 123.15315E7;
+ printf("%.1lf\n", f64);
+ printf("%.2lf\n", f64);
+
+ f64 = 1231531.7;
+ printf("%.1lf\n", f64);
+ printf("%.2lf\n", f64);
+
+ f64 = 0.12315315E-3;
+ printf("%.1lf\n", f64);
+ printf("%.2lf\n", f64);
+ printf("%.8lf\n", f64);
+
+ f64 = -0.0012315E-7;
+ printf("%.2lf\n", f64);
+ printf("%.8lf\n", f64);
+ printf("%.9lf\n", f64);
+ printf("%.10lf\n", f64);
+ printf("%lf\n", f64);
+
+}
diff --git a/libc/dfp/test/test_decref.c b/libc/dfp/test/test_decref.c
new file mode 100644
index 000000000..875f3c395
--- /dev/null
+++ b/libc/dfp/test/test_decref.c
@@ -0,0 +1,23 @@
+#ifndef __STDC_WANT_DEC_FP__
+#define __STDC_WANT_DEC_FP__
+#endif
+
+#include <stdio.h>
+
+void function(_Decimal32 *d)
+{
+ _Decimal32 *e;
+ _Decimal32 f;
+ e = d;
+ f = *e;
+ printf("f == %Hf\n",f);
+}
+
+int main() {
+ _Decimal32 d32 = 23.234E12DF;
+ printf("d32 == %Hf\n", d32);
+ printf("Calling 'function'.\n");
+ function(&d32);
+
+ return 0;
+}
diff --git a/libc/dfp/test/test_double_to_decimal.c b/libc/dfp/test/test_double_to_decimal.c
new file mode 100644
index 000000000..a684b5a37
--- /dev/null
+++ b/libc/dfp/test/test_double_to_decimal.c
@@ -0,0 +1,400 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+#include "test_convert.h"
+
+extern char * decoded32 (_Decimal32, char*);
+extern char * decoded64 (_Decimal64, char*);
+extern char * decoded128 (_Decimal128, char*);
+
+const long double binpowof10 [] =
+ {
+ 1e+00L, /* 10**0 */
+ 1e+01L, /* 10**1 */
+ 1e+02L, /* 10**2 */
+ 1e+03L, /* 10**3 */
+ 1e+04L, /* 10**4 */
+ 1e+05L, /* 10**5 */
+ 1e+06L, /* 10**6 */
+ 1e+07L, /* 10**7 */
+ 1e+08L, /* 10**8 */
+ 1e+09L, /* 10**9 */
+ 1e+10L, /* 10**10 */
+ 1e+11L, /* 10**11 */
+ 1e+12L, /* 10**12 */
+ 1e+13L, /* 10**13 */
+ 1e+14L, /* 10**14 */
+ 1e+15L, /* 10**15 */
+ 1e+16L, /* 10**16 */
+ 1e+17L, /* 10**17 */
+ 1e+18L, /* 10**18 */
+ 1e+19L, /* 10**19 */
+ 1e+20L, /* 10**20 */
+ 1e+21L, /* 10**21 */
+ 1e+22L, /* 10**22 */
+ 1e+23L, /* 10**23 */
+ 1e+24L, /* 10**24 */
+ 1e+25L, /* 10**25 */
+ 1e+26L, /* 10**26 */
+ 1e+27L, /* 10**27 */
+ 1e+28L, /* 10**28 */
+ 1e+29L, /* 10**29 */
+ 1e+30L, /* 10**30 */
+ 1e+31L, /* 10**31 */
+ 1e+32L, /* 10**32 */
+ 1e+33L, /* 10**33 */
+ 1e+34L, /* 10**34 */
+ 1e+35L, /* 10**35 */
+ 1e+36L, /* 10**36 */
+ 1e+37L, /* 10**37 */
+ 1e+38L, /* 10**38 */
+ 1e+39L, /* 10**39 */
+ 1e+40L, /* 10**40 */
+ 1e+41L, /* 10**41 */
+ 1e+42L, /* 10**42 */
+ 1e+43L, /* 10**43 */
+ 1e+44L, /* 10**44 */
+ 1e+45L, /* 10**45 */
+ 1e+46L, /* 10**46 */
+ 1e+47L, /* 10**47 */
+ 1e+48L, /* 10**48 */
+ 1e+49L, /* 10**49 */
+ 1e+50L, /* 10**50 */
+ 1e+51L, /* 10**51 */
+ 1e+52L, /* 10**52 */
+ 1e+53L, /* 10**53 */
+ 1e+54L, /* 10**54 */
+ 1e+55L, /* 10**55 */
+ 1e+56L, /* 10**56 */
+ 1e+57L, /* 10**57 */
+ 1e+58L, /* 10**58 */
+ 1e+59L, /* 10**59 */
+ 1e+60L, /* 10**60 */
+ 1e+61L, /* 10**61 */
+ 1e+62L, /* 10**62 */
+ 1e+63L, /* 10**63 */
+ 1e+64L, /* 10**64 */
+ 1e+65L, /* 10**65 */
+ 1e+66L, /* 10**66 */
+ 1e+67L, /* 10**67 */
+ 1e+68L, /* 10**68 */
+ 1e+69L, /* 10**69 */
+ 1e+70L, /* 10**70 */
+ 1e+71L, /* 10**71 */
+ 1e+72L, /* 10**72 */
+ 1e+73L, /* 10**73 */
+ 1e+74L, /* 10**74 */
+ 1e+75L, /* 10**75 */
+ 1e+76L, /* 10**76 */
+ 1e+77L, /* 10**77 */
+ 1e+78L, /* 10**78 */
+ 1e+79L, /* 10**79 */
+ 1e+80L, /* 10**80 */
+ 1e+81L, /* 10**81 */
+ 1e+82L, /* 10**82 */
+ 1e+83L, /* 10**83 */
+ 1e+84L, /* 10**84 */
+ 1e+85L, /* 10**85 */
+ 1e+86L, /* 10**86 */
+ 1e+87L, /* 10**87 */
+ 1e+88L, /* 10**88 */
+ 1e+89L, /* 10**89 */
+ 1e+90L, /* 10**90 */
+ 1e+91L, /* 10**91 */
+ 1e+92L, /* 10**92 */
+ 1e+93L, /* 10**93 */
+ 1e+94L, /* 10**94 */
+ 1e+95L, /* 10**95 */
+ 1e+96L, /* 10**96 */
+ 1e+97L, /* 10**97 */
+ 1e+98L, /* 10**98 */
+ 1e+99L, /* 10**99 */
+ 1e+100L, /* 10**100 */
+ 1e+101L, /* 10**101 */
+ 1e+102L, /* 10**102 */
+ 1e+103L, /* 10**103 */
+ 1e+104L, /* 10**104 */
+ 1e+105L, /* 10**105 */
+ 1e+106L, /* 10**106 */
+ 1e+107L, /* 10**107 */
+ 1e+108L, /* 10**108 */
+ 1e+109L, /* 10**109 */
+ 1e+110L, /* 10**110 */
+ 1e+111L, /* 10**111 */
+ 1e+112L, /* 10**112 */
+ 1e+113L, /* 10**113 */
+ 1e+114L, /* 10**114 */
+ 1e+115L, /* 10**115 */
+ 1e+116L, /* 10**116 */
+ 1e+117L, /* 10**117 */
+ 1e+118L, /* 10**118 */
+ 1e+119L, /* 10**119 */
+ 1e+120L, /* 10**120 */
+ 1e+121L, /* 10**121 */
+ 1e+122L, /* 10**122 */
+ 1e+123L, /* 10**123 */
+ 1e+124L, /* 10**124 */
+ 1e+125L, /* 10**125 */
+ 1e+126L, /* 10**126 */
+ 1e+127L, /* 10**127 */
+ 1e+128L, /* 10**128 */
+ 1e+129L, /* 10**129 */
+ 1e+130L, /* 10**130 */
+ 1e+131L, /* 10**131 */
+ 1e+132L, /* 10**132 */
+ 1e+133L, /* 10**133 */
+ 1e+134L, /* 10**134 */
+ 1e+135L, /* 10**135 */
+ 1e+136L, /* 10**136 */
+ 1e+137L, /* 10**137 */
+ 1e+138L, /* 10**138 */
+ 1e+139L, /* 10**139 */
+ 1e+140L, /* 10**140 */
+ 1e+141L, /* 10**141 */
+ 1e+142L, /* 10**142 */
+ 1e+143L, /* 10**143 */
+ 1e+144L, /* 10**144 */
+ 1e+145L, /* 10**145 */
+ 1e+146L, /* 10**146 */
+ 1e+147L, /* 10**147 */
+ 1e+148L, /* 10**148 */
+ 1e+149L, /* 10**149 */
+ 1e+150L, /* 10**150 */
+ 1e+151L, /* 10**151 */
+ 1e+152L, /* 10**152 */
+ 1e+153L, /* 10**153 */
+ 1e+154L, /* 10**154 */
+ 1e+155L, /* 10**155 */
+ 1e+156L, /* 10**156 */
+ 1e+157L, /* 10**157 */
+ 1e+158L, /* 10**158 */
+ 1e+159L, /* 10**159 */
+ 1e+160L, /* 10**160 */
+ 1e+161L, /* 10**161 */
+ 1e+162L, /* 10**162 */
+ 1e+163L, /* 10**163 */
+ 1e+164L, /* 10**164 */
+ 1e+165L, /* 10**165 */
+ 1e+166L, /* 10**166 */
+ 1e+167L, /* 10**167 */
+ 1e+168L, /* 10**168 */
+ 1e+169L, /* 10**169 */
+ 1e+170L, /* 10**170 */
+ 1e+171L, /* 10**171 */
+ 1e+172L, /* 10**172 */
+ 1e+173L, /* 10**173 */
+ 1e+174L, /* 10**174 */
+ 1e+175L, /* 10**175 */
+ 1e+176L, /* 10**176 */
+ 1e+177L, /* 10**177 */
+ 1e+178L, /* 10**178 */
+ 1e+179L, /* 10**179 */
+ 1e+180L, /* 10**180 */
+ 1e+181L, /* 10**181 */
+ 1e+182L, /* 10**182 */
+ 1e+183L, /* 10**183 */
+ 1e+184L, /* 10**184 */
+ 1e+185L, /* 10**185 */
+ 1e+186L, /* 10**186 */
+ 1e+187L, /* 10**187 */
+ 1e+188L, /* 10**188 */
+ 1e+189L, /* 10**189 */
+ 1e+190L, /* 10**190 */
+ 1e+191L, /* 10**191 */
+ 1e+192L, /* 10**192 */
+ 1e+193L, /* 10**193 */
+ 1e+194L, /* 10**194 */
+ 1e+195L, /* 10**195 */
+ 1e+196L, /* 10**196 */
+ 1e+197L, /* 10**197 */
+ 1e+198L, /* 10**198 */
+ 1e+199L, /* 10**199 */
+ 1e+200L, /* 10**200 */
+ 1e+201L, /* 10**201 */
+ 1e+202L, /* 10**202 */
+ 1e+203L, /* 10**203 */
+ 1e+204L, /* 10**204 */
+ 1e+205L, /* 10**205 */
+ 1e+206L, /* 10**206 */
+ 1e+207L, /* 10**207 */
+ 1e+208L, /* 10**208 */
+ 1e+209L, /* 10**209 */
+ 1e+210L, /* 10**210 */
+ 1e+211L, /* 10**211 */
+ 1e+212L, /* 10**212 */
+ 1e+213L, /* 10**213 */
+ 1e+214L, /* 10**214 */
+ 1e+215L, /* 10**215 */
+ 1e+216L, /* 10**216 */
+ 1e+217L, /* 10**217 */
+ 1e+218L, /* 10**218 */
+ 1e+219L, /* 10**219 */
+ 1e+220L, /* 10**220 */
+ 1e+221L, /* 10**221 */
+ 1e+222L, /* 10**222 */
+ 1e+223L, /* 10**223 */
+ 1e+224L, /* 10**224 */
+ 1e+225L, /* 10**225 */
+ 1e+226L, /* 10**226 */
+ 1e+227L, /* 10**227 */
+ 1e+228L, /* 10**228 */
+ 1e+229L, /* 10**229 */
+ 1e+230L, /* 10**230 */
+ 1e+231L, /* 10**231 */
+ 1e+232L, /* 10**232 */
+ 1e+233L, /* 10**233 */
+ 1e+234L, /* 10**234 */
+ 1e+235L, /* 10**235 */
+ 1e+236L, /* 10**236 */
+ 1e+237L, /* 10**237 */
+ 1e+238L, /* 10**238 */
+ 1e+239L, /* 10**239 */
+ 1e+240L, /* 10**240 */
+ 1e+241L, /* 10**241 */
+ 1e+242L, /* 10**242 */
+ 1e+243L, /* 10**243 */
+ 1e+244L, /* 10**244 */
+ 1e+245L, /* 10**245 */
+ 1e+246L, /* 10**246 */
+ 1e+247L, /* 10**247 */
+ 1e+248L, /* 10**248 */
+ 1e+249L, /* 10**249 */
+ 1e+250L, /* 10**250 */
+ 1e+251L, /* 10**251 */
+ 1e+252L, /* 10**252 */
+ 1e+253L, /* 10**253 */
+ 1e+254L, /* 10**254 */
+ 1e+255L, /* 10**255 */
+ 1e+256L, /* 10**256 */
+ 1e+257L, /* 10**257 */
+ 1e+258L, /* 10**258 */
+ 1e+259L, /* 10**259 */
+ 1e+260L, /* 10**260 */
+ 1e+261L, /* 10**261 */
+ 1e+262L, /* 10**262 */
+ 1e+263L, /* 10**263 */
+ 1e+264L, /* 10**264 */
+ 1e+265L, /* 10**265 */
+ 1e+266L, /* 10**266 */
+ 1e+267L, /* 10**267 */
+ 1e+268L, /* 10**268 */
+ 1e+269L, /* 10**269 */
+ 1e+270L, /* 10**270 */
+ 1e+271L, /* 10**271 */
+ 1e+272L, /* 10**272 */
+ 1e+273L, /* 10**273 */
+ 1e+274L, /* 10**274 */
+ 1e+275L, /* 10**275 */
+ 1e+276L, /* 10**276 */
+ 1e+277L, /* 10**277 */
+ 1e+278L, /* 10**278 */
+ 1e+279L, /* 10**279 */
+ 1e+280L, /* 10**280 */
+ 1e+281L, /* 10**281 */
+ 1e+282L, /* 10**282 */
+ 1e+283L, /* 10**283 */
+ 1e+284L, /* 10**284 */
+ 1e+285L, /* 10**285 */
+ 1e+286L, /* 10**286 */
+ 1e+287L, /* 10**287 */
+ 1e+288L, /* 10**288 */
+ 1e+289L, /* 10**289 */
+ 1e+290L, /* 10**290 */
+ 1e+291L, /* 10**291 */
+ 1e+292L, /* 10**292 */
+ 1e+293L, /* 10**293 */
+ 1e+294L, /* 10**294 */
+ 1e+295L, /* 10**295 */
+ 1e+296L, /* 10**296 */
+ 1e+297L, /* 10**297 */
+ 1e+298L, /* 10**298 */
+ 1e+299L, /* 10**299 */
+ 1e+300L, /* 10**300 */
+ 1e+301L, /* 10**301 */
+ 1e+302L, /* 10**302 */
+ 1e+303L, /* 10**303 */
+ 1e+304L, /* 10**304 */
+ 1e+305L, /* 10**305 */
+ 1e+306L, /* 10**306 */
+ 1e+307L, /* 10**307 */
+ 1e+308L, /* 10**308 */
+ 1e+309L};/* 10**309 */
+
+
+
+_Decimal32 my_truncdddf(double a) {
+ long double temp;
+ _Decimal32 a_norm;
+ _Decimal32 a_half;
+ long long mant;
+ int exp, sexp;
+ _Decimal32 result;
+
+ a_norm = frexpd64 (a, &exp);
+
+ /* Avoid going beyond the bounds of the table, which would also
+ mean an overflow or underflow. */
+ //if (exp > BINPOWOF10_LIMIT) /* Obvious overflow. */
+// if (exp > 308) /* Obvious overflow. */
+ // {
+ // if (DFP_EXCEPTIONS_ENABLED)
+ // DFP_HANDLE_EXCEPTIONS (FE_OVERFLOW|FE_INEXACT);
+ // return SIGNBIT(a) ? -INFINITY : INFINITY;
+ // }
+ // else if (exp < -BINPOWOF10_LIMIT) /* Obvious underflow. */
+ // {
+ // if (DFP_EXCEPTIONS_ENABLED)
+ // DFP_HANDLE_EXCEPTIONS (FE_UNDERFLOW|FE_INEXACT);
+ // return SIGNBIT(a) ? -0.0 : 0.0;
+ //}
+
+ mant = a_norm * 1.E+16DD; /* 16 digits of mantissa. */
+ sexp = exp - 16; /* Exponent adjusted for mantissa. */
+ temp = mant; /* mantissa as TF */
+ if (sexp > 0)
+ result = temp * BINPOWOF10[sexp];
+ else if (sexp < 0)
+ {
+ /* Avoid going beyond the bounds of the exponent table for
+ negative exponents. */
+ if (sexp < -BINPOWOF10_LIMIT)
+ {
+ temp /= BINPOWOF10[BINPOWOF10_LIMIT];
+ sexp += BINPOWOF10_LIMIT;
+ }
+ result = temp / BINPOWOF10[-sexp];
+ }
+ else
+ result = temp;
+ /* Clear inexact exception raised by DFP arithmetic. */
+// if (DFP_EXCEPTIONS_ENABLED
+ // && DFP_TEST_EXCEPTIONS (FE_OVERFLOW|FE_UNDERFLOW) == 0)
+ // DFP_CLEAR_EXCEPTIONS (FE_INEXACT);
+
+ return result;
+}
+
+int main() {
+
+ _Decimal32 d32;
+ double f64 = 0.0625;
+ d32 = f64;
+ char s32[32];
+ printf("[%s]d32 = f64[%lf]\n", decoded32(d32,s32),f64);
+
+ d32 = my_truncdddf(f64);
+ printf("[%s]d32 = f64[%lf]\n", decoded32(d32,s32),f64);
+
+
+// DISP_HEXD32(d32,0.0625DF);
+// DISP_HEXD64(d64,0.0625DD);
+// DISP_HEXD128(d128,0.0625DL);
+
+// DISP_HEXD32(d32,(_Decimal32)cld);
+// DISP_HEXD64(d64,(_Decimal64)cld);
+ return -1;
+}
diff --git a/libc/dfp/test/test_errno.c b/libc/dfp/test/test_errno.c
new file mode 100644
index 000000000..6b064b3ea
--- /dev/null
+++ b/libc/dfp/test/test_errno.c
@@ -0,0 +1,212 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <fenv.h>
+#include <math.h>
+
+/* you can change this to 32,64,128 */
+#define TEST_SIZE 32
+
+#if TEST_SIZE == 128
+
+#define TYPE _Decimal128
+#define SIZE(x) x##d128
+#define DEC(x) x##DL
+#define FMT "%DDf"
+
+#elif TEST_SIZE == 64
+
+#define TYPE _Decimal64
+#define SIZE(x) x##d64
+#define DEC(x) x##DD
+#define FMT "%Df"
+
+#elif TEST_SIZE == 32
+
+#define TYPE _Decimal32
+#define SIZE(x) x##d32
+#define DEC(x) x##DF
+#define FMT "%Hf"
+
+#endif
+
+#define PASTE(x,y) x##y
+#define Stringify(x) Stringify2(x)
+#define Stringify2(x) #x
+
+
+int total_tests=0,
+ total_fail=0,
+ total_dec_fail=0,
+ total_errno_fail=0;
+
+void test(char *dec_str, TYPE dec_val, TYPE dec_expected, int dec_err,
+ char *str, double val, double expected, int err) {
+ int fail, dec_fail, errno_fail;
+ ++total_tests;
+ fail = bcmp(&val, &expected, sizeof(double));
+ dec_fail = bcmp(&dec_val, &dec_expected, sizeof(TYPE));
+ errno_fail = dec_err!=err;
+
+ total_fail += !!fail;
+ total_dec_fail += !!dec_fail;
+ total_errno_fail += !!errno_fail;
+
+ printf("%s = %f \t%s errno=%d, \"%s\"\n",
+ str,
+ val,
+ fail?"FAIL":"PASS",
+ err, strerror(err));
+ printf("%s = " FMT " \t%s\n",
+ dec_str,
+ dec_val,
+ dec_fail?"FAIL":"PASS");
+ printf(" errno=%d \"%s\" %s\n\n",
+ dec_err,
+ strerror(dec_err),
+ errno_fail?"FAIL":"PASS");
+ errno = 0;
+}
+
+#define TEST(op, op_dec, expected) { \
+ TYPE DEC(result); \
+ double result; \
+ int err_dec, err; \
+ errno = 0; \
+ DEC(result) = op_dec; \
+ err_dec = errno; \
+ errno = 0; \
+ result = op; \
+ err = errno; \
+ test(Stringify(op_dec), DEC(result), DEC(expected), err_dec, \
+ #op, result, expected, err); \
+}
+
+/* binary and unary testing macros */
+#define TESTb(name, arg1, arg2, expected) TEST(name(arg1,arg2), SIZE(name)(DEC(arg1), DEC(arg2)), expected)
+#define TESTu(name, arg, expected) TEST(name(arg), SIZE(name)(DEC(arg)), expected)
+
+
+int main() {
+
+ TYPE DEC(nan) = DEC_NAN;
+ TYPE DEC(inf) = DEC_INFINITY;
+ double nan = NAN;
+ double inf = INFINITY;
+ double nearinf = 1.5e308;
+ TYPE DEC(nearinf) = DEC(1.0e8);
+
+
+ TESTu(atan, -inf, result);
+ TESTu(atan, -0.5, result);
+ TESTu(atan, 0.0, 0.0);
+ TESTu(atan, 1.0, result);
+ TESTu(atan, 2.0, result);
+ TESTu(atan, inf, result);
+ TESTu(atan, nan, nan);
+
+ TESTu(sinh, 0.0, 0.0);
+ TESTu(sinh, 1.0, result);
+ TESTu(sinh, -1.0, result);
+ TESTu(sinh, inf, inf);
+ TESTu(sinh, -inf, -inf);
+ TESTu(sinh, nearinf, inf);
+ TESTu(sinh, -nearinf, -inf);
+ TESTu(sinh, nan, nan);
+
+ TESTu(cosh, 0.0, 1.);
+ TESTu(cosh, 1.0, result);
+ TESTu(cosh, -1.0, result);
+ TESTu(cosh, inf, inf);
+ TESTu(cosh, -inf, inf);
+ TESTu(cosh, nearinf, inf);
+ TESTu(cosh, -nearinf, inf);
+ TESTu(cosh, nan, nan);
+
+ TESTu(exp, 0.0, 1.);
+ TESTu(exp, nearinf, inf);
+ TESTu(exp, -nearinf, 0.);
+ TESTu(exp, inf, inf);
+ TESTu(exp, -inf, 0.);
+ TESTu(exp, nan, nan);
+ TESTu(exp, 1.0, result);
+
+ TESTu(log10, 0.0, -inf);
+ TESTu(log10, -1.0, nan);
+ TESTu(log10, inf, inf); //decNumber hangs on this one
+ TESTu(log10, -inf, nan);
+ TESTu(log10, 10.0, 1.);
+
+ TESTu(log, 0.0, -inf);
+ TESTu(log, -1.0, nan);
+ TESTu(log, inf, inf);
+ TESTu(log, -inf, nan);
+ {
+ double e = exp(1.0);
+ TYPE DEC(e) = SIZE(exp)(DEC(1.));
+ TESTu(log, e, 1.);
+ }
+
+ TESTb(pow, nan, 0.0, 1.);
+ TESTb(pow, nan, 1.0, nan);
+ TESTb(pow, 0.0, 0.0, 1.);
+ TESTb(pow, -0.0, -1.0, -inf);
+
+ TESTb(pow, 0.0, -1.0, inf);
+ TESTb(pow, -2.0, 1.1, nan);
+ TESTb(pow, 2.0, nearinf, inf);
+ TESTb(pow, 2.0, -nearinf, 0.);
+
+ TESTu(sqrt, -inf, nan);
+ TESTu(sqrt, -2.0, nan);
+ TESTu(sqrt, 0.0, result);
+ TESTu(sqrt, inf, inf);
+ TESTu(sqrt, nan, nan);
+
+
+ TESTu(acosh, -inf, nan);
+ TESTu(acosh, -1.5, nan);
+ TESTu(acosh, -1.0, nan);
+ TESTu(acosh, -0.5, nan);
+ TESTu(acosh, 0.0, nan);
+ TESTu(acosh, 0.5, nan);
+ TESTu(acosh, 1.0, result);
+ TESTu(acosh, 1.5, result);
+ TESTu(acosh, inf, inf);
+ TESTu(acosh, nan, nan);
+
+ TESTu(asinh, -inf, result);
+ TESTu(asinh, -1.5, result);
+ TESTu(asinh, -1.0, result);
+ TESTu(asinh, -0.5, result);
+ TESTu(asinh, 0.0, result);
+ TESTu(asinh, 0.5, result);
+ TESTu(asinh, 1.0, result);
+ TESTu(asinh, 1.5, result);
+ TESTu(asinh, inf, result);
+ TESTu(asinh, nan, nan);
+
+ TESTu(atanh, -inf, nan);
+ TESTu(atanh, -1.5, nan);
+ TESTu(atanh, -1.0, -inf);
+ TESTu(atanh, -0.5, result);
+ TESTu(atanh, 0.0, result);
+ TESTu(atanh, 0.5, result);
+ TESTu(atanh, 1.0, inf);
+ TESTu(atanh, 1.5, nan);
+ TESTu(atanh, inf, nan);
+ TESTu(atanh, nan, nan);
+
+ TESTb(atan2, 1.0, 1.0, result);
+ TESTb(atan2, -1.0, 1.0, result);
+ TESTb(atan2, -1.0, -1.0, result);
+ TESTb(atan2, 1.0, -1.0, result);
+
+ printf("%d tests, %d failed results, %d failed errno\n", total_tests,
+ total_dec_fail, total_errno_fail);
+}
diff --git a/libc/dfp/test/test_except.c b/libc/dfp/test/test_except.c
new file mode 100644
index 000000000..70064cbfc
--- /dev/null
+++ b/libc/dfp/test/test_except.c
@@ -0,0 +1,55 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+#include <math.h>
+#include <fenv.h>
+
+
+void reset() {
+ feclearexcept(FE_ALL_EXCEPT);
+}
+
+void report() {
+ int set_excepts;
+ set_excepts = fetestexcept(FE_ALL_EXCEPT);
+ if (set_excepts & FE_INVALID) printf(" FE_INVALID");
+ if (set_excepts & FE_OVERFLOW) printf(" FE_OVERFLOW");
+ if (set_excepts & FE_UNDERFLOW) printf(" FE_UNDERFLOW");
+ if (set_excepts & FE_INEXACT) printf(" FE_INEXACT");
+ if (set_excepts & FE_DIVBYZERO) printf(" FE_DIVBYZERO");
+ if (!set_excepts) printf(" none");
+ printf("\n");
+}
+
+#define TEST(x) printf(#x ":"); reset(); x; report();
+
+int
+main (void)
+{
+ _Decimal32 d;
+ _Decimal128 d128;
+ double f64;
+ float f32;
+
+TEST( acosd32 (2.0DF) )
+
+TEST( sqrtd32 (-1.0DF) )
+
+TEST( d=powd32(2e10DF, 2e10DF) );
+
+TEST( d=powd32(2e-1DF, 2e10DF) );
+
+TEST( d=1.DF / 0.DF );
+
+d128 = powd128(10, 309);
+TEST( f64 = d128 );
+TEST( f32 = d128 );
+
+// printf("%Hf\n", d);
+// printf("%f\n", f32);
+// printf("%DDf\n", d128);
+ return 0;
+}
+
diff --git a/libc/dfp/test/test_exceptions.c b/libc/dfp/test/test_exceptions.c
new file mode 100644
index 000000000..8e8d86735
--- /dev/null
+++ b/libc/dfp/test/test_exceptions.c
@@ -0,0 +1,25 @@
+#define _GNU_SOURCE
+#define __USE_GNU
+#define __STDC_WANT_DEC_FP__ 1
+#include <fenv.h>
+#include <math.h>
+#include <float.h>
+#include <stdio.h>
+
+int main() {
+ _Decimal64 d164;
+ _Decimal64 d264;
+ _Decimal64 res;
+ int exc;
+
+ exc = feenableexcept(FE_DIVBYZERO);
+
+ d164 = 35.0DD;
+ d264 = 0.0DD;
+
+ res = d164/d264;
+
+ printf ("res: %Df\n", res);
+
+ return 0;
+}
diff --git a/libc/dfp/test/test_fabsd.c b/libc/dfp/test/test_fabsd.c
new file mode 100644
index 000000000..f13e3492a
--- /dev/null
+++ b/libc/dfp/test/test_fabsd.c
@@ -0,0 +1,32 @@
+/* /opt/biarch/dfp/bin/gcc -g test_fabsd.c -o fabsd -ldfp */
+#include <stdio.h>
+#include <stdint.h>
+
+#define __STDC_WANT_DEC_FP__ 1
+#include <math.h>
+
+int main() {
+ _Decimal32 d32;
+ _Decimal32 absd32;
+ _Decimal64 d64;
+ _Decimal64 absd64;
+ _Decimal128 d128;
+ _Decimal128 absd128;
+
+ d32 = -19.54DF;
+ absd32 = 0.0DF;
+ d64 = -19.54DD;
+ absd64 = 0.0DD;
+ absd128 = 0.0DL;
+ d128 = -19.54DL;
+
+ absd32 = fabsd32(d32);
+
+ absd64 = fabsd64(d64);
+
+ absd128 = fabsd128(d128);
+
+ printf("%Hf = fabsd32(%Hf)\n", absd32, d32);
+ printf("%Df = fabsd64(%Df)\n", absd64, d64);
+ printf("%DDf = fabsd128(%DDf)\n", absd128, d128);
+}
diff --git a/libc/dfp/test/test_fdim.c b/libc/dfp/test/test_fdim.c
new file mode 100644
index 000000000..b440dd330
--- /dev/null
+++ b/libc/dfp/test/test_fdim.c
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION fdim
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 ad32;
+ _Decimal32 bd32;
+ _Decimal32 cd32;
+
+ _Decimal64 ad64;
+ _Decimal64 bd64;
+ _Decimal64 cd64;
+
+ _Decimal128 ad128;
+ _Decimal128 bd128;
+ _Decimal128 cd128;
+
+ ad32 = 10.0DF;
+ bd32 = 9.0DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = fdimd32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad32 = 10.0DF;
+ bd32 = 12.0DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = fdimd32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad32 = -10.0DF;
+ bd32 = -12.0DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = fdimd32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad32 = -10.0DF;
+ bd32 = -8.0DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = fdimd32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad32 = -0.012DF;
+ bd32 = 0.010DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = fdimd32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad64 = 10.0DD;
+ bd64 = 9.0DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,bd64);
+ printf("%Df = fdimd64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad64 = 10.0DD;
+ bd64 = 12.0DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,bd64);
+ printf("%Df = fdimd64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad128 = 10.0DL;
+ bd128 = 9.0DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,bd128);
+ printf("%DDf = fdimd128(%DDf,%DDf)\n", cd128, ad128, bd128);
+
+ ad128 = 10.0DL;
+ bd128 = 12.0DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,bd128);
+ printf("%DDf = fdimd128(%DDf,%DDf)\n", cd128, ad128, bd128);
+}
diff --git a/libc/dfp/test/test_floor.c b/libc/dfp/test/test_floor.c
new file mode 100644
index 000000000..cb2935200
--- /dev/null
+++ b/libc/dfp/test/test_floor.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdint.h>
+#define __STDC_WANT_DEC_FP__ 1
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION floor
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 d32;
+ _Decimal32 fd32;
+ _Decimal64 d64;
+ _Decimal64 fd64;
+ _Decimal128 d128;
+ _Decimal128 fd128;
+
+ d32 = -19.54DF;
+ fd32 = 0.0DF;
+
+ d64 = -19.54DD;
+ fd64 = 0.0DD;
+
+ d128 = -19.54DL;
+ fd128 = 0.0DL;
+
+ fd32 = FUNCTION_CALL(d32)(d32);
+ printf("%Hf = floord32(%Hf)\n", fd32, d32);
+ d32 = 19.54DF;
+ fd32 = FUNCTION_CALL(d32)(d32);
+ printf("%Hf = floord32(%Hf)\n", fd32, d32);
+
+ fd64 = FUNCTION_CALL(d64)(d64);
+ printf("%Df = floord64(%Df)\n", fd64, d64);
+ d64 = 19.54DD;
+ fd64 = FUNCTION_CALL(d64)(d64);
+ printf("%Df = floord64(%Df)\n", fd64, d64);
+
+ fd128 = FUNCTION_CALL(d128)(d128);
+ printf("%DDf = floord128(%DDf)\n", fd128, d128);
+ d128 = 19.54DL;
+ fd128 = FUNCTION_CALL(d128)(d128);
+ printf("%DDf = floord128(%DDf)\n", fd128, d128);
+}
diff --git a/libc/dfp/test/test_fmax.c b/libc/dfp/test/test_fmax.c
new file mode 100644
index 000000000..6022fc11f
--- /dev/null
+++ b/libc/dfp/test/test_fmax.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION fmax
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 ad32;
+ _Decimal32 bd32;
+ _Decimal32 cd32;
+
+ _Decimal64 ad64;
+ _Decimal64 bd64;
+ _Decimal64 cd64;
+
+ _Decimal128 ad128;
+ _Decimal128 bd128;
+ _Decimal128 cd128;
+
+ ad32 = -19.54DF;
+ bd32 = 19.54DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = fmaxd32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad32 = 19.54DF;
+ bd32 = 0.0DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = fmaxd32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad64 = -19.54DD;
+ bd64 = -19.53DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,bd64);
+ printf("%Df = fmaxd64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad64 = 19.54DD;
+ bd64 = 20.02DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,bd64);
+ printf("%Df = fmaxd64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad128 = -19.54DL;
+ bd128 = -19.55DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,bd128);
+ printf("%DDf = fmaxd128(%DDf,%DDf)\n", cd128, ad128, bd128);
+
+ ad128 = 19.54DL;
+ bd128 = 0.0DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,bd128);
+ printf("%DDf = fmaxd128(%DDf,%DDf)\n", cd128, ad128, bd128);
+}
diff --git a/libc/dfp/test/test_fmin.c b/libc/dfp/test/test_fmin.c
new file mode 100644
index 000000000..72a796ee4
--- /dev/null
+++ b/libc/dfp/test/test_fmin.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION fmin
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 ad32;
+ _Decimal32 bd32;
+ _Decimal32 cd32;
+
+ _Decimal64 ad64;
+ _Decimal64 bd64;
+ _Decimal64 cd64;
+
+ _Decimal128 ad128;
+ _Decimal128 bd128;
+ _Decimal128 cd128;
+
+ ad32 = -19.54DF;
+ bd32 = -19.55DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = fmind32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad32 = 19.54DF;
+ bd32 = 19.55DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = fmind32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad64 = -19.54DD;
+ bd64 = -19.55DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,bd64);
+ printf("%Df = fmind64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad64 = 19.54DD;
+ bd64 = 19.55DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,bd64);
+ printf("%Df = fmind64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad128 = -19.54DL;
+ bd128 = -19.55DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,bd128);
+ printf("%DDf = fmind128(%DDf,%DDf)\n", cd128, ad128, bd128);
+
+ ad128 = 19.54DL;
+ bd128 = 19.55DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,bd128);
+ printf("%DDf = fmind128(%DDf,%DDf)\n", cd128, ad128, bd128);
+}
diff --git a/libc/dfp/test/test_fpclassify.c b/libc/dfp/test/test_fpclassify.c
new file mode 100644
index 000000000..b6c0c0295
--- /dev/null
+++ b/libc/dfp/test/test_fpclassify.c
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <stdint.h>
+
+#ifndef __STDC_WANT_DEC_FP__
+#define __STDC_WANT_DEC_FP__ 1
+#endif
+
+#include <fenv.h>
+#include <math.h>
+
+#define D32ZERO 0.0DF;
+#define D64ZERO 0.0DD;
+#define D128ZERO 0.0DL;
+
+void fpc(int i) {
+ switch (i) {
+ case FP_NAN:
+ printf("value is FP_NAN\n");
+ break;
+ case FP_INFINITE:
+ printf("value is FP_INFINITE\n");
+ break;
+ case FP_ZERO:
+ printf("value is FP_ZERO\n");
+ break;
+ case FP_SUBNORMAL:
+ printf("value is FP_SUBNORMAL\n");
+ break;
+ case FP_NORMAL:
+ printf("value is FP_NORMAL\n");
+ break;
+ default:
+ printf("value is unknown\n");
+ }
+}
+
+int main() {
+
+ _Decimal32 dnan32 = DEC_NAN;
+ _Decimal32 dinf32 = DEC_INFINITY;
+ _Decimal32 dzero32 = D32ZERO;
+ _Decimal32 dnormal32 = 2.3DF;
+ _Decimal32 dsub = 1.0e-100DF;
+ _Decimal32 min = 1.0e-95DF;
+ _Decimal32 trickynormal = 10.0e-96DF;
+ _Decimal32 justdenormal = 1.0e-96DF;
+
+ fpc(fpclassify(dnan32));
+ fpc(fpclassify(dinf32));
+ fpc(fpclassify(dzero32));
+ fpc(fpclassify(dnormal32));
+ fpc(fpclassify(dsub));
+ fpc(fpclassify(min));
+ fpc(fpclassify(trickynormal));
+ fpc(fpclassify(justdenormal));
+}
diff --git a/libc/dfp/test/test_frexpd.c b/libc/dfp/test/test_frexpd.c
new file mode 100644
index 000000000..f97a1f4c8
--- /dev/null
+++ b/libc/dfp/test/test_frexpd.c
@@ -0,0 +1,39 @@
+#ifndef __STDC_WANT_DEC_FP__
+#define __STDC_WANT_DEC_FP__
+#endif
+
+#include <math.h>
+#include <stdio.h>
+
+int main() {
+ _Decimal32 d32 = 1.2345df;
+ _Decimal32 a32;
+ int exp;
+
+ a32 = frexpd32(d32,&exp);
+ printf("%Hf = frexpd32(%Hf,&[%d])\n",a32,d32,exp);
+
+ d32 = 12.324df;
+ a32 = frexpd32(d32,&exp);
+ printf("%Hf = frexpd32(%Hf,&[%d])\n",a32,d32,exp);
+
+ d32 = 0.12315df;
+ a32 = frexpd32(d32,&exp);
+ printf("%Hf = frexpd32(%Hf,&[%d])\n",a32,d32,exp);
+
+ d32 = 0.012315df;
+ a32 = frexpd32(d32,&exp);
+ printf("%Hf = frexpd32(%Hf,&[%d])\n",a32,d32,exp);
+
+ d32 = 0.012315E12df;
+ a32 = frexpd32(d32,&exp);
+ printf("%Hf = frexpd32(%Hf,&[%d])\n",a32,d32,exp);
+
+ d32 = 0.0123155E7df;
+ a32 = frexpd32(d32,&exp);
+ printf("%Hf = frexpd32(%Hf,&[%d])\n",a32,d32,exp);
+
+ d32 = 123.123155E-7df;
+ a32 = frexpd32(d32,&exp);
+ printf("%Hf = frexpd32(%Hf,&[%d])\n",a32,d32,exp);
+}
diff --git a/libc/dfp/test/test_ilogb.c b/libc/dfp/test/test_ilogb.c
new file mode 100644
index 000000000..a889ab871
--- /dev/null
+++ b/libc/dfp/test/test_ilogb.c
@@ -0,0 +1,18 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+
+int main() {
+ TEST_i_f_all(ilogb,-3, 0.0023);
+ TEST_i_f_all(ilogb,-2, 0.023);
+ TEST_i_f_all(ilogb,-1, 0.23);
+ TEST_i_f_all(ilogb,-1, -0.23);
+ TEST_i_f_all(ilogb,-3, -0.0023);
+ TEST_i_f_all(ilogb,0, 2.30);
+ TEST_i_f_all(ilogb,1, 23.0);
+}
+
diff --git a/libc/dfp/test/test_iscomparison.c b/libc/dfp/test/test_iscomparison.c
new file mode 100644
index 000000000..efec0da7a
--- /dev/null
+++ b/libc/dfp/test/test_iscomparison.c
@@ -0,0 +1,213 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#include "test_math.h"
+
+/* These don't have prototypes because they aren't available to users. */
+extern int islessd32 (_Decimal32 x, _Decimal32 y);
+extern int islessd64 (_Decimal64 x, _Decimal64 y);
+extern int islessd128 (_Decimal128 x, _Decimal128 y);
+
+extern int islessequald32 (_Decimal32 x, _Decimal32 y);
+extern int islessequald64 (_Decimal64 x, _Decimal64 y);
+extern int islessequald128 (_Decimal128 x, _Decimal128 y);
+
+extern int isgreaterd32 (_Decimal32 x, _Decimal32 y);
+extern int isgreaterd64 (_Decimal64 x, _Decimal64 y);
+extern int isgreaterd128 (_Decimal128 x, _Decimal128 y);
+
+extern int isgreaterequald32 (_Decimal32 x, _Decimal32 y);
+extern int isgreaterequald64 (_Decimal64 x, _Decimal64 y);
+extern int isgreaterequald128 (_Decimal128 x, _Decimal128 y);
+
+extern int islessgreaterd32 (_Decimal32 x, _Decimal32 y);
+extern int islessgreaterd64 (_Decimal64 x, _Decimal64 y);
+extern int islessgreaterd128 (_Decimal128 x, _Decimal128 y);
+
+int main() {
+
+ //isgreater
+ TEST_POLY_i_2_all(isgreater,0, -1.20, 1.0);
+ TEST_i_2_all(isgreater,0, -1.20, 1.0);
+
+ TEST_POLY_i_2_all(isgreater,1, 1.20, -1.0);
+ TEST_i_2_all(isgreater,1, 1.20, -1.0);
+
+ TEST_POLY_i_2_all(isgreater,1, 1.20, 1.0);
+ TEST_i_2_all(isgreater,1, 1.20, 1.0);
+
+ TEST_POLY_i_2_all(isgreater,1, 0.0020, 0.0019);
+ TEST_i_2_all(isgreater,1, 0.0020, 0.0019);
+
+ TEST_POLY_i_2_all(isgreater,0, 0.0020, 0.0020);
+ TEST_i_2_all(isgreater,0, 0.0020, 0.0020);
+
+ TEST_POLY_i_2_all(isgreater,0, DEC_NAN, 1.0019);
+ TEST_i_2_all(isgreater,0, DEC_NAN, 1.0019);
+
+ TEST_POLY_i_2_all(isgreater,0, DEC_NAN, 3.0019);
+ TEST_i_2_all(isgreater,0, DEC_NAN, 3.0019);
+
+ TEST_POLY_i_2_all(isgreater,0, 1.0019, DEC_NAN);
+ TEST_i_2_all(isgreater,0, 1.0019, DEC_NAN);
+
+ TEST_POLY_i_2_all(isgreater,1, DEC_INFINITY, DEC_MAX);
+ TEST_i_2_all(isgreater,1, DEC_INFINITY, DEC_MAX);
+
+ TEST_POLY_i_2_all(isgreater,0, DEC_INFINITY, DEC_INFINITY);
+ TEST_i_2_all(isgreater,0, DEC_INFINITY, DEC_INFINITY);
+ //isgreaterequal
+ TEST_POLY_i_2_all(isgreaterequal,0, -1.20, 1.0);
+ TEST_i_2_all(isgreaterequal,0, -1.20, 1.0);
+
+ TEST_POLY_i_2_all(isgreaterequal,1, 1.20, -1.0);
+ TEST_i_2_all(isgreaterequal,1, 1.20, -1.0);
+
+ TEST_POLY_i_2_all(isgreaterequal,1, 1.20, 1.0);
+ TEST_i_2_all(isgreaterequal,1, 1.20, 1.0);
+
+ TEST_POLY_i_2_all(isgreaterequal,1, 0.0020, 0.0019);
+ TEST_i_2_all(isgreaterequal,1, 0.0020, 0.0019);
+
+ TEST_POLY_i_2_all(isgreaterequal,1, 0.0020, 0.0020);
+ TEST_i_2_all(isgreaterequal,1, 0.0020, 0.0020);
+
+ TEST_POLY_i_2_all(isgreaterequal,0, DEC_NAN, 1.0019);
+ TEST_i_2_all(isgreaterequal,0, DEC_NAN, 1.0019);
+
+ TEST_POLY_i_2_all(isgreaterequal,0, DEC_NAN, 3.0019);
+ TEST_i_2_all(isgreaterequal,0, DEC_NAN, 3.0019);
+
+ TEST_POLY_i_2_all(isgreaterequal,0, 1.0019, DEC_NAN);
+ TEST_i_2_all(isgreaterequal,0, 1.0019, DEC_NAN);
+
+ TEST_POLY_i_2_all(isgreaterequal,1, DEC_INFINITY, DEC_MAX);
+ TEST_i_2_all(isgreaterequal,1, DEC_INFINITY, DEC_MAX);
+
+ TEST_POLY_i_2_all(isgreaterequal,1, DEC_INFINITY, DEC_INFINITY);
+ TEST_i_2_all(isgreaterequal,1, DEC_INFINITY, DEC_INFINITY);
+ //isless
+ TEST_POLY_i_2_all(isless,1, -1.20, 1.0);
+ TEST_i_2_all(isless,1, -1.20, 1.0);
+
+ TEST_POLY_i_2_all(isless,0, 1.20, -1.0);
+ TEST_i_2_all(isless,0, 1.20, -1.0);
+
+ TEST_POLY_i_2_all(isless,0, 1.20, 1.0);
+ TEST_i_2_all(isless,0, 1.20, 1.0);
+
+ TEST_POLY_i_2_all(isless,0, 0.0020, 0.0019);
+ TEST_i_2_all(isless,0, 0.0020, 0.0019);
+
+ TEST_POLY_i_2_all(isless,0, 0.0020, 0.0020);
+ TEST_i_2_all(isless,0, 0.0020, 0.0020);
+
+ TEST_POLY_i_2_all(isless,0, DEC_NAN, 1.0019);
+ TEST_i_2_all(isless,0, DEC_NAN, 1.0019);
+
+ TEST_POLY_i_2_all(isless,0, DEC_NAN, 3.0019);
+ TEST_i_2_all(isless,0, DEC_NAN, 3.0019);
+
+ TEST_POLY_i_2_all(isless,0, 1.0019, DEC_NAN);
+ TEST_i_2_all(isless,0, 1.0019, DEC_NAN);
+
+ TEST_POLY_i_2_all(isless,0, DEC_INFINITY, DEC_MAX);
+ TEST_i_2_all(isless,0, DEC_INFINITY, DEC_MAX);
+
+ TEST_POLY_i_2_all(isless,0, DEC_INFINITY, DEC_INFINITY);
+ TEST_i_2_all(isless,0, DEC_INFINITY, DEC_INFINITY);
+ //islessequal
+ TEST_POLY_i_2_all(islessequal,1, -1.20, 1.0);
+ TEST_i_2_all(islessequal,1, -1.20, 1.0);
+
+ TEST_POLY_i_2_all(islessequal,0, 1.20, -1.0);
+ TEST_i_2_all(islessequal,0, 1.20, -1.0);
+
+ TEST_POLY_i_2_all(islessequal,0, 1.20, 1.0);
+ TEST_i_2_all(islessequal,0, 1.20, 1.0);
+
+ TEST_POLY_i_2_all(islessequal,0, 0.0020, 0.0019);
+ TEST_i_2_all(islessequal,0, 0.0020, 0.0019);
+
+ TEST_POLY_i_2_all(islessequal,1, 0.0020, 0.0020);
+ TEST_i_2_all(islessequal,1, 0.0020, 0.0020);
+
+ TEST_POLY_i_2_all(islessequal,0, DEC_NAN, 1.0019);
+ TEST_i_2_all(islessequal,0, DEC_NAN, 1.0019);
+
+ TEST_POLY_i_2_all(islessequal,0, DEC_NAN, 3.0019);
+ TEST_i_2_all(islessequal,0, DEC_NAN, 3.0019);
+
+ TEST_POLY_i_2_all(islessequal,0, 1.0019, DEC_NAN);
+ TEST_i_2_all(islessequal,0, 1.0019, DEC_NAN);
+
+ TEST_POLY_i_2_all(islessequal,0, DEC_INFINITY, DEC_MAX);
+ TEST_i_2_all(islessequal,0, DEC_INFINITY, DEC_MAX);
+
+ TEST_POLY_i_2_all(islessequal,1, DEC_INFINITY, DEC_INFINITY);
+ TEST_i_2_all(islessequal,1, DEC_INFINITY, DEC_INFINITY);
+ //isgreater
+/* TEST_POLY_i_2_all(isgreater,0, -1.20, 1.0);
+ TEST_i_2_all(isgreater,0, -1.20, 1.0);
+
+ TEST_POLY_i_2_all(isgreater,1, 1.20, -1.0);
+ TEST_i_2_all(isgreater,1, 1.20, -1.0);
+
+ TEST_POLY_i_2_all(isgreater,1, 1.20, 1.0);
+ TEST_i_2_all(isgreater,1, 1.20, 1.0);
+
+ TEST_POLY_i_2_all(isgreater,1, 0.0020, 0.0019);
+ TEST_i_2_all(isgreater,1, 0.0020, 0.0019);
+
+ TEST_POLY_i_2_all(isgreater,0, 0.0020, 0.0020);
+ TEST_i_2_all(isgreater,0, 0.0020, 0.0020);
+
+ TEST_POLY_i_2_all(isgreater,0, DEC_NAN, 1.0019);
+ TEST_i_2_all(isgreater,0, DEC_NAN, 1.0019);
+
+ TEST_POLY_i_2_all(isgreater,0, DEC_NAN, 3.0019);
+ TEST_i_2_all(isgreater,0, DEC_NAN, 3.0019);
+
+ TEST_POLY_i_2_all(isgreater,0, 1.0019, DEC_NAN);
+ TEST_i_2_all(isgreater,0, 1.0019, DEC_NAN);
+
+ TEST_POLY_i_2_all(isgreater,1, DEC_INFINITY, DEC_MAX);
+ TEST_i_2_all(isgreater,1, DEC_INFINITY, DEC_MAX);
+
+ TEST_POLY_i_2_all(isgreater,0, DEC_INFINITY, DEC_INFINITY);
+ TEST_i_2_all(isgreater,0, DEC_INFINITY, DEC_INFINITY); */
+ //islessgreater
+ TEST_POLY_i_2_all(islessgreater,1, -1.20, 1.0);
+ TEST_i_2_all(islessgreater,1, -1.20, 1.0);
+
+ TEST_POLY_i_2_all(islessgreater,1, 1.20, -1.0);
+ TEST_i_2_all(islessgreater,1, 1.20, -1.0);
+
+ TEST_POLY_i_2_all(islessgreater,1, 1.20, 1.0);
+ TEST_i_2_all(islessgreater,1, 1.20, 1.0);
+
+ TEST_POLY_i_2_all(islessgreater,1, 0.0020, 0.0019);
+ TEST_i_2_all(islessgreater,1, 0.0020, 0.0019);
+
+ TEST_POLY_i_2_all(islessgreater,0, 0.0020, 0.0020);
+ TEST_i_2_all(islessgreater,0, 0.0020, 0.0020);
+
+ TEST_POLY_i_2_all(islessgreater,0, DEC_NAN, 1.0019);
+ TEST_i_2_all(islessgreater,0, DEC_NAN, 1.0019);
+
+ TEST_POLY_i_2_all(islessgreater,0, DEC_NAN, 3.0019);
+ TEST_i_2_all(islessgreater,0, DEC_NAN, 3.0019);
+
+ TEST_POLY_i_2_all(islessgreater,0, 1.0019, DEC_NAN);
+ TEST_i_2_all(islessgreater,0, 1.0019, DEC_NAN);
+
+ TEST_POLY_i_2_all(islessgreater,1, DEC_INFINITY, DEC_MAX);
+ TEST_i_2_all(islessgreater,1, DEC_INFINITY, DEC_MAX);
+
+ TEST_POLY_i_2_all(islessgreater,0, DEC_INFINITY, DEC_INFINITY);
+ TEST_i_2_all(islessgreater,0, DEC_INFINITY, DEC_INFINITY);
+}
diff --git a/libc/dfp/test/test_isfinite.c b/libc/dfp/test/test_isfinite.c
new file mode 100644
index 000000000..6b2c59d6c
--- /dev/null
+++ b/libc/dfp/test/test_isfinite.c
@@ -0,0 +1,99 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION isfinite
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+#define DEC_INFINITYDF DEC_INFINITY
+#define DEC_INFINITYDD (_Decimal64)DEC_INFINITY
+#define DEC_INFINITYDL (_Decimal128)DEC_INFINITY
+int main() {
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+ int finite;
+
+ d32 = -1.20DF;
+ /* finite = FUNCTION_CALL()(d32); */
+ finite = isfinite(d32);
+ printf("%d = isfinite(%Hf)\n", finite, d32);
+ /*printf("%d = __finited32(%Hf)\n", __finited32(d32), d32); */
+
+ d32 = DEC_INFINITY;
+ /* finite = FUNCTION_CALL()(d32); */
+ finite = isfinite(d32);
+ printf("%d = isfinite(%Hf)\n", finite, d32);
+ /*printf("%d = __finited32(%Hf)\n", __finited32(d32), d32); */
+
+ d32 = DEC_INFINITYDF;
+ /* finite = FUNCTION_CALL()(d32); */
+ finite = isfinite(d32);
+ printf("%d = isfinite(%Hf)\n", finite, d32);
+ /*printf("%d = __finited32(%Hf)\n", __finited32(d32), d32); */
+
+ d32 = -DEC_INFINITYDF;
+ /* finite = FUNCTION_CALL()(d32); */
+ finite = isfinite(d32);
+ printf("%d = isfinite(%Hf)\n", finite, d32);
+ /*printf("%d = __finited32(%Hf)\n", __finited32(d32), d32); */
+
+
+ d64 = -1.20DD;
+ finite = isfinite(d64);
+ /* finite = FUNCTION_CALL()(d64); */
+ printf("%d = isfinite(%Df)\n", finite, d64);
+ /* printf("%d = __finited64(%Df)\n", __finited64(d64), d64); */
+
+ d64 = DEC_INFINITY;
+ finite = isfinite(d64);
+ /* finite = FUNCTION_CALL()(d64); */
+ printf("%d = isfinite(%Df)\n", finite, d64);
+ /* printf("%d = __finited64(%Df)\n", __finited64(d64), d64); */
+
+ d64 = DEC_INFINITYDD;
+ finite = isfinite(d64);
+ /* finite = FUNCTION_CALL()(d64); */
+ printf("%d = isfinite(%Df)\n", finite, d64);
+ /* printf("%d = __finited64(%Df)\n", __finited64(d64), d64); */
+
+ d64 = -DEC_INFINITYDD;
+ finite = isfinite(d64);
+ /* finite = FUNCTION_CALL()(d64); */
+ printf("%d = isfinite(%Df)\n", finite, d64);
+ /* printf("%d = __finited64(%Df)\n", __finited64(d64), d64); */
+
+ d128 = -1.20DL;
+ finite = isfinite(d128);
+ /* finite = FUNCTION_CALL()(d128); */
+ printf("%d = isfinite(%DDf)\n", finite, d128);
+ /* printf("%d = __finited128(%DDf)\n", __finited128(d128), d128); */
+
+ d128 = DEC_INFINITY;
+ finite = isfinite(d128);
+ /* finite = FUNCTION_CALL()(d128); */
+ printf("%d = isfinite(%DDf)\n", finite, d128);
+ /* printf("%d = __finited128(%DDf)\n", __finited128(d128), d128); */
+
+ d128 = DEC_INFINITYDL;
+ finite = isfinite(d128);
+ /* finite = FUNCTION_CALL()(d128); */
+ printf("%d = isfinite(%DDf)\n", finite, d128);
+ /* printf("%d = __finited128(%DDf)\n", __finited128(d128), d128); */
+
+ d128 = -DEC_INFINITYDL;
+ finite = isfinite(d128);
+ /* finite = FUNCTION_CALL()(d128); */
+ printf("%d = isfinite(%DDf)\n", finite, d128);
+ /* printf("%d = __finited128(%DDf)\n", __finited128(d128), d128); */
+
+
+}
diff --git a/libc/dfp/test/test_isinf.c b/libc/dfp/test/test_isinf.c
new file mode 100644
index 000000000..a4aa41e5c
--- /dev/null
+++ b/libc/dfp/test/test_isinf.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION isinf
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+#define DEC_INFINITYDF DEC_INFINITY
+#define DEC_INFINITYDD (_Decimal64)DEC_INFINITY
+#define DEC_INFINITYDL (_Decimal128)DEC_INFINITY
+
+int main() {
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+ int inf;
+
+ d32 = -1.20DF;
+ inf = FUNCTION_CALL()(d32);
+ printf("%d = isinf(%Hf)\n", inf, d32);
+
+ d32 = DEC_INFINITY;
+ inf = FUNCTION_CALL()(d32);
+ printf("%d = isinf(%Hf)\n", inf, d32);
+
+ d32 = DEC_INFINITYDF;
+ inf = FUNCTION_CALL()(d32);
+ printf("%d = isinf(%Hf)\n", inf, d32);
+
+ d32 = -DEC_INFINITYDF;
+ inf = FUNCTION_CALL()(d32);
+ printf("%d = isinf(%Hf)\n", inf, d32);
+
+ d64 = -1.20DD;
+ inf = FUNCTION_CALL()(d64);
+ printf("%d = isinf(%Df)\n", inf, d64);
+
+ d64 = DEC_INFINITY;
+ inf = FUNCTION_CALL()(d64);
+ printf("%d = isinf(%Df)\n", inf, d64);
+
+ d64 = DEC_INFINITYDD;
+ inf = FUNCTION_CALL()(d64);
+ printf("%d = isinf(%Df)\n", inf, d64);
+
+ d64 = -DEC_INFINITYDD;
+ inf = FUNCTION_CALL()(d64);
+ printf("%d = isinf(%Df)\n", inf, d64);
+
+ d128 = -1.20DL;
+ inf = FUNCTION_CALL()(d128);
+ printf("%d = isinf(%DDf)\n", inf, d128);
+
+ d128 = DEC_INFINITY;
+ inf = FUNCTION_CALL()(d128);
+ printf("%d = isinf(%DDf)\n", inf, d128);
+
+ d128 = DEC_INFINITY;
+ inf = FUNCTION_CALL()(d128);
+ printf("%d = isinf(%DDf)\n", inf, d128);
+
+ d128 = -DEC_INFINITYDL;
+ inf = FUNCTION_CALL()(d128);
+ printf("%d = isinf(%DDf)\n", inf, d128);
+
+ return 0;
+}
diff --git a/libc/dfp/test/test_isnan.c b/libc/dfp/test/test_isnan.c
new file mode 100644
index 000000000..30df45d9d
--- /dev/null
+++ b/libc/dfp/test/test_isnan.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION isnan
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+ int inf;
+
+ d32 = -1.20DF;
+ inf = FUNCTION_CALL()(d32);
+ printf("%d = isnan(%Hf)\n", inf, d32);
+
+ d32 = NAN;
+ inf = FUNCTION_CALL()(d32);
+ printf("%d = isnan(%Hf)\n", inf, d32);
+
+ d64 = -0.00DD/0.0DD;
+ inf = FUNCTION_CALL()(d64);
+ printf("%d = isnan(%Df)\n", inf, d64);
+
+ d64 = NAN;
+ inf = FUNCTION_CALL()(d64);
+ printf("%d = isnan(%Df)\n", inf, d64);
+
+ d128 = -1.20DL;
+ inf = FUNCTION_CALL()(d128);
+ printf("%d = isnan(%DDf)\n", inf, d128);
+
+ d128 = NAN;
+ inf = FUNCTION_CALL()(d128);
+ printf("%d = isnan(%DDf)\n", inf, d128);
+}
diff --git a/libc/dfp/test/test_isnormal.c b/libc/dfp/test/test_isnormal.c
new file mode 100644
index 000000000..a7aaf0ace
--- /dev/null
+++ b/libc/dfp/test/test_isnormal.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+#include <float.h>
+
+#ifndef FUNCTION
+#define FUNCTION isnormal
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+union dec32 {
+ _Decimal32 d;
+ int i;
+};
+
+int main() {
+ /*_Decimal32 d32; */
+ union dec32 d32;
+ _Decimal32 d33;
+ _Decimal64 d64;
+ _Decimal128 d128;
+ int normal;
+
+ d33 = -1.20DF;
+ normal = FUNCTION_CALL()(d33);
+ printf("%d = isnormal(%Hf)\n", normal, d33);
+
+ d33 = __DEC32_DEN__;
+ normal = FUNCTION_CALL()(d33);
+ printf("%d = isnormal(%Hf)\n", normal, d33);
+
+ d64 = -1.20DD;
+ normal = FUNCTION_CALL()(d64);
+ printf("%d = isnormal(%Df)\n", normal, d64);
+
+ d64 = -1.20DD;
+ normal = FUNCTION_CALL()(d64);
+ printf("%d = isnormal(%Df)\n", normal, d64);
+
+ d128 = __DEC128_DEN__;
+ normal = FUNCTION_CALL()(d128);
+ printf("%d = isnormal(%DDf)\n", normal, d128);
+
+ d128 = -1.20DL;
+ normal = FUNCTION_CALL()(d128);
+ printf("%d = isnormal(%DDf)\n", normal, d128);
+
+ d33 = 10.0E-96DF;
+ normal = FUNCTION_CALL()(d33);
+ printf("%d = isnormal(%Hf)\n", normal, d33);
+
+ d33 = 1000.0E-98DF;
+ normal = FUNCTION_CALL()(d33);
+ printf("%d = isnormal(%Hf)\n", normal, d33);
+
+ d33 = 1.0E-96DF;
+ normal = FUNCTION_CALL()(d33);
+ printf("%d = isnormal(%Hf)\n", normal, d33);
+}
diff --git a/libc/dfp/test/test_isunordered.c b/libc/dfp/test/test_isunordered.c
new file mode 100644
index 000000000..0dfe73cf8
--- /dev/null
+++ b/libc/dfp/test/test_isunordered.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION isunordered
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 d32;
+ _Decimal32 e32;
+ _Decimal64 d64;
+ _Decimal64 e64;
+ _Decimal128 d128;
+ _Decimal128 e128;
+ int unordered;
+
+ d32 = -1.20DF;
+ e32 = 1.0DF;
+ unordered = FUNCTION_CALL()(d32,e32);
+ printf("%d = isunordered(%Hf,%Hf)\n", unordered, d32, e32);
+
+ d32 = NAN;
+ e32 = 1.0DD;
+ unordered = FUNCTION_CALL()(d32,e32);
+ printf("%d = isunordered(%Hf,%Hf)\n", unordered, d32, e32);
+
+ d64 = -1.20DD;
+ e64 = 1.0DD;
+ unordered = FUNCTION_CALL()(d64,e64);
+ printf("%d = isunordered(%Df,%Df)\n", unordered, d64, e64);
+
+ d64 = NAN;
+ e64 = 1.0DL;
+ unordered = FUNCTION_CALL()(d64,e64);
+ printf("%d = isunordered(%Df,%Df)\n", unordered, d64, e64);
+
+ d128 = -1.20DL;
+ e128 = 1.0DL;
+ unordered = FUNCTION_CALL()(d128,e128);
+ printf("%d = isunordered(%DDf,%DDf)\n", unordered, d128, e128);
+
+ d128 = NAN;
+ e128 = 1.0DL;
+ unordered = FUNCTION_CALL()(d128,e128);
+ printf("%d = isunordered(%DDf,%DDf)\n", unordered, d128, e128);
+}
diff --git a/libc/dfp/test/test_itoa.c b/libc/dfp/test/test_itoa.c
new file mode 100644
index 000000000..3f5e82228
--- /dev/null
+++ b/libc/dfp/test/test_itoa.c
@@ -0,0 +1,56 @@
+#include <string.h>
+#include <stdio.h>
+
+static const short int inttostr[10] = {
+0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
+};
+
+static void exptostr(char * str, int exp) {
+ int idx = 0;
+ int fidx = 0;
+ int digit;
+ int reduce = exp;
+ int until;
+ while(reduce >= 10)
+ {
+ digit = reduce % 10;
+ reduce = reduce/10;
+ str[idx++]=inttostr[digit];
+ }
+ str[idx++]=inttostr[reduce];
+ str[idx] = '\0';
+
+ /* Process half the string. */
+ until = idx/2;
+ --idx;
+ /* Reverse the string. */
+ for (fidx=0; fidx<until; fidx++,idx--) {
+ str[idx]=str[idx]+str[fidx];
+ str[fidx]=str[idx]-str[fidx];
+ str[idx]=str[idx]-str[fidx];
+ }
+}
+
+int main() {
+ char str[32];
+ int exp=123;
+ exptostr(&str[0], exp);
+ printf("%s\n", &str[0]);
+
+ exptostr(&str[0], 10);
+ printf("%s\n", &str[0]);
+
+ exptostr(&str[0], 3);
+ printf("%s\n", &str[0]);
+
+ memset(&str[0],0x40,32);
+ exptostr(&str[10], 1238348);
+ printf("%s\n", &str[0]);
+
+ exptostr(&str[0], 0);
+ printf("%s\n", &str[0]);
+
+ exptostr(&str[0], 83746578);
+ printf("%s\n", &str[0]);
+ return 0;
+}
diff --git a/libc/dfp/test/test_longdouble.c b/libc/dfp/test/test_longdouble.c
new file mode 100644
index 000000000..8e79a3d01
--- /dev/null
+++ b/libc/dfp/test/test_longdouble.c
@@ -0,0 +1,27 @@
+void
+f (long r3, long r4, long r5, long r6,
+ long r7, long r8, long r9, long r10,
+ double f1, double f2, double f3, double f4,
+ double f5, double f6, double f7, double f8,
+ long onstack, ...)
+{
+ __builtin_va_list ap;
+ long double ld;
+
+ __builtin_va_start (ap, onstack);
+
+ ld = __builtin_va_arg (ap, long double);
+ if (ld != 1.23L)
+ __builtin_abort ();
+
+ __builtin_va_end (ap);
+}
+
+int
+main (void)
+{
+ f (1, 2, 3, 4, 5, 6, 7, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 99, 1.23L);
+ return 0;
+}
diff --git a/libc/dfp/test/test_math.h b/libc/dfp/test/test_math.h
new file mode 100644
index 000000000..5b45bf0f8
--- /dev/null
+++ b/libc/dfp/test/test_math.h
@@ -0,0 +1,229 @@
+#ifndef __TEST_DN_MATH_H
+#define __TEST_DN_MATH_H
+
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+
+/*#define DECNUMDIGITS 34 */
+
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+
+//Useable test case constants: DEC_NAN, DEC_INFINITY, DEC_MAX, DEC_MIN, DEC_DEN, DEC_EPSILON
+//This is rather hackish... but it works (and this whole framework is supposed
+//to be temporary
+#define DEC_NANDF DEC_NAN
+#define DEC_NANDD (_Decimal64)DEC_NAN
+#define DEC_NANDL (_Decimal128)DEC_NAN
+#define DEC_INFINITYDF DEC_INFINITY
+#define DEC_INFINITYDD (_Decimal64)DEC_INFINITY
+#define DEC_INFINITYDL (_Decimal128)DEC_INFINITY
+#define DEC_MAXDF DEC32_MAX
+#define DEC_MAXDD DEC64_MAX
+#define DEC_MAXDL DEC128_MAX
+#define DEC_MINDF DEC32_MIN
+#define DEC_MINDD DEC64_MIN
+#define DEC_MINDL DEC128_MIN
+#define DEC_DENDF DEC32_DEN
+#define DEC_DENDD DEC64_DEN
+#define DEC_DENDL DEC128_DEN
+#define DEC_EPSILONDF DEC32_EPSILON
+#define DEC_EPSILONDD DEC64_EPSILON
+#define DEC_EPSILONDL DEC128_EPSILON
+#define trueDF true
+#define trueDD true
+#define trueDL true
+#define falseDF false
+#define falseDD false
+#define falseDL false
+
+//TEST_f(fabsd32,2.0DF,%Hf,-2.0DF)
+//#define TEST_f(func,result,printf_t,args...) \
+// do { \
+// typeof(result)pres = result; \
+// typeof(result) res = func (args); \
+// if(res == result || (isnan(result) && isnan(res))) \
+// printf("Success: "#printf_t" = "#func" ("#args")\n",res);\
+// else \
+// printf("Error: "#printf_t" = "#func" ("#args"): should be "#printf_t"\n", res, pres);\
+// } while(0)
+// /*printf("Error: "#printf_t" = "#func" ("#args") : should be "#result"\n", res);*/
+
+
+extern char * decoded32 (_Decimal32, char*);
+extern char * decoded64 (_Decimal64, char*);
+extern char * decoded128 (_Decimal128, char*);
+
+typedef union {
+ _Decimal32 d;
+ long l[1];
+ } convertd32;
+
+typedef union {
+ _Decimal64 d;
+ long l[2];
+ } convertd64;
+
+typedef union {
+ _Decimal128 d;
+ long l[4];
+ } convertd128;
+
+#define DISP_HEXD32(got, expect) \
+ do { \
+ convertd32 g32, e32; \
+ g32.d = got; \
+ e32.d = expect; \
+ char s32[32]; \
+ printf(" Result(0x%.8x) <-> expected(0x%.8x)\n", g32.l[0], e32.l[0]); \
+ if (g32.d == e32.d) \
+ printf(" g32.d(%Hf) == e32.d(%Hf)\n", g32.d, e32.d); \
+ else \
+ printf(" g32.d(%Hf) != e32.d(%Hf)\n", g32.d, e32.d); \
+ printf(" DPD for g32.d [%s]\n", decoded32(g32.d,s32)); \
+ printf(" DPD for e32.d [%s]\n", decoded32(e32.d,s32)); \
+ printf("\n"); \
+ } while (0)
+
+#define DISP_HEXD64(got, expect) \
+ do { \
+ convertd64 g64, e64; \
+ g64.d = got; \
+ e64.d = expect; \
+ char s64[64]; \
+ printf(" Result(0x%.8x%.8x) <-> expected(0x%.8x%.8x)\n", g64.l[0], g64.l[1], e64.l[0], e64.l[1]); \
+ if (g64.d == e64.d) \
+ printf(" g64.d(%Df) == e64.d(%Df)\n", g64.d, e64.d); \
+ else \
+ printf(" g64.d(%Df) != e64.d(%Df)\n", g64.d, e64.d); \
+ printf(" DPD for g64.d [%s]\n", decoded64(g64.d,s64));\
+ printf(" DPD for e64.d [%s]\n", decoded64(e64.d,s64));\
+ printf("\n"); \
+ } while (0)
+
+#define DISP_HEXD128(got, expect) \
+ do { \
+ convertd128 g128, e128; \
+ g128.d = got; \
+ e128.d = expect; \
+ char s128[128]; \
+ printf(" Result(0x%.8x%.8x%.8x%.8x) <-> expected(0x%.8x%.8x%.8x%.8x)\n", g128.l[0], g128.l[1], g128.l[2], g128.l[3],e128.l[0], e128.l[1], e128.l[2], e128.l[3]); \
+ if (g128.d == e128.d) \
+ printf(" g128.d(%DDf) == e128.d(%DDf)\n", g128.d, e128.d); \
+ else \
+ printf(" g128.d(%DDf) != e128.d(%DDf)\n", g128.d, e128.d); \
+ printf(" DPD for g128.d [%s]\n", decoded128(g128.d,s128));\
+ printf(" DPD for e128.d [%s]\n", decoded128(e128.d,s128));\
+ printf("\n"); \
+ } while (0)
+
+//TEST_f(fabsd32,2.0DF,%Hf,-2.0DF)
+#define TEST_f(func,result,printf_t,args...) \
+ do { \
+ typeof(result)pres = result; \
+ typeof(result) res = func (args); \
+ if(res == result || (isnan(result) && isnan(res))) \
+ printf("Success: "#printf_t" = "#func" ("#args")\n",res);\
+ else { \
+ printf("Error: "#printf_t" = "#func" ("#args"): should be "#printf_t" (" #result")\n", res, pres);\
+ if (sizeof(typeof(result)) == 16) \
+ DISP_HEXD128(res, pres); \
+ else if (sizeof(typeof(result)) == 8) \
+ DISP_HEXD64(res, pres); \
+ else \
+ DISP_HEXD32(res, pres); \
+ } \
+ } while(0)
+ /*printf("Error: "#printf_t" = "#func" ("#args") : should be "#result"\n", res);*/
+
+
+#define TEST_i(func,result,args...) \
+ do { \
+ long long int res = func (args); \
+ if(res != result ) \
+ printf("Error: %lld = "#func" ("#args") : should be "#result"\n", res); \
+ else \
+ printf("Success: %lld = "#func" ("#args")\n",res);\
+ } while(0)
+
+#define TEST_fI(func,printf_t,result,resultI,args...) \
+ do { \
+ int the_int; \
+ typeof(result) res = func (args, &the_int); \
+ if((res == result && the_int == resultI) || \
+ (isnan(result) && isnan(res))) \
+ printf("Success: "#printf_t","#resultI" = "#func" ("#args",&i)\n",res);\
+ else \
+ printf("Error: "#printf_t",%d = "#func" ("#args",&i) : should be "#result","#resultI"\n", res,the_int);\
+ } while(0)
+
+
+
+//Pattern is TEST_<returntype>_<# of dfp arguments>_all(func,result,arguments)
+// or TEST_<returntype>_{<f/i (for type) of arguments>_}+_all(func,result,args)
+//TEST_f_all(fabs,-2.0,2.0)
+#define TEST_f_1_all(func,result,arg) \
+ do { \
+ TEST_f(func##d32,result##DF,%Hf,arg##DF); \
+ TEST_f(func##d64,result##DD,%Df,arg##DD); \
+ TEST_f(func##d128,result##DL,%DDf,arg##DL); \
+ } while(0)
+#define TEST_f_f_all(func,result,arg) TEST_f_1_all(func,result,arg)
+
+
+//TEST_i_all(nearbyint,0.2,0.0)
+#define TEST_i_1_all(func,result,arg) \
+ do { \
+ TEST_i(func##d32,result,arg##DF); \
+ TEST_i(func##d64,result,arg##DD); \
+ TEST_i(func##d128,result,arg##DL); \
+ } while(0)
+#define TEST_i_f_all(func,result,arg) TEST_i_1_all(func,result,arg)
+
+#define TEST_f_2_all(func,result,arg1,arg2) \
+ do { \
+ TEST_f(func##d32,result##DF,%Hf,arg1##DF, arg2##DF); \
+ TEST_f(func##d64,result##DD,%Df,arg1##DD, arg2##DD); \
+ TEST_f(func##d128,result##DL,%DDf,arg1##DL, arg2##DL); \
+ } while(0)
+#define TEST_f_f_f_all(func,result,arg1,arg2) TEST_f_2_all(func,result,arg1,arg2)
+
+#define TEST_f_3_all(func,result,arg1,arg2,arg3) \
+ do { \
+ TEST_f(func##d32,result##DF,%Hf,arg1##DF, arg2##DF, arg3##DF); \
+ TEST_f(func##d64,result##DD,%Df,arg1##DD, arg2##DD, arg3##DD); \
+ TEST_f(func##d128,result##DL,%DDf,arg1##DL, arg2##DL, arg3##DL);\
+ } while(0)
+
+#define TEST_POLY_i_2_all(func,result,arg1,arg2) \
+ do { \
+ TEST_i(func,result,arg1##DF, arg2##DF); \
+ TEST_i(func,result,arg1##DD, arg2##DD); \
+ TEST_i(func,result,arg1##DL, arg2##DL); \
+ } while(0)
+
+
+#define TEST_i_2_all(func,result,arg1,arg2) \
+ do { \
+ TEST_i(func##d32,result,arg1##DF, arg2##DF); \
+ TEST_i(func##d64,result,arg1##DD, arg2##DD); \
+ TEST_i(func##d128,result,arg1##DL, arg2##DL); \
+ } while(0)
+#define TEST_i_f_f_all(func,result,arg1,arg2) TEST_i_2_all(func,result,arg1,arg2)
+
+#define TEST_f_i_all(func,result,arg) \
+ do { \
+ TEST_f(func##d32,result##DF,%Hf,arg); \
+ TEST_f(func##d64,result##DD,%Df,arg); \
+ TEST_f(func##d128,result##DL,%DDf,arg); \
+ } while(0)
+
+#define TEST_f_f_i_all(func,result,arg1,arg2) \
+ do { \
+ TEST_f(func##d32,result##DF,%Hf,arg1##DF, arg2); \
+ TEST_f(func##d64,result##DD,%Df,arg1##DD, arg2); \
+ TEST_f(func##d128,result##DL,%DDf,arg1##DL, arg2); \
+ } while(0)
+#endif
diff --git a/libc/dfp/test/test_modf.c b/libc/dfp/test/test_modf.c
new file mode 100644
index 000000000..b64aace31
--- /dev/null
+++ b/libc/dfp/test/test_modf.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION modf
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 ad32;
+ _Decimal32 bd32;
+ _Decimal32 cd32;
+
+ _Decimal64 ad64;
+ _Decimal64 bd64;
+ _Decimal64 cd64;
+
+ _Decimal128 ad128;
+ _Decimal128 bd128;
+ _Decimal128 cd128;
+
+ ad32 = -19.54DF;
+ bd32 = 0.0DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,&bd32);
+ printf("%Hf = modfd32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad32 = 19.54DF;
+ bd32 = 0.0DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,&bd32);
+ printf("%Hf = modfd32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad64 = -19.54DD;
+ bd64 = 0.0DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,&bd64);
+ printf("%Df = modfd64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad64 = 19.54DD;
+ bd64 = 0.0DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,&bd64);
+ printf("%Df = modfd64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad128 = -19.54DL;
+ bd128 = 0.0DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,&bd128);
+ printf("%DDf = modfd128(%DDf,%DDf)\n", cd128, ad128, bd128);
+
+ ad128 = 19.54DL;
+ bd128 = 0.0DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,&bd128);
+ printf("%DDf = modfd128(%DDf,%DDf)\n", cd128, ad128, bd128);
+}
diff --git a/libc/dfp/test/test_nearbyintd.c b/libc/dfp/test/test_nearbyintd.c
new file mode 100644
index 000000000..e1d240a82
--- /dev/null
+++ b/libc/dfp/test/test_nearbyintd.c
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+#include <fenv.h>
+
+void nearby(void) {
+ _Decimal32 d32;
+ _Decimal32 nbd32;
+
+ _Decimal64 d64;
+ _Decimal64 nbd64;
+
+ _Decimal128 d128;
+ _Decimal128 nbd128;
+
+ d32 = 19.54DF;
+ d64 = 19.54DD;
+ d128 = 19.54DL;
+
+ nbd32 = nearbyintd32(d32);
+ printf(" %Hf = nearbyintd32( %Hf)\n", nbd32, d32);
+ d32 = -19.54DF;
+ nbd32 = nearbyintd32(d32);
+ printf("%Hf = nearbyintd32( %Hf)\n", nbd32, d32);
+
+ nbd64 = nearbyintd64(d64);
+ printf(" %Df = nearbyintd64( %Df)\n", nbd64, d64);
+ d64 = -19.54DD;
+ nbd64 = nearbyintd64(d64);
+ printf("%Df = nearbyintd64( %Df)\n", nbd64, d64);
+
+ nbd128 = nearbyintd128(d128);
+ printf(" %DDf = nearbyintd128( %DDf)\n", nbd128, d128);
+ d128 = -19.54DL;
+ nbd128 = nearbyintd128(d128);
+ printf("%DDf = nearbyintd128(%DDf)\n", nbd128, d128);
+}
+
+int main() {
+
+ int round = 0;
+
+ printf("*** Default rounding mode is FE_DEC_TONEAREST\n", round );
+ nearby();
+
+ printf ("*** Changing rounding mode to FE_DEC_TOWARDZERO\n");
+ round = fe_dec_setround(FE_DEC_TOWARDZERO);
+ nearby();
+
+ printf ("*** Changing rounding mode to FE_DEC_UPWARD\n");
+ round = fe_dec_setround(FE_DEC_UPWARD);
+ nearby();
+
+ printf ("*** Changing rounding mode to FE_DEC_TONEARESTFROMZERO\n");
+ round = fe_dec_setround(FE_DEC_TONEARESTFROMZERO);
+ nearby();
+
+ printf ("*** Changing rounding mode to FE_DEC_DOWNWARD\n");
+ round = fe_dec_setround(FE_DEC_DOWNWARD);
+ nearby();
+}
diff --git a/libc/dfp/test/test_pow.c b/libc/dfp/test/test_pow.c
new file mode 100644
index 000000000..e13600a73
--- /dev/null
+++ b/libc/dfp/test/test_pow.c
@@ -0,0 +1,260 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <fenv.h>
+#include <math.h>
+
+/* you can change this to 32,64,128 */
+#define TEST_SIZE 32
+
+#if TEST_SIZE == 128
+
+#define TYPE _Decimal128
+#define SIZE(x) x##d128
+#define DEC(x) x##DL
+#define FMT "%DDf"
+
+#elif TEST_SIZE == 64
+
+#define TYPE _Decimal64
+#define SIZE(x) x##d64
+#define DEC(x) x##DD
+#define FMT "%Df"
+
+#elif TEST_SIZE == 32
+
+#define TYPE _Decimal32
+#define SIZE(x) x##d32
+#define DEC(x) x##DF
+#define FMT "%Hf"
+
+#endif
+
+#define PASTE(x,y) x##y
+#define Stringify(x) Stringify2(x)
+#define Stringify2(x) #x
+
+
+int total_tests=0,
+ total_fail=0,
+ total_dec_fail=0,
+ total_errno_fail=0;
+
+void test(char *dec_str, TYPE dec_val, TYPE dec_expected, int dec_err,
+ char *str, double val, double expected, int err) {
+ int fail, dec_fail, errno_fail;
+ ++total_tests;
+ fail = bcmp(&val, &expected, sizeof(double));
+ dec_fail = bcmp(&dec_val, &dec_expected, sizeof(TYPE));
+ errno_fail = dec_err!=err;
+
+ total_fail += !!fail;
+ total_dec_fail += !!dec_fail;
+ total_errno_fail += !!errno_fail;
+
+ printf("%s = %f \t%s errno=%d, \"%s\"\n",
+ str,
+ val,
+ fail?"FAIL":"PASS",
+ err, strerror(err));
+ printf("%s = " FMT " \t%s\n",
+ dec_str,
+ dec_val,
+ dec_fail?"FAIL":"PASS");
+ printf(" errno=%d \"%s\" %s\n\n",
+ dec_err,
+ strerror(dec_err),
+ errno_fail?"FAIL":"PASS");
+ errno = 0;
+}
+
+#define TEST(op, op_dec, expected) { \
+ TYPE DEC(result); \
+ double result; \
+ int err_dec, err; \
+ errno = 0; \
+ DEC(result) = op_dec; \
+ err_dec = errno; \
+ errno = 0; \
+ result = op; \
+ err = errno; \
+ test(Stringify(op_dec), DEC(result), DEC(expected), err_dec, \
+ #op, result, expected, err); \
+}
+
+/* binary and unary testing macros */
+#define TESTb(name, arg1, arg2, expected) TEST(name(arg1,arg2), SIZE(name)(DEC(arg1), DEC(arg2)), expected)
+#define TESTu(name, arg, expected) TEST(name(arg), SIZE(name)(DEC(arg)), expected)
+
+
+int main() {
+
+ TYPE DEC(nan) = DEC_NAN;
+ TYPE DEC(inf) = DEC_INFINITY;
+ double nan = NAN;
+ double inf = INFINITY;
+ double nearinf = 1.5e308;
+ TYPE DEC(nearinf) = DEC(1.0e8);
+
+ TESTb(pow, -inf, -inf, 0.);
+ TESTb(pow, -inf, -1.0, -0.);
+ TESTb(pow, -inf, -1.5, 0.);
+ TESTb(pow, -inf, -2.0, 0.);
+ TESTb(pow, -inf, -0.0, 1.0);
+ TESTb(pow, -inf, 0.0, 1.0);
+ TESTb(pow, -inf, 2.0, inf);
+ TESTb(pow, -inf, 1.5, inf);
+ TESTb(pow, -inf, 1.0, -inf);
+ TESTb(pow, -inf, inf, inf);
+ TESTb(pow, -inf, nan, nan);
+
+ TESTb(pow, -5.0, -inf, 0.);
+ TESTb(pow, -5.0, -1.0, -0.2);
+ TESTb(pow, -5.0, -1.5, nan);
+ TESTb(pow, -5.0, -2.0, 0.04);
+ TESTb(pow, -5.0, -0.0, 1.0);
+ TESTb(pow, -5.0, 0.0, 1.0);
+ TESTb(pow, -5.0, 2.0, 25.0);
+ TESTb(pow, -5.0, 1.5, nan);
+ TESTb(pow, -5.0, 1.0, -5.0);
+ TESTb(pow, -5.0, inf, inf);
+ TESTb(pow, -5.0, nan, nan);
+
+ TESTb(pow, -2.0, -inf, 0.);
+ TESTb(pow, -2.0, -1.0, -0.5);
+ TESTb(pow, -2.0, -1.5, nan);
+ TESTb(pow, -2.0, -2.0, 0.25);
+ TESTb(pow, -2.0, -0.0, 1.0);
+ TESTb(pow, -2.0, 0.0, 1.0);
+ TESTb(pow, -2.0, 2.0, 4.0);
+ TESTb(pow, -2.0, 1.0, -2.0);
+ TESTb(pow, -2.0, 1.5, nan);
+ TESTb(pow, -2.0, inf, inf);
+ TESTb(pow, -2.0, nan, nan);
+
+ TESTb(pow, -1.0, -inf, 1.0);
+ TESTb(pow, -1.0, -1.0, -1.0);
+ TESTb(pow, -1.0, -1.5, nan);
+ TESTb(pow, -1.0, -2.0, 1.0);
+ TESTb(pow, -1.0, -0.0, 1.0);
+ TESTb(pow, -1.0, 0.0, 1.0);
+ TESTb(pow, -1.0, 2.0, 1.0);
+ TESTb(pow, -1.0, 1.0, -1.0);
+ TESTb(pow, -1.0, 1.5, nan);
+ TESTb(pow, -1.0, inf, 1.0);
+ TESTb(pow, -1.0, nan, nan);
+
+ TESTb(pow, -0.5, -inf, inf);
+ TESTb(pow, -0.5, -1.0, -2.);
+ TESTb(pow, -0.5, -1.5, nan);
+ TESTb(pow, -0.5, -2.0, 4.0);
+ TESTb(pow, -0.5, -0.0, 1.0);
+ TESTb(pow, -0.5, 0.0, 1.0);
+ TESTb(pow, -0.5, 2.0, 0.25);
+ TESTb(pow, -0.5, 1.5, nan);
+ TESTb(pow, -0.5, 1.0, -0.5);
+ TESTb(pow, -0.5, inf, 0.);
+ TESTb(pow, -0.5, nan, nan);
+
+ TESTb(pow, -0.0, -inf, inf);
+ TESTb(pow, -0.0, -1.0, -inf);
+ TESTb(pow, -0.0, -1.5, inf);
+ TESTb(pow, -0.0, -2.0, inf);
+ TESTb(pow, -0.0, -0.0, 1.0);
+ TESTb(pow, -0.0, 0.0, 1.0);
+ TESTb(pow, -0.0, 2.0, 0.);
+ TESTb(pow, -0.0, 1.0, -0.);
+ TESTb(pow, -0.0, 1.5, 0.);
+ TESTb(pow, -0.0, inf, 0.);
+ TESTb(pow, -0.0, nan, nan);
+
+ TESTb(pow, 0.0, -inf, inf);
+ TESTb(pow, 0.0, -1.0, inf);
+ TESTb(pow, 0.0, -1.5, inf);
+ TESTb(pow, 0.0, -2.0, inf);
+ TESTb(pow, 0.0, -0.0, 1.0);
+ TESTb(pow, 0.0, 0.0, 1.0);
+ TESTb(pow, 0.0, 2.0, 0.);
+ TESTb(pow, 0.0, 1.5, 0.);
+ TESTb(pow, 0.0, 1.0, 0.);
+ TESTb(pow, 0.0, inf, 0.);
+ TESTb(pow, 0.0, nan, nan);
+
+ TESTb(pow, 0.5, -inf, inf);
+ TESTb(pow, 0.5, -1.0, 2.);
+ TESTb(pow, 0.5, -1.5, 2.828424);
+ TESTb(pow, 0.5, -2.0, 4.);
+ TESTb(pow, 0.5, -0.0, 1.0);
+ TESTb(pow, 0.5, 0.0, 1.0);
+ TESTb(pow, 0.5, 2.0, .25);
+ TESTb(pow, 0.5, 1.5, 0.3535536);
+ TESTb(pow, 0.5, 1.0, 0.5);
+ TESTb(pow, 0.5, inf, 0.);
+ TESTb(pow, 0.5, nan, nan);
+
+ TESTb(pow, 1.0, -inf, 1.0);
+ TESTb(pow, 1.0, -1.0, 1.0);
+ TESTb(pow, 1.0, -1.5, 1.0);
+ TESTb(pow, 1.0, -2.0, 1.0);
+ TESTb(pow, 1.0, -0.0, 1.0);
+ TESTb(pow, 1.0, 0.0, 1.0);
+ TESTb(pow, 1.0, 2.0, 1.0);
+ TESTb(pow, 1.0, 1.5, 1.0);
+ TESTb(pow, 1.0, 1.0, 1.0);
+ TESTb(pow, 1.0, inf, 1.0);
+ TESTb(pow, 1.0, nan, 1.0);
+
+ TESTb(pow, 2.0, -inf, 0.);
+ TESTb(pow, 2.0, -1.0, 0.5);
+ TESTb(pow, 2.0, -1.5, 0.3535536);
+ TESTb(pow, 2.0, -2.0, 0.25);
+ TESTb(pow, 2.0, -0.0, 1.0);
+ TESTb(pow, 2.0, 0.0, 1.0);
+ TESTb(pow, 2.0, 2.0, 4.0);
+ TESTb(pow, 2.0, 1.5, 2.828424);
+ TESTb(pow, 2.0, 1.0, 2.0);
+ TESTb(pow, 2.0, inf, inf);
+ TESTb(pow, 2.0, nan, nan);
+
+ TESTb(pow, 5.0, -inf, 0.);
+ TESTb(pow, 5.0, -1.0, .2);
+ TESTb(pow, 5.0, -1.5, .08944272);
+ TESTb(pow, 5.0, -2.0, 0.04);
+ TESTb(pow, 5.0, -0.0, 1.0);
+ TESTb(pow, 5.0, 0.0, 1.0);
+ TESTb(pow, 5.0, 2.0, 25.0);
+ TESTb(pow, 5.0, 1.5, 11.18035);
+ TESTb(pow, 5.0, 1.0, 5.0);
+ TESTb(pow, 5.0, inf, inf);
+ TESTb(pow, 5.0, nan, nan);
+
+// TESTb(pow, inf, -inf, 0.);
+ TESTb(pow, inf, -1.0, 0.);
+// TESTb(pow, inf, -1.5, 0.);
+ TESTb(pow, inf, -2.0, 0.);
+ TESTb(pow, inf, -0.0, 1.0);
+ TESTb(pow, inf, 0.0, 1.0);
+ TESTb(pow, inf, 2.0, inf);
+// TESTb(pow, inf, 1.5, inf);
+ TESTb(pow, inf, 1.0, inf);
+// TESTb(pow, inf, inf, inf);
+// TESTb(pow, inf, nan, nan);
+
+// TESTb(pow, nan, -inf, nan);
+ TESTb(pow, nan, -1.0, nan);
+ TESTb(pow, nan, -2.0, nan);
+ TESTb(pow, nan, -0.0, 1.0);
+ TESTb(pow, nan, 0.0, 1.0);
+ TESTb(pow, nan, 2.0, nan);
+ TESTb(pow, nan, 1.0, nan);
+// TESTb(pow, nan, inf, nan);
+// TESTb(pow, nan, nan, nan);
+
+ printf("%d tests, %d failed results, %d failed errno\n", total_tests,
+ total_dec_fail, total_errno_fail);
+}
diff --git a/libc/dfp/test/test_printf.c b/libc/dfp/test/test_printf.c
new file mode 100644
index 000000000..6999d4c86
--- /dev/null
+++ b/libc/dfp/test/test_printf.c
@@ -0,0 +1,259 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+
+int main() {
+
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+ _Decimal128 e128;
+ _Decimal128 f128;
+ float f32;
+
+ d32 = 349.23456923482E27DF;
+ printf("349.23456923482E27DF\n");
+ printf("_Decimal32 Scientific: %Hf\n", d32);
+ printf("_Decimal32 Engineering: %He\n", d32);
+ printf("\n");
+
+ d32 = 349E27DF;
+ printf("349E27DF\n");
+ printf("_Decimal32 Scientific: %Hf\n", d32);
+ printf("_Decimal32 Engineering: %He\n", d32);
+ printf("\n");
+
+ d64 = 349.1231115DD;
+ printf("349.1231115DD\n");
+ printf("_Decimal64 Scientific: %Df\n", d64);
+ printf("_Decimal64 Enginerring: %De\n", d64);
+ printf("_Decimal64 with format flags:\n");
+ printf(" %%.3Df: '%.3Df'\n", d64);
+ printf(" %%12.3Df: '%12.3Df'\n", d64);
+ printf(" %%-12.3Df: '%-12.3Df'\n", d64);
+ printf("\n");
+
+ d128 = 1.2315DL;
+ printf("1.2315DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf("_Decimal128 Engineering: %DDe\n", d128);
+ printf("_Decimal128 with format flags:\n");
+ printf(" %%.3DDf: '%.3DDf'\n", d128);
+ printf(" %%12.3DDf: '%12.3DDf'\n", d128);
+ printf(" %%-12.3DDf: '%-12.3DDf'\n", d128);
+ printf("\n");
+
+ d128 = 231.2315DL;
+ printf("231.2315DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf("_Decimal128 Engineering: %DDe\n", d128);
+ printf("_Decimal128 with format flags:\n");
+ printf(" %%.3DDf: '%.3DDf'\n", d128);
+ printf(" %%12.3DDf: '%12.3DDf'\n", d128);
+ printf(" %%-12.3DDf: '%-12.3DDf'\n", d128);
+ printf("\n");
+
+ d128 = 0.12315DL;
+ printf("0.12315DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf("_Decimal128 Engineering: %DDe\n", d128);
+ printf("_Decimal128 with format flags:\n");
+ printf(" %%.4DDf: '%.4DDf'\n", d128);
+ printf(" %%12.4DDf: '%12.4DDf'\n", d128);
+ printf(" %%-12.4DDf: '%-12.4DDf'\n", d128);
+ printf("\n");
+
+ d128 = -0.12315DL;
+ printf("-0.12315DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf("_Decimal128 Engineering: %DDe\n", d128);
+ printf("_Decimal128 with format flags:\n");
+ printf(" %%.4DDf: '%.4DDf'\n", d128);
+ printf(" %%12.4DDf: '%12.4DDf'\n", d128);
+ printf(" %%-12.4DDf: '%-12.4DDf'\n", d128);
+ printf("\n");
+
+
+ d128 = 0.012315DL;
+ printf("0.012315DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf("_Decimal128 Engineering: %DDe\n", d128);
+ printf("_Decimal128 with format flags:\n");
+ printf(" %%.3DDf: '%.3DDf'\n", d128);
+ printf(" %%.4DDf: '%.4DDf'\n", d128);
+ printf(" %%.5DDf: '%.5DDf'\n", d128);
+ printf(" %%12.5DDf: '%12.5DDf'\n", d128);
+ printf(" %%-12.5DDf: '%-12.5DDf'\n", d128);
+ printf(" %%-12DDf: '%-12DDf'\n", d128);
+
+ d128 = 0.012315E7DL;
+ printf("0.012315E7DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf("_Decimal128 Engineering: %DDe\n", d128);
+ printf("_Decimal128 with format flags:\n");
+ printf(" %%.3DDf: '%.3DDf'\n", d128);
+ printf(" %%.4DDf: '%.4DDf'\n", d128);
+ printf(" %%.5DDf: '%.5DDf'\n", d128);
+ printf(" %%13.5DDf: '%13.5DDf'\n", d128);
+ printf(" %%-13.5DDf: '%-13.5DDf'\n", d128);
+ printf(" %%-13DDf: '%-13DDf'\n", d128);
+
+ d128 = -0.012315E7DL;
+ printf("-0.012315E7DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.3DDf: '%.3DDf'\n", d128);
+ printf(" %%.4DDf: '%.4DDf'\n", d128);
+ printf(" %%.5DDf: '%.5DDf'\n", d128);
+
+ d128 = -0.012315E-7DL;
+ printf("-0.012315E-7DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+
+ d128 = 1231.5E27DL;
+ printf("1231.5E27DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+
+ d128 = 1231.5E26DL;
+ printf("1231.5E26DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+
+ d128 = 12.365DL;
+ printf("12.365DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+
+ d128 = -12.365DL;
+ printf("-12.365DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+
+ d128 = -12.375DL;
+ printf("-12.375DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+
+ d128 = 12.375DL;
+ printf("12.375DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+
+ d128 = DEC_NAN;
+ printf("DEC_NAN\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+ printf(" %%12.3DDf: '%12.3DDf'\n", d128);
+ printf(" %%-12.3DDf: '%-12.3DDf'\n", d128);
+
+ d128 = DEC_INFINITY;
+ printf("INF\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+ printf(" %%12.3DDf: '%12.3DDf'\n", d128);
+ printf(" %%-12.3DDf: '%-12.3DDf'\n", d128);
+
+ d128 = -DEC_INFINITY;
+ printf("-INF\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%.2DDf: '%.2DDf'\n", d128);
+ printf(" %%.8DDf: '%.8DDf'\n", d128);
+ printf(" %%.9DDf: '%.9DDf'\n", d128);
+ printf(" %%.10DDf: '%.10DDf'\n", d128);
+ printf(" %%12.3DDf: '%12.3DDf'\n", d128);
+ printf(" %%-12.3DDf: '%-12.3DDf'\n", d128);
+
+
+ d128 = 99999999999999.99999999999DL;
+ printf("99999999999999.99999999999DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%30.1DDf: '%30.1DDf'\n", d128);
+ printf(" %%30.2DDf: '%30.2DDf'\n", d128);
+ printf(" %%30.3DDf: '%30.3DDf'\n", d128);
+ printf(" %%30.4DDf: '%30.4DDf'\n", d128);
+ printf(" %%30.5DDf: '%30.5DDf'\n", d128);
+ printf(" %%30.6DDf: '%30.6DDf'\n", d128);
+ printf(" %%30.7DDf: '%30.7DDf'\n", d128);
+ printf(" %%30.8DDf: '%30.8DDf'\n", d128);
+ printf(" %%30.9DDf: '%30.9DDf'\n", d128);
+ printf(" %%30.10DDf: '%30.10DDf'\n", d128);
+ printf(" %%30.11DDf: '%30.11DDf'\n", d128);
+ printf(" %%30.12DDf: '%30.12DDf'\n", d128);
+ printf(" %%30.13DDf: '%30.13DDf'\n", d128);
+
+ d128 = 9.999DL;
+ printf("9.999DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%10.1DDf: '%10.1DDf'\n", d128);
+ printf(" %%10.2DDf: '%10.2DDf'\n", d128);
+ printf(" %%10.3DDf: '%10.3DDf'\n", d128);
+ printf(" %%10.4DDf: '%10.4DDf'\n", d128);
+ printf(" %%10.5DDf: '%10.5DDf'\n", d128);
+
+ d128 = 99999999999999.99999999999999999999DL;
+ printf("99999999999999.99999999999999999999DL\n");
+ printf("_Decimal128 Scientific: %DDf\n", d128);
+ printf(" %%30.1DDf: '%30.1DDf'\n", d128);
+ printf(" %%30.2DDf: '%30.2DDf'\n", d128);
+ printf(" %%30.3DDf: '%30.3DDf'\n", d128);
+ printf(" %%30.4DDf: '%30.4DDf'\n", d128);
+ printf(" %%30.5DDf: '%30.5DDf'\n", d128);
+ printf(" %%30.6DDf: '%30.6DDf'\n", d128);
+ printf(" %%30.7DDf: '%30.7DDf'\n", d128);
+ printf(" %%30.8DDf: '%30.8DDf'\n", d128);
+ printf(" %%30.9DDf: '%30.9DDf'\n", d128);
+ printf(" %%30.10DDf: '%30.10DDf'\n", d128);
+ printf(" %%30.11DDf: '%30.11DDf'\n", d128);
+ printf(" %%36.20DDf: '%36.20DDf'\n", d128);
+ printf(" %%36.21DDf: '%36.21DDf'\n", d128);
+
+ d32 = 999.9999DF;
+ printf("999.999999DF\n");
+ printf("_Decimal32 Scientific: %Hf\n", d32);
+ printf("_Decimal32 Engineering: %He\n", d32);
+ printf(" %%16.3Hf: '%16.3Hf'\n", d32);
+ printf(" %%16.4Hf: '%16.4Hf'\n", d32);
+ printf(" %%16.5Hf: '%16.5Hf'\n", d32);
+ printf("\n");
+
+ d32 = 999.999999DF;
+ printf("999.999999DF\n");
+ printf("_Decimal32 Scientific: %Hf\n", d32);
+ printf("_Decimal32 Engineering: %He\n", d32);
+ printf(" %%16.3Hf: '%16.3Hf'\n", d32);
+ printf("\n");
+
+ return -1;
+}
diff --git a/libc/dfp/test/test_printf2.c b/libc/dfp/test/test_printf2.c
new file mode 100644
index 000000000..6c1fa6e39
--- /dev/null
+++ b/libc/dfp/test/test_printf2.c
@@ -0,0 +1,104 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+
+int main() {
+
+ float f32;
+ double f64;
+ printf("\nfloat printf as float\n");
+ f32 = 1.245;
+ printf("'%7.2f' =(%%7.2f)%f\n",f32,f32);
+ printf("'%-7.2f' = (%%-7.2f)%f\n",f32,f32);
+ printf("'%.2f' = (%%.2f)%f\n",f32,f32);
+ printf("'%-.2f' = (%%-.2f)%f\n",f32,f32);
+ printf("'%6f' = (%%6f)%f\n",f32,f32);
+ printf("'%6.f' = (%%6.f)%f\n",f32,f32);
+ printf("'%.f' = (%%.f)%f\n",f32,f32);
+ printf("'%f' = (%%f)%f\n",f32,f32);
+ f32 = 1.245435;
+ printf("'%6f' = (%%6f)%f\n",f32,f32);
+ printf("'%.5f' = (%%.5f)%f\n",f32,f32);
+ printf("'%-.5f' = (%%-.5f)%f\n",f32,f32);
+ printf("'%-6.5f' = (%%-6.5f)%f\n",f32,f32);
+ printf("'%-.4f' = (%%-.4f)%f\n",f32,f32);
+ printf("'%-.5f' = (%%-.5f)%f\n",f32,f32);
+ printf("'%-.6f' = (%%-.6f)%f\n",f32,f32);
+ printf("'%-.7f' = (%%-.7f)%f\n",f32,f32);
+ printf("'%-f' = (%%-f)%f\n",f32,f32);
+ printf("'%f' = (%%f)%f\n",f32,f32);
+ printf("'%10f' = (%%10f)%f\n",f32,f32);
+ printf("'%-10f' = (%%-10f)%f\n",f32,f32);
+ f32 = 1.245445;
+ printf("'%-.4f' = (%%-.4f)%f\n",f32,f32);
+ printf("'%-.5f' = (%%-.5f)%f\n",f32,f32);
+ printf("'%-.6f' = (%%-.6f)%f\n",f32,f32);
+ printf("'%-.6f' = (%%-.7f)%f\n",f32,f32);
+
+ printf("\nDouble printf as float\n");
+ f64 = 1.245;
+ printf("'%7.2f' =(%%7.2f)%f\n",f64,f64);
+ printf("'%-7.2f' = (%%-7.2f)%f\n",f64,f64);
+ printf("'%.2f' = (%%.2f)%f\n",f64,f64);
+ printf("'%-.2f' = (%%-.2f)%f\n",f64,f64);
+ printf("'%6f' = (%%6f)%f\n",f64,f64);
+ printf("'%6.f' = (%%6.f)%f\n",f64,f64);
+ printf("'%.f' = (%%.f)%f\n",f64,f64);
+ printf("'%f' = (%%f)%f\n",f64,f64);
+ f64 = 1.245435;
+ printf("'%6f' = (%%6f)%f\n",f64,f64);
+ printf("'%.5f' = (%%.5f)%f\n",f64,f64);
+ printf("'%-.5f' = (%%-.5f)%f\n",f64,f64);
+ printf("'%-6.5f' = (%%-6.5f)%f\n",f64,f64);
+ printf("'%-.4f' = (%%-.4f)%f\n",f64,f64);
+ printf("'%-.5f' = (%%-.5f)%f\n",f64,f64);
+ printf("'%-.6f' = (%%-.6f)%f\n",f64,f64);
+ printf("'%-.7f' = (%%-.7f)%f\n",f64,f64);
+ printf("'%-f' = (%%-f)%f\n",f64,f64);
+ printf("'%f' = (%%f)%f\n",f64,f64);
+ printf("'%10f' = (%%10f)%f\n",f64,f64);
+ printf("'%-10f' = (%%-10f)%f\n",f64,f64);
+ f64 = 1.245445;
+ printf("'%-.4f' = (%%-.4f)%f\n",f64,f64);
+ printf("'%-.5f' = (%%-.5f)%f\n",f64,f64);
+ printf("'%-.6f' = (%%-.6f)%f\n",f64,f64);
+ printf("'%-.6f' = (%%-.7f)%f\n",f64,f64);
+
+ printf("\nDouble printf as double\n");
+ f64 = 1.245;
+ printf("'%7.2lf' =(%%7.2lf)%lf)\n",f64,f64);
+ printf("'%-7.2lf' = (%%-7.2lf)%lf)\n",f64,f64);
+ printf("'%.2lf' = (%%.2lf)%lf\n)",f64,f64);
+ printf("'%-.2lf' = (%%-.2lf)%lf)\n",f64,f64);
+ printf("'%6lf' = (%%6lf)%lf)\n",f64,f64);
+ printf("'%6.lf' = (%%6.lf)%lf)\n",f64,f64);
+ printf("'%.lf' = (%%.lf)%lf)\n",f64,f64);
+ printf("'%lf' = (%%lf)%lf)\n",f64,f64);
+ f64 = 1.245435;
+ printf("'%6lf' = (%%6lf)%lf)\n",f64,f64);
+ printf("'%.5lf' = (%%.5lf)%lf)\n",f64,f64);
+ printf("'%-.5lf' = (%%-.5lf)%lf)\n",f64,f64);
+ printf("'%-6.5lf' = (%%-6.5lf)%lf)\n",f64,f64);
+ printf("'%-.4lf' = (%%-.4lf)%lf)\n",f64,f64);
+ printf("'%-.5lf' = (%%-.5lf)%lf)\n",f64,f64);
+ printf("'%-.6lf' = (%%-.6lf)%lf)\n",f64,f64);
+ printf("'%-.7lf' = (%%-.7lf)%lf)\n",f64,f64);
+ printf("'%-lf' = (%%-lf)%lf)\n",f64,f64);
+ printf("'%lf' = (%%lf)%lf)\n",f64,f64);
+ printf("'%10lf' = (%%10lf)%lf)\n",f64,f64);
+ printf("'%-10lf' = (%%-10lf)%lf)\n",f64,f64);
+ f64 = 1.245445;
+ printf("'%-.4lf' = (%%-.4lf)%lf)\n",f64,f64);
+ printf("'%-.5lf' = (%%-.5lf)%lf)\n",f64,f64);
+ printf("'%-.6lf' = (%%-.6lf)%lf)\n",f64,f64);
+ printf("'%-.6lf' = (%%-.7lf)%lf)\n",f64,f64);
+ f64 = 120000000.00E10;
+ printf("'%-25le'\n",f64);
+
+
+ return -1;
+}
diff --git a/libc/dfp/test/test_quantize.c b/libc/dfp/test/test_quantize.c
new file mode 100644
index 000000000..07bdaff34
--- /dev/null
+++ b/libc/dfp/test/test_quantize.c
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <math.h>
+
+#ifndef FUNCTION
+#define FUNCTION quantize
+#endif
+
+#define FUNCTION_CALL(type) PASTE(FUNCTION,type)
+#define PASTE(x,y) PASTE1(x,y)
+#define PASTE1(x,y) x##y
+
+int main() {
+ _Decimal32 ad32;
+ _Decimal32 bd32;
+ _Decimal32 cd32;
+
+ _Decimal64 ad64;
+ _Decimal64 bd64;
+ _Decimal64 cd64;
+
+ _Decimal128 ad128;
+ _Decimal128 bd128;
+ _Decimal128 cd128;
+
+ ad32 = 123.456DF;
+ bd32 = 0.12DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = quantized32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad32 = -1.95DF;
+ bd32 = -190.55DF;
+ cd32 = FUNCTION_CALL(d32)(ad32,bd32);
+ printf("%Hf = quantized32(%Hf,%Hf)\n", cd32, ad32, bd32);
+
+ ad64 = 123.456DD;
+ bd64 = 0.12DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,bd64);
+ printf("%Df = quantized64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad64 = -1.95DD;
+ bd64 = -190.55DD;
+ cd64 = FUNCTION_CALL(d64)(ad64,bd64);
+ printf("%Df = quantized64(%Df,%Df)\n", cd64, ad64, bd64);
+
+ ad128 = 123.456DL;
+ bd128 = 0.12DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,bd128);
+ printf("%DDf = quantized128(%DDf,%DDf)\n", cd128, ad128, bd128);
+
+ ad128 = -1.95DL;
+ bd128 = -190.55DL;
+ cd128 = FUNCTION_CALL(d128)(ad128,bd128);
+ printf("%DDf = quantized128(%DDf,%DDf)\n", cd128, ad128, bd128);
+
+
+}
diff --git a/libc/dfp/test/test_round.c b/libc/dfp/test/test_round.c
new file mode 100644
index 000000000..9db3c90c3
--- /dev/null
+++ b/libc/dfp/test/test_round.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdint.h>
+
+#define __STDC_WANT_DEC_FP__ 1
+#include <fenv.h>
+
+static void print_roundingmode(int rounding_mode) {
+ switch(rounding_mode)
+ {
+ case 0:
+ printf ("[%d] FE_DEC_TONEAREST(DEFAULT) = fe_dec_getround()\n", rounding_mode);
+ break;
+ case 1:
+ printf ("[%d] FE_DEC_TOWARDZERO = fe_dec_getround()\n", rounding_mode);
+ break;
+ case 2:
+ printf ("[%d] FE_DEC_UPWARD = fe_dec_getround()\n", rounding_mode);
+ break;
+ case 3:
+ printf ("[%d] FE_DEC_DOWNWARD = fe_dec_getround()\n", rounding_mode);
+ break;
+ case 4:
+ printf ("[%d] FE_DEC_TONEARESTFROMZERO = fe_dec_getround()\n", rounding_mode);
+ break;
+ case 5:
+ printf ("[%d] Round to nearest, ties toward zero = fe_dec_getround()\n", rounding_mode);
+ break;
+ case 6:
+ printf ("[%d] Round away from zero = fe_dec_getround()\n", rounding_mode);
+ break;
+ case 7:
+ printf ("[%d] Round for prepare for shorter precision = fe_dec_getround()\n", rounding_mode);
+ break;
+ default:
+ printf ("[%d] UNKNOWN = fe_dec_getround()\n",rounding_mode);
+ break;
+ }
+}
+
+int main() {
+ int round, result = -1;
+ printf ("Query default rounding mode:\n", round);
+ print_roundingmode(fe_dec_getround());
+
+ result = fe_dec_setround(FE_DEC_TOWARDZERO);
+ printf ("%d = fe_dec_setround(FE_DEC_TOWARDZERO);\n", result);
+ print_roundingmode(fe_dec_getround());
+
+ result = fe_dec_setround(FE_DEC_TONEAREST);
+ printf ("%d = fe_dec_setround(FE_DEC_TONEAREST);\n", result);
+ print_roundingmode(fe_dec_getround());
+
+ result = fe_dec_setround(FE_DEC_DOWNWARD);
+ printf ("%d = fe_dec_setround(FE_DEC_DOWNWARD);\n", result);
+ print_roundingmode(fe_dec_getround());
+
+ result = fe_dec_setround(FE_DEC_UPWARD);
+ printf ("%d = fe_dec_setround(FE_DEC_UPWARD);\n", result);
+ print_roundingmode(fe_dec_getround());
+
+ result = fe_dec_setround(FE_DEC_TONEARESTFROMZERO);
+ printf ("%d = fe_dec_setround(FE_DEC_TONEARESTFROMZERO);\n", result);
+ print_roundingmode(fe_dec_getround());
+
+ result = fe_dec_setround(5);
+ printf ("%d = fe_dec_setround(5);\n", result);
+ print_roundingmode(fe_dec_getround());
+
+ result = fe_dec_setround(6);
+ printf ("%d = fe_dec_setround(6);\n", result);
+ print_roundingmode(fe_dec_getround());
+
+ result = fe_dec_setround(7);
+ printf ("%d = fe_dec_setround(7);\n", result);
+ print_roundingmode(fe_dec_getround());
+}
diff --git a/libc/dfp/test/test_scalb.c b/libc/dfp/test/test_scalb.c
new file mode 100644
index 000000000..c0c655ca3
--- /dev/null
+++ b/libc/dfp/test/test_scalb.c
@@ -0,0 +1,25 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+
+int main() {
+
+// TEST_f(scalbnd64, 500.0DD,%Df,5.0DD,2);
+
+// TEST_f_f_i_all(scalbn,500.0,5.0,2);
+ TEST_f_f_i_all(scalbn,100000.0,100.0,3);
+// TEST_f_f_i_all(scalbn,0.003,3.0,-3);
+/*
+ TEST_f_f_i_all(scalbn,100000.0,100.0,3);
+ TEST_f_f_i_all(scalbn,0.003,3.0,-3);
+
+
+ do { do { typeof(500.0DF) res = scalbnd32 (5.0DF, 2); if(res == 500.0DF || ((!((_Decimal128)(__typeof__(500.0DF))1.E-50DL == 1.E-50DL) ? ((sizeof (500.0DF) == sizeof (float) ? __isnanf (500.0DF) : sizeof (500.0DF) == sizeof (double) ? __isnan (500.0DF) : __isnanl (500.0DF))) : (sizeof (500.0DF) == sizeof (_Decimal128) ? __isnand128(500.0DF) : (sizeof (500.0DF) == sizeof (_Decimal64) ? __isnand64(500.0DF) : __isnand32(500.0DF))) ) && (!((_Decimal128)(__typeof__(res))1.E-50DL == 1.E-50DL) ? ((sizeof (res) == sizeof (float) ? __isnanf (res) : sizeof (res) == sizeof (double) ? __isnan (res) : __isnanl (res))) : (sizeof (res) == sizeof (_Decimal128) ? __isnand128(res) : (sizeof (res) == sizeof (_Decimal64) ? __isnand64(res) : __isnand32(res))) ))) printf("Success: ""%Hf"" = ""scalbnd32"" (""5.0DF, 2"")\n",res); else printf("Error: ""%Hf"" = ""scalbnd32"" (""5.0DF, 2"") : should be ""500.0DF""\n", res); } while(0);
+ do { typeof(500.0DD) res = scalbnd64 (5.0DD, 2); if(res == 500.0DD || ((!((_Decimal128)(__typeof__(500.0DD))1.E-50DL == 1.E-50DL) ? ((sizeof (500.0DD) == sizeof (float) ? __isnanf (500.0DD) : sizeof (500.0DD) == sizeof (double) ? __isnan (500.0DD) : __isnanl (500.0DD))) : (sizeof (500.0DD) == sizeof (_Decimal128) ? __isnand128(500.0DD) : (sizeof (500.0DD) == sizeof (_Decimal64) ? __isnand64(500.0DD) : __isnand32(500.0DD))) ) && (!((_Decimal128)(__typeof__(res))1.E-50DL == 1.E-50DL) ? ((sizeof (res) == sizeof (float) ? __isnanf (res) : sizeof (res) == sizeof (double) ? __isnan (res) : __isnanl (res))) : (sizeof (res) == sizeof (_Decimal128) ? __isnand128(res) : (sizeof (res) == sizeof (_Decimal64) ? __isnand64(res) : __isnand32(res))) ))) printf("Success: ""%Df"" = ""scalbnd64"" (""5.0DD, 2"")\n",res); else printf("Error: ""%Df"" = ""scalbnd64"" (""5.0DD, 2"") : should be ""500.0DD""\n", res); } while(0); } while(0);
+ */
+}
+
diff --git a/libc/dfp/test/test_scanf.c b/libc/dfp/test/test_scanf.c
new file mode 100644
index 000000000..73a1e96a5
--- /dev/null
+++ b/libc/dfp/test/test_scanf.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdint.h>
+
+int main() {
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+
+ char *testcases[] = { "12.04","19","19E2","-0.0001","-5","NaN", "INF"};
+ int i,numCases=7;
+
+ for(i=0; i< numCases; i++) {
+ printf("in: %s\n",testcases[i]);
+ sscanf(testcases[i],"%Hf", &d32);
+ sscanf(testcases[i],"%Df", &d64);
+ sscanf(testcases[i],"%DDf", &d128);
+ printf("out: %Hf, %Df, %DDf\n",d32,d64,d128);
+ }
+/* sscanf("12.04e3", "%Hf", &d32);
+ sscanf("12.04", "%Df", &d64);
+ sscanf("12.04", "%DDf", &d128);
+
+ printf("out: %Hf\n",d32);
+ printf("out: %Df\n",d64);
+ printf("out: %DDf\n",d128); */
+
+/* printf("%Hf\n", d32);
+ printf("%HE\n", d32); */
+
+/* printf("The hex value 0x%.8x%.8x = %Df in _Decimal64.\n", d64[0],
+ * d64[1], d64); */
+
+/* printf("%Df\n", d64);
+ printf("%DE\n", d64); */
+
+/* printf("The hex value 0x%.8x%.8x%.8x%.8x = %DDf in _Decimal128.\n",
+ * d128[0], d128[1], d128[2], d128[3], d128); */
+/* printf("%DDf\n", d128); */
+/* printf("%DDE\n", d128); */
+
+}
diff --git a/libc/dfp/test/test_set1a.c b/libc/dfp/test/test_set1a.c
new file mode 100644
index 000000000..b3d5b6187
--- /dev/null
+++ b/libc/dfp/test/test_set1a.c
@@ -0,0 +1,80 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+
+//Functions that need testing in set1a
+//_Decimal nextafter (_Decimal, _Decimal)
+//_Decimal nexttoward (_Decimal, _Decimal128)
+//_Decimal scalbn (_Decimal, int)
+//_Decimal scalbln (_Decimal, long)
+//_Decimal logb (_Decimal)
+//_Decimal ldexp (_Decimal, int)
+//int ilogb (_Decimal, _Decimal)
+//_Bool samequantum (_Decimal, _Decimal)
+//the various fe_set/get functions also need testing, but seperately
+
+int main() {
+//_Decimal nextafter (_Decimal, _Decimal)
+ TEST_f(nextafterd32,-0.6999999DF,%Hf,-0.7DF,0.3DF);
+ TEST_f(nextafterd32, 0.6999999DF,%Hf,0.7DF,0.3DF);
+ TEST_f(nextafterd32, 6.999999DF,%Hf,7.0DF,3.0DF);
+ TEST_f(nextafterd32, 69.99999DF,%Hf,70.0DF,3.0DF);
+ /* Doing this with DEC_MIN actually pushes it toward DENORMAL, not
+ * -DEC_INFINITY. */
+ /* TEST_f_2_all(nextafter,-DEC_INFINITY,DEC_MIN,-DEC_INFINITY); */
+ TEST_f_2_all(nextafter,-DEC_INFINITY,-DEC_MAX,-DEC_INFINITY);
+ TEST_f_2_all(nextafter,DEC_INFINITY,DEC_MAX,DEC_INFINITY);
+
+//_Decimal nexttoward (_Decimal, _Decimal128)
+ TEST_f(nexttowardd32,-0.6999999DF,%Hf,-0.7DF,0.3DL);
+ TEST_f(nexttowardd32,0.6999999DF,%Hf,0.7DF,0.3DL);
+ TEST_f(nexttowardd32,6.999999DF,%Hf,7.0DF,3.0DL);
+ TEST_f(nexttowardd32,69.99999DF,%Hf,70.0DF,3.0DL);
+ /* Doing this with DEC_MIN actually pushes it toward DENORMAL, not
+ * -DEC_INFINITY. */
+ /* TEST_f_2_all(nexttoward,-DEC_INFINITY,DEC_MIN,-DEC_INFINITY); */
+ TEST_f_2_all(nexttoward,-DEC_INFINITY,-DEC_MAX,-DEC_INFINITY);
+ TEST_f_2_all(nexttoward,DEC_INFINITY,DEC_MAX,DEC_INFINITY);
+
+//_Decimal scalbn (_Decimal, int)
+ TEST_f_f_i_all(scalbn,500.0,5.0,2);
+ TEST_f_f_i_all(scalbn,100000.0,100.0,3);
+ TEST_f_f_i_all(scalbn,0.003,3.0,-3);
+
+//_Decimal scalbln (_Decimal, long)
+ TEST_f_f_i_all(scalbln,500.0,5.0,2);
+ TEST_f_f_i_all(scalbln,100000.0,100.0,3);
+ TEST_f_f_i_all(scalbln,0.003,3.0,-3);
+
+//_Decimal logb (_Decimal)
+ TEST_f_f_all(logb, 3.0, 1024.0);
+ TEST_f_f_all(logb, 4.0, 10024.0);
+ TEST_f_f_all(logb,-3.0, 0.0023);
+ TEST_f_f_all(logb, 5.0, 302234.0);
+
+//int ilogb (_Decimal)
+ TEST_i_f_all(ilogb, 3, 1024.0);
+ TEST_i_f_all(ilogb, 4, 10024.0);
+ TEST_i_f_all(ilogb,-3, 0.0023);
+ TEST_i_f_all(ilogb, 5, 302234.0);
+
+//_Decimal ldexp (_Decimal, int)
+//
+ TEST_f_f_i_all(ldexp, 0.0, 0.0, 4);
+ TEST_f_f_i_all(ldexp, 80000.0, 0.8, 4);
+ TEST_f_f_i_all(ldexp, -854375.0, -0.854375, 5);
+
+//_Bool samequantum (_Decimal, _Decimal)
+ TEST_i_2_all(samequantum, true, 0.3, 0.5);
+ TEST_i_2_all(samequantum, false, 0.03, 0.5);
+ TEST_i_2_all(samequantum, false, 0.3, 2.5);
+ TEST_i_2_all(samequantum, false, 30000.2, 0.5);
+ TEST_i_2_all(samequantum, false, DEC_NAN, 5.3);
+ TEST_i_2_all(samequantum, false, 0.2, DEC_INFINITY);
+ TEST_i_2_all(samequantum, true, DEC_NAN, DEC_NAN);
+ TEST_i_2_all(samequantum, true, DEC_INFINITY, DEC_INFINITY);
+}
diff --git a/libc/dfp/test/test_set2.c b/libc/dfp/test/test_set2.c
new file mode 100644
index 000000000..731eaca87
--- /dev/null
+++ b/libc/dfp/test/test_set2.c
@@ -0,0 +1,94 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+
+_Decimal32 tgammad32 (_Decimal32);
+_Decimal64 tgammad64 (_Decimal64);
+_Decimal128 tgammad128 (_Decimal128);
+//Functions that need testing in set2 (does not include hyperbolic
+// or arctrig functions)
+//_Decimal erf (_Decimal)
+//_Decimal erfc (_Decimal)
+//_Decimal lgamma (_Decimal)
+//_Decimal tgamma (_Decimal)
+//_Decimal remainder (_Decimal, _Decimal)
+
+int main() {
+//_Decimal erf (_Decimal)
+ TEST_f_1_all(erf, 0.0, 0.0);
+ TEST_f_1_all(erf, -0.0, -0.0);
+ TEST_f_1_all(erf, 1.0, DEC_INFINITY);
+ TEST_f_1_all(erf, -1.0, -DEC_INFINITY);
+ TEST_f_1_all(erf, DEC_NAN, DEC_NAN);
+ TEST_f_1_all(erf, 0.140316204801333817393029446521623398, 0.125);
+ TEST_f_1_all(erf, 0.711155633653515131598937834591410777, 0.75);
+ TEST_f_1_all(erf, 0.922900128256458230136523481197281140, 1.25);
+ TEST_f_1_all(erf, 0.995322265018952734162069256367252929, 2.0);
+ TEST_f_1_all(erf, 0.999999994576599200434933994687765914, 4.125);
+ TEST_f_1_all(erf, 1.0, 27.0);
+
+//_Decimal erfc (_Decimal)
+ TEST_f_1_all (erfc, 0.0, DEC_INFINITY);
+ TEST_f_1_all (erfc, 2.0, -DEC_INFINITY);
+ TEST_f_1_all (erfc, 1.0, 0.0);
+ TEST_f_1_all (erfc, 1.0, -0.0);
+ TEST_f_1_all (erfc, DEC_NAN, DEC_NAN);
+ TEST_f_1_all (erfc, 0.859683795198666182606970553478376602, 0.125);
+ TEST_f_1_all (erfc, 0.288844366346484868401062165408589223, 0.75);
+ TEST_f_1_all (erfc, 0.0770998717435417698634765188027188596, 1.25);
+ TEST_f_1_all (erfc, 0.00467773498104726583793074363274707139, 2.0);
+ TEST_f_1_all (erfc, 0.542340079956506600531223408575531062e-8, 4.125);
+// TEST_f (erfcd128, 0.523704892378925568501606768284954709e-318DL, %Hf, 27.0DL);
+
+//_Decimal lgamma (_Decimal)
+ TEST_f_1_all (lgamma, DEC_INFINITY, DEC_INFINITY);
+ TEST_f_1_all (lgamma, DEC_INFINITY, 0.0);
+ TEST_f_1_all (lgamma, DEC_NAN, DEC_NAN);
+ /* lgamma (x) == +inf plus divide by zero exception for integer x <=
+ * 0. */
+ TEST_f_1_all (lgamma, DEC_INFINITY, -3.0 );
+ TEST_f_1_all (lgamma, DEC_INFINITY, -DEC_INFINITY);
+/* Reminder: arguments are backwards on the below commented section
+ TEST_f_f1 (lgamma, 1, 0, 1);
+ TEST_f_f1 (lgamma, 3, M_LN2l, 1);
+ TEST_f_f1 (lgamma, 0.5, M_LOG_SQRT_PIl, 1);
+ TEST_f_f1 (lgamma, -0.5, M_LOG_2_SQRT_PIl, -1);
+ TEST_f_f1 (lgamma, 0.7L, 0.260867246531666514385732417016759578L,1);
+ TEST_f_f1 (lgamma, 1.2L,
+ -0.853740900033158497197028392998854470e-1L, 1);
+*/
+
+//_Decimal tgamma (_Decimal)
+TEST_f_1_all (tgamma, DEC_INFINITY, DEC_INFINITY);
+TEST_f_1_all (tgamma, DEC_INFINITY, 0.0);
+TEST_f_1_all (tgamma, -DEC_INFINITY, -0.0);
+/* tgamma (x) == NaN plus invalid exception for integer x <= 0. */
+TEST_f_1_all (tgamma, DEC_NAN, -2.0);
+TEST_f_1_all (tgamma, -DEC_INFINITY, -DEC_INFINITY);
+TEST_f_1_all (tgamma, DEC_NAN, DEC_NAN);
+
+//TEST_f_1_all (tgamma, 0.5, M_SQRT_PIl);
+//TEST_f_1_all (tgamma, -0.5, -M_2_SQRT_PIl);
+TEST_f_1_all (tgamma, 1.0, 1.0);
+TEST_f_1_all (tgamma, 6.0, 4.0);
+TEST_f_1_all (tgamma, 1.29805533264755778568117117915281162, 0.7);
+TEST_f_1_all (tgamma, 0.918168742399760610640951655185830401, 1.2);
+
+//_Decimal remainder (_Decimal, _Decimal)
+TEST_f_2_all (remainder, DEC_NAN, 1.0, 0.0);
+TEST_f_2_all (remainder, DEC_NAN, 1.0, -0.0);
+TEST_f_2_all (remainder, DEC_NAN, DEC_INFINITY, 1.0);
+TEST_f_2_all (remainder, DEC_NAN, -DEC_INFINITY, 1.0);
+TEST_f_2_all (remainder, DEC_NAN, DEC_NAN, DEC_NAN);
+TEST_f_2_all (remainder, -0.375, 1.625, 1.0);
+TEST_f_2_all (remainder, 0.375, -1.625, 1.0);
+TEST_f_2_all (remainder, -0.375, 1.625, -1.0);
+TEST_f_2_all (remainder, 0.375, -1.625, -1.0);
+TEST_f_2_all (remainder, 1.0, 5.0, 2.0);
+TEST_f_2_all (remainder, -1.0, 3.0, 2.0);
+
+}
diff --git a/libc/dfp/test/test_set2a.c b/libc/dfp/test/test_set2a.c
new file mode 100644
index 000000000..ed715d48f
--- /dev/null
+++ b/libc/dfp/test/test_set2a.c
@@ -0,0 +1,220 @@
+#define __STDC_WANT_DEC_FP__ 1
+#include <stdio.h>
+#include <stdint.h>
+
+#include "test_math.h"
+
+ _Decimal32 exp2d32 (_Decimal32);
+ _Decimal32 log2d32 (_Decimal32);
+ _Decimal64 exp2d64 (_Decimal64);
+ _Decimal64 log2d64 (_Decimal64);
+ _Decimal128 exp2d128 (_Decimal128);
+ _Decimal128 log2d128 (_Decimal128);
+ _Decimal32 remquod32 (_Decimal32,_Decimal32,int*);
+ _Decimal64 remquod64 (_Decimal64,_Decimal64,int*);
+ _Decimal128 remquod128 (_Decimal128,_Decimal128,int*);
+extern _Decimal32 fmad32 (_Decimal32,_Decimal32,_Decimal32);
+extern _Decimal64 fmad64 (_Decimal64,_Decimal64,_Decimal64);
+extern _Decimal128 fmad128 (_Decimal128,_Decimal128,_Decimal128);
+//Functions that need testing in set2 (does not include hyperbolic
+// or arctrig functions)
+// _Decimal exp2 (_Decimal)
+// _Decimal expm1 (_Decimal)
+// _Decimal log1p (_Decimal)
+// _Decimal log2 (_Decimal)
+// _Decimal remquo (_Decimal, _Decimal, *int)
+// _Decimal hypot (_Decimal, _Decimal)
+// _Decimal fmod (_Decimal, _Decimal)
+// _Decimal cbrt (_Decimal)
+// _Decimal fma (_Decimal, _Decimal, _Decimal)
+
+int main() {
+// _Decimal exp2 (_Decimal)
+ TEST_f_1_all (exp2, 1.0, 0.0);
+ TEST_f_1_all (exp2, 1.0, -0.0);
+ TEST_f_1_all (exp2, DEC_INFINITY, DEC_INFINITY);
+ TEST_f_1_all (exp2, 0.0, -DEC_INFINITY);
+ TEST_f_1_all (exp2, DEC_NAN, DEC_NAN);
+
+ TEST_f_1_all (exp2, 1024.0, 10.0);
+ TEST_f_1_all (exp2, 0.5, -1.0);
+ TEST_f_1_all (exp2, DEC_INFINITY, 1.0E6);
+ TEST_f_1_all (exp2, 0.0, -1.0E6);
+ TEST_f_1_all (exp2, 1.68179283050742908606225095246642979, 0.75);
+
+// _Decimal expm1 (_Decimal)
+ TEST_f_1_all (expm1, 0.0, 0.0);
+ TEST_f_1_all (expm1, -0.0, -0.0);
+ TEST_f_1_all (expm1, DEC_INFINITY, DEC_INFINITY);
+ TEST_f_1_all (expm1, -1.0, -DEC_INFINITY);
+ TEST_f_1_all (expm1, DEC_NAN, DEC_NAN);
+// TEST_f_1_all (expm1, M_Edl - 1.0DL, 1.0);
+ TEST_f_1_all (expm1, 1.11700001661267466854536981983709561, 0.75);
+
+// _Decimal log1p (_Decimal)
+ TEST_f_1_all (log1p, 0.0, 0.0);
+ TEST_f_1_all (log1p, -0.0, -0.0);
+ TEST_f_1_all (log1p, -DEC_INFINITY, -1.0);
+ TEST_f_1_all (log1p, DEC_NAN, -2.0);
+ TEST_f_1_all (log1p, DEC_INFINITY, DEC_INFINITY);
+ TEST_f_1_all (log1p, DEC_NAN, DEC_NAN);
+// TEST_f_1_all (log1p, 1, M_El - 1.0);
+ TEST_f_1_all (log1p, -0.287682072451780927439219005993827432, -0.25);
+ TEST_f_1_all (log1p, -2.07944154167983592825169636437452970, -0.875);
+
+// _Decimal log2 (_Decimal)
+ TEST_f_1_all (log2, -DEC_INFINITY, 0.0);
+ TEST_f_1_all (log2, -0.0, -DEC_INFINITY);
+ TEST_f_1_all (log2, 0.0, 1.0);
+ TEST_f_1_all (log2, DEC_NAN, -1.0);
+ TEST_f_1_all (log2, DEC_INFINITY, DEC_INFINITY);
+ TEST_f_1_all (log2, DEC_NAN, DEC_NAN);
+// TEST_f_1_all (log2, M_El, M_LOG2El);
+ TEST_f_1_all (log2, 1.0, 2.0);
+ TEST_f_1_all (log2, 4.0, 16.0);
+ TEST_f_1_all (log2, 8.0, 256.0);
+ TEST_f_1_all (log2, -0.415037499278843818546261056052183492, 0.75);
+/* Removed from the latest TR
+// _Decimal remquo (_Decimal, _Decimal, *int)
+// remquo needs it's own define to hanlde the odd int pointer
+#define TEST_remquo_noquo(res,x,y) \
+ do { int quo; \
+ TEST_f(remquod32,res##DF,%Hf,x##DF,y##DF,&quo); \
+ TEST_f(remquod64,res##DD,%Df,x##DD,y##DD,&quo); \
+ TEST_f(remquod128,res##DL,%DDf,x##DL,y##DL,&quo); \
+ } while(0)
+
+#define TEST_remquo(res,x,y,i) \
+ do { int quo; \
+ TEST_f(remquod32,res##DF,%Hf,x##DF,y##DF,&quo); \
+ if(i==quo) printf(" Success: quo value returned was: "#i"\n"); \
+ else printf(" Failure: quo returned was %d,"\
+ "was supposed to be "#i"\n", quo); \
+ TEST_f(remquod64,res##DD,%Df,x##DD,y##DD,&quo); \
+ if(i==quo) printf(" Success: quo value returned was: "#i"\n"); \
+ else printf(" Failure: quo returned was %d,"\
+ "was supposed to be "#i"\n", quo); \
+ TEST_f(remquod128,res##DL,%DDf,x##DL,y##DL,&quo); \
+ if(i==quo) printf(" Success: quo value returned was: "#i"\n"); \
+ else printf(" Failure: quo returned was %d,"\
+ "was supposed to be "#i"\n", quo); \
+ } while(0)
+
+ TEST_remquo_noquo (DEC_NAN, 1.0, 0.0);
+ TEST_remquo_noquo (DEC_NAN, 1.0, -0.0);
+ TEST_remquo_noquo (DEC_NAN, DEC_INFINITY, 1.0);
+ TEST_remquo_noquo (DEC_NAN, -DEC_INFINITY, 1.0);
+ TEST_remquo_noquo (DEC_NAN, DEC_NAN, DEC_NAN);
+ TEST_remquo (-0.375, 1.625, 1.0, 2);
+ TEST_remquo (0.375, -1.625, 1.0, -2);
+ TEST_remquo (-0.375, 1.625, -1.0, -2);
+ TEST_remquo (0.375, -1.625, -1.0, 2);
+ TEST_remquo (1.0, 5.0, 2.0, 2);
+ TEST_remquo (-1.0, 3.0, 2.0, 2);
+*/
+// _Decimal hypot (_Decimal, _Decimal)
+ TEST_f_2_all (hypot, DEC_INFINITY, DEC_INFINITY, 1.0);
+ TEST_f_2_all (hypot, -DEC_INFINITY, -DEC_INFINITY, 1.0);
+ TEST_f_2_all (hypot, DEC_INFINITY, DEC_NAN, DEC_INFINITY);
+ TEST_f_2_all (hypot, -DEC_INFINITY, -DEC_INFINITY, DEC_NAN);
+ TEST_f_2_all (hypot, DEC_INFINITY, DEC_NAN, DEC_INFINITY);
+ TEST_f_2_all (hypot, -DEC_INFINITY, DEC_NAN, -DEC_INFINITY);
+ TEST_f_2_all (hypot, DEC_NAN, DEC_NAN, DEC_NAN);
+ TEST_f_2_all (hypot, 12.419742348374220601176836866763271, 0.7, 12.4);
+ TEST_f_2_all (hypot, 12.419742348374220601176836866763271, -0.7, 12.4);
+ TEST_f_2_all (hypot, 12.419742348374220601176836866763271, 0.7, -12.4);
+ TEST_f_2_all (hypot, 12.419742348374220601176836866763271, -0.7, -12.4);
+ TEST_f_2_all (hypot, 12.419742348374220601176836866763271, 12.4, 0.7);
+ TEST_f_2_all (hypot, 12.419742348374220601176836866763271, -12.4, 0.7);
+ TEST_f_2_all (hypot, 12.419742348374220601176836866763271, 12.4, -0.7);
+ TEST_f_2_all (hypot, 12.419742348374220601176836866763271, -12.4, -0.7);
+ TEST_f_2_all (hypot, 0.75, 0.75, 0.0); /* hypot (x,0) == fabs (x) */
+ TEST_f_2_all (hypot, 0.75, -0.75, 0.0);
+ TEST_f_2_all (hypot, 5.7e7, -5.7e7, 0.0);
+ TEST_f_2_all (hypot, 1.45773797371132511771853821938639577, 0.75, 1.25);
+
+// _Decimal fmod (_Decimal, _Decimal)
+ /* fmod (+0, y) == +0 for y != 0. */
+ TEST_f_2_all (fmod, 0.0, 0.0, 3.0);
+ /* fmod (-0, y) == -0 for y != 0. */
+ TEST_f_2_all (fmod, -0.0, -0.0, 3.0);
+ /* fmod (+inf, y) == NaN plus invalid exception. */
+ TEST_f_2_all (fmod, DEC_NAN, DEC_INFINITY, 3.0);
+ /* fmod (-inf, y) == NaN + invalid */
+ TEST_f_2_all (fmod, DEC_NAN, -DEC_INFINITY, 3.0);
+ /* fmod (x, +0) == NaN + invalid */
+ TEST_f_2_all (fmod, DEC_NAN, 3.0, 0.0);
+ /* fmod (x, -0) == NaN+invalid */
+ TEST_f_2_all (fmod, DEC_NAN, 3.0, -0.0);
+ /* fmod (x, +inf) == x for x not infinite. */
+ TEST_f_2_all (fmod, 3.0, 3.0, DEC_INFINITY);
+ /* fmod (x, -inf) == x for x not infinite. */
+ TEST_f_2_all (fmod, 3.0, 3.0, -DEC_INFINITY);
+ TEST_f_2_all (fmod, DEC_NAN, DEC_NAN, DEC_NAN);
+ /* Special test case */
+ TEST_f_2_all (fmod, 1.0, 1e50, 3.0);
+
+ TEST_f_2_all (fmod, 2.0, 6.5, 2.25);
+ TEST_f_2_all (fmod, -2.0, -6.5, 2.25);
+ TEST_f_2_all (fmod, 2.0, 6.5, -2.25);
+ TEST_f_2_all (fmod, -2.0, -6.5, -2.25);
+
+// _Decimal cbrt (_Decimal)
+ TEST_f_1_all (cbrt, 0.0, 0.0);
+ TEST_f_1_all (cbrt, -0.0, -0.0);
+ TEST_f_1_all (cbrt, DEC_INFINITY, DEC_INFINITY);
+ TEST_f_1_all (cbrt, -DEC_INFINITY, -DEC_INFINITY);
+ TEST_f_1_all (cbrt, DEC_NAN, DEC_NAN);
+ TEST_f_1_all (cbrt, -0.1, -0.001);
+ TEST_f_1_all (cbrt, 2.0, 8.0);
+ TEST_f_1_all (cbrt, -3.0, -27.0);
+ TEST_f_1_all (cbrt, 0.997389022060725270579075195353955217, 0.9921875);
+ TEST_f_1_all (cbrt, 0.908560296416069829445605878163630251, 0.75);
+
+// _Decimal fma (_Decimal, _Decimal, _Decimal)
+
+ TEST_f_3_all (fma, 5.0, 1.0, 2.0, 3.0);
+ TEST_f_3_all (fma, DEC_NAN, DEC_NAN, 2.0, 3.0);
+ TEST_f_3_all (fma, DEC_NAN, 1.0, DEC_NAN, 3.0);
+ TEST_f_3_all (fma, DEC_NAN, 1.0, 2.0, DEC_NAN);
+ TEST_f_3_all (fma, DEC_NAN, DEC_INFINITY, 0.0, DEC_NAN);
+ TEST_f_3_all (fma, DEC_NAN, -DEC_INFINITY, 0.0, DEC_NAN);
+ TEST_f_3_all (fma, DEC_NAN, 0.0, DEC_INFINITY, DEC_NAN);
+ TEST_f_3_all (fma, DEC_NAN, 0.0, -DEC_INFINITY, DEC_NAN);
+ TEST_f_3_all (fma, DEC_NAN, DEC_INFINITY, 0.0, 1.0);
+ TEST_f_3_all (fma, DEC_NAN, -DEC_INFINITY, 0.0, 1.0);
+ TEST_f_3_all (fma, DEC_NAN, 0.0, DEC_INFINITY, 1.0);
+ TEST_f_3_all (fma, DEC_NAN, 0.0, -DEC_INFINITY, 1.0);
+
+ TEST_f_3_all (fma, DEC_NAN, DEC_INFINITY, DEC_INFINITY,-DEC_INFINITY);
+ TEST_f_3_all (fma, DEC_NAN,-DEC_INFINITY, DEC_INFINITY, DEC_INFINITY);
+ TEST_f_3_all (fma, DEC_NAN, DEC_INFINITY,-DEC_INFINITY, DEC_INFINITY);
+ TEST_f_3_all (fma, DEC_NAN,-DEC_INFINITY,-DEC_INFINITY,-DEC_INFINITY);
+ TEST_f_3_all (fma, 1.0, 1.25, 0.75, 0.0625);
+
+// _Decimal frexp (_Decimal, int*);
+ TEST_fI (frexpd32, %Hf, 0.128DF, 23, 128E20DF);
+ TEST_fI (frexpd64, %Df, 0.128DD, 23, 128E20DD);
+ TEST_fI (frexpd128, %DDf, 0.128DL, 23, 128E20DL);
+ TEST_fI (frexpd32, %Hf, 0.128DF, 2, 12.8DF);
+ TEST_fI (frexpd64, %Df, 0.128DD, 2, 12.8DD);
+ TEST_fI (frexpd128, %DDf, 0.128DL, 2, 12.8DL);
+ TEST_fI (frexpd32, %Hf, -0.2734DF, 2, -27.34DF);
+ TEST_fI (frexpd64, %Df, -0.2734DD, 2, -27.34DD);
+ TEST_fI (frexpd128, %DDf, -0.2734DL, 2, -27.34DL);
+ TEST_fI (frexpd32, %Hf, -0.2734DF, 0, -0.2734DF);
+ TEST_fI (frexpd64, %Df, -0.2734DD, 0, -0.2734DD);
+ TEST_fI (frexpd128, %DDf, -0.2734DL, 0, -0.2734DL);
+ TEST_fI (frexpd32, %Hf, -0.2734DF, -1, -0.02734DF);
+ TEST_fI (frexpd64, %Df, -0.2734DD, -1, -0.02734DD);
+ TEST_fI (frexpd128, %DDf, -0.2734DL, -1, -0.02734DL);
+ TEST_fI (frexpd32, %Hf, 0.1DF, 0, 0.1000DF);
+ TEST_fI (frexpd64, %Df, 0.1DD, 0, 0.1000DD);
+ TEST_fI (frexpd128, %DDf, 0.1DL, 0, 0.1000DL);
+ TEST_fI (frexpd32, %Hf, 0.1DF, -1, 0.010DF);
+ TEST_fI (frexpd64, %Df, 0.1DD, -1, 0.0100DD);
+ TEST_fI (frexpd128, %DDf, 0.1DL, -1, 0.01000DL);
+ TEST_fI (frexpd32, %Hf, 0.256DF, 3, 256.0DF);
+ TEST_fI (frexpd64, %Df, 0.256DD, 3, 256.0DD);
+ TEST_fI (frexpd128, %DDf, 0.256DL, 3, 256.0DL);
+}
diff --git a/libc/dfp/test/test_signbit.c b/libc/dfp/test/test_signbit.c
new file mode 100644
index 000000000..aecb6f32f
--- /dev/null
+++ b/libc/dfp/test/test_signbit.c
@@ -0,0 +1,36 @@
+/* /opt/biarch/dfp/bin/gcc -g test_signbit.c -o signbit -ldfp */
+#include <stdio.h>
+#include <stdint.h>
+
+#define __STDC_WANT_DEC_FP__ 1
+#include <math.h>
+
+int main() {
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+ int sign;
+
+ d32 = -19.54DF;
+ d64 = -19.54DD;
+ d128 = -19.54DL;
+
+ sign = signbit(d32);
+ printf("%d = signbit(%Hf)\n", sign, d32);
+ sign = signbit(d64);
+ printf("%d = signbit(%Df)\n", sign, d64);
+ sign = signbit(d128);
+ printf("%d = signbit(%DDf)\n", sign, d128);
+
+ d32 = 19.54DF;
+ d64 = 19.54DD;
+ d128 = 19.54DL;
+
+ sign = signbit(d32);
+ printf("%d = signbit(%Hf)\n", sign, d32);
+ sign = signbit(d64);
+ printf("%d = signbit(%Df)\n", sign, d64);
+ sign = signbit(d128);
+ printf("%d = signbit(%DDf)\n", sign, d128);
+
+}
diff --git a/libc/dfp/test/test_sqrt.c b/libc/dfp/test/test_sqrt.c
new file mode 100644
index 000000000..24fdffb4b
--- /dev/null
+++ b/libc/dfp/test/test_sqrt.c
@@ -0,0 +1,36 @@
+/* /opt/biarch/dfp/bin/gcc -g test_sqrtd.c -o sqrtd -ldfp */
+#include <stdio.h>
+#include <stdint.h>
+
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+
+#include <math.h>
+
+int main() {
+ _Decimal32 d32;
+ _Decimal32 s32;
+ _Decimal64 d64;
+ _Decimal64 s64;
+ _Decimal128 d128;
+ _Decimal128 s128;
+
+ d32 = 144.0DF;
+ s32 = 0.0DF;
+
+ d64 = 144.0DD;
+ s64 = 0.0DD;
+ d128 = 144.0DL;
+ s128 = 0.0DL;
+
+ s32 = sqrtd32(d32);
+
+ s64 = sqrtd64(d64);
+
+ s128 = sqrtd128(d128);
+
+ printf("%Hf = sqrtd32(%Hf)\n", s32, d32);
+ printf("%Df = sqrtd64(%Df)\n", s64, d64);
+ printf("%DDf = sqrtd128(%DDf)\n", s128, d128);
+}
diff --git a/libc/dfp/test/test_strtod.c b/libc/dfp/test/test_strtod.c
new file mode 100644
index 000000000..16c84402d
--- /dev/null
+++ b/libc/dfp/test/test_strtod.c
@@ -0,0 +1,45 @@
+#define __STDC_WANT_DEC_FP__ 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+int main() {
+ _Decimal32 d32;
+ _Decimal64 d64;
+ _Decimal128 d128;
+
+ char *testcases[] = { "12.04","19","19E2","-0.0001","-5","NaN", "INF"};
+ int i,numCases=7;
+
+ for(i=0; i< numCases; i++) {
+ printf("in: %s\n",testcases[i]);
+ printf("out32: %Hf, 64: %Df, 128: %DDf\n",
+ strtod32(testcases[i],NULL),
+ strtod64(testcases[i],NULL),
+ strtod128(testcases[i],NULL)
+ );
+ }
+/* sscanf("12.04e3", "%Hf", &d32);
+ sscanf("12.04", "%Df", &d64);
+ sscanf("12.04", "%DDf", &d128);
+
+ printf("out: %Hf\n",d32);
+ printf("out: %Df\n",d64);
+ printf("out: %DDf\n",d128); */
+
+/* printf("%Hf\n", d32);
+ printf("%HE\n", d32); */
+
+/* printf("The hex value 0x%.8x%.8x = %Df in _Decimal64.\n", d64[0],
+ * d64[1], d64); */
+
+/* printf("%Df\n", d64);
+ printf("%DE\n", d64); */
+
+/* printf("The hex value 0x%.8x%.8x%.8x%.8x = %DDf in _Decimal128.\n",
+ * d128[0], d128[1], d128[2], d128[3], d128); */
+/* printf("%DDf\n", d128); */
+/* printf("%DDE\n", d128); */
+
+}
diff --git a/libc/dfp/test/test_varargs.c b/libc/dfp/test/test_varargs.c
new file mode 100644
index 000000000..942fe6be9
--- /dev/null
+++ b/libc/dfp/test/test_varargs.c
@@ -0,0 +1,13 @@
+/* /opt/biarch/dfp/bin/gcc -g test_fabsd.c -o fabsd -ldfp */
+#include <stdio.h>
+/*#include <stdint.h>
+
+#define __STDC_WANT_DEC_FP__ 1
+#include <math.h> */
+
+int main() {
+ _Decimal128 d128;
+ d128 = -1.0DL;
+ printf("1 %DDf\n", d128);
+ printf("1a %DDf,%DDf,%DDf\n", d128,d128,d128);
+}
diff --git a/libc/dfp/test/test_zero.c b/libc/dfp/test/test_zero.c
new file mode 100644
index 000000000..5c3b4521d
--- /dev/null
+++ b/libc/dfp/test/test_zero.c
@@ -0,0 +1,60 @@
+#ifndef __STDC_WANT_DEC_FP__
+# define __STDC_WANT_DEC_FP__ 1
+#endif
+#include <stdio.h>
+#include <stdint.h>
+#include <math.h>
+#include <fenv.h>
+
+
+
+
+
+
+
+
+
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile float sf;
+volatile double df;
+
+void
+f1 (void)
+{
+ dd = -0.DD;
+ df = dd;
+ printf ("expected -0, got %f, signbit = %d\n",
+ df, (__builtin_signbit (df) != 0));
+}
+
+void
+f2 (void)
+{
+ sd = 0.DD;
+ df = sd;
+ printf ("expected 0, got %f, signbit = %d\n",
+ df, (__builtin_signbit (df) != 0));
+}
+
+void
+f3 (void)
+{
+ sd = __builtin_infd32 ();
+ df = sd;
+ printf ("expected inf, got %f, signbit = %d\n",
+ df, (__builtin_signbit (df) != 0));
+}
+
+int
+main ()
+{
+
+
+ f1 ();
+ f2 ();
+ f3 ();
+
+ return 0;
+}