summaryrefslogtreecommitdiff
path: root/gcc/genmodes.c
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-25 02:03:40 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-25 02:03:40 +0000
commitb8bc42e99d868c3a5913d34a1ebeaf1b58d17dc8 (patch)
tree924272e8a87e09c7f5bd7aa5ee638d29f45b3b8b /gcc/genmodes.c
parentb7192c3de779b21fad33425e7b68d62df95e1dc9 (diff)
downloadgcc-b8bc42e99d868c3a5913d34a1ebeaf1b58d17dc8.tar.gz
* genmodes.c (struct mode_data): Add contained and next_cont
fields. (complete_mode): Maintain linked list of modes that have a given component. (emit_mode_unit_size): Delete. (emit_mode_nunits): New. (emit_insn_modes_c): Update to match. (emit_mode_adjustments): Propagate size and alignment adjustments from component modes to their containers. * machmode.h (mode_unit_size): Delete. (mode_nunits): New. (GET_MODE_NUNITS): Just return the value in the table. (GET_MODE_UNIT_SIZE): Compute using GET_MODE_INNER and GET_MODE_SIZE. * expmed.c (store_bit_field, extract_bit_field): Can use a plain move instruction if bitsize >= GET_MODE_BITSIZE of destination/source mode, respectively. * varasm.c (assemble_real): Write out the full size of the constant, not just its bitsize. (output_constant): Honor TYPE_MODE of TREE_REAL_CSTs. * config/ia64/ia64-modes.def: Define XFmode as well as TFmode. Use ADJUST_BYTESIZE and ADJUST_ALIGNMENT to set size and alignment of XF and TF modes in compliance with ia64 ABIs. Can now hardwire the format of both modes. * config/ia64/ia64.c: Change TFmode to XFmode wherever appropriate. (general_tfmode_operand, destination_tfmode_operand) (tfreg_or_fp01_operand, spill_tfmode_operand): Rename to general_xfmode_operand, destination_xfmode_operand, xfreg_or_fp01_operand, spill_xfmode_operand respectively. (ia64_init_builtins): Make TYPE_PRECISION of fpreg_type and float80_type be 96 so they get XFmode. Use !TARGET_HPUX, not INTEL_EXTENDED_IEEE_FORMAT, to decide how to define __float128. * config/ia64/ia64.h: Default TARGET_HPUX to 0. Change TFmode to XFmode wherever appropriate. Remove all references to INTEL_EXTENDED_IEEE_FORMAT. (LONG_DOUBLE_TYPE_SIZE): Varies with TARGET_HPUX. (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define (always 96). (PREDICATE_CODES): Update to match function renames. * config/ia64/ia64.md: Change TF to XF throughout; rename all patterns to match. Remove all references to INTEL_EXTENDED_IEEE_FORMAT. Update predicate calls to match function renames. * config/ia64/ia64-protos.c: Update all prototypes to match renamed functions. * config/ia64/hpux.h: Redefine TARGET_HPUX to 1. Remove all references to INTEL_EXTENDED_IEEE_FORMAT. * config/ia64/lib1funcs.asm: Add __divxf3 as new name for __divtf3; keep old name for backward compatibility. (L__compat): New section providing forwarding stubs for __fixtfti, __fixunstfti, __floattitf. * config/ia64/t-ia64: Add __compat to LIB1ASMFUNCS. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72916 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/genmodes.c')
-rw-r--r--gcc/genmodes.c109
1 files changed, 91 insertions, 18 deletions
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index a5521a4420b..13456555be6 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -65,6 +65,10 @@ struct mode_data
struct mode_data *component; /* mode of components */
struct mode_data *wider; /* next wider mode */
+ struct mode_data *contained; /* Pointer to list of modes that have
+ this mode as a component. */
+ struct mode_data *next_cont; /* Next mode in that list. */
+
const char *file; /* file and line of definition, */
unsigned int line; /* for error reporting */
};
@@ -76,7 +80,7 @@ static struct mode_data *void_mode;
static const struct mode_data blank_mode = {
0, "<unknown>", MAX_MODE_CLASS,
-1, -1, -1, -1,
- 0, 0, 0,
+ 0, 0, 0, 0, 0,
"<unknown>", 0
};
@@ -372,6 +376,14 @@ complete_mode (struct mode_data *m)
alignment = m->bytesize;
m->alignment = alignment & (~alignment + 1);
+
+ /* If this mode has components, make the component mode point back
+ to this mode, for the sake of adjustments. */
+ if (m->component)
+ {
+ m->next_cont = m->component->contained;
+ m->component->contained = m;
+ }
}
static void
@@ -912,18 +924,15 @@ emit_mode_size (void)
}
static void
-emit_mode_unit_size (void)
+emit_mode_nunits (void)
{
enum mode_class c;
struct mode_data *m;
- print_decl ("unsigned char", "mode_unit_size", "NUM_MACHINE_MODES");
+ print_decl ("unsigned char", "mode_nunits", "NUM_MACHINE_MODES");
for_all_modes (c, m)
- tagged_printf ("%u",
- m->component
- ? m->component->bytesize : m->bytesize,
- m->name);
+ tagged_printf ("%u", m->ncomponents, m->name);
print_closer ();
}
@@ -1055,23 +1064,87 @@ static void
emit_mode_adjustments (void)
{
struct mode_adjust *a;
+ struct mode_data *m;
- puts ("\nvoid\ninit_adjust_machine_modes (void)\n{");
+ puts ("\
+\nvoid\
+\ninit_adjust_machine_modes (void)\
+\n{\
+\n size_t s ATTRIBUTE_UNUSED;");
+ /* 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)
- printf (" /* %s:%d */\n mode_size[%smode] = %s;\n",
- a->file, a->line, a->mode->name, a->adjustment);
- if (adj_bytesize && (adj_alignment || adj_format))
- putchar ('\n');
+ {
+ 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_base_align[%smode] = s & (~s + 1);\n",
+ a->mode->name);
+
+ for (m = a->mode->contained; m; m = m->next_cont)
+ {
+ switch (m->class)
+ {
+ case MODE_COMPLEX_INT:
+ case MODE_COMPLEX_FLOAT:
+ printf (" mode_size[%smode] = 2*s;\n", m->name);
+ printf (" mode_base_align[%smode] = s & (~s + 1);\n",
+ m->name);
+ break;
+
+ case MODE_VECTOR_INT:
+ case MODE_VECTOR_FLOAT:
+ printf (" mode_size[%smode] = %d*s;\n",
+ m->name, m->ncomponents);
+ printf (" mode_base_align[%smode] = (%d*s) & (~(%d*s)+1);\n",
+ m->name, m->ncomponents, m->ncomponents);
+ break;
+
+ default:
+ internal_error (
+ "mode %s is neither vector nor complex but contains %s",
+ m->name, a->mode->name);
+ /* NOTREACHED */
+ }
+ }
+ }
+ /* Alignment adjustments propagate too.
+ ??? This may not be the right thing for vector modes. */
for (a = adj_alignment; a; a = a->next)
- printf (" /* %s:%d */\n mode_base_align[%smode] = %s;\n",
- a->file, a->line, a->mode->name, a->adjustment);
- if (adj_alignment && adj_format)
- putchar ('\n');
+ {
+ printf ("\n /* %s:%d */\n s = %s;\n",
+ a->file, a->line, a->adjustment);
+ printf (" mode_base_align[%smode] = s;\n", a->mode->name);
+ for (m = a->mode->contained; m; m = m->next_cont)
+ {
+ switch (m->class)
+ {
+ case MODE_COMPLEX_INT:
+ case MODE_COMPLEX_FLOAT:
+ printf (" mode_base_align[%smode] = s;\n", m->name);
+ break;
+
+ case MODE_VECTOR_INT:
+ case MODE_VECTOR_FLOAT:
+ printf (" mode_base_align[%smode] = %d*s;\n",
+ m->name, m->ncomponents);
+ break;
+
+ default:
+ internal_error (
+ "mode %s is neither vector nor complex but contains %s",
+ m->name, a->mode->name);
+ /* NOTREACHED */
+ }
+ }
+ }
+
+ /* Real mode formats don't have to propagate anywhere. */
for (a = adj_format; a; a = a->next)
- printf (" /* %s:%d */\n REAL_MODE_FORMAT (%smode) = %s;\n",
+ printf ("\n /* %s:%d */\n REAL_MODE_FORMAT (%smode) = %s;\n",
a->file, a->line, a->mode->name, a->adjustment);
puts ("}");
@@ -1085,7 +1158,7 @@ emit_insn_modes_c (void)
emit_mode_class ();
emit_mode_bitsize ();
emit_mode_size ();
- emit_mode_unit_size ();
+ emit_mode_nunits ();
emit_mode_wider ();
emit_mode_mask ();
emit_mode_inner ();