public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/meissner/heads/work104)] Allow for FP types with the same precision.
@ 2023-01-07  1:16 Michael Meissner
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Meissner @ 2023-01-07  1:16 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b2fdf513ed25dabeb8d2b1e0d0f8fe054d672397

commit b2fdf513ed25dabeb8d2b1e0d0f8fe054d672397
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Fri Jan 6 20:15:38 2023 -0500

    Allow for FP types with the same precision.
    
    This patch allows 2 or more floating point modes to have the same precision.
    The PowerPC has 3 128-bit floating point types (IFmode that uses the IBM
    extended double format, KFmode that uses the IEEE 128-bit format, and TFmode
    that can eithe use the IBM extended format or the IEEE 128-bit format depending
    on the switches used when compiling the module and switches used to configure
    the compiler.
    
    In the past, we needed to use 3 different precisions to separate these types.
    
    This patch adds a new macro (FRACTIONAL_FLOAT_MODE_NO_WIDEN) that a machine
    description can use to say this particular mode is not a standard floating point
    mode.  The machine independent part of the compiler will not automatically widen
    other floating point modes to these special modes.  In the case of the PowerPC,
    IFmode and KFmode use this no warn mode creation, while TFmode uses the normal
    creation.
    
    I also moved changing the TFmode format from ieee to ibm to rs6000-modes.def
    from rs6000.cc.
    
    We used to have an include file defining the special precisions used for the 3
    modes, and this include file is now deleted.
    
    2022-01-06   Michael Meissner  <meissner@linux.ibm.com>
    
    gcc/
    
            * config/rs6000/rs6000-modes.def (rs6000-modes.h): Remove inclusion.
            (IFmode): Rework set up to use FRACTIONAL_FLOAT_MODE_NO_WIDEN.  Use 128
            as the precision.
            (KFmode): Likewise.
            (TFmode): Set the precision to 128.  Adjust the format of TFmode based
            on the -mabi={ibm,ieee}longdouble option.
            * config/rs6000/rs6000-modes.h: Delete.
            * config/rs6000/rs6000.cc (rs6000_option_override_internal): Use 128
            bits as the precision for 128-bit float, instead of using a special
            values for the 3 different 128-bit FP modes.  Move resetting the format
            of TFmode to rs6000-modes.def.
            * config/rs6000/rs6000.h (rs6000-modes.h): Remove inclusion.
            * config/rs6000/t-rs6000 (TM_H): Don't add rs6000-modes.h.
            * expr.cc (convert_mode_scalar): Don't abort if we are converting
            floating point modes that are the same precision but use different
            encodings.
            * genmodes.cc (struct mode_data): Add normal_widen field.
            (blank_mode): Likewise.
            (FRACTIONAL_FLOAT_MODE): Add support for NO_WIDEN capability.
            (FRACTIONAL_FLOAT_MODE_NO_WIDEN): New macro.
            (make_float_mode): Add support for NO_WIDEN capability.
            (cmp_modes): Likewise.
            (emit_mode_wider): Likewise.
            * machmode.def (FRACTIONAL_FLOAT_MODE_NO_WIDEN): Document.

Diff:
---
 gcc/config/rs6000/rs6000-modes.def | 36 +++++++++-------------------
 gcc/config/rs6000/rs6000-modes.h   | 36 ----------------------------
 gcc/config/rs6000/rs6000.cc        |  9 +------
 gcc/config/rs6000/rs6000.h         |  5 ----
 gcc/config/rs6000/t-rs6000         |  1 -
 gcc/expr.cc                        |  6 ++---
 gcc/genmodes.cc                    | 48 +++++++++++++++++++++++++++-----------
 gcc/machmode.def                   |  6 +++++
 8 files changed, 55 insertions(+), 92 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def
index 8ef910869c5..571b92c4480 100644
--- a/gcc/config/rs6000/rs6000-modes.def
+++ b/gcc/config/rs6000/rs6000-modes.def
@@ -18,39 +18,25 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
-/* We order the 3 128-bit floating point types so that IFmode (IBM 128-bit
-   floating point) is the 128-bit floating point type with the highest
-   precision (128 bits).  This so that machine independent parts of the
-   compiler do not try to widen IFmode to TFmode on ISA 3.0 (power9) that has
-   hardware support for IEEE 128-bit.  We set TFmode (long double mode) in
-   between, and KFmode (explicit __float128) below it.
-
-   Previously, IFmode and KFmode were defined to be fractional modes and TFmode
-   was the standard mode.  Since IFmode does not define the normal arithmetic
-   insns (other than neg/abs), on a ISA 3.0 system, the machine independent
-   parts of the compiler would see that TFmode has the necessary hardware
-   support, and widen the operation from IFmode to TFmode.  However, IEEE
-   128-bit is not strictly a super-set of IBM extended double and the
-   conversion to/from IEEE 128-bit was a function call.
-
-   We now make IFmode the highest fractional mode, which means its values are
-   not considered for widening.  Since we don't define insns for IFmode, the
-   IEEE 128-bit modes would not widen to IFmode.  */
-
-#ifndef RS6000_MODES_H
-#include "config/rs6000/rs6000-modes.h"
-#endif
+/* We mark IFmode and KFmode as being types that are not in the mode_wider and
+   mode_2xwider tables.  Thus these types will never automatically be widened
+   to when the compiler can't perform an operation in a smaller mode.  Also,
+   the float_mode_for_size function will only return TFmode if the size is 128
+   bits.  */
 
 /* IBM 128-bit floating point.  */
-FRACTIONAL_FLOAT_MODE (IF, FLOAT_PRECISION_IFmode, 16, ibm_extended_format);
+FRACTIONAL_FLOAT_MODE_NO_WIDEN (IF, 128, 16, ibm_extended_format);
 
 /* Explicit IEEE 128-bit floating point.  */
-FRACTIONAL_FLOAT_MODE (KF, FLOAT_PRECISION_KFmode, 16, ieee_quad_format);
+FRACTIONAL_FLOAT_MODE_NO_WIDEN (KF, 128, 16, ieee_quad_format);
 
 /* 128-bit floating point, either IBM 128-bit or IEEE 128-bit.  This is
    adjusted in rs6000_option_override_internal to be the appropriate floating
    point type.  */
-FRACTIONAL_FLOAT_MODE (TF, FLOAT_PRECISION_TFmode, 16, ieee_quad_format);
+FRACTIONAL_FLOAT_MODE (TF, 128, 16, ieee_quad_format);
+ADJUST_FLOAT_FORMAT (TF, (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD
+			  ? &ibm_extended_format
+			  : &ieee_quad_format));
 
 /* Add any extra modes needed to represent the condition code.
 
diff --git a/gcc/config/rs6000/rs6000-modes.h b/gcc/config/rs6000/rs6000-modes.h
deleted file mode 100644
index 64abf886db3..00000000000
--- a/gcc/config/rs6000/rs6000-modes.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Definitions 128-bit floating point precisions used by PowerPC.
-   Copyright (C) 2018-2022 Free Software Foundation, Inc.
-   Contributed by Michael Meissner (meissner@linux.ibm.com)
-
-   This file is part of GCC.
-
-   GCC is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published
-   by the Free Software Foundation; either version 3, or (at your
-   option) any later version.
-
-   GCC is distributed in the hope that it will be useful, but WITHOUT
-   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-   License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with GCC; see the file COPYING3.  If not see
-   <http://www.gnu.org/licenses/>.  */
-
-/* We order the 3 128-bit floating point types so that IFmode (IBM 128-bit
-   floating point) is the 128-bit floating point type with the highest
-   precision (128 bits).  This so that machine independent parts of the
-   compiler do not try to widen IFmode to TFmode on ISA 3.0 (power9) that has
-   hardware support for IEEE 128-bit.  We set TFmode (long double mode) in
-   between, and KFmode (explicit __float128) below it.
-
-   We won't encounter conversion from IEEE 128-bit to IBM 128-bit because we
-   don't have insns to support the IBM 128-bit aritmetic operations.  */
-
-#ifndef RS6000_MODES_H
-#define RS6000_MODES_H		1
-#define FLOAT_PRECISION_IFmode	128
-#define FLOAT_PRECISION_TFmode	127
-#define FLOAT_PRECISION_KFmode	126
-#endif	/* RS6000_MODES_H */
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index c508e891413..3c6f9b81a99 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -4115,7 +4115,7 @@ rs6000_option_override_internal (bool global_init_p)
      128 into the precision used for TFmode.  */
   int default_long_double_size = (RS6000_DEFAULT_LONG_DOUBLE_SIZE == 64
 				  ? 64
-				  : FLOAT_PRECISION_TFmode);
+				  : 128);
 
   /* Set long double size before the IEEE 128-bit tests.  */
   if (!OPTION_SET_P (rs6000_long_double_type_size))
@@ -4127,10 +4127,6 @@ rs6000_option_override_internal (bool global_init_p)
       else
 	rs6000_long_double_type_size = default_long_double_size;
     }
-  else if (rs6000_long_double_type_size == FLOAT_PRECISION_TFmode)
-    ; /* The option value can be seen when cl_target_option_restore is called.  */
-  else if (rs6000_long_double_type_size == 128)
-    rs6000_long_double_type_size = FLOAT_PRECISION_TFmode;
 
   /* Set -mabi=ieeelongdouble on some old targets.  In the future, power server
      systems will also set long double to be IEEE 128-bit.  AIX and Darwin
@@ -4562,9 +4558,6 @@ rs6000_option_override_internal (bool global_init_p)
 	flag_signed_bitfields = 0;
 #endif
 
-      if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
-	REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
-
       ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
 
       /* We can only guarantee the availability of DI pseudo-ops when
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index b4df22b6030..440ab55a067 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -30,11 +30,6 @@
 #include "config/rs6000/rs6000-opts.h"
 #endif
 
-/* 128-bit floating point precision values.  */
-#ifndef RS6000_MODES_H
-#include "config/rs6000/rs6000-modes.h"
-#endif
-
 /* Definitions for the object file format.  These are set at
    compile-time.  */
 
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index 597cea423ec..72bf66dddf2 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -19,7 +19,6 @@
 # <http://www.gnu.org/licenses/>.
 
 TM_H += $(srcdir)/config/rs6000/rs6000-cpus.def
-TM_H += $(srcdir)/config/rs6000/rs6000-modes.h
 PASSES_EXTRA += $(srcdir)/config/rs6000/rs6000-passes.def
 EXTRA_GTYPE_DEPS += rs6000-builtins.h
 
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 15be1c8db99..c1c1e9729e8 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -345,10 +345,8 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)
 		   != GET_MODE_PRECISION (to_mode))
 		  || (DECIMAL_FLOAT_MODE_P (from_mode)
 		      != DECIMAL_FLOAT_MODE_P (to_mode))
-		  || (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
-		      && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
-		  || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
-		      && REAL_MODE_FORMAT (from_mode) == &ieee_half_format));
+		  || (REAL_MODE_FORMAT (from_mode)
+		      != REAL_MODE_FORMAT (to_mode)));
 
       if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
 	/* Conversion between decimal float and binary float, same size.  */
diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
index 2d418f09aab..32ee508a00e 100644
--- a/gcc/genmodes.cc
+++ b/gcc/genmodes.cc
@@ -79,6 +79,8 @@ struct mode_data
 				   adjustment */
   unsigned int int_n;		/* If nonzero, then __int<INT_N> will be defined */
   bool boolean;
+  bool normal_widen;		/* Whether the type should be listed in the
+				   mode_wider and mode_2xwider tables.  */
 };
 
 static struct mode_data *modes[MAX_MODE_CLASS];
@@ -90,7 +92,7 @@ static const struct mode_data blank_mode = {
   0, -1U, -1U, -1U, -1U,
   0, 0, 0, 0, 0, 0,
   "<unknown>", 0, 0, 0, 0, false, false, 0,
-  false
+  false, true
 };
 
 static htab_t modes_by_name;
@@ -658,18 +660,22 @@ make_fixed_point_mode (enum mode_class cl,
 
 #define FLOAT_MODE(N, Y, F)             FRACTIONAL_FLOAT_MODE (N, -1U, Y, F)
 #define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \
-  make_float_mode (#N, B, Y, #F, __FILE__, __LINE__)
+  make_float_mode (#N, B, Y, #F, __FILE__, __LINE__, true)
+#define FRACTIONAL_FLOAT_MODE_NO_WIDEN(N, B, Y, F) \
+  make_float_mode (#N, B, Y, #F, __FILE__, __LINE__, false)
 
 static void
 make_float_mode (const char *name,
 		 unsigned int precision, unsigned int bytesize,
 		 const char *format,
-		 const char *file, unsigned int line)
+		 const char *file, unsigned int line,
+		 bool normal_widen)
 {
   struct mode_data *m = new_mode (MODE_FLOAT, name, file, line);
   m->bytesize = bytesize;
   m->precision = precision;
   m->format = format;
+  m->normal_widen = normal_widen;
 }
 
 #define DECIMAL_FLOAT_MODE(N, Y, F)	\
@@ -871,7 +877,13 @@ create_modes (void)
    they have the same bytesize; this is the right thing because
    the precision must always be smaller than the bytesize * BITS_PER_UNIT.
    We don't have to do anything special to get this done -- an unset
-   precision shows up as (unsigned int)-1, i.e. UINT_MAX.  */
+   precision shows up as (unsigned int)-1, i.e. UINT_MAX.
+
+   If a mode is listed as no widen, sort it after the modes that are allowed as
+   widening types.  This is for machine dependent floating point types that we
+   don't want to promotion.  In particular on the PowerPC there are 2 different
+   128-bit floating point types (IBM and IEEE) and there are values in each
+   type that can't be represented in the other type.  */
 static int
 cmp_modes (const void *a, const void *b)
 {
@@ -893,6 +905,11 @@ cmp_modes (const void *a, const void *b)
   else if (m->precision < n->precision)
     return -1;
 
+  if (!m->normal_widen && n->normal_widen)
+    return 1;
+  else if (m->normal_widen && !n->normal_widen)
+    return -1;
+
   if (!m->component && !n->component)
     {
       if (m->counter < n->counter)
@@ -1541,17 +1558,20 @@ emit_mode_wider (void)
     {
       struct mode_data *m2 = 0;
 
-      if (m->cl == MODE_INT
-	  || m->cl == MODE_PARTIAL_INT
-	  || m->cl == MODE_FLOAT
-	  || m->cl == MODE_DECIMAL_FLOAT
-	  || m->cl == MODE_COMPLEX_FLOAT
-	  || m->cl == MODE_FRACT
-	  || m->cl == MODE_UFRACT
-	  || m->cl == MODE_ACCUM
-	  || m->cl == MODE_UACCUM)
+      if (m->normal_widen
+	  && (m->cl == MODE_INT
+	      || m->cl == MODE_PARTIAL_INT
+	      || m->cl == MODE_FLOAT
+	      || m->cl == MODE_DECIMAL_FLOAT
+	      || m->cl == MODE_COMPLEX_FLOAT
+	      || m->cl == MODE_FRACT
+	      || m->cl == MODE_UFRACT
+	      || m->cl == MODE_ACCUM
+	      || m->cl == MODE_UACCUM))
 	for (m2 = m->wider; m2 && m2 != void_mode; m2 = m2->wider)
 	  {
+	    if (!m2->normal_widen)
+	      continue;
 	    if (m2->bytesize == m->bytesize
 		&& m2->precision == m->precision)
 	      continue;
@@ -1576,6 +1596,8 @@ emit_mode_wider (void)
 	   m2 && m2 != void_mode;
 	   m2 = m2->wider)
 	{
+	  if (!m2->normal_widen)
+	    continue;
 	  if (m2->bytesize < 2 * m->bytesize)
 	    continue;
 	  if (m->precision != (unsigned int) -1)
diff --git a/gcc/machmode.def b/gcc/machmode.def
index 62e2ba10d45..fb10a3af705 100644
--- a/gcc/machmode.def
+++ b/gcc/machmode.def
@@ -90,6 +90,12 @@ along with GCC; see the file COPYING3.  If not see
 	storage, but with only PRECISION significant bits, using
 	floating point format FORMAT.
 
+     FRACTIONAL_FLOAT_MODE_NO_WIDEN (MODE, PRECISION, BYTESIZE, FORMAT);
+        declares MODE to be of class FLOAT, BYTESIZE bytes wide in
+	storage, but with only PRECISION significant bits, using
+	floating point format FORMAT.  Unlike FRACTIONAL_FLOAT_MODE,
+	MODE is not listed in the mode_wider and mode_2xwider tables.
+
      DECIMAL_FLOAT_MODE (MODE, BYTESIZE, FORMAT);
 	declares MODE to be of class DECIMAL_FLOAT and BYTESIZE bytes
 	wide.  All of the bits of its representation are significant.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [gcc(refs/users/meissner/heads/work104)] Allow for FP types with the same precision.
@ 2023-01-06 20:01 Michael Meissner
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Meissner @ 2023-01-06 20:01 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:bffe9c86441ea2609644a42198b4eb541eb786e4

commit bffe9c86441ea2609644a42198b4eb541eb786e4
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Fri Jan 6 15:00:42 2023 -0500

    Allow for FP types with the same precision.
    
    2022-01-06   Michael Meissner  <meissner@linux.ibm.com>
    
    gcc/
    
            * config/rs6000/rs6000-modes.def (rs6000-modes.h): Remove inclusion.
            (IFmode): Rework set up to use FRACTIONAL_FLOAT_MODE_NO_WIDEN.  Use 128
            as the precision.
            (KFmode): Likewise.
            (TFmode): Set the precision to 128.  Adjust the format of TFmode based
            on the -mabi={ibm,ieee}longdouble option.
            * config/rs6000/rs6000-modes.h: Delete.
            * config/rs6000/rs6000.cc (rs6000_option_override_internal): Use 128
            bits as the precision for 128-bit float, instead of using a special
            values for the 3 different 128-bit FP modes.  Move resetting the format
            of TFmode to rs6000-modes.def.
            * config/rs6000/rs6000.h (rs6000-modes.h): Remove inclusion.
            * config/rs6000/t-rs6000 (TM_H): Don't add rs6000-modes.h.
            * expr.cc (convert_mode_scalar): Don't abort if we are converting
            floating point modes that are the same precision but use different
            encodings.
            * genmodes.cc (struct mode_data): Add normal_widen field.
            (blank_mode): Likewise.
            (FRACTIONAL_FLOAT_MODE): Add support for NO_WIDEN capability.
            (FRACTIONAL_FLOAT_MODE_NO_WIDEN): New macro.
            (make_float_mode): Add support for NO_WIDEN capability.
            (cmp_modes): Likewise.
            (emit_mode_wider): Likewise.
            * machmode.def (FRACTIONAL_FLOAT_MODE_NO_WIDEN): Document.

Diff:
---
 gcc/config/rs6000/rs6000-modes.def | 36 +++++++++-------------------
 gcc/config/rs6000/rs6000-modes.h   | 36 ----------------------------
 gcc/config/rs6000/rs6000.cc        |  9 +------
 gcc/config/rs6000/rs6000.h         |  5 ----
 gcc/config/rs6000/t-rs6000         |  1 -
 gcc/expr.cc                        |  6 ++---
 gcc/genmodes.cc                    | 48 +++++++++++++++++++++++++++-----------
 gcc/machmode.def                   |  6 +++++
 8 files changed, 55 insertions(+), 92 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def
index 8ef910869c5..571b92c4480 100644
--- a/gcc/config/rs6000/rs6000-modes.def
+++ b/gcc/config/rs6000/rs6000-modes.def
@@ -18,39 +18,25 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
-/* We order the 3 128-bit floating point types so that IFmode (IBM 128-bit
-   floating point) is the 128-bit floating point type with the highest
-   precision (128 bits).  This so that machine independent parts of the
-   compiler do not try to widen IFmode to TFmode on ISA 3.0 (power9) that has
-   hardware support for IEEE 128-bit.  We set TFmode (long double mode) in
-   between, and KFmode (explicit __float128) below it.
-
-   Previously, IFmode and KFmode were defined to be fractional modes and TFmode
-   was the standard mode.  Since IFmode does not define the normal arithmetic
-   insns (other than neg/abs), on a ISA 3.0 system, the machine independent
-   parts of the compiler would see that TFmode has the necessary hardware
-   support, and widen the operation from IFmode to TFmode.  However, IEEE
-   128-bit is not strictly a super-set of IBM extended double and the
-   conversion to/from IEEE 128-bit was a function call.
-
-   We now make IFmode the highest fractional mode, which means its values are
-   not considered for widening.  Since we don't define insns for IFmode, the
-   IEEE 128-bit modes would not widen to IFmode.  */
-
-#ifndef RS6000_MODES_H
-#include "config/rs6000/rs6000-modes.h"
-#endif
+/* We mark IFmode and KFmode as being types that are not in the mode_wider and
+   mode_2xwider tables.  Thus these types will never automatically be widened
+   to when the compiler can't perform an operation in a smaller mode.  Also,
+   the float_mode_for_size function will only return TFmode if the size is 128
+   bits.  */
 
 /* IBM 128-bit floating point.  */
-FRACTIONAL_FLOAT_MODE (IF, FLOAT_PRECISION_IFmode, 16, ibm_extended_format);
+FRACTIONAL_FLOAT_MODE_NO_WIDEN (IF, 128, 16, ibm_extended_format);
 
 /* Explicit IEEE 128-bit floating point.  */
-FRACTIONAL_FLOAT_MODE (KF, FLOAT_PRECISION_KFmode, 16, ieee_quad_format);
+FRACTIONAL_FLOAT_MODE_NO_WIDEN (KF, 128, 16, ieee_quad_format);
 
 /* 128-bit floating point, either IBM 128-bit or IEEE 128-bit.  This is
    adjusted in rs6000_option_override_internal to be the appropriate floating
    point type.  */
-FRACTIONAL_FLOAT_MODE (TF, FLOAT_PRECISION_TFmode, 16, ieee_quad_format);
+FRACTIONAL_FLOAT_MODE (TF, 128, 16, ieee_quad_format);
+ADJUST_FLOAT_FORMAT (TF, (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD
+			  ? &ibm_extended_format
+			  : &ieee_quad_format));
 
 /* Add any extra modes needed to represent the condition code.
 
diff --git a/gcc/config/rs6000/rs6000-modes.h b/gcc/config/rs6000/rs6000-modes.h
index 64abf886db3..e69de29bb2d 100644
--- a/gcc/config/rs6000/rs6000-modes.h
+++ b/gcc/config/rs6000/rs6000-modes.h
@@ -1,36 +0,0 @@
-/* Definitions 128-bit floating point precisions used by PowerPC.
-   Copyright (C) 2018-2022 Free Software Foundation, Inc.
-   Contributed by Michael Meissner (meissner@linux.ibm.com)
-
-   This file is part of GCC.
-
-   GCC is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published
-   by the Free Software Foundation; either version 3, or (at your
-   option) any later version.
-
-   GCC is distributed in the hope that it will be useful, but WITHOUT
-   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-   License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with GCC; see the file COPYING3.  If not see
-   <http://www.gnu.org/licenses/>.  */
-
-/* We order the 3 128-bit floating point types so that IFmode (IBM 128-bit
-   floating point) is the 128-bit floating point type with the highest
-   precision (128 bits).  This so that machine independent parts of the
-   compiler do not try to widen IFmode to TFmode on ISA 3.0 (power9) that has
-   hardware support for IEEE 128-bit.  We set TFmode (long double mode) in
-   between, and KFmode (explicit __float128) below it.
-
-   We won't encounter conversion from IEEE 128-bit to IBM 128-bit because we
-   don't have insns to support the IBM 128-bit aritmetic operations.  */
-
-#ifndef RS6000_MODES_H
-#define RS6000_MODES_H		1
-#define FLOAT_PRECISION_IFmode	128
-#define FLOAT_PRECISION_TFmode	127
-#define FLOAT_PRECISION_KFmode	126
-#endif	/* RS6000_MODES_H */
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 585faedc4e6..9240887a5d3 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -4115,7 +4115,7 @@ rs6000_option_override_internal (bool global_init_p)
      128 into the precision used for TFmode.  */
   int default_long_double_size = (RS6000_DEFAULT_LONG_DOUBLE_SIZE == 64
 				  ? 64
-				  : FLOAT_PRECISION_TFmode);
+				  : 128);
 
   /* Set long double size before the IEEE 128-bit tests.  */
   if (!OPTION_SET_P (rs6000_long_double_type_size))
@@ -4127,10 +4127,6 @@ rs6000_option_override_internal (bool global_init_p)
       else
 	rs6000_long_double_type_size = default_long_double_size;
     }
-  else if (rs6000_long_double_type_size == FLOAT_PRECISION_TFmode)
-    ; /* The option value can be seen when cl_target_option_restore is called.  */
-  else if (rs6000_long_double_type_size == 128)
-    rs6000_long_double_type_size = FLOAT_PRECISION_TFmode;
 
   /* Set -mabi=ieeelongdouble on some old targets.  In the future, power server
      systems will also set long double to be IEEE 128-bit.  AIX and Darwin
@@ -4562,9 +4558,6 @@ rs6000_option_override_internal (bool global_init_p)
 	flag_signed_bitfields = 0;
 #endif
 
-      if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
-	REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
-
       ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
 
       /* We can only guarantee the availability of DI pseudo-ops when
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index b4df22b6030..440ab55a067 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -30,11 +30,6 @@
 #include "config/rs6000/rs6000-opts.h"
 #endif
 
-/* 128-bit floating point precision values.  */
-#ifndef RS6000_MODES_H
-#include "config/rs6000/rs6000-modes.h"
-#endif
-
 /* Definitions for the object file format.  These are set at
    compile-time.  */
 
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index 597cea423ec..72bf66dddf2 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -19,7 +19,6 @@
 # <http://www.gnu.org/licenses/>.
 
 TM_H += $(srcdir)/config/rs6000/rs6000-cpus.def
-TM_H += $(srcdir)/config/rs6000/rs6000-modes.h
 PASSES_EXTRA += $(srcdir)/config/rs6000/rs6000-passes.def
 EXTRA_GTYPE_DEPS += rs6000-builtins.h
 
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 15be1c8db99..c1c1e9729e8 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -345,10 +345,8 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)
 		   != GET_MODE_PRECISION (to_mode))
 		  || (DECIMAL_FLOAT_MODE_P (from_mode)
 		      != DECIMAL_FLOAT_MODE_P (to_mode))
-		  || (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
-		      && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
-		  || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
-		      && REAL_MODE_FORMAT (from_mode) == &ieee_half_format));
+		  || (REAL_MODE_FORMAT (from_mode)
+		      != REAL_MODE_FORMAT (to_mode)));
 
       if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
 	/* Conversion between decimal float and binary float, same size.  */
diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
index 2d418f09aab..32ee508a00e 100644
--- a/gcc/genmodes.cc
+++ b/gcc/genmodes.cc
@@ -79,6 +79,8 @@ struct mode_data
 				   adjustment */
   unsigned int int_n;		/* If nonzero, then __int<INT_N> will be defined */
   bool boolean;
+  bool normal_widen;		/* Whether the type should be listed in the
+				   mode_wider and mode_2xwider tables.  */
 };
 
 static struct mode_data *modes[MAX_MODE_CLASS];
@@ -90,7 +92,7 @@ static const struct mode_data blank_mode = {
   0, -1U, -1U, -1U, -1U,
   0, 0, 0, 0, 0, 0,
   "<unknown>", 0, 0, 0, 0, false, false, 0,
-  false
+  false, true
 };
 
 static htab_t modes_by_name;
@@ -658,18 +660,22 @@ make_fixed_point_mode (enum mode_class cl,
 
 #define FLOAT_MODE(N, Y, F)             FRACTIONAL_FLOAT_MODE (N, -1U, Y, F)
 #define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \
-  make_float_mode (#N, B, Y, #F, __FILE__, __LINE__)
+  make_float_mode (#N, B, Y, #F, __FILE__, __LINE__, true)
+#define FRACTIONAL_FLOAT_MODE_NO_WIDEN(N, B, Y, F) \
+  make_float_mode (#N, B, Y, #F, __FILE__, __LINE__, false)
 
 static void
 make_float_mode (const char *name,
 		 unsigned int precision, unsigned int bytesize,
 		 const char *format,
-		 const char *file, unsigned int line)
+		 const char *file, unsigned int line,
+		 bool normal_widen)
 {
   struct mode_data *m = new_mode (MODE_FLOAT, name, file, line);
   m->bytesize = bytesize;
   m->precision = precision;
   m->format = format;
+  m->normal_widen = normal_widen;
 }
 
 #define DECIMAL_FLOAT_MODE(N, Y, F)	\
@@ -871,7 +877,13 @@ create_modes (void)
    they have the same bytesize; this is the right thing because
    the precision must always be smaller than the bytesize * BITS_PER_UNIT.
    We don't have to do anything special to get this done -- an unset
-   precision shows up as (unsigned int)-1, i.e. UINT_MAX.  */
+   precision shows up as (unsigned int)-1, i.e. UINT_MAX.
+
+   If a mode is listed as no widen, sort it after the modes that are allowed as
+   widening types.  This is for machine dependent floating point types that we
+   don't want to promotion.  In particular on the PowerPC there are 2 different
+   128-bit floating point types (IBM and IEEE) and there are values in each
+   type that can't be represented in the other type.  */
 static int
 cmp_modes (const void *a, const void *b)
 {
@@ -893,6 +905,11 @@ cmp_modes (const void *a, const void *b)
   else if (m->precision < n->precision)
     return -1;
 
+  if (!m->normal_widen && n->normal_widen)
+    return 1;
+  else if (m->normal_widen && !n->normal_widen)
+    return -1;
+
   if (!m->component && !n->component)
     {
       if (m->counter < n->counter)
@@ -1541,17 +1558,20 @@ emit_mode_wider (void)
     {
       struct mode_data *m2 = 0;
 
-      if (m->cl == MODE_INT
-	  || m->cl == MODE_PARTIAL_INT
-	  || m->cl == MODE_FLOAT
-	  || m->cl == MODE_DECIMAL_FLOAT
-	  || m->cl == MODE_COMPLEX_FLOAT
-	  || m->cl == MODE_FRACT
-	  || m->cl == MODE_UFRACT
-	  || m->cl == MODE_ACCUM
-	  || m->cl == MODE_UACCUM)
+      if (m->normal_widen
+	  && (m->cl == MODE_INT
+	      || m->cl == MODE_PARTIAL_INT
+	      || m->cl == MODE_FLOAT
+	      || m->cl == MODE_DECIMAL_FLOAT
+	      || m->cl == MODE_COMPLEX_FLOAT
+	      || m->cl == MODE_FRACT
+	      || m->cl == MODE_UFRACT
+	      || m->cl == MODE_ACCUM
+	      || m->cl == MODE_UACCUM))
 	for (m2 = m->wider; m2 && m2 != void_mode; m2 = m2->wider)
 	  {
+	    if (!m2->normal_widen)
+	      continue;
 	    if (m2->bytesize == m->bytesize
 		&& m2->precision == m->precision)
 	      continue;
@@ -1576,6 +1596,8 @@ emit_mode_wider (void)
 	   m2 && m2 != void_mode;
 	   m2 = m2->wider)
 	{
+	  if (!m2->normal_widen)
+	    continue;
 	  if (m2->bytesize < 2 * m->bytesize)
 	    continue;
 	  if (m->precision != (unsigned int) -1)
diff --git a/gcc/machmode.def b/gcc/machmode.def
index 62e2ba10d45..fb10a3af705 100644
--- a/gcc/machmode.def
+++ b/gcc/machmode.def
@@ -90,6 +90,12 @@ along with GCC; see the file COPYING3.  If not see
 	storage, but with only PRECISION significant bits, using
 	floating point format FORMAT.
 
+     FRACTIONAL_FLOAT_MODE_NO_WIDEN (MODE, PRECISION, BYTESIZE, FORMAT);
+        declares MODE to be of class FLOAT, BYTESIZE bytes wide in
+	storage, but with only PRECISION significant bits, using
+	floating point format FORMAT.  Unlike FRACTIONAL_FLOAT_MODE,
+	MODE is not listed in the mode_wider and mode_2xwider tables.
+
      DECIMAL_FLOAT_MODE (MODE, BYTESIZE, FORMAT);
 	declares MODE to be of class DECIMAL_FLOAT and BYTESIZE bytes
 	wide.  All of the bits of its representation are significant.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-01-07  1:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-07  1:16 [gcc(refs/users/meissner/heads/work104)] Allow for FP types with the same precision Michael Meissner
  -- strict thread matches above, loose matches on Subject: below --
2023-01-06 20:01 Michael Meissner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).