Hi,

I am trying to add a 256 byte opaque mode for the rs6000 backend in order to
represent a 2048 bit (pair of 1024 bit DMR) registers, following a similar
approach as we did for OO and XOmodes.

The problem is the mode_unit_size is declared as 'unsigned char' array in
genmodes.cc. Because of this I get an overflow warning, and querying this array
for the new QDOmode implemented below will return 0.

mode_unit_size_inline (machine_mode mode)\n\
{\n\
  extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];\
\n\

Is it safe to change this array type to unsigned int, since the struct 
mode_data's
fields for bytesize and ncomponents are also unsigned int?

Work in progress patch is below, here I am trying to add opaque mode in
rs6000-modes.def.

Thanks and regards,
Avinash

---
 gcc/config/rs6000/rs6000-builtin.cc | 16 ++++++++++++++++
 gcc/config/rs6000/rs6000-modes.def  |  3 ++-
 gcc/config/rs6000/rs6000.cc         | 15 +++++++++++----
 gcc/config/rs6000/rs6000.h          |  4 ++++
 4 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtin.cc 
b/gcc/config/rs6000/rs6000-builtin.cc
index ad6f1fc09f4..0081c3cb0e4 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -519,6 +519,8 @@ const char *rs6000_type_string (tree type_node)
     return "__vector_quad";
   else if (type_node == dmr1024_type_node)
     return "__dmr1024";
+  else if (type_node == dmr2048_type_node)
+    return "__dmr2048";
 
   return "unknown";
 }
@@ -835,6 +837,17 @@ rs6000_init_builtins (void)
   t = build_qualified_type (dmr1024_type_node, TYPE_QUAL_CONST);
   ptr_dmr1024_type_node = build_pointer_type (t);
 
+  dmr2048_type_node = make_node (OPAQUE_TYPE);
+  SET_TYPE_MODE (dmr2048_type_node, QDOmode);
+  TYPE_SIZE (dmr2048_type_node) = bitsize_int (GET_MODE_BITSIZE (QDOmode));
+  TYPE_PRECISION (dmr2048_type_node) = GET_MODE_BITSIZE (QDOmode);
+  TYPE_SIZE_UNIT (dmr2048_type_node) = size_int (GET_MODE_SIZE (QDOmode));
+  SET_TYPE_ALIGN (dmr2048_type_node, 512);
+  TYPE_USER_ALIGN (dmr2048_type_node) = 0;
+  lang_hooks.types.register_builtin_type (dmr2048_type_node, "__dmr2048");
+  t = build_qualified_type (dmr2048_type_node, TYPE_QUAL_CONST);
+  ptr_dmr2048_type_node = build_pointer_type (t);
+
   tdecl = add_builtin_type ("__bool char", bool_char_type_node);
   TYPE_NAME (bool_char_type_node) = tdecl;
 
@@ -1337,6 +1350,9 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
     case OOmode:
       lhs_type = vector_pair_type_node;
       break;
+    case QDOmode:
+      lhs_type = dmr2048_type_node;
+      break;
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/config/rs6000/rs6000-modes.def 
b/gcc/config/rs6000/rs6000-modes.def
index 0ad326751c4..e9fdc145d43 100644
--- a/gcc/config/rs6000/rs6000-modes.def
+++ b/gcc/config/rs6000/rs6000-modes.def
@@ -76,7 +76,8 @@ VECTOR_MODE (INT, SI, 2);     /*                 V2SI  */
    combination.  */
 PARTIAL_INT_MODE (TI, 128, PTI);
 
-/* Modes used by __vector_pair, __vector_quad and __dmr1024.  */
+/* Modes used by __vector_pair, __vector_quad, __dmr1024, __dmr2048.  */
 OPAQUE_MODE (OO, 32);
 OPAQUE_MODE (XO, 64);
 OPAQUE_MODE (TDO, 128);
+OPAQUE_MODE (QDO, 256);
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 99555988913..bca421fe1fb 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1868,8 +1868,9 @@ rs6000_hard_regno_mode_ok_uncached (int regno, 
machine_mode mode)
   if (COMPLEX_MODE_P (mode))
     mode = GET_MODE_INNER (mode);
 
-  /* No other types other than XOmode or TDOmode can go in DMRs.  */
-  if (DMR_REGNO_P (regno) && !(mode ==XOmode || mode == TDOmode))
+  /* No other types other than XOmode, TDOmode or QDOmode can go in DMRs.  */
+  if (DMR_REGNO_P (regno)
+      && !(mode == XOmode || mode == TDOmode || mode == QDOmode))
     return 0;
 
   /* TDOmode value can be held in either 1 DMR register or 8 VSX
@@ -1884,6 +1885,11 @@ rs6000_hard_regno_mode_ok_uncached (int regno, 
machine_mode mode)
       else
        return 0;
     }
+  /* QDOmode needs even/odd DMR register pairs.  */
+  if (mode == QDOmode)
+    {
+      return (TARGET_DMF && DMR_REGNO_P (regno) && (regno & 1) == 0);
+    }
 
   /* Vector pair modes need even/odd VSX register pairs.  Only allow vector
      registers.  */
@@ -2011,8 +2017,9 @@ static bool
 rs6000_modes_tieable_p (machine_mode mode1, machine_mode mode2)
 {
   if (mode1 == PTImode || mode1 == OOmode || mode1 == XOmode
-      || mode1 == TDOmode || mode2 == PTImode || mode2 == OOmode
-      || mode2 == XOmode || mode2 == TDOmode)
+      || mode1 == TDOmode || mode1 == QDOmode || mode2 == PTImode
+      || mode2 == OOmode || mode2 == XOmode || mode2 == TDOmode
+      || mode2 == QDOmode)
     return mode1 == mode2;
 
   if (ALTIVEC_OR_VSX_VECTOR_MODE (mode1))
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index bcd4c39d24d..c06de1396b1 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2277,6 +2277,7 @@ enum rs6000_builtin_type_index
   RS6000_BTI_vector_pair,       /* unsigned 256-bit types (vector pair).  */
   RS6000_BTI_vector_quad,       /* unsigned 512-bit types (vector quad).  */
   RS6000_BTI_dmr1024,            /* unsigned 1024-bit type (dmr1024).  */
+  RS6000_BTI_dmr2048,            /* unsigned 2048-bit type (dmr2048).  */
   RS6000_BTI_const_ptr_void,     /* const pointer to void */
   RS6000_BTI_ptr_V16QI,
   RS6000_BTI_ptr_V1TI,
@@ -2316,6 +2317,7 @@ enum rs6000_builtin_type_index
   RS6000_BTI_ptr_vector_pair,
   RS6000_BTI_ptr_vector_quad,
   RS6000_BTI_ptr_dmr1024,
+  RS6000_BTI_ptr_dmr2048,
   RS6000_BTI_ptr_long_long,
   RS6000_BTI_ptr_long_long_unsigned,
   RS6000_BTI_INTPTI,
@@ -2378,6 +2380,7 @@ enum rs6000_builtin_type_index
 #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 dmr1024_type_node                
(rs6000_builtin_types[RS6000_BTI_dmr1024])
+#define dmr2048_type_node                
(rs6000_builtin_types[RS6000_BTI_dmr2048])
 #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])
@@ -2417,6 +2420,7 @@ enum rs6000_builtin_type_index
 #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_dmr1024_type_node            
(rs6000_builtin_types[RS6000_BTI_ptr_dmr1024])
+#define ptr_dmr2048_type_node            
(rs6000_builtin_types[RS6000_BTI_ptr_dmr2048])
 #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])
 
-- 
2.54.0

Reply via email to