This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: decimal float testsuite


This patch merges all of the decimal floating point tests from the
dfp-branch to the trunk.  There are a few parts to the patch:

  * new gcc.dg/dfp test cases;

  * an assortment of other tests in gcc.dg/format, gcc.dg/compat,
    gcc.dg/debug and gcc.misc-tests, where applicable; and

  * some infrastructure enhancements in lib/.

I'm only posting patches for the second and third parts.  The new
tests in gcc.dg/dfp total 4500 new lines of text, so I will spare you
the details (unless there is a pressing need to post them--they are on
the dfp-branch).

The most important point about these test cases is that they use a new
`check_effective_target_dfp' proc to guard against the test cases
running on a non-DFP capable compiler.  Thus, none of these changes
will have any noticable effect (yet).

Tested with a bootstrap and `make check' run on i686-pc-linux-gnu.  No
regressions.  Okay for the trunk?

Thanks,
Ben

2006-01-10  Janis Johnson <janis187@us.ibm.com>
            Yao Qi  <qiyaoltc@cn.ibm.com>
            Ben Elliston  <bje@au.ibm.com>
            Jon Grimm  <jgrimm2@us.ibm.com>

        * gcc.dg/nodfp-1.c: New test.
        * gcc.dg/compat/scalar-return-dfp_x.c: Likewise.
        * gcc.dg/compat/scalar-return-dfp_x.c: Likewise.
        * gcc.dg/compat/scalar-return-dfp_main.c: Likewise.
        * gcc.dg/compat/scalar-by-value-dfp_main.c: Likewise.
        * gcc.dg/compat/scalar-by-value-dfp_x.c: Likewise.
        * gcc.dg/compat/scalar-return-dfp_y.c: Likewise.
        * gcc.dg/compat/scalar-by-value-dfp_y.c: Likewise.
        * gcc.dg/debug/dwarf2/dwarf-float.c: Likewise.
        * gcc.dg/debug/dwarf2/dwarf-dfp.c: Likewise.
        * gcc.dg/format/dfp-scanf-1.c: Likewise.
        * gcc.dg/format/dfp-printf-1.c: Likewise.
        * gcc.dg/compat/struct-layout-1.exp: Use c-compat.exp.
        (compat_setup_dfp): New.
        * gcc.dg/compat/compat.exp: Use it.
        (compat-use-alt-compiler, compat-use-tst-compiler): Move to new file.
        Make some variables global, prepend "compat_" to their names.
        * gcc.dg/compat/struct-layout-1.h: Conditional DFP support.
        * gcc.dg/compat/struct-layout-1_generate.c: Ditto.
        * gcc.misc-tests/dectest.exp: New test driver for decTest.
        * lib/compat.exp (compat_skip_list): Make global, rename.
        * lib/c-compat.exp: New file.
        * lib/target-supports.exp (check_effective_target_dfp): New.
        * gcc.dg/dfp/dec-eval-method.c, gcc.dg/dfp/func-array.c,
        gcc.dg/dfp/convert-dfp-fold.c, gcc.dg/dfp/struct-union.c,
        gcc.dg/dfp/inf-1.c, gcc.dg/dfp/compare-rel.h,
        gcc.dg/dfp/convert-dfp-round.c, gcc.dg/dfp/func-struct.c,
        gcc.dg/dfp/constants-c99.c, gcc.dg/dfp/compare-eq-d32.c,
        gcc.dg/dfp/func-vararg-mixed.c, gcc.dg/dfp/compare-rel-d128.c,
        gcc.dg/dfp/operator-comma.c, gcc.dg/dfp/decfloat-constants.c,
        gcc.dg/dfp/operator-bitwise.c, gcc.dg/dfp/func-mixed.c,
        gcc.dg/dfp/compare-eq-dfp.c, gcc.dg/dfp/operator-assignment.c,
        gcc.dg/dfp/dfp-round.h, gcc.dg/dfp/modes.c,
        gcc.dg/dfp/keywords-c99.c, gcc.dg/dfp/nan-1.c,
        gcc.dg/dfp/loop-index.c, gcc.dg/dfp/compare-eq-d64.c,
        gcc.dg/dfp/convert-bfp.c, gcc.dg/dfp/usual-arith-conv-const.c,
        gcc.dg/dfp/convert-dfp.c, gcc.dg/dfp/compare-rel-const.c,
        gcc.dg/dfp/convert-int-fold.c, gcc.dg/dfp/keywords-pedantic.c,
        gcc.dg/dfp/compare-rel-d32.c, gcc.dg/dfp/call-by-value.c,
        gcc.dg/dfp/constants-hex.c, gcc.dg/dfp/func-scalar.c,
        gcc.dg/dfp/keywords-ignored-c99.c, gcc.dg/dfp/snan.c,
        gcc.dg/dfp/usual-arith-conv.c, gcc.dg/dfp/constants-pedantic.c,
        gcc.dg/dfp/operator-logical.c, gcc.dg/dfp/compare-eq-d128.c,
        gcc.dg/dfp/convert-bfp-fold.c, gcc.dg/dfp/ctypes.c,
        gcc.dg/dfp/convert-int.c, gcc.dg/dfp/keywords-c89.c,
        gcc.dg/dfp/constants.c, gcc.dg/dfp/compare-rel-dfp.c,
        gcc.dg/dfp/compare-eq-const.c, gcc.dg/dfp/cast-bad.c,
        gcc.dg/dfp/operator-arith-fold.c, gcc.dg/dfp/union-init.c,
        gcc.dg/dfp/struct-layout-1.c,
        gcc.dg/dfp/compare-eq.hgcc.dg/dfp/convert-int-saturate.c,
        gcc.dg/dfp/compare-rel-d64.c, gcc.dg/dfp/func-vararg-size0.c,
        gcc.dg/dfp/Wconversion-2.c, gcc.dg/dfp/nan-2.c,
        gcc.dg/dfp/operator-cond.c, gcc.dg/dfp/composite-type.c,
        gcc.dg/dfp/func-vararg-dfp.c,
        gcc.dg/dfp/dfp.expgcc.dg/dfp/keywords-reserved.c,
        gcc.dg/dfp/convert-complex.c, gcc.dg/dfp/Wbad-function-cast-1.c,
        gcc.dg/dfp/operator-unary.c, gcc.dg/dfp/altivec-types.c,
        gcc.dg/dfp/cast.c, gcc.dg/dfp/typespec.c,
        gcc.dg/dfp/wtr-conversion-1.c: New tests.

Index: gcc.dg/nodfp-1.c
===================================================================
--- gcc.dg/nodfp-1.c	(revision 0)
+++ gcc.dg/nodfp-1.c	(revision 0)
@@ -0,0 +1,6 @@
+/* { dg-do compile { target {! dfp} } } */
+/* { dg-options "-std=gnu99" } */
+
+_Decimal32 x;	/* { dg-error "not supported" "reject decimal float" } */
+_Decimal64 y;	/* { dg-error "not supported" "reject decimal float" } */
+_Decimal128 z;	/* { dg-error "not supported" "reject decimal float" } */
Index: gcc.dg/compat/scalar-return-dfp_x.c
===================================================================
--- gcc.dg/compat/scalar-return-dfp_x.c	(revision 0)
+++ gcc.dg/compat/scalar-return-dfp_x.c	(revision 0)
@@ -0,0 +1,109 @@
+#include "compat-common.h"
+
+#ifdef SKIP_VA
+const int test_va = 0;
+#else
+const int test_va = 1;
+#endif
+
+#define T(NAME, TYPE, INITVAL) 					\
+TYPE g01##NAME, g02##NAME, g03##NAME, g04##NAME;		\
+TYPE g05##NAME, g06##NAME, g07##NAME, g08##NAME;		\
+TYPE g09##NAME, g10##NAME, g11##NAME, g12##NAME;		\
+TYPE g13##NAME, g14##NAME, g15##NAME, g16##NAME;		\
+								\
+extern void init##NAME (TYPE *p, TYPE v);			\
+extern void checkg##NAME (void);				\
+extern TYPE test0##NAME (void);					\
+extern TYPE test1##NAME (TYPE);					\
+extern TYPE testva##NAME (int n, ...);				\
+								\
+void								\
+check##NAME (TYPE x, TYPE v)					\
+{								\
+  if (x != v)							\
+    DEBUG_CHECK							\
+}								\
+								\
+void								\
+testit##NAME (void)						\
+{								\
+  TYPE rslt;							\
+  DEBUG_FPUTS (#NAME);						\
+  DEBUG_FPUTS (" init: ");					\
+  init##NAME (&g01##NAME,  1);					\
+  init##NAME (&g02##NAME,  2);					\
+  init##NAME (&g03##NAME,  3);					\
+  init##NAME (&g04##NAME,  4);					\
+  init##NAME (&g05##NAME,  5);					\
+  init##NAME (&g06##NAME,  6);					\
+  init##NAME (&g07##NAME,  7);					\
+  init##NAME (&g08##NAME,  8);					\
+  init##NAME (&g09##NAME,  9);					\
+  init##NAME (&g10##NAME, 10);					\
+  init##NAME (&g11##NAME, 11);					\
+  init##NAME (&g12##NAME, 12);					\
+  init##NAME (&g13##NAME, 13);					\
+  init##NAME (&g14##NAME, 14);					\
+  init##NAME (&g15##NAME, 15);					\
+  init##NAME (&g16##NAME, 16);					\
+  checkg##NAME ();						\
+  DEBUG_NL;							\
+  DEBUG_FPUTS (#NAME);						\
+  DEBUG_FPUTS (" test0: ");					\
+  rslt = test0##NAME ();					\
+  check##NAME (rslt, g01##NAME);				\
+  DEBUG_NL;							\
+  DEBUG_FPUTS (#NAME);						\
+  DEBUG_FPUTS (" test1: ");					\
+  rslt = test1##NAME (g01##NAME);				\
+  check##NAME (rslt, g01##NAME);				\
+  if (test_va)							\
+    {								\
+      DEBUG_NL;							\
+      DEBUG_FPUTS (#NAME);					\
+      DEBUG_FPUTS (" testva:");					\
+      rslt = testva##NAME (1, g01##NAME);			\
+      check##NAME (rslt, g01##NAME);				\
+      rslt = testva##NAME (5, g01##NAME, g02##NAME, g03##NAME,	\
+			   g04##NAME, g05##NAME);		\
+      check##NAME (rslt, g05##NAME);				\
+      rslt = testva##NAME (9, g01##NAME, g02##NAME, g03##NAME,	\
+			   g04##NAME, g05##NAME, g06##NAME,	\
+			   g07##NAME, g08##NAME, g09##NAME);	\
+      check##NAME (rslt, g09##NAME);				\
+      rslt = testva##NAME (16, g01##NAME, g02##NAME, g03##NAME,	\
+			   g04##NAME, g05##NAME, g06##NAME,	\
+			   g07##NAME, g08##NAME, g09##NAME,	\
+			   g10##NAME, g11##NAME, g12##NAME,	\
+			   g13##NAME, g14##NAME, g15##NAME,	\
+			   g16##NAME);				\
+      check##NAME (rslt, g16##NAME);				\
+    }								\
+  DEBUG_NL;							\
+}
+
+T(d32, _Decimal32, 1.2df)
+T(d64, _Decimal64, 12.34dd)
+T(d128, _Decimal128, 123.456dl)
+
+#undef T
+
+void
+scalar_return_dfp_x ()
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+T(d32)
+T(d64)
+T(d128)
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc.dg/compat/scalar-return-dfp_main.c
===================================================================
--- gcc.dg/compat/scalar-return-dfp_main.c	(revision 0)
+++ gcc.dg/compat/scalar-return-dfp_main.c	(revision 0)
@@ -0,0 +1,15 @@
+/* Test function return values.  This test includes scalar types that
+   are supported by va_arg.  */
+
+/* { dg-require-compat-dfp "" } */
+
+extern void scalar_return_dfp_x(void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+  scalar_return_dfp_x ();
+  exit (0);
+}
Index: gcc.dg/compat/scalar-by-value-dfp_main.c
===================================================================
--- gcc.dg/compat/scalar-by-value-dfp_main.c	(revision 0)
+++ gcc.dg/compat/scalar-by-value-dfp_main.c	(revision 0)
@@ -0,0 +1,15 @@
+/* Test passing scalars by value.  This test includes scalar types that
+   are supported by va_arg.  */
+
+/* { dg-require-compat-dfp "" } */
+
+extern void scalar_by_value_dfp_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+  scalar_by_value_dfp_x ();
+  exit (0);
+}
Index: gcc.dg/compat/scalar-by-value-dfp_x.c
===================================================================
--- gcc.dg/compat/scalar-by-value-dfp_x.c	(revision 0)
+++ gcc.dg/compat/scalar-by-value-dfp_x.c	(revision 0)
@@ -0,0 +1,170 @@
+#include "compat-common.h"
+
+#define T(NAME, TYPE, INITVAL) 					\
+TYPE g01##NAME, g02##NAME, g03##NAME, g04##NAME;		\
+TYPE g05##NAME, g06##NAME, g07##NAME, g08##NAME;		\
+TYPE g09##NAME, g10##NAME, g11##NAME, g12##NAME;		\
+TYPE g13##NAME, g14##NAME, g15##NAME, g16##NAME;		\
+								\
+extern void init##NAME (TYPE *p, TYPE v);			\
+extern void checkg##NAME (void);				\
+extern void							\
+test##NAME (TYPE x01, TYPE x02, TYPE x03, TYPE x04,		\
+            TYPE x05, TYPE x06, TYPE x07, TYPE x08,		\
+            TYPE x09, TYPE x10, TYPE x11, TYPE x12,		\
+            TYPE x13, TYPE x14, TYPE x15, TYPE x16);		\
+extern void testva##NAME (int n, ...);				\
+								\
+void								\
+check##NAME (TYPE x, TYPE v)					\
+{								\
+  if (x != v + INITVAL)						\
+    DEBUG_CHECK							\
+}								\
+								\
+void								\
+test2_##NAME (TYPE x01, TYPE x02, TYPE x03, TYPE x04,		\
+	      TYPE x05, TYPE x06, TYPE x07, TYPE x08)		\
+{								\
+  test##NAME (x01, g02##NAME, x02, g04##NAME,			\
+	      x03, g06##NAME, x04, g08##NAME,			\
+	      x05, g10##NAME, x06, g12##NAME,			\
+	      x07, g14##NAME, x08, g16##NAME);			\
+}								\
+								\
+void								\
+testit##NAME (void)						\
+{								\
+  DEBUG_FPUTS (#NAME);						\
+  DEBUG_FPUTS (" init: ");					\
+  init##NAME (&g01##NAME,  1);					\
+  init##NAME (&g02##NAME,  2);					\
+  init##NAME (&g03##NAME,  3);					\
+  init##NAME (&g04##NAME,  4);					\
+  init##NAME (&g05##NAME,  5);					\
+  init##NAME (&g06##NAME,  6);					\
+  init##NAME (&g07##NAME,  7);					\
+  init##NAME (&g08##NAME,  8);					\
+  init##NAME (&g09##NAME,  9);					\
+  init##NAME (&g10##NAME, 10);					\
+  init##NAME (&g11##NAME, 11);					\
+  init##NAME (&g12##NAME, 12);					\
+  init##NAME (&g13##NAME, 13);					\
+  init##NAME (&g14##NAME, 14);					\
+  init##NAME (&g15##NAME, 15);					\
+  init##NAME (&g16##NAME, 16);					\
+  checkg##NAME ();						\
+  DEBUG_NL;							\
+  DEBUG_FPUTS (#NAME);						\
+  DEBUG_FPUTS (" test: ");					\
+  test##NAME (g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+	      g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+	      g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+	      g13##NAME, g14##NAME, g15##NAME, g16##NAME);	\
+  DEBUG_NL;							\
+  DEBUG_FPUTS (#NAME);						\
+  DEBUG_FPUTS (" testva:");					\
+  DEBUG_NL;							\
+  testva##NAME (1,						\
+		g01##NAME);					\
+  DEBUG_NL;							\
+  testva##NAME (2,						\
+		g01##NAME, g02##NAME);				\
+  DEBUG_NL;							\
+  testva##NAME (3,						\
+		g01##NAME, g02##NAME, g03##NAME);		\
+  DEBUG_NL;							\
+  testva##NAME (4,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME);	\
+  DEBUG_NL;							\
+  testva##NAME (5,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME);					\
+  DEBUG_NL;							\
+  testva##NAME (6,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME);				\
+  DEBUG_NL;							\
+  testva##NAME (7,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME);		\
+  DEBUG_NL;							\
+  testva##NAME (8,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME);	\
+  DEBUG_NL;							\
+  testva##NAME (9,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME);					\
+  DEBUG_NL;							\
+  testva##NAME (10,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME);				\
+  DEBUG_NL;							\
+  testva##NAME (11,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME);		\
+  DEBUG_NL;							\
+  testva##NAME (12,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME);	\
+  DEBUG_NL;							\
+  testva##NAME (13,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+		g13##NAME);					\
+  DEBUG_NL;							\
+  testva##NAME (14,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+		g13##NAME, g14##NAME);				\
+  DEBUG_NL;							\
+  testva##NAME (15,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+		g13##NAME, g14##NAME, g15##NAME);		\
+  DEBUG_NL;							\
+  testva##NAME (16,						\
+		g01##NAME, g02##NAME, g03##NAME, g04##NAME,	\
+		g05##NAME, g06##NAME, g07##NAME, g08##NAME,	\
+		g09##NAME, g10##NAME, g11##NAME, g12##NAME,	\
+		g13##NAME, g14##NAME, g15##NAME, g16##NAME);	\
+  DEBUG_NL;							\
+  DEBUG_FPUTS (#NAME);						\
+  DEBUG_FPUTS (" test2: ");					\
+  test2_##NAME (g01##NAME, g03##NAME, g05##NAME, g07##NAME,	\
+		g09##NAME, g11##NAME, g13##NAME, g15##NAME);	\
+  DEBUG_NL;							\
+}
+
+T(d32, _Decimal32, 1.2df)
+T(d64, _Decimal64, 12.34dd)
+T(d128, _Decimal128, 123.456dl)
+
+#undef T
+
+void
+scalar_by_value_dfp_x ()
+{
+DEBUG_INIT
+
+#define T(NAME) testit##NAME ();
+
+T(d32)
+T(d64)
+T(d128)
+
+DEBUG_FINI
+
+if (fails != 0)
+  abort ();
+
+#undef T
+}
Index: gcc.dg/compat/struct-layout-1.h
===================================================================
--- gcc.dg/compat/struct-layout-1.h	(revision 109530)
+++ gcc.dg/compat/struct-layout-1.h	(working copy)
@@ -204,6 +204,11 @@ typedef _Complex unsigned long long int 
 typedef float Tfloat;
 typedef double Tdouble;
 typedef long double Tldouble;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 TDecimal32;
+typedef _Decimal64 TDecimal64;
+typedef _Decimal128 TDecimal128;
+#endif
 typedef _Complex float Tcfloat;
 typedef _Complex double Tcdouble;
 typedef _Complex long double Tcldouble;
@@ -248,6 +253,11 @@ typedef _Complex unsigned long long int 
 typedef float Talfloat atal;
 typedef double Taldouble atal;
 typedef long double Talldouble atal;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 TalDecimal32 atal;
+typedef _Decimal64 TalDecimal64 atal;
+typedef _Decimal128 TalDecimal128 atal;
+#endif
 typedef _Complex float Talcfloat atal;
 typedef _Complex double Talcdouble atal;
 typedef _Complex long double Talcldouble atal;
@@ -292,6 +302,11 @@ typedef _Complex unsigned long long int 
 typedef float Tal1float atal1;
 typedef double Tal1double atal1;
 typedef long double Tal1ldouble atal1;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 Tal1Decimal32 atal1;
+typedef _Decimal64 Tal1Decimal64 atal1;
+typedef _Decimal128 Tal1Decimal128 atal1;
+#endif
 typedef _Complex float Tal1cfloat atal1;
 typedef _Complex double Tal1cdouble atal1;
 typedef _Complex long double Tal1cldouble atal1;
@@ -336,6 +351,11 @@ typedef _Complex unsigned long long int 
 typedef float Tal2float atal2;
 typedef double Tal2double atal2;
 typedef long double Tal2ldouble atal2;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 Tal2Decimal32 atal2;
+typedef _Decimal64 Tal2Decimal64 atal2;
+typedef _Decimal128 Tal2Decimal128 atal2;
+#endif
 typedef _Complex float Tal2cfloat atal2;
 typedef _Complex double Tal2cdouble atal2;
 typedef _Complex long double Tal2cldouble atal2;
@@ -380,6 +400,11 @@ typedef _Complex unsigned long long int 
 typedef float Tal4float atal4;
 typedef double Tal4double atal4;
 typedef long double Tal4ldouble atal4;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 Tal4Decimal32 atal4;
+typedef _Decimal64 Tal4Decimal64 atal4;
+typedef _Decimal128 Tal4Decimal128 atal4;
+#endif
 typedef _Complex float Tal4cfloat atal4;
 typedef _Complex double Tal4cdouble atal4;
 typedef _Complex long double Tal4cldouble atal4;
@@ -424,6 +449,11 @@ typedef _Complex unsigned long long int 
 typedef float Tal8float atal8;
 typedef double Tal8double atal8;
 typedef long double Tal8ldouble atal8;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 Tal8Decimal32 atal8;
+typedef _Decimal64 Tal8Decimal64 atal8;
+typedef _Decimal128 Tal8Decimal128 atal8;
+#endif
 typedef _Complex float Tal8cfloat atal8;
 typedef _Complex double Tal8cdouble atal8;
 typedef _Complex long double Tal8cldouble atal8;
@@ -468,6 +498,11 @@ typedef _Complex unsigned long long int 
 typedef float Tal16float atal16;
 typedef double Tal16double atal16;
 typedef long double Tal16ldouble atal16;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 Tal16Decimal32 atal16;
+typedef _Decimal64 Tal16Decimal64 atal16;
+typedef _Decimal128 Tal16Decimal128 atal16;
+#endif
 typedef _Complex float Tal16cfloat atal16;
 typedef _Complex double Tal16cdouble atal16;
 typedef _Complex long double Tal16cldouble atal16;
@@ -512,6 +547,11 @@ typedef _Complex unsigned long long int 
 typedef float Talx1float atalx1;
 typedef double Talx1double atalx1;
 typedef long double Talx1ldouble atalx1;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 Talx1Decimal32 atalx1;
+typedef _Decimal64 Talx1Decimal64 atalx1;
+typedef _Decimal128 Talx1Decimal128 atalx1;
+#endif
 typedef _Complex float Talx1cfloat atalx1;
 typedef _Complex double Talx1cdouble atalx1;
 typedef _Complex long double Talx1cldouble atalx1;
@@ -553,6 +593,11 @@ typedef _Complex unsigned long long int 
 typedef float Talx2float atalx2;
 typedef double Talx2double atalx2;
 typedef long double Talx2ldouble atalx2;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 Talx2Decimal32 atalx2;
+typedef _Decimal64 Talx2Decimal64 atalx2;
+typedef _Decimal128 Talx2Decimal128 atalx2;
+#endif
 typedef _Complex float Talx2cfloat atalx2;
 typedef _Complex double Talx2cdouble atalx2;
 typedef _Complex long double Talx2cldouble atalx2;
@@ -588,6 +633,11 @@ typedef _Complex unsigned long long int 
 typedef float Talx4float atalx4;
 typedef double Talx4double atalx4;
 typedef long double Talx4ldouble atalx4;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal32 Talx4Decimal32 atalx4;
+typedef _Decimal64 Talx4Decimal64 atalx4;
+typedef _Decimal128 Talx4Decimal128 atalx4;
+#endif
 typedef _Complex float Talx4cfloat atalx4;
 typedef _Complex double Talx4cdouble atalx4;
 typedef _Complex long double Talx4cldouble atalx4;
@@ -618,6 +668,10 @@ typedef _Complex unsigned long long int 
 #endif
 typedef double Talx8double atalx8;
 typedef long double Talx8ldouble atalx8;
+#ifndef SKIP_DECIMAL_FLOAT
+typedef _Decimal64 Talx8Decimal64 atalx8;
+typedef _Decimal128 Talx8Decimal128 atalx8;
+#endif
 typedef _Complex float Talx8cfloat atalx8;
 typedef _Complex double Talx8cdouble atalx8;
 typedef _Complex long double Talx8cldouble atalx8;
Index: gcc.dg/compat/scalar-return-dfp_y.c
===================================================================
--- gcc.dg/compat/scalar-return-dfp_y.c	(revision 0)
+++ gcc.dg/compat/scalar-return-dfp_y.c	(revision 0)
@@ -0,0 +1,67 @@
+#include <stdarg.h>
+
+#include "compat-common.h"
+
+#define T(NAME, TYPE, INITVAL)					\
+extern TYPE g01##NAME, g02##NAME, g03##NAME, g04##NAME;		\
+extern TYPE g05##NAME, g06##NAME, g07##NAME, g08##NAME;		\
+extern TYPE g09##NAME, g10##NAME, g11##NAME, g12##NAME;		\
+extern TYPE g13##NAME, g14##NAME, g15##NAME, g16##NAME;		\
+								\
+extern void check##NAME (TYPE x, TYPE v);			\
+								\
+void								\
+init##NAME (TYPE *p, TYPE v)					\
+{								\
+  *p = v + INITVAL;						\
+}								\
+								\
+void								\
+checkg##NAME (void)						\
+{								\
+  check##NAME (g01##NAME,  1+INITVAL);				\
+  check##NAME (g02##NAME,  2+INITVAL);				\
+  check##NAME (g03##NAME,  3+INITVAL);				\
+  check##NAME (g04##NAME,  4+INITVAL);				\
+  check##NAME (g05##NAME,  5+INITVAL);				\
+  check##NAME (g06##NAME,  6+INITVAL);				\
+  check##NAME (g07##NAME,  7+INITVAL);				\
+  check##NAME (g08##NAME,  8+INITVAL);				\
+  check##NAME (g09##NAME,  9+INITVAL);				\
+  check##NAME (g10##NAME, 10+INITVAL);				\
+  check##NAME (g11##NAME, 11+INITVAL);				\
+  check##NAME (g12##NAME, 12+INITVAL);				\
+  check##NAME (g13##NAME, 13+INITVAL);				\
+  check##NAME (g14##NAME, 14+INITVAL);				\
+  check##NAME (g15##NAME, 15+INITVAL);				\
+  check##NAME (g16##NAME, 16+INITVAL);				\
+}								\
+								\
+TYPE								\
+test0##NAME (void)						\
+{								\
+  return g01##NAME;						\
+}								\
+								\
+TYPE								\
+test1##NAME (TYPE x01)						\
+{								\
+  return x01;							\
+}								\
+								\
+TYPE								\
+testva##NAME (int n, ...)					\
+{								\
+  int i;							\
+  TYPE rslt;							\
+  va_list ap;							\
+  va_start (ap, n);						\
+  for (i = 0; i < n; i++)					\
+    rslt = va_arg (ap, TYPE);					\
+  va_end (ap);							\
+  return rslt;							\
+}
+
+T(d32, _Decimal32, 1.2df)
+T(d64, _Decimal64, 12.34dd)
+T(d128, _Decimal128, 123.456dl)
Index: gcc.dg/compat/struct-layout-1.exp
===================================================================
--- gcc.dg/compat/struct-layout-1.exp	(revision 109530)
+++ gcc.dg/compat/struct-layout-1.exp	(working copy)
@@ -35,49 +35,26 @@ if $tracelevel then {
 }
 
 global GCC_UNDER_TEST
+global compat_save_gcc_under_test
+global compat_use_alt
+global compat_same_alt
+global compat_have_dfp
 
 # Load procedures from common libraries. 
 load_lib standard.exp
 load_lib gcc.exp
 
-#
-# compat-use-alt-compiler -- make the alternate compiler the default
-# 
-proc compat-use-alt-compiler { } {
-    global GCC_UNDER_TEST ALT_CC_UNDER_TEST
-    global same_alt
-
-    # We don't need to do this if the alternate compiler is actually
-    # the same as the compiler under test.
-    if { $same_alt == 0 } then {
-	set GCC_UNDER_TEST $ALT_CC_UNDER_TEST
-    }
-}
-
-#
-# compat-use-tst-compiler -- make compiler under test the default
-#
-proc compat-use-tst-compiler { } {
-    global GCC_UNDER_TEST save_gcc_under_test
-    global same_alt
-
-    # We don't need to do this if the alternate compiler is actually
-    # the same as the compiler under test.
-
-    if { $same_alt == 0 } then {
-	set GCC_UNDER_TEST $save_gcc_under_test
-    }
-}
+# Load the language-dependent compabibility support procedures.
+load_lib c-compat.exp
 
 # Load the language-independent compabibility support procedures.
-# This must be done after the compat-use-*-compiler definitions.
 load_lib compat.exp
 
 gcc_init
 
 # Save variables for the C compiler under test, which each test will
 # change a couple of times.  This must be done after calling gcc-init.
-set save_gcc_under_test $GCC_UNDER_TEST
+set compat_save_gcc_under_test $GCC_UNDER_TEST
 
 # Define an identifier for use with this suite to avoid name conflicts
 # with other compat tests running at the same time.
@@ -87,22 +64,31 @@ set sid "c_compat"
 # variable is defined but is set to "same", that means we use the same
 # compiler twice, which is meaningful if the two parts of COMPAT_OPTIONS
 # are different.
-set use_alt 0
-set same_alt 0
+set compat_use_alt 0
+set compat_same_alt 0
+
 if [info exists ALT_CC_UNDER_TEST] then {
-    set use_alt 1
+    set compat_use_alt 1
     if [string match "same" $ALT_CC_UNDER_TEST] then {
-	set same_alt 1
+	set compat_same_alt 1
     }
 }
 
+compat_setup_dfp
+
+if { $compat_have_dfp == 0 } {
+    set skip_dfp "-DSKIP_DECIMAL_FLOAT"
+} else {
+    set skip_dfp ""
+}
+
 set tstobjdir "$tmpdir/gcc.dg-struct-layout-1"
 set generator "$tmpdir/gcc.dg-struct-layout-1_generate"
 
 set generator_src "$srcdir/$subdir/struct-layout-1_generate.c"
 set generator_src "$generator_src $srcdir/$subdir/generate-random.c"
 set generator_src "$generator_src $srcdir/$subdir/generate-random_r.c"
-set generator_cmd "-o $generator $generator_src"
+set generator_cmd "-o $generator $skip_dfp $generator_src"
 
 set status [remote_exec host "$HOSTCC $HOSTCFLAGS $generator_cmd"]
 set status [lindex $status 0]
@@ -123,7 +109,7 @@ if { $status == 0 } then {
 		continue
 	    }
 
-	    compat-execute $src $sid $use_alt
+	    compat-execute $src $sid $compat_use_alt
 	}
     } else {
 	warning "Could not execute gcc.dg/compat/struct-layout-1 generator"
Index: gcc.dg/compat/scalar-by-value-dfp_y.c
===================================================================
--- gcc.dg/compat/scalar-by-value-dfp_y.c	(revision 0)
+++ gcc.dg/compat/scalar-by-value-dfp_y.c	(revision 0)
@@ -0,0 +1,89 @@
+#include <stdarg.h>
+
+#include "compat-common.h"
+
+#ifdef SKIP_VA
+const int test_va = 0;
+#else
+const int test_va = 1;
+#endif
+
+#define T(NAME, TYPE, INITVAL)					\
+extern TYPE g01##NAME, g02##NAME, g03##NAME, g04##NAME;		\
+extern TYPE g05##NAME, g06##NAME, g07##NAME, g08##NAME;		\
+extern TYPE g09##NAME, g10##NAME, g11##NAME, g12##NAME;		\
+extern TYPE g13##NAME, g14##NAME, g15##NAME, g16##NAME;		\
+								\
+extern void check##NAME (TYPE x, TYPE v);			\
+								\
+void								\
+init##NAME (TYPE *p, TYPE v)					\
+{								\
+  *p = v + INITVAL;						\
+}								\
+								\
+void								\
+checkg##NAME (void)						\
+{								\
+  check##NAME (g01##NAME,  1);					\
+  check##NAME (g02##NAME,  2);					\
+  check##NAME (g03##NAME,  3);					\
+  check##NAME (g04##NAME,  4);					\
+  check##NAME (g05##NAME,  5);					\
+  check##NAME (g06##NAME,  6);					\
+  check##NAME (g07##NAME,  7);					\
+  check##NAME (g08##NAME,  8);					\
+  check##NAME (g09##NAME,  9);					\
+  check##NAME (g10##NAME, 10);					\
+  check##NAME (g11##NAME, 11);					\
+  check##NAME (g12##NAME, 12);					\
+  check##NAME (g13##NAME, 13);					\
+  check##NAME (g14##NAME, 14);					\
+  check##NAME (g15##NAME, 15);					\
+  check##NAME (g16##NAME, 16);					\
+}								\
+								\
+void								\
+test##NAME (TYPE x01, TYPE x02, TYPE x03, TYPE x04,		\
+            TYPE x05, TYPE x06, TYPE x07, TYPE x08,		\
+            TYPE x09, TYPE x10, TYPE x11, TYPE x12,		\
+            TYPE x13, TYPE x14, TYPE x15, TYPE x16)		\
+{								\
+  check##NAME (x01,  1);					\
+  check##NAME (x02,  2);					\
+  check##NAME (x03,  3);					\
+  check##NAME (x04,  4);					\
+  check##NAME (x05,  5);					\
+  check##NAME (x06,  6);					\
+  check##NAME (x07,  7);					\
+  check##NAME (x08,  8);					\
+  check##NAME (x09,  9);					\
+  check##NAME (x10, 10);					\
+  check##NAME (x11, 11);					\
+  check##NAME (x12, 12);					\
+  check##NAME (x13, 13);					\
+  check##NAME (x14, 14);					\
+  check##NAME (x15, 15);					\
+  check##NAME (x16, 16);					\
+}								\
+								\
+void								\
+testva##NAME (int n, ...)					\
+{								\
+  int i;							\
+  va_list ap;							\
+  if (test_va)							\
+    {								\
+      va_start (ap, n);						\
+      for (i = 0; i < n; i++)					\
+	{							\
+	  TYPE t = va_arg (ap, TYPE);				\
+	  check##NAME (t, i+1);					\
+	}							\
+      va_end (ap);						\
+    }								\
+}
+
+T(d32, _Decimal32, 1.2df)
+T(d64, _Decimal64, 12.34dd)
+T(d128, _Decimal128, 123.456dl)
Index: gcc.dg/compat/compat.exp
===================================================================
--- gcc.dg/compat/compat.exp	(revision 109530)
+++ gcc.dg/compat/compat.exp	(working copy)
@@ -30,49 +30,27 @@ if $tracelevel then {
 }
 
 global GCC_UNDER_TEST
+global ALT_CC_UNDER_TEST
+global compat_save_gcc_under_test
+global compat_use_alt
+global compat_same_alt
+global compat_have_dfp
 
 # Load procedures from common libraries. 
 load_lib standard.exp
 load_lib gcc.exp
 
-#
-# compat-use-alt-compiler -- make the alternate compiler the default
-# 
-proc compat-use-alt-compiler { } {
-    global GCC_UNDER_TEST ALT_CC_UNDER_TEST
-    global same_alt
-
-    # We don't need to do this if the alternate compiler is actually
-    # the same as the compiler under test.
-    if { $same_alt == 0 } then {
-	set GCC_UNDER_TEST $ALT_CC_UNDER_TEST
-    }
-}
-
-#
-# compat-use-tst-compiler -- make compiler under test the default
-#
-proc compat-use-tst-compiler { } {
-    global GCC_UNDER_TEST save_gcc_under_test
-    global same_alt
-
-    # We don't need to do this if the alternate compiler is actually
-    # the same as the compiler under test.
-
-    if { $same_alt == 0 } then {
-	set GCC_UNDER_TEST $save_gcc_under_test
-    }
-}
+# Load the language-dependent compatibility support procedures.
+load_lib c-compat.exp
 
 # Load the language-independent compabibility support procedures.
-# This must be done after the compat-use-*-compiler definitions.
 load_lib compat.exp
 
 gcc_init
 
 # Save variables for the C compiler under test, which each test will
 # change a couple of times.  This must be done after calling gcc-init.
-set save_gcc_under_test $GCC_UNDER_TEST
+set compat_save_gcc_under_test $GCC_UNDER_TEST
 
 # Define an identifier for use with this suite to avoid name conflicts
 # with other compat tests running at the same time.
@@ -82,15 +60,18 @@ set sid "c_compat"
 # variable is defined but is set to "same", that means we use the same
 # compiler twice, which is meaningful if the two parts of COMPAT_OPTIONS
 # are different.
-set use_alt 0
-set same_alt 0
+set compat_use_alt 0
+set compat_same_alt 0
+
 if [info exists ALT_CC_UNDER_TEST] then {
-    set use_alt 1
+    set compat_use_alt 1
     if [string match "same" $ALT_CC_UNDER_TEST] then {
-	set same_alt 1
+	set compat_same_alt 1
     }
 }
 
+compat_setup_dfp
+
 # Main loop.
 foreach src [lsort [find $srcdir/$subdir *_main.c]] {
     # If we're only testing specific files and this isn't one of them, skip it.
@@ -98,7 +79,7 @@ foreach src [lsort [find $srcdir/$subdir
 	continue
     }
 
-    compat-execute $src $sid $use_alt
+    compat-execute $src $sid $compat_use_alt
 }
 
 # Restore the original compiler under test.
Index: gcc.dg/compat/struct-layout-1_generate.c
===================================================================
--- gcc.dg/compat/struct-layout-1_generate.c	(revision 109530)
+++ gcc.dg/compat/struct-layout-1_generate.c	(working copy)
@@ -46,6 +46,7 @@ enum TYPE
   TYPE_CUINT,
   TYPE_FLOAT,
   TYPE_CFLOAT,
+  TYPE_DEC_FLOAT,
   TYPE_SENUM,
   TYPE_UENUM,
   TYPE_PTR,
@@ -82,7 +83,14 @@ struct types base_types[] = {
 { "float", TYPE_FLOAT, 0, 0 },
 { "double", TYPE_FLOAT, 0, 0 },
 { "long double", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "_Decimal32", TYPE_DEC_FLOAT, 0, 0 },
+{ "_Decimal64", TYPE_DEC_FLOAT, 0, 0 },
+{ "_Decimal128", TYPE_DEC_FLOAT, 0, 0 },
+#define NTYPES1 21
+#else
 #define NTYPES1 18
+#endif
 { "Tchar", TYPE_UINT, 127, 'C' },
 { "Tschar", TYPE_INT, 127, 'C' },
 { "Tuchar", TYPE_UINT, 255, 'C' },
@@ -103,6 +111,11 @@ struct types base_types[] = {
 { "Tfloat", TYPE_FLOAT, 0, 0 },
 { "Tdouble", TYPE_FLOAT, 0, 0 },
 { "Tldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "TDecimal32", TYPE_DEC_FLOAT, 0, 0 },
+{ "TDecimal64", TYPE_DEC_FLOAT, 0, 0 },
+{ "TDecimal128", TYPE_DEC_FLOAT, 0, 0 },
+#endif
 { "enum E0", TYPE_UENUM, 0, ' ' },
 { "enum E1", TYPE_UENUM, 1, ' ' },
 { "enum E2", TYPE_SENUM, 3, ' ' },
@@ -214,6 +227,11 @@ struct types attrib_types[] = {
 { "Talfloat", TYPE_FLOAT, 0, 0 },
 { "Taldouble", TYPE_FLOAT, 0, 0 },
 { "Talldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "TalDecimal32", TYPE_DEC_FLOAT, 0, 0 },
+{ "TalDecimal64", TYPE_DEC_FLOAT, 0, 0 },
+{ "TalDecimal128", TYPE_DEC_FLOAT, 0, 0 },
+#endif
 { "TalE0", TYPE_UENUM, 0, ' ' },
 { "TalE1", TYPE_UENUM, 1, ' ' },
 { "TalE2", TYPE_SENUM, 3, ' ' },
@@ -242,6 +260,11 @@ struct types attrib_types[] = {
 { "Tal1float", TYPE_FLOAT, 0, 0 },
 { "Tal1double", TYPE_FLOAT, 0, 0 },
 { "Tal1ldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "Tal1Decimal32", TYPE_DEC_FLOAT, 0, 0},
+{ "Tal1Decimal64", TYPE_DEC_FLOAT, 0, 0},
+{ "Tal1Decimal128", TYPE_DEC_FLOAT, 0, 0},
+#endif
 { "Tal1E0", TYPE_UENUM, 0, ' ' },
 { "Tal1E1", TYPE_UENUM, 1, ' ' },
 { "Tal1E2", TYPE_SENUM, 3, ' ' },
@@ -270,6 +293,11 @@ struct types attrib_types[] = {
 { "Tal2float", TYPE_FLOAT, 0, 0 },
 { "Tal2double", TYPE_FLOAT, 0, 0 },
 { "Tal2ldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "Tal2Decimal32", TYPE_DEC_FLOAT, 0, 0 },
+{ "Tal2Decimal64", TYPE_DEC_FLOAT, 0, 0 },
+{ "Tal2Decimal128", TYPE_DEC_FLOAT, 0, 0 },
+#endif
 { "Tal2E0", TYPE_UENUM, 0, ' ' },
 { "Tal2E1", TYPE_UENUM, 1, ' ' },
 { "Tal2E2", TYPE_SENUM, 3, ' ' },
@@ -298,6 +326,11 @@ struct types attrib_types[] = {
 { "Tal4float", TYPE_FLOAT, 0, 0 },
 { "Tal4double", TYPE_FLOAT, 0, 0 },
 { "Tal4ldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "Tal4Decimal32", TYPE_DEC_FLOAT, 0, 0 },
+{ "Tal4Decimal64", TYPE_DEC_FLOAT, 0, 0 },
+{ "Tal4Decimal128", TYPE_DEC_FLOAT, 0, 0 },
+#endif
 { "Tal4E0", TYPE_UENUM, 0, ' ' },
 { "Tal4E1", TYPE_UENUM, 1, ' ' },
 { "Tal4E2", TYPE_SENUM, 3, ' ' },
@@ -326,6 +359,11 @@ struct types attrib_types[] = {
 { "Tal8float", TYPE_FLOAT, 0, 0 },
 { "Tal8double", TYPE_FLOAT, 0, 0 },
 { "Tal8ldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "Tal8Decimal32", TYPE_DEC_FLOAT, 0, 0 },
+{ "Tal8Decimal64", TYPE_DEC_FLOAT, 0, 0 },
+{ "Tal8Decimal128", TYPE_DEC_FLOAT, 0, 0 },
+#endif
 { "Tal8E0", TYPE_UENUM, 0, ' ' },
 { "Tal8E1", TYPE_UENUM, 1, ' ' },
 { "Tal8E2", TYPE_SENUM, 3, ' ' },
@@ -354,6 +392,11 @@ struct types attrib_types[] = {
 { "Tal16float", TYPE_FLOAT, 0, 0 },
 { "Tal16double", TYPE_FLOAT, 0, 0 },
 { "Tal16ldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "Tal16Decimal32", TYPE_DEC_FLOAT, 0, 0 },
+{ "Tal16Decimal64", TYPE_DEC_FLOAT, 0, 0 },
+{ "Tal16Decimal128", TYPE_DEC_FLOAT, 0, 0 },
+#endif
 { "Tal16E0", TYPE_UENUM, 0, ' ' },
 { "Tal16E1", TYPE_UENUM, 1, ' ' },
 { "Tal16E2", TYPE_SENUM, 3, ' ' },
@@ -472,6 +515,11 @@ struct types attrib_array_types[] = {
 { "Talx1float", TYPE_FLOAT, 0, 0 },
 { "Talx1double", TYPE_FLOAT, 0, 0 },
 { "Talx1ldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "Talx1Decimal32", TYPE_DEC_FLOAT, 0 ,0 },
+{ "Talx1Decimal64", TYPE_DEC_FLOAT, 0 ,0 },
+{ "Talx1Decimal128", TYPE_DEC_FLOAT, 0 ,0 },
+#endif
 { "Talx1E0", TYPE_UENUM, 0, ' ' },
 { "Talx1E1", TYPE_UENUM, 1, ' ' },
 { "Talx1E2", TYPE_SENUM, 3, ' ' },
@@ -496,6 +544,11 @@ struct types attrib_array_types[] = {
 { "Talx2float", TYPE_FLOAT, 0, 0 },
 { "Talx2double", TYPE_FLOAT, 0, 0 },
 { "Talx2ldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "Talx2Decimal32", TYPE_DEC_FLOAT, 0 , 0 },
+{ "Talx2Decimal64", TYPE_DEC_FLOAT, 0 , 0 },
+{ "Talx2Decimal128", TYPE_DEC_FLOAT, 0 , 0 },
+#endif
 { "Talx2E0", TYPE_UENUM, 0, ' ' },
 { "Talx2E1", TYPE_UENUM, 1, ' ' },
 { "Talx2E2", TYPE_SENUM, 3, ' ' },
@@ -518,6 +571,11 @@ struct types attrib_array_types[] = {
 { "Talx4float", TYPE_FLOAT, 0, 0 },
 { "Talx4double", TYPE_FLOAT, 0, 0 },
 { "Talx4ldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "Talx4Decimal32", TYPE_DEC_FLOAT, 0 , 0 },
+{ "Talx4Decimal64", TYPE_DEC_FLOAT, 0 , 0 },
+{ "Talx4Decimal128", TYPE_DEC_FLOAT, 0 , 0 },
+#endif
 { "Talx4E0", TYPE_UENUM, 0, ' ' },
 { "Talx4E1", TYPE_UENUM, 1, ' ' },
 { "Talx4E2", TYPE_SENUM, 3, ' ' },
@@ -536,7 +594,11 @@ struct types attrib_array_types[] = {
 { "Taly8cptr", TYPE_PTR, 0, 0 },
 { "Taly8iptr", TYPE_PTR, 0, 0 },
 { "Talx8double", TYPE_FLOAT, 0, 0 },
-{ "Talx8ldouble", TYPE_FLOAT, 0, 0 }
+{ "Talx8ldouble", TYPE_FLOAT, 0, 0 },
+#ifndef SKIP_DECIMAL_FLOAT
+{ "Talx8Decimal64", TYPE_DEC_FLOAT, 0, 0 },
+{ "Talx8Decimal128", TYPE_DEC_FLOAT, 0, 0 }
+#endif
 #define NAATYPES2 (sizeof (attrib_array_types) / sizeof (attrib_array_types[0]))
 };
 struct types complex_attrib_array_types[] = {
@@ -950,6 +1012,11 @@ output_FNB (char mode, struct entry *e)
 {
   unsigned long long int l1, l2, m;
   int signs = 0;
+#ifndef SKIP_DECIMAL_FLOAT
+  int suffix = 0;
+  char DEC_SUFFIX[3][3]={"DF","DD","DL"};
+#endif
+  
   const char *p, *q;
 
   if (e->type->type == TYPE_OTHER)
@@ -991,6 +1058,29 @@ output_FNB (char mode, struct entry *e)
       fprintf (outfile, "%s%f,%s%f", (signs & 1) ? "-" : "",
 	       ((double) l1) / 64, (signs & 2) ? "-" : "", ((double) l2) / 64);
       break;
+#ifndef SKIP_DECIMAL_FLOAT
+    case TYPE_DEC_FLOAT:
+      l1 &= 0xffffff;
+      l2 &= 0xffffff;
+      signs = generate_random () & 3;
+      
+      /* Get the suffix of Decimal Floting Points per 
+	 e->type->name.  Distinguish these three DFP types by
+         e->type->name.  */
+      if (strstr(e->type->name, "Decimal32")) suffix=0;
+      else if (strstr(e->type->name, "Decimal64")) suffix=1;
+      else if (strstr(e->type->name, "Decimal128")) suffix=2;
+      else
+	abort ();
+
+      /* Formatted input/output specifiers for DFP types have not been
+         implemented in GLIBC.  %f here used in fprintf is just to 
+         dump the numbers to outfile.  */
+      fprintf (outfile, "%s%f%s,%s%f%s", 
+	       (signs & 1) ? "-" : "", ((double) l1) / 64, DEC_SUFFIX[suffix], 
+	       (signs & 2) ? "-" : "", ((double) l2) / 64, DEC_SUFFIX[suffix]);
+      break;
+#endif
     case TYPE_CINT:
       signs = generate_random () & 3;
       l1 &= e->type->maxval;
Index: gcc.dg/debug/dwarf2/dwarf-float.c
===================================================================
--- gcc.dg/debug/dwarf2/dwarf-float.c	(revision 0)
+++ gcc.dg/debug/dwarf2/dwarf-float.c	(revision 0)
@@ -0,0 +1,15 @@
+/* Verify the DWARF encoding of C99 floating point types.  */
+
+/* { dg-do compile */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-final { scan-assembler "0x4.*DW_AT_encoding" } } */
+/* { dg-final { scan-assembler "0x4.*DW_AT_byte_size" } } */
+/* { dg-final { scan-assembler "0x8.*DW_AT_byte_size" } } */
+/* { dg-final { scan-assembler "0x10.*DW_AT_byte_size" } } */
+
+void foo ()
+{
+  float f = 1.5f;
+  double d = 1.5;
+  long double l = 1.5l;
+}
Index: gcc.dg/debug/dwarf2/dwarf-dfp.c
===================================================================
--- gcc.dg/debug/dwarf2/dwarf-dfp.c	(revision 0)
+++ gcc.dg/debug/dwarf2/dwarf-dfp.c	(revision 0)
@@ -0,0 +1,15 @@
+/* Verify the DWARF encoding of C99 decimal floating point types.  */
+
+/* { dg-do compile */
+/* { dg-require-effective-target dfp } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-final { scan-assembler "0x10.*DW_AT_encoding" } } */
+/* { dg-final { scan-assembler "0x4.*DW_AT_byte_size" } } */
+/* { dg-final { scan-assembler "0x8.*DW_AT_byte_size" } } */
+/* { dg-final { scan-assembler "0x10.*DW_AT_byte_size" } } */
+
+void foo ()
+{
+  _Decimal32 f = 1.5df;
+  _Decimal64 d = 1.5dd;
+  _Decimal128 l = 1.5dl;
+}
Index: gcc.dg/format/dfp-scanf-1.c
===================================================================
--- gcc.dg/format/dfp-scanf-1.c	(revision 0)
+++ gcc.dg/format/dfp-scanf-1.c	(revision 0)
@@ -0,0 +1,99 @@
+/* Test for scanf formats for Decimal Floating Point types.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target dfp } */
+/* { dg-options "-Wformat" } */
+
+
+#include "format.h"
+
+void
+voo (_Decimal32 *x, _Decimal64 *y, _Decimal128 *z, int *i, unsigned int *j,
+     double *d, char **p)
+{
+  /* See ISO/IEC DTR 24732 subclause 9.3 (currently Working Draft 5 from
+      2005-03-06).  */
+  /* Formatted input/output specifiers.  */
+
+  /* Check lack of warnings for valid usage.  */
+
+  scanf ("%Hf", x);
+  scanf ("%HF", x);
+  scanf ("%He", x);
+  scanf ("%HE", x);
+  scanf ("%Hg", x);
+  scanf ("%HG", x);
+
+  scanf ("%Df", y);
+  scanf ("%DF", y);
+  scanf ("%De", y);
+  scanf ("%DE", y);
+  scanf ("%Dg", y);
+  scanf ("%DG", y);
+
+  scanf ("%DDf", z);
+  scanf ("%DDF", z);
+  scanf ("%DDe", z);
+  scanf ("%DDE", z);
+  scanf ("%DDg", z);
+  scanf ("%DDG", z);
+
+  scanf ("%DG%DDE%HF%DDe%He%HE%DF%DDF%De%DDG%HG%Df%Hg%DE%DDf%Dg%DDg%Hf\n",
+           y, z, x, z, x, x, y, z, y, z, x, y, x, y, z, y, z, x);
+
+  /* Check warnings for type mismatches.  */
+
+  scanf ("%Hf", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%HF", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%He", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%HE", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%Hg", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%HG", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%Hf", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%HF", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%He", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%HE", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%Hg", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  scanf ("%HG", z);	/* { dg-warning "expects type" "bad use of %H" } */
+
+  scanf ("%Df", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%DF", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%De", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%DE", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%Dg", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%DG", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%Df", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%DF", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%De", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%DE", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%Dg", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  scanf ("%DG", z);	/* { dg-warning "expects type" "bad use of %D" } */
+
+  scanf ("%DDf", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDF", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDe", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDE", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDg", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDG", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDf", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDF", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDe", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDE", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDg", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  scanf ("%DDG", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+
+  /* Check for warnings for bad use of H, D, and DD length specifiers.  */
+
+  scanf ("%Hd\n", i);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%Hi\n", i);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%Ho\n", j);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%Hu\n", j);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%Hx\n", j);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%HX\n", j);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%Ha\n", d);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%HA\n", d);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%Hc\n", i);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%Hs\n", p);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%Hp\n", p);	/* { dg-warning "length" "bad use of %H" } */
+  scanf ("%Hn\n", p);	/* { dg-warning "length" "bad use of %H" } */
+}
Index: gcc.dg/format/dfp-printf-1.c
===================================================================
--- gcc.dg/format/dfp-printf-1.c	(revision 0)
+++ gcc.dg/format/dfp-printf-1.c	(revision 0)
@@ -0,0 +1,122 @@
+/* Test for printf formats for Decimal Floating Point types.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target dfp } */
+/* { dg-options "-Wformat" } */
+
+extern int printf (const char *restrict, ...);
+
+void
+foo (_Decimal32 x, _Decimal64 y, _Decimal128 z, int i, unsigned int j,
+     double d, char *p)
+{
+  /* See ISO/IEC DTR 24732 subclause 9.3 (currently Working Draft 5 from
+      2005-03-06).  */
+  /* Formatted input/output specifiers.  */
+
+  /* Check lack of warnings for valid usage.  */
+
+  printf ("%Hf\n", x);
+  printf ("%HF\n", x);
+  printf ("%He\n", x);
+  printf ("%HE\n", x);
+  printf ("%Hg\n", x);
+  printf ("%HG\n", x);
+
+  printf ("%Df\n", y);
+  printf ("%DF\n", y);
+  printf ("%De\n", y);
+  printf ("%DE\n", y);
+  printf ("%Dg\n", y);
+  printf ("%DG\n", y);
+
+  printf ("%DDf\n", z);
+  printf ("%DDF\n", z);
+  printf ("%DDe\n", z);
+  printf ("%DDE\n", z);
+  printf ("%DDg\n", z);
+  printf ("%DDG\n", z);
+
+  printf ("%DG%DDE%HF%DDe%He%HE%DF%DDF%De%DDG%HG%Df%Hg%DE%DDf%Dg%DDg%Hf\n",
+           y, z, x, z, x, x, y, z, y, z, x, y, x, y, z, y, z, x);
+
+  /* Check warnings for type mismatches.  */
+
+  printf ("%Hf\n", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%HF\n", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%He\n", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%HE\n", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%Hg\n", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%HG\n", y);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%Hf\n", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%HF\n", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%He\n", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%HE\n", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%Hg\n", z);	/* { dg-warning "expects type" "bad use of %H" } */
+  printf ("%HG\n", z);	/* { dg-warning "expects type" "bad use of %H" } */
+
+  printf ("%Df\n", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%DF\n", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%De\n", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%DE\n", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%Dg\n", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%DG\n", x);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%Df\n", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%DF\n", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%De\n", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%DE\n", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%Dg\n", z);	/* { dg-warning "expects type" "bad use of %D" } */
+  printf ("%DG\n", z);	/* { dg-warning "expects type" "bad use of %D" } */
+
+  printf ("%DDf\n", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDF\n", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDe\n", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDE\n", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDg\n", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDG\n", x);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDf\n", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDF\n", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDe\n", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDE\n", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDg\n", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+  printf ("%DDG\n", y);	/* { dg-warning "expects type" "bad use of %DD" } */
+
+  /* Check for warnings for bad use of H, D, and DD length specifiers.  */
+
+  printf ("%Hd\n", i);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%Hi\n", i);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%Ho\n", j);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%Hu\n", j);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%Hx\n", j);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%HX\n", j);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%Ha\n", d);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%HA\n", d);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%Hc\n", i);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%Hs\n", p);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%Hp\n", p);	/* { dg-warning "length" "bad use of %H" } */
+  printf ("%Hn\n", p);	/* { dg-warning "length" "bad use of %H" } */
+
+  /* Sanity checks for flags, field width, and precision in formats for
+     DFP types.  */
+
+  printf ("%-Hf\n", x);
+  printf ("%+HF\n", x);
+  printf ("% He\n", x);
+  printf ("%#HE\n", x);
+  printf ("%0Hg\n", x);
+  printf ("%#0HG\n", x);
+
+  printf ("%0#Df\n", y);
+  printf ("%0DF\n", y);
+  printf ("%#De\n", y);
+  printf ("%-#DE\n", y);
+  printf ("%-#0Dg\n", y);  /* { dg-warning "flag ignored" "ignore flag" } */
+  printf ("%0+ DG\n", y);  /* { dg-warning "flag ignored" "ignore flag" } */
+
+  printf ("%DDf\n", z);
+  printf ("%0DDF\n", z);
+  printf ("%#0DDe\n", z);
+  printf ("%+DDE\n", z);
+  printf ("%0-#DDg\n", z); /* { dg-warning "flag ignored" "ignore flag" } */
+  printf ("% DDG\n", z);
+}
Index: gcc.misc-tests/dectest.exp
===================================================================
--- gcc.misc-tests/dectest.exp	(revision 0)
+++ gcc.misc-tests/dectest.exp	(revision 0)
@@ -0,0 +1,526 @@
+# Copyright 2005 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# DejaGnu test driver around Mike Cowlishaw's testsuite for decimal
+# decimal arithmetic ("dectest").  See:
+#    <http://www2.hursley.ibm.com/decimal/dectest.html>.
+#
+# Contributed by Ben Elliston <bje@au.ibm.com>.
+
+set TORTURE_OPTIONS [list {} -O1 -O2 -O3 -msoft-float]
+
+# On x86 and x86-64 systems, -Os makes the stack alignment too small,
+# leading to segmentation faults when executing SSE instructions.
+# Force the alignment of the stack to 2^4 (16) bytes.
+
+if {[istarget i?86-*-linux-gnu] || [istarget x86_64-*-linux-gnu]} {
+    lappend TORTURE_OPTIONS {-Os -mpreferred-stack-boundary=4}
+} else {
+    lappend TORTURE_OPTIONS {-Os}
+}
+
+proc target-specific-flags {} {
+  set result "-frounding-math "
+  return $result
+}
+  
+# Load support procs (borrow these from c-torture).
+load_lib c-torture.exp
+load_lib target-supports.exp
+
+# Skip these tests for targets that don't support this extension.
+if { ![check_effective_target_dfp] } {
+    return
+}
+
+# The list format is [coefficient, max-exponent, min-exponent].
+set properties(_Decimal32) [list 7 96 -95]
+set properties(_Decimal64) [list 16 384 -383]
+set properties(_Decimal128) [list 34 6144 -6143]
+
+# Operations implemented by the compiler.
+set operators(add) {+}
+set operators(compare) {==}
+set operators(divide) {/}
+set operators(multiply) {*}
+set operators(subtract) {-}
+set operators(minus) {-}
+set operators(plus) {+}
+set operators(apply) {}
+
+# Operations imlemented by the library.
+set libfuncs(abs) fabsl
+set libfuncs(squareroot) sqrtl
+set libfuncs(max) fmaxl
+set libfuncs(min) fminl
+set libfuncs(quantize) quantize
+set libfuncs(samequantum) samequantum
+set libfuncs(power) powl
+set libfuncs(toSci) unknown
+set libfuncs(tosci) unknown
+set libfuncs(toEng) unknown
+set libfuncs(toeng) unknown
+set libfuncs(divideint) unknown
+set libfuncs(rescale) unknown
+set libfuncs(remainder) unknown
+set libfuncs(remaindernear) unknown
+set libfuncs(normalize) unknown
+set libfuncs(tointegral) unknown
+set libfuncs(trim) unknown
+
+# Run all of the tests listed in TESTCASES by invoking df-run-test on
+# each.  Skip tests that not included by the user invoking runtest
+# with the foo.exp=test.c syntax.
+
+proc dfp-run-tests { testcases } {
+    global runtests
+    foreach test $testcases {
+	# If we're only testing specific files and this isn't one of
+	# them, skip it.
+	if ![runtest_file_p $runtests $test] continue
+	dfp-run-test $test
+    }
+}
+
+# Run a single test case named by TESTCASE.
+# Called for each test by dfp-run-tests.
+
+proc dfp-run-test { testcase } {
+    set fd [open $testcase r]
+    while {[gets $fd line] != -1} {
+	switch -regexp -- $line {
+	    {^[ \t]*--.*$} {
+		# Ignore comments.
+	    }
+	    {^[ \t]*$} {
+		# Ignore blank lines.
+	    }
+	    {^[ \t]*[^:]*:[^:]*} {
+		regsub -- {[ \t]*--.*$} $line {} line
+		process-directive $line
+	    }
+	    default {
+		process-test-case $testcase $line
+	    }
+	}
+    }
+    close $fd
+}
+
+# Return the appropriate constant from <fenv.h> for MODE.
+
+proc c-rounding-mode { mode } { 
+    switch [string tolower $mode] {
+	"floor"		{ return 0 } # FE_DEC_DOWNWARD
+	"half_even"	{ return 1 } # FE_DEC_TONEARESTFROMZERO
+	"half_up"	{ return 2 } # FE_DEC_TONEAREST
+	"down"		{ return 3 } # FE_DEC_TOWARDZERO
+	"ceiling"	{ return 4 } # FE_DEC_UPWARD
+    }
+    error "unsupported rounding mode ($mode)"
+}
+
+# Return a string of C code that forms the preamble to perform the
+# test named ID.
+
+proc c-test-preamble { id } {
+    append result "/* Machine generated test case for $id */\n"
+    append result "\n"
+    append result "\#include <assert.h>\n"
+    append result "\#include <fenv.h>\n"
+    append result "\#include <math.h>\n"
+    append result "\n"
+    append result "int main ()\n"
+    append result "\{"
+    return $result
+}
+
+# Return a string of C code that forms the postable to the test named ID.
+
+proc c-test-postamble { id } {
+    return "\}"
+}
+
+# Generate a C unary expression that applies OPERATION to OP.
+
+proc c-unary-expression {operation op} {
+    global operators
+    global libfuncs
+    if [catch {set result "$operators($operation) $op"}] {
+	# If operation isn't in the operators or libfuncs arrays,
+	# we'll throw an error.  That's what we want.
+	# FIXME: append d32, etc. here.
+	set result "$libfuncs($operation) ($op)"
+    }
+    return $result
+}
+
+# Generate a C binary expression that applies OPERATION to OP1 and OP2.
+
+proc c-binary-expression {operation op1 op2} {
+    global operators
+    global libfuncs
+    if [catch {set result "$op1 $operators($operation) $op2"}] {
+	# If operation isn't in the operators or libfuncs arrays,
+	# we'll throw an error.  That's what we want.
+	set result "$libfuncs($operation) ($op1, $op2)"
+    }
+    return $result
+}
+
+# Return the most appropriate C type (_Decimal32, etc) for this test.
+
+proc c-decimal-type { } {
+    global directives
+    if [catch {set precision $directives(precision)}] {
+	set precision "_Decimal128"
+    }  
+    if { $precision == 7 } {
+	set result "_Decimal32"
+    } elseif {$precision == 16} {
+	set result "_Decimal64"
+    } elseif {$precision == 34} {
+	set result "_Decimal128"
+    } else {
+	error "Unsupported precision"
+    }
+    return $result
+}
+
+# Return the size of the most appropriate C type, in bytes.
+
+proc c-sizeof-decimal-type { } {
+    switch [c-decimal-type] {
+	"_Decimal32"    { return 4 }
+	"_Decimal64"    { return 8 }
+	"_Decimal128"   { return 16 }
+    }
+    error "Unsupported precision"
+}
+
+# Return the right literal suffix for CTYPE.
+
+proc c-type-suffix { ctype } {
+    switch $ctype {
+        "_Decimal32"   { return "df" }
+        "_Decimal64"   { return "dd" }
+        "_Decimal128"  { return "dl" }
+        "float"        { return "f" }
+	"long double"  { return "l" }
+    }
+    return ""
+}
+
+proc nan-p { operand } {
+    if {[string match "NaN*" $operand] || [string match "-NaN*" $operand]} {
+	return 1
+    } else {
+	return 0
+    }
+}
+
+proc infinity-p { operand } {
+    if {[string match "Inf*" $operand] || [string match "-Inf*" $operand]} {
+	return 1
+    } else {
+	return 0
+    }
+}
+
+proc isnan-builtin-name { } {
+    set bits [expr [c-sizeof-decimal-type] * 8]
+    return "__builtin_isnand$bits"
+}
+
+proc isinf-builtin-name { } {
+    set bits [expr [c-sizeof-decimal-type] * 8]
+    return "__builtin_isinfd$bits"
+}
+
+# Return a string that declares a C union containing the decimal type
+# and an unsigned char array of the right size.
+
+proc c-union-decl { } {
+    append result "  union {\n"
+    append result "    [c-decimal-type] d;\n"
+    append result "    unsigned char bytes\[[c-sizeof-decimal-type]\];\n"
+    append result "  } u;"
+    return $result
+}
+
+proc transform-hex-constant {value} {
+    regsub \# $value {} value
+    regsub -all (\.\.) $value {0x\1, } bytes
+    return [list $bytes]
+}
+
+# Create a C program file (named using ID) containing a test for a
+# binary OPERATION on OP1 and OP2 that expects RESULT and CONDITIONS.
+
+proc make-c-test {testcase id operation result conditions op1 {op2 "NONE"}} {
+    global directives
+    set filename ${id}.c
+    set outfd [open $filename w]
+
+    puts $outfd [c-test-preamble $id]
+    puts $outfd [c-union-decl]
+    if {[string compare $result ?] != 0} {
+	if {[string index $result 0] == "\#"} {
+	    puts $outfd "  static unsigned char compare\[[c-sizeof-decimal-type]\] = [transform-hex-constant $result];"
+	}
+    }
+    if {[string compare $op2 NONE] == 0} {
+	if {[string index $op1 0] == "\#"} {
+	    puts $outfd "  static unsigned char fill\[[c-sizeof-decimal-type]\] = [transform-hex-constant $op1];"
+	}
+    }
+
+    puts $outfd ""
+    puts $outfd "  /*  FIXME: Set rounding mode with fesetround() once in libc.  */"
+    puts $outfd "  __dfp_set_round ([c-rounding-mode $directives(rounding)]);"
+    puts $outfd ""
+
+    # Build the expression to be tested.
+    if {[string compare $op2 NONE] == 0} {
+	if {[string index $op1 0] == "\#"} {
+	    puts $outfd "  memcpy (u.bytes, fill, [c-sizeof-decimal-type]);"
+	} else {
+	    puts $outfd "  u.d = [c-unary-expression $operation [c-operand $op1]];"
+	}
+    } else {
+	puts $outfd "  u.d = [c-binary-expression $operation [c-operand $op1] [c-operand $op2]];"
+    }
+
+    # Test the result.
+    if {[string compare $result ?] != 0} {
+	# Not an undefined result ..
+	if {[string index $result 0] == "\#"} {
+	    # Handle hex comparisons.
+	    puts $outfd "  return memcmp (u.bytes, compare, [c-sizeof-decimal-type]);"
+	} elseif {[nan-p $result]} {
+	    puts $outfd "  return ![isnan-builtin-name] (u.d);"
+	} elseif {[infinity-p $result]} {
+	    puts $outfd "  return ![isinf-builtin-name] (u.d);"
+	} else {
+	    # Ordinary values.
+	    puts $outfd "  return !(u.d == [c-operand $result]);"
+	}
+    } else {
+	puts $outfd "  return 0;"
+    }
+
+    puts $outfd [c-test-postamble $id]
+    close $outfd
+    return $filename
+}
+
+# Is the test supported for this target?
+
+proc supported-p { id op } {
+    global directives
+    global libfuncs
+
+    # Ops that are unsupported.  Many of these tests fail because they
+    # do not tolerate the C front-end rounding the value of floating
+    # point literals to suit the type of the constant.  Otherwise, by
+    # treating the `apply' operator like C assignment, some of them do
+    # pass.
+    switch -- $op {
+	apply		{ return 0 }
+    }
+
+    # Ditto for the following miscellaneous tests.
+    switch $id {
+	addx1130	{ return 0 }
+	addx1131	{ return 0 }
+	addx1132	{ return 0 }
+	addx1133	{ return 0 }
+	addx1134	{ return 0 }
+	addx1135	{ return 0 }
+	addx1136	{ return 0 }
+	addx1138	{ return 0 }
+	addx1139	{ return 0 }
+	addx1140	{ return 0 }
+	addx1141	{ return 0 }
+	addx1142	{ return 0 }
+	addx1151	{ return 0 }
+	addx1152	{ return 0 }
+	addx1153	{ return 0 }
+	addx1154	{ return 0 }
+	addx1160	{ return 0 }
+	addx690		{ return 0 }
+	mulx263		{ return 0 }
+	subx947		{ return 0 }
+    }
+
+    if [info exist libfuncs($op)] {
+	# No library support for now.
+	return 0
+    }
+    if [catch {c-rounding-mode $directives(rounding)}] {
+	# Unsupported rounding mode.
+	return 0
+    }
+    if [catch {c-decimal-type}] {
+	# Unsupported precision.
+	return 0
+    }
+    return 1
+}
+
+# Break LINE into a list of tokens.  Be sensitive to quoting.
+# There has to be a better way to do this :-|
+
+proc tokenize { line } {
+    set quoting 0
+    set tokens [list]
+
+    foreach char [split $line {}] {
+	if {!$quoting} {
+	    if { [info exists token] && $char == " " } {
+		if {[string compare "$token" "--"] == 0} {
+		    # Only comments remain.
+		    return $tokens
+		}
+		lappend tokens $token
+		unset token
+	    } else {
+		if {![info exists token] && $char == "'" } {
+		    set quoting 1
+		} else {
+		    if { $char != " " } {
+			append token $char
+		    }
+		}
+	    }
+	} else {
+	    # Quoting.
+	    if { $char == "'" } {
+		set quoting 0
+		if [info exists token] {
+		    lappend tokens $token
+		    unset token
+		} else {
+		    lappend tokens {}
+		}
+	    } else {
+		append token $char
+	    }
+	}
+    }
+    # Flush any residual token.
+    if {[info exists token] && [string compare $token "--"]} {
+	lappend tokens $token
+    }
+    return $tokens
+}
+
+# Process a directive in LINE.
+
+proc process-directive { line } {
+    global directives
+    set keyword [string tolower [string trim [lindex [split $line :] 0]]]
+    set value [string tolower [string trim [lindex [split $line :] 1]]]
+    set directives($keyword) $value
+}
+
+# Produce a C99-valid floating point literal.
+
+proc c-operand {operand} {
+    set bits [expr 8 * [c-sizeof-decimal-type]]
+
+    switch -glob -- $operand {
+	"Inf*"		{ return "__builtin_infd${bits} ()" }
+	"-Inf*"		{ return "- __builtin_infd${bits} ()" }
+    	"NaN*"		{ return "__builtin_nand${bits} (\"\")" }
+	"-NaN*"		{ return "- __builtin_nand${bits} (\"\")" }
+	"sNaN*"		{ return "__builtin_nand${bits} (\"\")" }
+	"-sNaN*"	{ return "- __builtin_nand${bits} (\"\")" }
+    }
+
+    if {[string first . $operand] < 0 && \
+	    [string first E $operand] < 0 && \
+	    [string first e $operand] < 0} {
+	append operand .
+    }
+    set suffix [c-type-suffix [c-decimal-type]]
+    return [append operand $suffix]
+}
+
+# Process an arithmetic test in LINE from TESTCASE.
+
+proc process-test-case { testcase line } {
+    set testfile [file tail $testcase]
+
+    # Compress multiple spaces down to one.
+    regsub -all {  *} $line { } line
+
+    set args [tokenize $line]
+    if {[llength $args] < 5} {
+	error "Skipping invalid test: $line"
+	return
+    }
+    
+    set id [string trim [lindex $args 0]]
+    set operation [string trim [lindex $args 1]]
+    set operand1 [string trim [lindex $args 2]]
+    
+    if { [string compare [lindex $args 3] -> ] == 0 } {
+	# Unary operation.
+	set operand2 NONE
+	set result_index 4
+	set cond_index 5
+    } else {
+	# Binary operation.
+	set operand2 [string trim [lindex $args 3]]
+	if { [string compare [lindex $args 4] -> ] != 0 } {
+	    warning "Skipping invalid test: $line"
+	    return
+	}
+	set result_index 5
+	set cond_index 6
+    }
+
+    set result [string trim [lindex $args $result_index]]
+    set conditions [list]
+    for { set i $cond_index } { $i < [llength $args] } { incr i } {
+	lappend conditions [string tolower [lindex $args $i]]
+    }
+    
+    # If this test is unsupported, say so.
+    if ![supported-p $id $operation] {
+	unsupported "$testfile ($id)"
+	return
+    }
+
+    if {[string compare $operand1 \#] == 0 || \
+	    [string compare $operand2 \#] == 0} {
+	unsupported "$testfile ($id), null reference"
+ 	return
+    }
+
+    # Construct a C program and then compile/execute it on the target.
+    # Grab some stuff from the c-torture.exp test driver for this.
+
+    set cprog [make-c-test $testfile $id $operation $result $conditions $operand1 $operand2]
+    c-torture-execute $cprog [target-specific-flags]
+}
+
+### Script mainline:
+
+if [catch {set testdir $env(DECTEST)}] {
+    # If $DECTEST is unset, skip this test driver altogether.
+    return
+}
+
+note "Using tests in $testdir"
+dfp-run-tests [lsort [glob -nocomplain $testdir/*.decTest]]
+unset testdir
Index: lib/c-compat.exp
===================================================================
--- lib/c-compat.exp	(revision 0)
+++ lib/c-compat.exp	(revision 0)
@@ -0,0 +1,110 @@
+#   Copyright (C) 2002, 2003, 2005, 02005 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# gcc-patches@gcc.gnu.org
+
+# Globals.
+
+global compat_use_alt
+global compat_same_alt
+global compat_have_dfp
+global compat_skip_list
+
+# This file defines procs for determining features supported by both C
+# compilers for compatibility tests.
+
+load_lib target-supports.exp
+
+#
+# compat-use-alt-compiler -- make the alternate compiler the default
+# 
+proc compat-use-alt-compiler { } {
+    global GCC_UNDER_TEST ALT_CC_UNDER_TEST
+    global compat_same_alt
+
+    # We don't need to do this if the alternate compiler is actually
+    # the same as the compiler under test.
+    if { $compat_same_alt == 0 } then {
+	set GCC_UNDER_TEST $ALT_CC_UNDER_TEST
+    }
+}
+
+#
+# compat-use-tst-compiler -- make compiler under test the default
+#
+proc compat-use-tst-compiler { } {
+    global GCC_UNDER_TEST compat_save_gcc_under_test
+    global compat_same_alt
+
+    # We don't need to do this if the alternate compiler is actually
+    # the same as the compiler under test.
+
+    if { $compat_same_alt == 0 } then {
+	set GCC_UNDER_TEST $compat_save_gcc_under_test
+    }
+}
+
+# Find out whether both compilers support decimal float types.
+proc compat_setup_dfp { } {
+    global compat_use_alt
+    global compat_same_alt
+    global compat_have_dfp
+
+    verbose "compat_setup_dfp: $compat_use_alt $compat_same_alt" 2
+    set compat_have_dfp 1
+    # If there is an alternate compiler, does it support decimal float types?
+    if { $compat_use_alt == 1 && $compat_same_alt == 0 } {
+	compat-use-alt-compiler
+	set compat_have_dfp [check_dfp]
+	compat-use-tst-compiler
+	verbose "compat_have_dfp for alt compiler: $compat_have_dfp" 2
+    }
+    # Does the compiler under test support it?
+    if { $compat_have_dfp == 1 } {
+	set compat_have_dfp [check_dfp]
+	verbose "compat_have_dfp for tst compiler: $compat_have_dfp" 2
+    }
+
+    # If decimal float is not supported, add it to the skip list, which
+    # affects code in the header files.
+    if { $compat_have_dfp == 0 } {
+	global compat_skip_list
+	lappend compat_skip_list "DECIMAL_FLOAT"
+    }
+}
+
+# Return 1 if the compiler supports decimal float types, 0 otherwise.
+#
+# Don't use check_effective_target since this will differ depending
+# on the compiler, not the target.
+#
+proc check_dfp { } {
+    set result [string match "" [get_compiler_messages dfp2 object {
+	_Decimal32 x; _Decimal64 y; _Decimal128 z;
+    }]]
+    return $result
+}
+
+# If either compiler does not support decimal float types, skip this test.
+
+proc dg-require-compat-dfp { args } {
+    global compat_have_dfp
+    if { $compat_have_dfp == 0 } {
+	upvar dg-do-what dg-do-what
+	set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+    }
+}
Index: lib/compat.exp
===================================================================
--- lib/compat.exp	(revision 109530)
+++ lib/compat.exp	(working copy)
@@ -1,4 +1,4 @@
-# Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -62,7 +62,8 @@ if ![info exists COMPAT_SKIPS] {
     set COMPAT_SKIPS [list {}]
 }
 
-set skip_list $COMPAT_SKIPS
+global compat_skip_list
+set compat_skip_list $COMPAT_SKIPS
 
 load_lib dg.exp
 load_lib gcc-dg.exp
@@ -81,10 +82,10 @@ proc compat-obj { source dest optall opt
     global testcase
     global tool
     global compiler_conditional_xfail_data
-    global skip_list
+    global compat_skip_list
 
     # Add the skip specifiers.
-    foreach skip $skip_list {
+    foreach skip $compat_skip_list {
 	if { ![string match $skip ""] } {
 	    lappend optall "-DSKIP_$skip"
 	}
Index: lib/target-supports.exp
===================================================================
--- lib/target-supports.exp	(revision 109530)
+++ lib/target-supports.exp	(working copy)
@@ -1050,6 +1050,25 @@ proc check_effective_target_lp64 { } {
     return $et_lp64_saved
 }
 
+# Return 1 if the target supports Decimal Floating Point, 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_dfp { } {
+    global et_dfp_saved
+
+    if [info exists et_dfp_saved] {
+	verbose "check_effective_target_dfp: using cached result" 2
+    } else {
+	verbose "check_effective_target_dfp: compiling source" 2
+	set et_dfp_saved [string match "" [get_compiler_messages dfp object {
+	    _Decimal32 x; _Decimal64 y; _Decimal128 z;
+	}]]
+    }
+    verbose "check_effective_target_dfp: returning $et_dfp_saved" 2
+    return $et_dfp_saved
+}
+
 # Return 1 if the target needs a command line argument to enable a SIMD
 # instruction set.
 #


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]