genmodes.c (emit_mode_unit_size_inline): New function.
authorDavid Sherwood <david.sherwood@arm.com>
Wed, 19 Aug 2015 15:23:11 +0000 (15:23 +0000)
committerDavid Sherwood <davids@gcc.gnu.org>
Wed, 19 Aug 2015 15:23:11 +0000 (15:23 +0000)
2015-08-19  David Sherwood  <david.sherwood@arm.com>

    gcc/
* genmodes.c (emit_mode_unit_size_inline): New function.
(emit_mode_unit_precision_inline): New function.
(emit_insn_modes_h): Emit new #define.  Emit new functions.
(emit_mode_unit_size): New function.
(emit_mode_unit_precision): New function.
(emit_mode_adjustments): Add mode_unit_size adjustments.
(emit_insn_modes_c): Emit new arrays.
* machmode.h (GET_MODE_UNIT_SIZE, GET_MODE_UNIT_PRECISION): Update to
use new inline methods.

From-SVN: r227013

gcc/ChangeLog
gcc/genmodes.c
gcc/machmode.h

index 9ef8497033f7e31a5234e26ebca5db30271b23fe..0f39e3f9dafe3123e5bee091d517b15efe7159ca 100644 (file)
@@ -1,3 +1,15 @@
+2015-08-19  David Sherwood  <david.sherwood@arm.com>
+
+       * genmodes.c (emit_mode_unit_size_inline): New function.
+       (emit_mode_unit_precision_inline): New function.
+       (emit_insn_modes_h): Emit new #define.  Emit new functions.
+       (emit_mode_unit_size): New function.
+       (emit_mode_unit_precision): New function.
+       (emit_mode_adjustments): Add mode_unit_size adjustments.
+       (emit_insn_modes_c): Emit new arrays.
+       * machmode.h (GET_MODE_UNIT_SIZE, GET_MODE_UNIT_PRECISION): Update to
+       use new inline methods.
+
 2015-08-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/aarch64/aarch64.c (bit_count): Delete prototype
index f4db427ffe3365346a22b4f53ef9c2cd6bc59060..065ca54f30bd7b20e361e107b38beca88eb24b2e 100644 (file)
@@ -1047,6 +1047,79 @@ mode_inner_inline (machine_mode mode)\n\
 }\n");
 }
 
+/* Emit mode_unit_size_inline routine into insn-modes.h header.  */
+static void
+emit_mode_unit_size_inline (void)
+{
+  int c;
+  struct mode_data *m;
+
+  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_inline (machine_mode mode)\n\
+{\n\
+  extern unsigned char mode_unit_size[NUM_MACHINE_MODES];\n\
+  switch (mode)\n\
+    {");
+
+  for_all_modes (c, m)
+    {
+      const char *name = m->name;
+      struct mode_data *m2 = m;
+      if (c != MODE_PARTIAL_INT && m2->component)
+       m2 = m2->component;
+      if (!m2->need_bytesize_adj)
+       printf ("    case %smode: return %u;\n", name, m2->bytesize);
+    }
+
+  puts ("\
+    default: return mode_unit_size[mode];\n\
+    }\n\
+}\n");
+}
+
+/* Emit mode_unit_precision_inline routine into insn-modes.h header.  */
+static void
+emit_mode_unit_precision_inline (void)
+{
+  int c;
+  struct mode_data *m;
+
+  puts ("\
+#ifdef __cplusplus\n\
+inline __attribute__((__always_inline__))\n\
+#else\n\
+extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
+#endif\n\
+unsigned short\n\
+mode_unit_precision_inline (machine_mode mode)\n\
+{\n\
+  extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];\n\
+  switch (mode)\n\
+    {");
+
+  for_all_modes (c, m)
+    {
+      struct mode_data *m2
+       = (c != MODE_PARTIAL_INT && m->component) ? m->component : m;
+      if (m2->precision != (unsigned int)-1)
+       printf ("    case %smode: return %u;\n", m->name, m2->precision);
+      else
+       printf ("    case %smode: return %u*BITS_PER_UNIT;\n",
+               m->name, m2->bytesize);
+    }
+
+  puts ("\
+    default: return mode_unit_precision[mode];\n\
+    }\n\
+}\n");
+}
+
 static void
 emit_insn_modes_h (void)
 {
@@ -1107,6 +1180,7 @@ enum machine_mode\n{");
 
   /* I can't think of a better idea, can you?  */
   printf ("#define CONST_MODE_SIZE%s\n", adj_bytesize ? "" : " const");
+  printf ("#define CONST_MODE_UNIT_SIZE%s\n", adj_bytesize ? "" : " const");
   printf ("#define CONST_MODE_BASE_ALIGN%s\n", adj_alignment ? "" : " const");
 #if 0 /* disabled for backward compatibility, temporary */
   printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
@@ -1125,6 +1199,8 @@ enum machine_mode\n{");
   emit_mode_size_inline ();
   emit_mode_nunits_inline ();
   emit_mode_inner_inline ();
+  emit_mode_unit_size_inline ();
+  emit_mode_unit_precision_inline ();
   puts ("#endif /* GCC_VERSION >= 4001 */");
 
   puts ("\
@@ -1344,6 +1420,47 @@ emit_mode_inner (void)
   print_closer ();
 }
 
+/* Emit mode_unit_size array into insn-modes.c file.  */
+static void
+emit_mode_unit_size (void)
+{
+  int c;
+  struct mode_data *m;
+
+  print_maybe_const_decl ("%sunsigned char", "mode_unit_size",
+                         "NUM_MACHINE_MODES", bytesize);
+
+  for_all_modes (c, m)
+    tagged_printf ("%u",
+                  c != MODE_PARTIAL_INT && m->component
+                  ? m->component->bytesize : m->bytesize, m->name);
+
+  print_closer ();
+}
+
+/* Emit mode_unit_precision array into insn-modes.c file.  */
+static void
+emit_mode_unit_precision (void)
+{
+  int c;
+  struct mode_data *m;
+
+  print_decl ("unsigned short", "mode_unit_precision", "NUM_MACHINE_MODES");
+
+  for_all_modes (c, m)
+    {
+      struct mode_data *m2 = (c != MODE_PARTIAL_INT && m->component) ?
+                            m->component : m;
+      if (m2->precision != (unsigned int)-1)
+       tagged_printf ("%u", m2->precision, m->name);
+      else
+       tagged_printf ("%u*BITS_PER_UNIT", m2->bytesize, m->name);
+    }
+
+  print_closer ();
+}
+
+
 static void
 emit_mode_base_align (void)
 {
@@ -1439,6 +1556,7 @@ emit_mode_adjustments (void)
       printf ("\n  /* %s:%d */\n  s = %s;\n",
              a->file, a->line, a->adjustment);
       printf ("  mode_size[%smode] = s;\n", a->mode->name);
+      printf ("  mode_unit_size[%smode] = s;\n", a->mode->name);
       printf ("  mode_base_align[%smode] = s & (~s + 1);\n",
              a->mode->name);
 
@@ -1449,6 +1567,7 @@ emit_mode_adjustments (void)
            case MODE_COMPLEX_INT:
            case MODE_COMPLEX_FLOAT:
              printf ("  mode_size[%smode] = 2*s;\n", m->name);
+             printf ("  mode_unit_size[%smode] = s;\n", m->name);
              printf ("  mode_base_align[%smode] = s & (~s + 1);\n",
                      m->name);
              break;
@@ -1461,6 +1580,7 @@ emit_mode_adjustments (void)
            case MODE_VECTOR_UACCUM:
              printf ("  mode_size[%smode] = %d*s;\n",
                      m->name, m->ncomponents);
+             printf ("  mode_unit_size[%smode] = s;\n", m->name);
              printf ("  mode_base_align[%smode] = (%d*s) & (~(%d*s)+1);\n",
                      m->name, m->ncomponents, m->ncomponents);
              break;
@@ -1626,6 +1746,8 @@ emit_insn_modes_c (void)
   emit_mode_wider ();
   emit_mode_mask ();
   emit_mode_inner ();
+  emit_mode_unit_size ();
+  emit_mode_unit_precision ();
   emit_mode_base_align ();
   emit_class_narrowest_mode ();
   emit_real_format_for_mode ();
index 66ac7c0539d8afa9612cbe45c06a2c681507b76a..5de1634991969a631548a917f6883d125dc7a49f 100644 (file)
@@ -225,12 +225,28 @@ extern const unsigned char mode_inner[NUM_MACHINE_MODES];
 /* Get the size in bytes or bits of the basic parts of an
    object of mode MODE.  */
 
-#define GET_MODE_UNIT_SIZE(MODE) GET_MODE_SIZE (GET_MODE_INNER (MODE))
+extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
+#if GCC_VERSION >= 4001
+#define GET_MODE_UNIT_SIZE(MODE) \
+  ((unsigned char) (__builtin_constant_p (MODE) \
+                  ? mode_unit_size_inline (MODE) : mode_unit_size[MODE]))
+#else
+#define GET_MODE_UNIT_SIZE(MODE) mode_unit_size[MODE]
+#endif
 
 #define GET_MODE_UNIT_BITSIZE(MODE) \
   ((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))
 
-#define GET_MODE_UNIT_PRECISION(MODE) GET_MODE_PRECISION (GET_MODE_INNER (MODE))
+extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
+#if GCC_VERSION >= 4001
+#define GET_MODE_UNIT_PRECISION(MODE) \
+  ((unsigned short) (__builtin_constant_p (MODE) \
+                   ? mode_unit_precision_inline (MODE)\
+                   : mode_unit_precision[MODE]))
+#else
+#define GET_MODE_UNIT_PRECISION(MODE) mode_unit_precision[MODE]
+#endif
+
 
 /* Get the number of units in the object.  */