aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/genmodes.c69
-rw-r--r--gcc/machmode.def6
-rw-r--r--gcc/machmode.h4
4 files changed, 86 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 29154cc..dd5d703 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,30 @@
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * machmode.h (mode_precision): Prefix with CONST_MODE_PRECISION.
+ (mode_nunits): Likewise CONST_MODE_NUNITS.
+ * machmode.def (ADJUST_NUNITS): Document.
+ * genmodes.c (mode_data::need_nunits_adj): New field.
+ (blank_mode): Update accordingly.
+ (adj_nunits): New variable.
+ (print_maybe_const_decl): Replace CATEGORY with a NEEDS_ADJ
+ parameter.
+ (emit_mode_size_inline): Set need_bytesize_adj for all modes
+ listed in adj_nunits.
+ (emit_mode_nunits_inline): Set need_nunits_adj for all modes
+ listed in adj_nunits. Don't emit case statements for such modes.
+ (emit_insn_modes_h): Emit definitions of CONST_MODE_NUNITS
+ and CONST_MODE_PRECISION. Make CONST_MODE_SIZE expand to
+ nothing if adj_nunits is nonnull.
+ (emit_mode_precision, emit_mode_nunits): Use print_maybe_const_decl.
+ (emit_mode_unit_size, emit_mode_base_align, emit_mode_ibit)
+ (emit_mode_fbit): Update use of print_maybe_const_decl.
+ (emit_move_size): Likewise. Treat the array as non-const
+ if adj_nunits.
+ (emit_mode_adjustments): Handle adj_nunits.
+
+2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
* machmode.def (VECTOR_MODES_WITH_PREFIX): Document.
* genmodes.c (VECTOR_MODES_WITH_PREFIX): New macro.
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);
diff --git a/gcc/machmode.def b/gcc/machmode.def
index c9d17f1..d5d5efc 100644
--- a/gcc/machmode.def
+++ b/gcc/machmode.def
@@ -174,6 +174,12 @@ along with GCC; see the file COPYING3. If not see
Unlike a FORMAT argument, if you are adjusting a float format
you must put an & in front of the name of each format structure.
+ ADJUST_NUNITS (MODE, EXPR);
+ Like the above, but set the number of nunits of MODE to EXPR.
+ This changes the size and precision of the mode in proportion
+ to the change in the number of units; for example, doubling
+ the number of units doubles the size and precision as well.
+
Note: If a mode is ever made which is more than 255 bytes wide,
machmode.h and genmodes.c will have to be changed to allocate
more space for the mode_size and mode_alignment arrays. */
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 5eaa868..b938eea 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -23,9 +23,9 @@ along with GCC; see the file COPYING3. If not see
typedef opt_mode<machine_mode> opt_machine_mode;
extern CONST_MODE_SIZE poly_uint16_pod mode_size[NUM_MACHINE_MODES];
-extern const poly_uint16_pod mode_precision[NUM_MACHINE_MODES];
+extern CONST_MODE_PRECISION poly_uint16_pod mode_precision[NUM_MACHINE_MODES];
extern const unsigned char mode_inner[NUM_MACHINE_MODES];
-extern const poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];
+extern CONST_MODE_NUNITS poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];
extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
extern const unsigned char mode_wider[NUM_MACHINE_MODES];