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 */
};
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;
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;
#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)
#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 ("};")
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\
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)
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\
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\
};\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 */
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)
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);
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);
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",
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);
\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)
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);
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);