===================================================================
@@ -23,9 +23,9 @@ #define HAVE_MACHINE_MODES
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];
===================================================================
@@ -169,6 +169,12 @@ along with GCC; see the file COPYING3.
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. */
===================================================================
@@ -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;
@@ -786,6 +789,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)
@@ -955,9 +959,9 @@ #define tagged_printf(FMT, ARG, TAG) do
#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 ("};")
@@ -1015,6 +1019,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\
@@ -1027,7 +1036,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)
@@ -1046,7 +1055,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\
@@ -1055,12 +1067,13 @@ extern __inline__ __attribute__((__alway
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\
@@ -1277,7 +1290,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 */
@@ -1392,7 +1408,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)
@@ -1411,7 +1428,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);
@@ -1425,7 +1442,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);
@@ -1563,7 +1581,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",
@@ -1604,7 +1622,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);
@@ -1685,6 +1703,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)
@@ -1825,7 +1860,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);
@@ -1843,7 +1878,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);