diff options
Diffstat (limited to 'gcc/genmodes.c')
-rw-r--r-- | gcc/genmodes.c | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/gcc/genmodes.c b/gcc/genmodes.c index 7d58865..c096434 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -72,7 +72,9 @@ struct mode_data unsigned int counter; /* Rank ordering of modes */ unsigned int ibit; /* the number of integral bits */ unsigned int fbit; /* the number of fractional bits */ - bool need_bytesize_adj; /* true if this mode need dynamic size + bool need_nunits_adj; /* true if this mode needs dynamic nunits + adjustment */ + bool need_bytesize_adj; /* true if this mode needs dynamic size adjustment */ unsigned int int_n; /* If nonzero, then __int<INT_N> will be defined */ }; @@ -85,7 +87,7 @@ static const struct mode_data blank_mode = { 0, "<unknown>", MAX_MODE_CLASS, -1U, -1U, -1U, -1U, 0, 0, 0, 0, 0, 0, - "<unknown>", 0, 0, 0, 0, false, 0 + "<unknown>", 0, 0, 0, 0, false, false, 0 }; static htab_t modes_by_name; @@ -103,6 +105,7 @@ struct mode_adjust unsigned int line; }; +static struct mode_adjust *adj_nunits; static struct mode_adjust *adj_bytesize; static struct mode_adjust *adj_alignment; static struct mode_adjust *adj_format; @@ -780,6 +783,7 @@ make_vector_mode (enum mode_class bclass, #define _ADD_ADJUST(A, M, X, C1, C2) \ new_adjust (#M, &adj_##A, #A, #X, MODE_##C1, MODE_##C2, __FILE__, __LINE__) +#define ADJUST_NUNITS(M, X) _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM) #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) @@ -949,9 +953,9 @@ calc_wider_mode (void) #define print_decl(TYPE, NAME, ASIZE) \ puts ("\nconst " TYPE " " NAME "[" ASIZE "] =\n{"); -#define print_maybe_const_decl(TYPE, NAME, ASIZE, CATEGORY) \ +#define print_maybe_const_decl(TYPE, NAME, ASIZE, NEEDS_ADJ) \ printf ("\n" TYPE " " NAME "[" ASIZE "] = \n{\n", \ - adj_##CATEGORY ? "" : "const ") + NEEDS_ADJ ? "" : "const ") #define print_closer() puts ("};") @@ -1009,6 +1013,11 @@ emit_mode_size_inline (void) m->need_bytesize_adj = true; } + /* Changing the number of units by a factor of X also changes the size + by a factor of X. */ + for (mode_adjust *a = adj_nunits; a; a = a->next) + a->mode->need_bytesize_adj = true; + printf ("\ #ifdef __cplusplus\n\ inline __attribute__((__always_inline__))\n\ @@ -1021,7 +1030,7 @@ mode_size_inline (machine_mode mode)\n\ extern %spoly_uint16_pod mode_size[NUM_MACHINE_MODES];\n\ gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\ switch (mode)\n\ - {\n", adj_bytesize ? "" : "const "); + {\n", adj_nunits || adj_bytesize ? "" : "const "); for_all_modes (c, m) if (!m->need_bytesize_adj) @@ -1040,7 +1049,10 @@ emit_mode_nunits_inline (void) int c; struct mode_data *m; - puts ("\ + for (mode_adjust *a = adj_nunits; a; a = a->next) + a->mode->need_nunits_adj = true; + + printf ("\ #ifdef __cplusplus\n\ inline __attribute__((__always_inline__))\n\ #else\n\ @@ -1049,12 +1061,13 @@ extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\ poly_uint16\n\ mode_nunits_inline (machine_mode mode)\n\ {\n\ - extern poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];\n\ + extern %spoly_uint16_pod mode_nunits[NUM_MACHINE_MODES];\n\ switch (mode)\n\ - {"); + {\n", adj_nunits ? "" : "const "); for_all_modes (c, m) - printf (" case E_%smode: return %u;\n", m->name, m->ncomponents); + if (!m->need_nunits_adj) + printf (" case E_%smode: return %u;\n", m->name, m->ncomponents); puts ("\ default: return mode_nunits[mode];\n\ @@ -1271,7 +1284,10 @@ enum machine_mode\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_NUNITS%s\n", adj_nunits ? "" : " const"); + printf ("#define CONST_MODE_PRECISION%s\n", adj_nunits ? "" : " const"); + printf ("#define CONST_MODE_SIZE%s\n", + adj_bytesize || adj_nunits ? "" : " 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 */ @@ -1386,7 +1402,8 @@ emit_mode_precision (void) int c; struct mode_data *m; - print_decl ("poly_uint16_pod", "mode_precision", "NUM_MACHINE_MODES"); + print_maybe_const_decl ("%spoly_uint16_pod", "mode_precision", + "NUM_MACHINE_MODES", adj_nunits); for_all_modes (c, m) if (m->precision != (unsigned int)-1) @@ -1405,7 +1422,7 @@ emit_mode_size (void) struct mode_data *m; print_maybe_const_decl ("%spoly_uint16_pod", "mode_size", - "NUM_MACHINE_MODES", bytesize); + "NUM_MACHINE_MODES", adj_nunits || adj_bytesize); for_all_modes (c, m) tagged_printf ("{ %u" ZERO_COEFFS " }", m->bytesize, m->name); @@ -1419,7 +1436,8 @@ emit_mode_nunits (void) int c; struct mode_data *m; - print_decl ("poly_uint16_pod", "mode_nunits", "NUM_MACHINE_MODES"); + print_maybe_const_decl ("%spoly_uint16_pod", "mode_nunits", + "NUM_MACHINE_MODES", adj_nunits); for_all_modes (c, m) tagged_printf ("{ %u" ZERO_COEFFS " }", m->ncomponents, m->name); @@ -1557,7 +1575,7 @@ emit_mode_unit_size (void) struct mode_data *m; print_maybe_const_decl ("%sunsigned char", "mode_unit_size", - "NUM_MACHINE_MODES", bytesize); + "NUM_MACHINE_MODES", adj_bytesize); for_all_modes (c, m) tagged_printf ("%u", @@ -1598,7 +1616,7 @@ emit_mode_base_align (void) print_maybe_const_decl ("%sunsigned short", "mode_base_align", "NUM_MACHINE_MODES", - alignment); + adj_alignment); for_all_modes (c, m) tagged_printf ("%u", m->alignment, m->name); @@ -1679,6 +1697,23 @@ emit_mode_adjustments (void) \n poly_uint16 ps ATTRIBUTE_UNUSED;\n\ size_t s ATTRIBUTE_UNUSED;"); + for (a = adj_nunits; a; a = a->next) + { + m = a->mode; + printf ("\n" + " {\n" + " /* %s:%d */\n ps = %s;\n", + a->file, a->line, a->adjustment); + printf (" int old_factor = vector_element_size" + " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n", + m->name, m->name); + printf (" mode_precision[E_%smode] = ps * old_factor;\n", m->name); + printf (" mode_size[E_%smode] = exact_div (mode_precision[E_%smode]," + " BITS_PER_UNIT);\n", m->name, m->name); + printf (" mode_nunits[E_%smode] = ps;\n", m->name); + printf (" }\n"); + } + /* Size adjustments must be propagated to all containing modes. A size adjustment forces us to recalculate the alignment too. */ for (a = adj_bytesize; a; a = a->next) @@ -1819,7 +1854,7 @@ emit_mode_ibit (void) print_maybe_const_decl ("%sunsigned char", "mode_ibit", "NUM_MACHINE_MODES", - ibit); + adj_ibit); for_all_modes (c, m) tagged_printf ("%u", m->ibit, m->name); @@ -1837,7 +1872,7 @@ emit_mode_fbit (void) print_maybe_const_decl ("%sunsigned char", "mode_fbit", "NUM_MACHINE_MODES", - fbit); + adj_fbit); for_all_modes (c, m) tagged_printf ("%u", m->fbit, m->name); |