The mode_unit_size array that is generated from
emit_mode_unit_size_inline function currently hard codes the type of
this array to unsigned char, since for most architectures the
mode_unit_size never exceeded 255.

For rs6000 however, we add an opaque mode with 256 bytes which overflows
this type. Therefore this patch adds a macro named MODE_UNIT_SIZE_TYPE
in the generated file which is defined based on the maximum value that
the mode_unit_size array will hold.
if < 256, unsigned char
else if < 1^16, unsigned short
else, usigned int

2026-08-26  Avinash Jayakar  <[email protected]>

gcc/ChangeLog:
        * genmodes.cc (emit_mode_unit_size): Generate MODE_UNIT_SIZE_TYPE macro 
based
        on values in mode_unit_size.
        * machmode.h: Use the new macro.
---
 gcc/genmodes.cc | 20 +++++++++++++++++---
 gcc/machmode.h  |  2 +-
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
index fa5f8923519..f50d39e4ea4 100644
--- a/gcc/genmodes.cc
+++ b/gcc/genmodes.cc
@@ -1167,16 +1167,30 @@ emit_mode_unit_size_inline (void)
   int c;
   struct mode_data *m;
 
+  unsigned int max_type_size = 0;
+  for_all_modes (c, m)
+    {
+      if (max_type_size < m->bytesize)
+       max_type_size = (c != MODE_PARTIAL_INT && m->component)
+                       ? m->component->bytesize : m->bytesize;
+    }
+  if (max_type_size < (1 << 8))
+    puts ("#define MODE_UNIT_SIZE_TYPE unsigned char\n");
+  else if (max_type_size < (1 << 16))
+    puts ("#define MODE_UNIT_SIZE_TYPE unsigned short\n");
+  else
+    puts ("#define MODE_UNIT_SIZE_TYPE unsigned int\n");
+
   puts ("\
 #ifdef __cplusplus\n\
 inline __attribute__((__always_inline__))\n\
 #else\n\
 extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
 #endif\n\
-unsigned char\n\
+MODE_UNIT_SIZE_TYPE\n\
 mode_unit_size_inline (machine_mode mode)\n\
 {\n\
-  extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];\
+  extern CONST_MODE_UNIT_SIZE MODE_UNIT_SIZE_TYPE 
mode_unit_size[NUM_MACHINE_MODES];\
 \n\
   gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
   switch (mode)\n\
@@ -1683,7 +1697,7 @@ emit_mode_unit_size (void)
   int c;
   struct mode_data *m;
 
-  print_maybe_const_decl ("%sunsigned char", "mode_unit_size",
+  print_maybe_const_decl ("%sMODE_UNIT_SIZE_TYPE", "mode_unit_size",
                          "NUM_MACHINE_MODES", adj_bytesize);
 
   for_all_modes (c, m)
diff --git a/gcc/machmode.h b/gcc/machmode.h
index b92b1572d8d..468fa886910 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -26,7 +26,7 @@ extern CONST_MODE_SIZE poly_uint16 
mode_size[NUM_MACHINE_MODES];
 extern CONST_MODE_PRECISION poly_uint16 mode_precision[NUM_MACHINE_MODES];
 extern const unsigned short mode_inner[NUM_MACHINE_MODES];
 extern CONST_MODE_NUNITS poly_uint16 mode_nunits[NUM_MACHINE_MODES];
-extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
+extern CONST_MODE_UNIT_SIZE MODE_UNIT_SIZE_TYPE 
mode_unit_size[NUM_MACHINE_MODES];
 extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
 extern const unsigned short mode_next[NUM_MACHINE_MODES];
 extern const unsigned short mode_wider[NUM_MACHINE_MODES];
-- 
2.54.0

Reply via email to