+2003-10-15 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c: Include hashtab.h.
+ (modes_by_name, hash_mode, eq_mode, struct mode_adjust)
+ (adj_bytesize, adj_alignment, adj_format, new_adjust)
+ (_ADD_ADJUST, ADJUST_BYTESIZE, ADJUST_ALIGNMENT, ADJUST_FORMAT)
+ (print_maybe_const_decl, emit_mode_adjustments): New.
+ (known_modes): Rename to modes.
+ (find_mode): Kill class argument; look up in hash table.
+ (new_mode): Insert into hash table also.
+ (new_adjust): New.
+ (reset_float_format, make_partial_integer_mode)
+ (make_vector_mode): Tweak error reporting.
+ (reset_float_format): Correct type of fourth argument.
+ (emit_insn_modes_h): Add #defines to help make mode_size,
+ mode_base_align, and real_format_for_mode conditionally const.
+ (emit_mode_size, emit_mode_base_align): Use print_maybe_const_decl.
+ (emit_real_format_for_mode): Likewise, but temporarily disabled.
+ (emit_insn_modes_c): Call emit_mode_adjustments.
+ (main): Initialize modes_by_name.
+ * Makefile.in: Update dependencies.
+ * machmode.def: Document EXPR arguments and new ADJUST_* statements.
+ * machmode.h: Use CONST_MODE_SIZE and CONST_MODE_BASE_ALIGN in
+ declarations of mode_size and mode_base_align. Declare
+ init_adjust_machine_modes.
+ * toplev.c (backend_init): Call init_adjust_machine_modes.
+
2003-10-15 Olivier Hainque <hainque@act-europe.fr>
* genmodes.c (calc_wider_mode): Allocate enough room for all the
entries we'll possibly assign in the sort buffer.
-
+
2003-10-15 Ulrich Weigand <uweigand@de.ibm.com>
* config.gcc (s390x-ibm-tpf*): New target.
New functions.
* config/s390/s390.h (PREDICATE_CODES): Add s390_alc_comparison
and s390_slb_comparison.
- * config/s390/s390.md ("*adddi3_31", "*subdi3_31"): Do not use on
+ * config/s390/s390.md ("*adddi3_31", "*subdi3_31"): Do not use on
zSeries machines.
("*adddi3_31z", "*subdi3_31z"): New insns.
("*adddi3_alc_cc", "*adddi3_alc", "*subdi3_slb_cc", "*subdi3_slb",
"*addsi3_alc_cc", "*addsi3_alc", "*subsi3_slb_cc", "*subsi3_slb"):
New insns.
-
+
2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
* configure.in: Clean up some feedback echoes.
* config/s390/s390.md ("muldf3", "*muldf3", "*muldf3_ibm",
"mulsf3", "*mulsf3", "*mulsf3_ibm"): Do not clobber CC.
- ("divdf3", "*divdf3", "*divdf3_ibm", "divsf3", "*divsf3",
+ ("divdf3", "*divdf3", "*divdf3_ibm", "divsf3", "*divsf3",
"*divsf3_ibm"): Likewise.
2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
* fixinc/inclhack.def (alpha_pthread_gcc): New fix.
* fixinc/fixincl.x: Regenerate.
* fixinc/tests/base/pthread.h [ALPHA_PTHREAD_GCC_CHECK]: New
- testcase.
+ testcase.
Fixes PR bootstrap/9330.
2003-10-13 Eric Christopher <echristo@redhat.com>
#include "bconfig.h"
#include "system.h"
#include "errors.h"
+#include "hashtab.h"
/* enum mode_class is normally defined by machmode.h but we can't
include that header here. */
unsigned int line; /* for error reporting */
};
-static struct mode_data *known_modes[MAX_MODE_CLASS];
+static struct mode_data *modes[MAX_MODE_CLASS];
static unsigned int n_modes[MAX_MODE_CLASS];
static struct mode_data *void_mode;
"<unknown>", 0
};
+static htab_t modes_by_name;
+
+/* Data structure for recording target-specified runtime adjustments
+ to a particular mode. We support varying the byte size, the
+ alignment, and the floating point format. */
+struct mode_adjust
+{
+ struct mode_adjust *next;
+ struct mode_data *mode;
+ const char *adjustment;
+
+ const char *file;
+ unsigned int line;
+};
+
+static struct mode_adjust *adj_bytesize;
+static struct mode_adjust *adj_alignment;
+static struct mode_adjust *adj_format;
+
/* Mode class operations. */
static enum mode_class
complex_class (enum mode_class class)
}
}
-static struct mode_data *
-find_mode (enum mode_class class, const char *name)
+/* Utility routines. */
+static inline struct mode_data *
+find_mode (const char *name)
{
- struct mode_data *m;
+ struct mode_data key;
- for (m = known_modes[class]; m; m = m->next)
- if (!strcmp (name, m->name))
- return m;
-
- return 0;
+ key.name = name;
+ return htab_find (modes_by_name, &key);
}
static struct mode_data *
{
struct mode_data *m;
- m = find_mode (class, name);
+ m = find_mode (name);
if (m)
{
error ("%s:%d: duplicate definition of mode \"%s\"",
m->file = trim_filename (file);
m->line = line;
- m->next = known_modes[class];
- known_modes[class] = m;
+ m->next = modes[class];
+ modes[class] = m;
n_modes[class]++;
+
+ *htab_find_slot (modes_by_name, m, INSERT) = m;
+
return m;
}
+static hashval_t
+hash_mode (const void *p)
+{
+ const struct mode_data *m = (const struct mode_data *)p;
+ return htab_hash_string (m->name);
+}
+
+static int
+eq_mode (const void *p, const void *q)
+{
+ const struct mode_data *a = (const struct mode_data *)p;
+ const struct mode_data *b = (const struct mode_data *)q;
+
+ return !strcmp (a->name, b->name);
+}
+
#define for_all_modes(C, M) \
for (C = 0; C < MAX_MODE_CLASS; C++) \
- for (M = known_modes[C]; M; M = M->next)
+ for (M = modes[C]; M; M = M->next)
+
+static void ATTRIBUTE_UNUSED
+new_adjust (const char *name,
+ struct mode_adjust **category, const char *catname,
+ const char *adjustment,
+ enum mode_class required_class,
+ const char *file, unsigned int line)
+{
+ struct mode_data *mode = find_mode (name);
+ struct mode_adjust *a;
+
+ file = trim_filename (file);
+
+ if (!mode)
+ {
+ error ("%s:%d: no mode \"%s\"", file, line, name);
+ return;
+ }
+
+ if (required_class != MODE_RANDOM && mode->class != required_class)
+ {
+ error ("%s:%d: mode \"%s\" is not class %s",
+ file, line, name, mode_class_names[required_class] + 5);
+ return;
+ }
+
+ for (a = *category; a; a = a->next)
+ if (a->mode == mode)
+ {
+ error ("%s:%d: mode \"%s\" already has a %s adjustment",
+ file, line, name, catname);
+ error ("%s:%d: previous adjustment here", a->file, a->line);
+ return;
+ }
+
+ a = xmalloc (sizeof (struct mode_adjust));
+ a->mode = mode;
+ a->adjustment = adjustment;
+ a->file = file;
+ a->line = line;
+
+ a->next = *category;
+ *category = a;
+}
/* Diagnose failure to meet expectations in a partially filled out
mode structure. */
if (cclass == MODE_RANDOM)
return;
- for (m = known_modes[class]; m; m = m->next)
+ for (m = modes[class]; m; m = m->next)
{
/* Skip BImode. FIXME: BImode probably shouldn't be MODE_INT. */
if (m->bitsize == 1)
if (vclass == MODE_RANDOM)
return;
- for (m = known_modes[class]; m; m = m->next)
+ for (m = modes[class]; m; m = m->next)
{
/* Do not construct vector modes with only one element, or
vector modes where the element size doesn't divide the full
reset_float_format (#N, #F, __FILE__, __LINE__)
static void ATTRIBUTE_UNUSED
reset_float_format (const char *name, const char *format,
- const char *file, const char *line)
+ const char *file, unsigned int line)
{
- struct mode_data *m = find_mode (MODE_FLOAT, name);
+ struct mode_data *m = find_mode (name);
if (!m)
{
- error ("%s:%d: no mode \"%s\" in class FLOAT", file, line, name);
+ error ("%s:%d: no mode \"%s\"", file, line, name);
+ return;
+ }
+ if (m->class != MODE_FLOAT)
+ {
+ error ("%s:%d: mode \"%s\" is not class FLOAT", file, line, name);
return;
}
m->format = format;
const char *file, unsigned int line)
{
struct mode_data *m;
- struct mode_data *component = find_mode (MODE_INT, base);
+ struct mode_data *component = find_mode (base);
if (!component)
{
- error ("%s:%d: no mode \"%s\" in class INT", file, line, name);
+ error ("%s:%d: no mode \"%s\"", file, line, name);
+ return;
+ }
+ if (component->class != MODE_INT)
+ {
+ error ("%s:%d: mode \"%s\" is not class INT", file, line, name);
return;
}
{
struct mode_data *v;
enum mode_class vclass = vector_class (bclass);
- struct mode_data *component = find_mode (bclass, base);
+ struct mode_data *component = find_mode (base);
char namebuf[8];
if (vclass == MODE_RANDOM)
return;
if (component == 0)
{
- error ("%s:%d: no mode \"%s\" in class %s",
+ error ("%s:%d: no mode \"%s\"", file, line, base);
+ return;
+ }
+ if (component->class != bclass)
+ {
+ error ("%s:%d: mode \"%s\" is not class %s",
file, line, base, mode_class_names[bclass] + 5);
return;
}
v->ncomponents = ncomponents;
v->component = component;
}
-
+
+/* Adjustability. */
+#define _ADD_ADJUST(A, M, X, C) \
+ new_adjust (#M, &adj_##A, #A, #X, MODE_##C, __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)
static void
create_modes (void)
{
struct mode_data *prev, *next;
- for (prev = 0, m = known_modes[c]; m; m = next)
+ for (prev = 0, m = modes[c]; m; m = next)
{
m->wider = void_mode;
m->next = prev;
prev = m;
}
- known_modes[c] = prev;
+ modes[c] = prev;
}
else
{
- if (!known_modes[c])
+ if (!modes[c])
continue;
- for (i = 0, m = known_modes[c]; m; i++, m = m->next)
+ for (i = 0, m = modes[c]; m; i++, m = m->next)
sortbuf[i] = m;
qsort (sortbuf, i, sizeof (struct mode_data *), cmp_modes);
sortbuf[j]->next = sortbuf[j]->wider = sortbuf[j + 1];
- known_modes[c] = sortbuf[0];
+ modes[c] = sortbuf[0];
}
}
}
} while (0)
#define print_decl(TYPE, NAME, ASIZE) \
- printf ("\nconst %s %s[%s] =\n{\n", TYPE, NAME, ASIZE);
+ puts ("\nconst " TYPE " " NAME "[" ASIZE "] =\n{");
+
+#define print_maybe_const_decl(TYPE, NAME, ASIZE, CATEGORY) \
+ printf ("\n" TYPE " " NAME "[" ASIZE "] = \n{\n", \
+ adj_##CATEGORY ? "" : "const ")
#define print_closer() puts ("};")
enum machine_mode\n{");
for (c = 0; c < MAX_MODE_CLASS; c++)
- for (m = known_modes[c]; m; m = m->next)
+ for (m = modes[c]; m; m = m->next)
{
int count_;
printf (" %smode,%n", m->name, &count_);
for (c = 0; c < MAX_MODE_CLASS; c++)
{
- first = known_modes[c];
+ first = modes[c];
last = 0;
for (m = first; m; last = m, m = m->next)
;
puts ("\
NUM_MACHINE_MODES = MAX_MACHINE_MODE\n\
-};\n\
+};\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_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");
+#endif
+ puts ("\
\n\
#endif /* insn-modes.h */");
}
enum mode_class c;
struct mode_data *m;
- print_decl ("unsigned char", "mode_size", "NUM_MACHINE_MODES");
+ print_maybe_const_decl ("%sunsigned char", "mode_size",
+ "NUM_MACHINE_MODES", bytesize);
for_all_modes (c, m)
tagged_printf ("%u", m->bytesize, m->name);
enum mode_class c;
struct mode_data *m;
- print_decl ("unsigned char", "mode_base_align", "NUM_MACHINE_MODES");
+ print_maybe_const_decl ("%sunsigned char",
+ "mode_base_align", "NUM_MACHINE_MODES",
+ alignment);
for_all_modes (c, m)
tagged_printf ("%u", m->alignment, m->name);
for (c = 0; c < MAX_MODE_CLASS; c++)
/* Bleah, all this to get the comment right for MIN_MODE_INT. */
tagged_printf ("MIN_%s", mode_class_names[c],
- known_modes[c]
- ? (known_modes[c]->bitsize != 1
- ? known_modes[c]->name
- : (known_modes[c]->next
- ? known_modes[c]->next->name
+ modes[c]
+ ? (modes[c]->bitsize != 1
+ ? modes[c]->name
+ : (modes[c]->next
+ ? modes[c]->next->name
: void_mode->name))
: void_mode->name);
{
struct mode_data *m;
- /* This will produce a table which is not constant, but points to
- entities that are constant, which is what we want. */
- print_decl ("struct real_format *\n ", "real_format_for_mode",
+ /* The entities pointed to by this table are constant, whether
+ or not the table itself is constant.
+
+ For backward compatibility this table is always writable
+ (several targets modify it in OVERRIDE_OPTIONS). FIXME:
+ convert all said targets to use ADJUST_FORMAT instead. */
+#if 0
+ print_maybe_const_decl ("const struct real_format *%s",
+ "real_format_for_mode",
+ "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1",
+ format);
+#else
+ print_decl ("struct real_format *\n", "real_format_for_mode",
"MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1");
+#endif
- for (m = known_modes[MODE_FLOAT]; m; m = m->next)
+ for (m = modes[MODE_FLOAT]; m; m = m->next)
if (!strcmp (m->format, "0"))
tagged_printf ("%s", m->format, m->name);
else
print_closer ();
}
+static void
+emit_mode_adjustments (void)
+{
+ struct mode_adjust *a;
+
+ puts ("\nvoid\ninit_adjust_machine_modes (void)\n{");
+
+ for (a = adj_bytesize; a; a = a->next)
+ printf (" /* %s:%d */\n mode_size[%smode] = %s;\n",
+ a->file, a->line, a->mode->name, a->adjustment);
+ if (adj_bytesize && (adj_alignment || adj_format))
+ putchar ('\n');
+
+ for (a = adj_alignment; a; a = a->next)
+ printf (" /* %s:%d */\n mode_base_align[%smode] = %s;\n",
+ a->file, a->line, a->mode->name, a->adjustment);
+ if (adj_alignment && adj_format)
+ putchar ('\n');
+
+ for (a = adj_format; a; a = a->next)
+ printf (" /* %s:%d */\n REAL_MODE_FORMAT (%smode) = %s;\n",
+ a->file, a->line, a->mode->name, a->adjustment);
+
+ puts ("}");
+}
+
static void
emit_insn_modes_c (void)
{
emit_mode_base_align ();
emit_class_narrowest_mode ();
emit_real_format_for_mode ();
+ emit_mode_adjustments ();
}
static void
return FATAL_EXIT_CODE;
}
+ modes_by_name = htab_create_alloc (64, hash_mode, eq_mode, 0, xcalloc, free);
+
create_modes ();
complete_all_modes ();