OSDN Git Service

* MAINTAINERS (Write After Approval): Add myself.
[pf3gnuchains/gcc-fork.git] / gcc / genmodes.c
index d8ba5df..3851aff 100644 (file)
@@ -1,12 +1,12 @@
 /* Generate the machine mode enumeration and associated tables.
 /* Generate the machine mode enumeration and associated tables.
-   Copyright (C) 2003, 2004
+   Copyright (C) 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 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
    Free Software Foundation, Inc.
 
 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 2, or (at your option) any later
+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
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +15,8 @@ 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
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "bconfig.h"
 #include "system.h"
 
 #include "bconfig.h"
 #include "system.h"
@@ -73,6 +72,8 @@ struct mode_data
   const char *file;            /* file and line of definition, */
   unsigned int line;           /* for error reporting */
   unsigned int counter;                /* Rank ordering of modes */
   const char *file;            /* file and line of definition, */
   unsigned int line;           /* for error reporting */
   unsigned int counter;                /* Rank ordering of modes */
+  unsigned int ibit;           /* the number of integral bits */
+  unsigned int fbit;           /* the number of fractional bits */
 };
 
 static struct mode_data *modes[MAX_MODE_CLASS];
 };
 
 static struct mode_data *modes[MAX_MODE_CLASS];
@@ -83,7 +84,7 @@ static const struct mode_data blank_mode = {
   0, "<unknown>", MAX_MODE_CLASS,
   -1U, -1U, -1U, -1U,
   0, 0, 0, 0, 0, 0,
   0, "<unknown>", MAX_MODE_CLASS,
   -1U, -1U, -1U, -1U,
   0, 0, 0, 0, 0, 0,
-  "<unknown>", 0, 0
+  "<unknown>", 0, 0, 0, 0
 };
 
 static htab_t modes_by_name;
 };
 
 static htab_t modes_by_name;
@@ -104,6 +105,8 @@ struct mode_adjust
 static struct mode_adjust *adj_bytesize;
 static struct mode_adjust *adj_alignment;
 static struct mode_adjust *adj_format;
 static struct mode_adjust *adj_bytesize;
 static struct mode_adjust *adj_alignment;
 static struct mode_adjust *adj_format;
+static struct mode_adjust *adj_ibit;
+static struct mode_adjust *adj_fbit;
 
 /* Mode class operations.  */
 static enum mode_class
 
 /* Mode class operations.  */
 static enum mode_class
@@ -126,6 +129,10 @@ vector_class (enum mode_class cl)
     {
     case MODE_INT: return MODE_VECTOR_INT;
     case MODE_FLOAT: return MODE_VECTOR_FLOAT;
     {
     case MODE_INT: return MODE_VECTOR_INT;
     case MODE_FLOAT: return MODE_VECTOR_FLOAT;
+    case MODE_FRACT: return MODE_VECTOR_FRACT;
+    case MODE_UFRACT: return MODE_VECTOR_UFRACT;
+    case MODE_ACCUM: return MODE_VECTOR_ACCUM;
+    case MODE_UACCUM: return MODE_VECTOR_UACCUM;
     default:
       error ("no vector class for class %s", mode_class_names[cl]);
       return MODE_RANDOM;
     default:
       error ("no vector class for class %s", mode_class_names[cl]);
       return MODE_RANDOM;
@@ -200,7 +207,8 @@ static void ATTRIBUTE_UNUSED
 new_adjust (const char *name,
            struct mode_adjust **category, const char *catname,
            const char *adjustment,
 new_adjust (const char *name,
            struct mode_adjust **category, const char *catname,
            const char *adjustment,
-           enum mode_class required_class,
+           enum mode_class required_class_from,
+           enum mode_class required_class_to,
            const char *file, unsigned int line)
 {
   struct mode_data *mode = find_mode (name);
            const char *file, unsigned int line)
 {
   struct mode_data *mode = find_mode (name);
@@ -214,10 +222,12 @@ new_adjust (const char *name,
       return;
     }
 
       return;
     }
 
-  if (required_class != MODE_RANDOM && mode->cl != required_class)
+  if (required_class_from != MODE_RANDOM
+      && (mode->cl < required_class_from || mode->cl > required_class_to))
     {
     {
-      error ("%s:%d: mode \"%s\" is not class %s",
-            file, line, name, mode_class_names[required_class] + 5);
+      error ("%s:%d: mode \"%s\" is not among class {%s, %s}",
+            file, line, name, mode_class_names[required_class_from] + 5,
+            mode_class_names[required_class_to] + 5);
       return;
     }
   
       return;
     }
   
@@ -327,11 +337,16 @@ complete_mode (struct mode_data *m)
     case MODE_INT:
     case MODE_FLOAT:
     case MODE_DECIMAL_FLOAT:
     case MODE_INT:
     case MODE_FLOAT:
     case MODE_DECIMAL_FLOAT:
+    case MODE_FRACT:
+    case MODE_UFRACT:
+    case MODE_ACCUM:
+    case MODE_UACCUM:
       /* A scalar mode must have a byte size, may have a bit size,
         and must not have components.   A float mode must have a
          format.  */
       validate_mode (m, OPTIONAL, SET, UNSET, UNSET,
       /* A scalar mode must have a byte size, may have a bit size,
         and must not have components.   A float mode must have a
          format.  */
       validate_mode (m, OPTIONAL, SET, UNSET, UNSET,
-                    m->cl != MODE_INT ? SET : UNSET);
+                    (m->cl == MODE_FLOAT || m->cl == MODE_DECIMAL_FLOAT)
+                    ? SET : UNSET);
 
       m->ncomponents = 1;
       m->component = 0;
 
       m->ncomponents = 1;
       m->component = 0;
@@ -361,6 +376,10 @@ complete_mode (struct mode_data *m)
 
     case MODE_VECTOR_INT:
     case MODE_VECTOR_FLOAT:
 
     case MODE_VECTOR_INT:
     case MODE_VECTOR_FLOAT:
+    case MODE_VECTOR_FRACT:
+    case MODE_VECTOR_UFRACT:
+    case MODE_VECTOR_ACCUM:
+    case MODE_VECTOR_UACCUM:
       /* Vector modes should have a component and a number of components.  */
       validate_mode (m, UNSET, UNSET, SET, SET, UNSET);
       if (m->component->precision != (unsigned int)-1)
       /* Vector modes should have a component and a number of components.  */
       validate_mode (m, UNSET, UNSET, SET, SET, UNSET);
       if (m->component->precision != (unsigned int)-1)
@@ -533,6 +552,35 @@ make_int_mode (const char *name,
   m->precision = precision;
 }
 
   m->precision = precision;
 }
 
+#define FRACT_MODE(N, Y, F) \
+       make_fixed_point_mode (MODE_FRACT, #N, Y, 0, F, __FILE__, __LINE__)
+
+#define UFRACT_MODE(N, Y, F) \
+       make_fixed_point_mode (MODE_UFRACT, #N, Y, 0, F, __FILE__, __LINE__)
+
+#define ACCUM_MODE(N, Y, I, F) \
+       make_fixed_point_mode (MODE_ACCUM, #N, Y, I, F, __FILE__, __LINE__)
+
+#define UACCUM_MODE(N, Y, I, F) \
+       make_fixed_point_mode (MODE_UACCUM, #N, Y, I, F, __FILE__, __LINE__)
+
+/* Create a fixed-point mode by setting CL, NAME, BYTESIZE, IBIT, FBIT,
+   FILE, and LINE.  */
+
+static void
+make_fixed_point_mode (enum mode_class cl,
+                      const char *name,
+                      unsigned int bytesize,
+                      unsigned int ibit,
+                      unsigned int fbit,
+                      const char *file, unsigned int line)
+{
+  struct mode_data *m = new_mode (cl, name, file, line);
+  m->bytesize = bytesize;
+  m->ibit = ibit;
+  m->fbit = fbit;
+}
+
 #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__)
 #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__)
@@ -635,7 +683,9 @@ make_vector_mode (enum mode_class bclass,
       error ("%s:%d: no mode \"%s\"", file, line, base);
       return;
     }
       error ("%s:%d: no mode \"%s\"", file, line, base);
       return;
     }
-  if (component->cl != bclass)
+  if (component->cl != bclass
+      && (component->cl != MODE_PARTIAL_INT
+         || bclass != MODE_INT))
     {
       error ("%s:%d: mode \"%s\" is not class %s",
             file, line, base, mode_class_names[bclass] + 5);
     {
       error ("%s:%d: mode \"%s\" is not class %s",
             file, line, base, mode_class_names[bclass] + 5);
@@ -656,12 +706,14 @@ make_vector_mode (enum mode_class bclass,
 }
 
 /* Adjustability.  */
 }
 
 /* Adjustability.  */
-#define _ADD_ADJUST(A, M, X, C) \
-  new_adjust (#M, &adj_##A, #A, #X, MODE_##C, __FILE__, __LINE__)
+#define _ADD_ADJUST(A, M, X, C1, C2) \
+  new_adjust (#M, &adj_##A, #A, #X, MODE_##C1, MODE_##C2, __FILE__, __LINE__)
 
 
-#define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST(bytesize, M, X, RANDOM)
-#define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST(alignment, M, X, RANDOM)
-#define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST(format, M, X, FLOAT)
+#define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST(bytesize, M, X, RANDOM, RANDOM)
+#define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST(alignment, M, X, RANDOM, RANDOM)
+#define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST(format, M, X, FLOAT, FLOAT)
+#define ADJUST_IBIT(M, X)  _ADD_ADJUST(ibit, M, X, ACCUM, UACCUM)
+#define ADJUST_FBIT(M, X)  _ADD_ADJUST(fbit, M, X, FRACT, UACCUM)
 
 static void
 create_modes (void)
 
 static void
 create_modes (void)
@@ -687,8 +739,8 @@ create_modes (void)
 static int
 cmp_modes (const void *a, const void *b)
 {
 static int
 cmp_modes (const void *a, const void *b)
 {
-  struct mode_data *m = *(struct mode_data **)a;
-  struct mode_data *n = *(struct mode_data **)b;
+  const struct mode_data *const m = *(const struct mode_data *const*)a;
+  const struct mode_data *const n = *(const struct mode_data *const*)b;
 
   if (m->bytesize > n->bytesize)
     return 1;
 
   if (m->bytesize > n->bytesize)
     return 1;
@@ -784,8 +836,7 @@ calc_wider_mode (void)
 /* Output routines.  */
 
 #define tagged_printf(FMT, ARG, TAG) do {              \
 /* Output routines.  */
 
 #define tagged_printf(FMT, ARG, TAG) do {              \
-  int count_;                                          \
-  printf ("  " FMT ",%n", ARG, &count_);               \
+  int count_ = printf ("  " FMT ",", ARG);             \
   printf ("%*s/* %s */\n", 27 - count_, "", TAG);      \
 } while (0)
 
   printf ("%*s/* %s */\n", 27 - count_, "", TAG);      \
 } while (0)
 
@@ -819,8 +870,7 @@ enum machine_mode\n{");
   for (c = 0; c < MAX_MODE_CLASS; c++)
     for (m = modes[c]; m; m = m->next)
       {
   for (c = 0; c < MAX_MODE_CLASS; c++)
     for (m = modes[c]; m; m = m->next)
       {
-       int count_;
-       printf ("  %smode,%n", m->name, &count_);
+       int count_ = printf ("  %smode,", m->name);
        printf ("%*s/* %s:%d */\n", 27 - count_, "",
                 trim_filename (m->file), m->line);
       }
        printf ("%*s/* %s:%d */\n", 27 - count_, "",
                 trim_filename (m->file), m->line);
       }
@@ -861,6 +911,8 @@ enum machine_mode\n{");
 #if 0 /* disabled for backward compatibility, temporary */
   printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
 #endif
 #if 0 /* disabled for backward compatibility, temporary */
   printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
 #endif
+  printf ("#define CONST_MODE_IBIT%s\n", adj_ibit ? "" : " const");
+  printf ("#define CONST_MODE_FBIT%s\n", adj_fbit ? "" : " const");
   puts ("\
 \n\
 #endif /* insn-modes.h */");
   puts ("\
 \n\
 #endif /* insn-modes.h */");
@@ -1173,6 +1225,10 @@ emit_mode_adjustments (void)
 
            case MODE_VECTOR_INT:
            case MODE_VECTOR_FLOAT:
 
            case MODE_VECTOR_INT:
            case MODE_VECTOR_FLOAT:
+           case MODE_VECTOR_FRACT:
+           case MODE_VECTOR_UFRACT:
+           case MODE_VECTOR_ACCUM:
+           case MODE_VECTOR_UACCUM:
              printf ("  mode_size[%smode] = %d*s;\n",
                      m->name, m->ncomponents);
              printf ("  mode_base_align[%smode] = (%d*s) & (~(%d*s)+1);\n",
              printf ("  mode_size[%smode] = %d*s;\n",
                      m->name, m->ncomponents);
              printf ("  mode_base_align[%smode] = (%d*s) & (~(%d*s)+1);\n",
@@ -1207,6 +1263,10 @@ emit_mode_adjustments (void)
 
            case MODE_VECTOR_INT:
            case MODE_VECTOR_FLOAT:
 
            case MODE_VECTOR_INT:
            case MODE_VECTOR_FLOAT:
+           case MODE_VECTOR_FRACT:
+           case MODE_VECTOR_UFRACT:
+           case MODE_VECTOR_ACCUM:
+           case MODE_VECTOR_UACCUM:
              printf ("  mode_base_align[%smode] = %d*s;\n",
                      m->name, m->ncomponents);
              break;
              printf ("  mode_base_align[%smode] = %d*s;\n",
                      m->name, m->ncomponents);
              break;
@@ -1219,6 +1279,22 @@ emit_mode_adjustments (void)
            }
        }
     }
            }
        }
     }
+
+  /* Ibit adjustments don't have to propagate.  */
+  for (a = adj_ibit; a; a = a->next)
+    {
+      printf ("\n  /* %s:%d */\n  s = %s;\n",
+             a->file, a->line, a->adjustment);
+      printf ("  mode_ibit[%smode] = s;\n", a->mode->name);
+    }
+
+  /* Fbit adjustments don't have to propagate.  */
+  for (a = adj_fbit; a; a = a->next)
+    {
+      printf ("\n  /* %s:%d */\n  s = %s;\n",
+             a->file, a->line, a->adjustment);
+      printf ("  mode_fbit[%smode] = s;\n", a->mode->name);
+    }
       
   /* Real mode formats don't have to propagate anywhere.  */
   for (a = adj_format; a; a = a->next)
       
   /* Real mode formats don't have to propagate anywhere.  */
   for (a = adj_format; a; a = a->next)
@@ -1228,6 +1304,43 @@ emit_mode_adjustments (void)
   puts ("}");
 }
 
   puts ("}");
 }
 
+/* Emit ibit for all modes.  */
+
+static void
+emit_mode_ibit (void)
+{
+  int c;
+  struct mode_data *m;
+
+  print_maybe_const_decl ("%sunsigned char",
+                         "mode_ibit", "NUM_MACHINE_MODES",
+                         ibit);
+
+  for_all_modes (c, m)
+    tagged_printf ("%u", m->ibit, m->name);
+
+  print_closer ();
+}
+
+/* Emit fbit for all modes.  */
+
+static void
+emit_mode_fbit (void)
+{
+  int c;
+  struct mode_data *m;
+
+  print_maybe_const_decl ("%sunsigned char",
+                         "mode_fbit", "NUM_MACHINE_MODES",
+                         fbit);
+
+  for_all_modes (c, m)
+    tagged_printf ("%u", m->fbit, m->name);
+
+  print_closer ();
+}
+
+
 static void
 emit_insn_modes_c (void)
 {
 static void
 emit_insn_modes_c (void)
 {
@@ -1244,6 +1357,8 @@ emit_insn_modes_c (void)
   emit_class_narrowest_mode ();
   emit_real_format_for_mode ();
   emit_mode_adjustments ();
   emit_class_narrowest_mode ();
   emit_real_format_for_mode ();
   emit_mode_adjustments ();
+  emit_mode_ibit ();
+  emit_mode_fbit ();
 }
 
 static void
 }
 
 static void
@@ -1258,7 +1373,7 @@ emit_min_insn_modes_c (void)
 
 /* Master control.  */
 int
 
 /* Master control.  */
 int
-main(int argc, char **argv)
+main (int argc, char **argv)
 {
   bool gen_header = false, gen_min = false;
   progname = argv[0];
 {
   bool gen_header = false, gen_min = false;
   progname = argv[0];