diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9ef8497033f..0f39e3f9daf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2015-08-19 David Sherwood + + * 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 * config/aarch64/aarch64.c (bit_count): Delete prototype diff --git a/gcc/genmodes.c b/gcc/genmodes.c index f4db427ffe3..065ca54f30b 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -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 (); diff --git a/gcc/machmode.h b/gcc/machmode.h index 66ac7c0539d..5de16349919 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -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. */