/* 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
-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
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"
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];
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 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
{
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;
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);
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;
}
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,
- m->cl != MODE_INT ? SET : UNSET);
+ (m->cl == MODE_FLOAT || m->cl == MODE_DECIMAL_FLOAT)
+ ? SET : UNSET);
m->ncomponents = 1;
m->component = 0;
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)
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__)
}
/* 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 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;
/* 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)
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);
}
#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 */");
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",
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;
}
}
}
+
+ /* 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)
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)
{
emit_class_narrowest_mode ();
emit_real_format_for_mode ();
emit_mode_adjustments ();
+ emit_mode_ibit ();
+ emit_mode_fbit ();
}
static void
/* Master control. */
int
-main(int argc, char **argv)
+main (int argc, char **argv)
{
bool gen_header = false, gen_min = false;
progname = argv[0];