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] C front end change for decimal float types


I've submitted this a couple of times before, first in December at
http://gcc.gnu.org/ml/gcc-patches/2005-12/msg01721.html, and have
pinged a couple times more.  This patch mixed-mode operations with
decimal float types only when the other type involved is another
decimal float type or an integer type.  This restriction was added
in draft TR N1150; earlier drafts had specified usual arithmetic
conversions for mixed-mode operations involving decimal float types.

I also need to update the documentation for the decimal float
extension; there's a patch for that at
http://gcc.gnu.org/ml/gcc-patches/2006-03/msg00958.html, but with a
new draft TR expected soon the docs will soon need another update.

Tested on powerpc64-linux with -m32/-m64 with --enable-decimal-float;
OK for mainline?

2006-05-15  Janis Johnson  <janis187@us.ibm.com>

	* c-typeck.c (c_common_type): Disallow operations between decimal
	float and various other types.
	* convert.c (convert_to_real): Don't short-circuit conversion for
	decimal float.

	* gcc.dg/dfp/usual-arith-conv-bad.c: New test.

Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c	(revision 113771)
+++ gcc/c-typeck.c	(working copy)
@@ -583,6 +583,31 @@
   gcc_assert (code2 == VECTOR_TYPE || code2 == COMPLEX_TYPE
 	      || code2 == REAL_TYPE || code2 == INTEGER_TYPE);
 
+  /* When one operand is a decimal float type, the other operand cannot be
+     a generic float type or a complex type.  We also disallow vector types
+     here.  */
+  if ((DECIMAL_FLOAT_MODE_P (TYPE_MODE (TYPE_MAIN_VARIANT (t1)))
+       || DECIMAL_FLOAT_MODE_P (TYPE_MODE (TYPE_MAIN_VARIANT (t2))))
+      && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TYPE_MAIN_VARIANT (t1)))
+           && DECIMAL_FLOAT_MODE_P (TYPE_MODE (TYPE_MAIN_VARIANT (t2)))))
+    {
+      if (code1 == VECTOR_TYPE || code2 == VECTOR_TYPE)
+	{
+	  error ("can%'t mix operands of decimal float and vector types");
+	  return error_mark_node;
+	}
+      if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
+	{
+	  error ("can%'t mix operands of decimal float and complex types");
+	  return error_mark_node;
+	}
+      if (code1 == REAL_TYPE && code2 == REAL_TYPE)
+	{
+	  error ("can%'t mix operands of decimal float and other float types");
+          return error_mark_node;
+	}
+    }
+
   /* If one type is a vector type, return that type.  (How the usual
      arithmetic conversions apply to the vector types extension is not
      precisely specified.)  */
Index: gcc/convert.c
===================================================================
--- gcc/convert.c	(revision 113771)
+++ gcc/convert.c	(working copy)
@@ -315,8 +315,12 @@
   switch (TREE_CODE (TREE_TYPE (expr)))
     {
     case REAL_TYPE:
-      return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
-		     type, expr);
+      /* Ignore the conversion if we don't need to store intermediate
+        results and if neither type is decimal float.  */
+      return build1 ((flag_float_store
+		      || DECIMAL_FLOAT_MODE_P (TYPE_MODE (type))
+		      || DECIMAL_FLOAT_MODE_P (TYPE_MODE (itype)))
+		     ? CONVERT_EXPR : NOP_EXPR, type, expr);
 
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
--- /dev/null	2004-06-24 11:06:20.000000000 -0700
+++ gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c	2006-05-15 12:14:25.000000000 -0700
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+/* N1150 5.4: Usual arithmetic conversions.
+   C99 6.3.1.8[1] (New).
+
+   Test arithmetic operators between decimal float types and generic
+   float types, which are not allowed.  */
+
+extern _Decimal32 d32a, d32b;
+extern _Decimal64 d64a, d64b;
+extern _Decimal128 d128a, d128b;
+extern float f;
+extern double d;
+extern long double ld;
+
+extern signed int __attribute__ ((vector_size (16))) vi;
+
+extern _Complex float cf;
+extern _Complex double cd;
+extern _Complex long double cld;
+extern _Complex int ci;
+
+void
+foo (void)
+{
+  /* Mixed operations with decimal and generic float operands.  */
+  d32a = d32b + f;	/* { dg-error "" "error.*mix operands of decimal float" } */
+  d32a = f * d32b;	/* { dg-error "" "error.* mix operands of decimal float" } */
+  d32a *= f;		/* { dg-error "" "error.* mix operands of decimal float" } */
+  f += d32b;		/* { dg-error "" "error.* mix operands of decimal float" } */
+  d64a = d32a + d;	/* { dg-error "" "error.* mix operands of decimal float" } */
+  d64a = d * d128a;	/* { dg-error "" "error.* mix operands of decimal float" } */
+  d64a -= d;		/* { dg-error "" "error.* mix operands of decimal float" } */
+  d128a = ld * d128b;	/* { dg-error "" "error.* mix operands of decimal float" } */
+  d128a = d64b + d;	/* { dg-error "" "error.* mix operands of decimal float" } */
+  d128a *= f;		/* { dg-error "" "error.* mix operands of decimal float" } */
+
+  /* Mixed operations with decimal float and a vector type.  */
+  d64a = d64b + vi;	/* { dg-error "" "error.* mix operands of decimal float" } */
+  d32a *= vi;		/* { dg-error "" "error.* mix operands of decimal float" } */
+  d128a = vi - d128b;	/* { dg-error "" "error.* mix operands of decimal float" } */
+
+  /* Mixed operations with decimal float and Complex types.  */
+  d32a += ci;		/* { dg-error "" "error.* mix operands of decimal float" } */
+  d64a = ci * d32a;	/* { dg-error "" "error.* mix operands of decimal float" } */
+  cd = d64a * cd;	/* { dg-error "" "error.* mix operands of decimal float" } */
+  d128b = cld * d128b;	/* { dg-error "" "error.* mix operands of decimal float" } */
+  d32a = cf * d32b;	/* { dg-error "" "error.* mix operands of decimal float" } */
+}


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