public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/meissner/heads/dmf001)] Initial support for __dmr type.
@ 2022-10-18  1:20 Michael Meissner
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Meissner @ 2022-10-18  1:20 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:7bd9791b245a9ffef556f27645b81d82670dd91c

commit 7bd9791b245a9ffef556f27645b81d82670dd91c
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Mon Oct 17 21:19:45 2022 -0400

    Initial support for __dmr type.
    
    2022-10-17   Michael Meissner  <meissner@linux.ibm.com>
    
    gcc/
    
            * config/rs6000/rs6000-call.cc (rs6000_return_in_memory): TDOmode needs
            to be returned in memory.
            (rs6000_function_arg): TDOmode can't be passed in a register.
            * config/rs6000/rs6000.cc (rs6000_hard_regno_mode_ok_uncached): Relax
            XOmode requirement that the register number must be divisible by 4 if
            -mdmf.  Add support for TDOmode registers.
            (rs6000_modes_tieable_p): Reorder tests for TDOmode.
            (rs6000_setup_reg_addr_masks): Allow TDOmode in DMR registers.
            (reg_offset_addressing_ok_p): Allow loading/storing TDOmode values with
            offset instructions.
            (rs6000_split_multireg_move): Update comment.
            (rs6000_invalid_conversion): Likewise.
            * config/rs6000/rs6000.h (VECTOR_ALIGNMENT_P): TDOmode has 512 bit
            alignment.
            (rs6000_builtin_type_index): Add support for dmr type node and pointer
            to dmr type node.
            (dmr_type_node): Likewise.
            (ptr_dmr_type_node): Likewise.

Diff:
---
 gcc/config/rs6000/rs6000-call.cc | 12 +++++-
 gcc/config/rs6000/rs6000.cc      | 91 +++++++++++++++++++++++++---------------
 gcc/config/rs6000/rs6000.h       |  7 +++-
 3 files changed, 74 insertions(+), 36 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc
index ac3cb7e3d36..aa08183c8b6 100644
--- a/gcc/config/rs6000/rs6000-call.cc
+++ b/gcc/config/rs6000/rs6000-call.cc
@@ -437,7 +437,8 @@ rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
   if (cfun
       && !cfun->machine->mma_return_type_error
       && TREE_TYPE (cfun->decl) == fntype
-      && (TYPE_MODE (type) == OOmode || TYPE_MODE (type) == XOmode))
+      && (TYPE_MODE (type) == OOmode || TYPE_MODE (type) == XOmode
+	  || TYPE_MODE (type) == TDOmode))
     {
       /* Record we have now handled function CFUN, so the next time we
 	 are called, we do not re-report the same error.  */
@@ -1641,6 +1642,15 @@ rs6000_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
       return NULL_RTX;
     }
 
+  if (mode == TDOmode)
+    {
+      if (TYPE_CANONICAL (type) != NULL_TREE)
+	type = TYPE_CANONICAL (type);
+      error ("invalid use of DMF operand of type %qs as a function parameter",
+	     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+      return NULL_RTX;
+    }
+
   /* Return a marker to indicate whether CR1 needs to set or clear the
      bit that V.4 uses to say fp args were passed in registers.
      Assume that we don't need the marker for software floating point,
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index d1a42d7ea5e..cf6f70a148b 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1854,26 +1854,51 @@ rs6000_hard_regno_mode_ok_uncached (int regno, machine_mode mode)
   if (mode == OOmode)
     return (TARGET_MMA && VSX_REGNO_P (regno) && (regno & 1) == 0);
 
-  /* On power10, MMA accumulator modes need FPR registers divisible by 4.  If
-     DMF is enabled, allow all VSX registers plus the DMF registers.  */
+  /* On power10, MMA accumulator modes need FPR registers divisible by 4.
+
+     If DMF is enabled, allow all VSX registers plus the DMF registers.  We
+     need to make sure we don't cross between the boundary of FPRs and
+     traditional Altiviec registers.  */
   if (mode == XOmode)
     {
-      if (TARGET_DMF)
-	return (DMF_REGNO_P (regno)
-		|| (VSX_REGNO_P (regno) && (regno & 3) == 0));
-
-      else if (TARGET_MMA)
+      if (TARGET_MMA && !TARGET_DMF)
 	return (FP_REGNO_P (regno) && (regno & 3) == 0);
 
+      else if (TARGET_DMF)
+	{
+	  if (DMF_REGNO_P (regno))
+	    return 1;
+
+	  if (FP_REGNO_P (regno))
+	    return ((regno & 1) == 0 && regno <= LAST_FPR_REGNO - 3);
+
+	  if (ALTIVEC_REGNO_P (regno))
+	    return ((regno & 1) == 0 && regno <= LAST_ALTIVEC_REGNO - 3);
+	}
+
       else
 	return 0;
     }
 
-  /* DMF register modes need DMF registers or VSX registers divisible by 4.  */
+  /* DMF register modes need DMF registers or VSX registers divisible by 2.  We
+     need to make sure we don't cross between the boundary of FPRs and
+     traditional Altiviec registers.  */
   if (mode == TDOmode)
-    return (TARGET_DMF
-	    && (DMF_REGNO_P (regno)
-		|| (VSX_REGNO_P (regno) && (regno & 3) == 0)));
+    {
+      if (!TARGET_DMF)
+	return 0;
+
+      if (DMF_REGNO_P (regno) && 0)
+	return 1;
+
+      if (FP_REGNO_P (regno))
+	return ((regno & 1) == 0 && regno <= LAST_FPR_REGNO - 7);
+
+      if (ALTIVEC_REGNO_P (regno))
+	return ((regno & 1) == 0 && regno <= LAST_ALTIVEC_REGNO - 7);
+
+      return 0;
+    }
 
   /* No other types other than XOmode or TDOmode can go in DMFs.  */
   if (DMF_REGNO_P (regno))
@@ -1983,9 +2008,11 @@ rs6000_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
    GPR registers, and TImode can go in any GPR as well as VSX registers (PR
    57744).
 
-   Similarly, don't allow OOmode (vector pair, restricted to even VSX
-   registers) or XOmode (vector quad, restricted to FPR registers divisible
-   by 4) to tie with other modes.
+   Similarly, don't allow OOmode (vector pair), XOmode (vector quad), or
+   TDOmode (dmr register) to pair with anything else.  Vector pairs are
+   restricted to even/odd VSX registers.  Without DMF, vector quads are limited
+   to FPR registers divisible by 4.  With DMF, vector quads are limited to even
+   VSX registers or DMR registers.
 
    Altivec/VSX vector tests were moved ahead of scalar float mode, so that IEEE
    128-bit floating point on VSX systems ties with other vectors.  */
@@ -1994,8 +2021,8 @@ static bool
 rs6000_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 {
   if (mode1 == PTImode || mode1 == OOmode || mode1 == XOmode
-      || mode2 == PTImode || mode2 == OOmode || mode2 == XOmode
-      || mode1 == TDOmode || mode2 == TDOmode)
+      || mode1 == TDOmode || mode2 == PTImode || mode2 == OOmode
+      || mode2 == XOmode || mode2 == TDOmode)
     return mode1 == mode2;
 
   if (ALTIVEC_OR_VSX_VECTOR_MODE (mode1))
@@ -2655,7 +2682,7 @@ rs6000_setup_reg_addr_masks (void)
 	  /* Special case DMF registers.  */
 	  if (rc == RELOAD_REG_DMF)
 	    {
-	      if (TARGET_DMF && m2 == XOmode)
+	      if (TARGET_DMF && (m2 == XOmode || m2 == TDOmode))
 		{
 		  addr_mask = RELOAD_REG_VALID | RELOAD_REG_NO_MEMORY;
 		  reg_addr[m].addr_mask[rc] = addr_mask;
@@ -2667,13 +2694,6 @@ rs6000_setup_reg_addr_masks (void)
 	      continue;
 	    }
 
-	  /* At the moment, don't enable TDOmode.  */
-	  if (m2 == TDOmode)
-	    {
-	      reg_addr[m].addr_mask[rc] = 0;
-	      continue;
-	    }
-
 	  /* Can mode values go in the GPR/FPR/Altivec registers?  */
 	  if (reg >= 0 && rs6000_hard_regno_mode_ok_p[m][reg])
 	    {
@@ -8693,9 +8713,11 @@ reg_offset_addressing_ok_p (machine_mode mode)
 	 if the underlying vectors support offset addressing.  */
     case E_OOmode:
     case E_XOmode:
-    case E_TDOmode:
       return TARGET_MMA;
 
+    case E_TDOmode:
+      return TARGET_DMF;
+
     case E_SDmode:
       /* If we can do direct load/stores of SDmode, restrict it to reg+reg
 	 addressing for the LFIWZX and STFIWX instructions.  */
@@ -27192,8 +27214,8 @@ rs6000_split_multireg_move (rtx dst, rtx src)
   mode = GET_MODE (dst);
   nregs = hard_regno_nregs (reg, mode);
 
-  /* If we have a vector quad register for MMA, and this is a load or store,
-     see if we can use vector paired load/stores.  */
+  /* If we have a vector quad register for MMA or DMR register for DMF, and
+     this is a load or store, see if we can use vector paired load/stores.  */
   if ((mode == XOmode || mode == TDOmode) && TARGET_MMA
       && (MEM_P (dst) || MEM_P (src)))
     {
@@ -27248,12 +27270,12 @@ rs6000_split_multireg_move (rtx dst, rtx src)
       return;
     }
 
-  /* The __vector_pair and __vector_quad modes are multi-register
-     modes, so if we have to load or store the registers, we have to be
-     careful to properly swap them if we're in little endian mode
-     below.  This means the last register gets the first memory
-     location.  We also need to be careful of using the right register
-     numbers if we are splitting XO to OO.  */
+  /* The __vector_pair, __vector_quad, and __dmr modes are multi-register
+     modes, so if we have to load or store the registers, we have to be careful
+     to properly swap them if we're in little endian mode below.  This means
+     the last register gets the first memory location.  We also need to be
+     careful of using the right register numbers if we are splitting XO to
+     OO.  */
   if (mode == OOmode || mode == XOmode || mode == TDOmode)
     {
       nregs = hard_regno_nregs (reg, mode);
@@ -28484,7 +28506,8 @@ rs6000_invalid_conversion (const_tree fromtype, const_tree totype)
 
   if (frommode != tomode)
     {
-      /* Do not allow conversions to/from XOmode and OOmode types.  */
+      /* Do not allow conversions to/from XOmode, OOmode, and TDOmode
+	 types.  */
       if (frommode == XOmode)
 	return N_("invalid conversion from type %<__vector_quad%>");
       if (tomode == XOmode)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index d47337f7c51..640d8462ab8 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1006,7 +1006,8 @@ enum data_align { align_abi, align_opt, align_both };
 /* Modes that are not vectors, but require vector alignment.  Treat these like
    vectors in terms of loads and stores.  */
 #define VECTOR_ALIGNMENT_P(MODE)					\
-  (FLOAT128_VECTOR_P (MODE) || (MODE) == OOmode || (MODE) == XOmode)
+  (FLOAT128_VECTOR_P (MODE) || (MODE) == OOmode || (MODE) == XOmode	\
+   || (MODE) == TDOmode)
 
 #define ALTIVEC_VECTOR_MODE(MODE)					\
   ((MODE) == V16QImode							\
@@ -2291,6 +2292,7 @@ enum rs6000_builtin_type_index
   RS6000_BTI_const_str,		 /* pointer to const char * */
   RS6000_BTI_vector_pair,	 /* unsigned 256-bit types (vector pair).  */
   RS6000_BTI_vector_quad,	 /* unsigned 512-bit types (vector quad).  */
+  RS6000_BTI_dmr,		 /* unsigned 1,024-bit types (dmr).  */
   RS6000_BTI_const_ptr_void,     /* const pointer to void */
   RS6000_BTI_ptr_V16QI,
   RS6000_BTI_ptr_V1TI,
@@ -2329,6 +2331,7 @@ enum rs6000_builtin_type_index
   RS6000_BTI_ptr_dfloat128,
   RS6000_BTI_ptr_vector_pair,
   RS6000_BTI_ptr_vector_quad,
+  RS6000_BTI_ptr_dmr,
   RS6000_BTI_ptr_long_long,
   RS6000_BTI_ptr_long_long_unsigned,
   RS6000_BTI_MAX
@@ -2386,6 +2389,7 @@ enum rs6000_builtin_type_index
 #define const_str_type_node		 (rs6000_builtin_types[RS6000_BTI_const_str])
 #define vector_pair_type_node		 (rs6000_builtin_types[RS6000_BTI_vector_pair])
 #define vector_quad_type_node		 (rs6000_builtin_types[RS6000_BTI_vector_quad])
+#define dmr_type_node			 (rs6000_builtin_types[RS6000_BTI_dmr])
 #define pcvoid_type_node		 (rs6000_builtin_types[RS6000_BTI_const_ptr_void])
 #define ptr_V16QI_type_node		 (rs6000_builtin_types[RS6000_BTI_ptr_V16QI])
 #define ptr_V1TI_type_node		 (rs6000_builtin_types[RS6000_BTI_ptr_V1TI])
@@ -2424,6 +2428,7 @@ enum rs6000_builtin_type_index
 #define ptr_dfloat128_type_node		 (rs6000_builtin_types[RS6000_BTI_ptr_dfloat128])
 #define ptr_vector_pair_type_node	 (rs6000_builtin_types[RS6000_BTI_ptr_vector_pair])
 #define ptr_vector_quad_type_node	 (rs6000_builtin_types[RS6000_BTI_ptr_vector_quad])
+#define ptr_dmr_type_node		 (rs6000_builtin_types[RS6000_BTI_ptr_dmr])
 #define ptr_long_long_integer_type_node	 (rs6000_builtin_types[RS6000_BTI_ptr_long_long])
 #define ptr_long_long_unsigned_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_long_unsigned])

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

* [gcc(refs/users/meissner/heads/dmf001)] Initial support for __dmr type.
@ 2022-10-18  1:27 Michael Meissner
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Meissner @ 2022-10-18  1:27 UTC (permalink / raw)
  To: gcc-cvs

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

commit fe91e0bb5e3f2d0ddf7a1b2bc1503726172d175f
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Mon Oct 17 21:27:41 2022 -0400

    Initial support for __dmr type.
    
    2022-10-17   Michael Meissner  <meissner@linux.ibm.com>
    
    gcc/
    
            * config/rs6000/rs6000-call.cc (rs6000_return_in_memory): TDOmode needs
            to be returned in memory.
            (rs6000_function_arg): TDOmode can't be passed in a register.
            * config/rs6000/rs6000.cc (rs6000_hard_regno_mode_ok_uncached): Relax
            XOmode requirement that the register number must be divisible by 4 if
            -mdmf.  Add support for TDOmode registers.
            (rs6000_modes_tieable_p): Reorder tests for TDOmode.
            (rs6000_setup_reg_addr_masks): Allow TDOmode in DMR registers.
            (reg_offset_addressing_ok_p): Allow loading/storing TDOmode values with
            offset instructions.
            (rs6000_split_multireg_move): Update comment.
            (rs6000_invalid_conversion): Likewise.
            * config/rs6000/rs6000.h (VECTOR_ALIGNMENT_P): TDOmode has 512 bit
            alignment.
            (rs6000_builtin_type_index): Add support for dmr type node and pointer
            to dmr type node.
            (dmr_type_node): Likewise.
            (ptr_dmr_type_node): Likewise.

Diff:
---
 gcc/ChangeLog.meissner | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/gcc/ChangeLog.meissner b/gcc/ChangeLog.meissner
index ba6cb792369..f14c3956d65 100644
--- a/gcc/ChangeLog.meissner
+++ b/gcc/ChangeLog.meissner
@@ -1,3 +1,30 @@
+==================== dmf001, patch #15
+
+Initial support for __dmr type.
+
+2022-10-17   Michael Meissner  <meissner@linux.ibm.com>
+
+gcc/
+
+	* config/rs6000/rs6000-call.cc (rs6000_return_in_memory): TDOmode needs
+	to be returned in memory.
+	(rs6000_function_arg): TDOmode can't be passed in a register.
+	* config/rs6000/rs6000.cc (rs6000_hard_regno_mode_ok_uncached): Relax
+	XOmode requirement that the register number must be divisible by 4 if
+	-mdmf.  Add support for TDOmode registers.
+	(rs6000_modes_tieable_p): Reorder tests for TDOmode.
+	(rs6000_setup_reg_addr_masks): Allow TDOmode in DMR registers.
+	(reg_offset_addressing_ok_p): Allow loading/storing TDOmode values with
+	offset instructions.
+	(rs6000_split_multireg_move): Update comment.
+	(rs6000_invalid_conversion): Likewise.
+	* config/rs6000/rs6000.h (VECTOR_ALIGNMENT_P): TDOmode has 512 bit
+	alignment.
+	(rs6000_builtin_type_index): Add support for dmr type node and pointer
+	to dmr type node.
+	(dmr_type_node): Likewise.
+	(ptr_dmr_type_node): Likewise.
+
 ==================== dmf001, patch #14
 
 Update comment.

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

end of thread, other threads:[~2022-10-18  1:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-18  1:20 [gcc(refs/users/meissner/heads/dmf001)] Initial support for __dmr type Michael Meissner
2022-10-18  1:27 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).