From e64e4ed9d22ed3e32f9c6c6393c53f5bdd542c12 Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 10 May 2005 22:40:37 +0000 Subject: [PATCH] * read-rtl.c (struct macro_traverse_data): Define. (map_attr_string): New static function, broken out of apply_macro_to_string. (mode_attr_index, apply_mode_maps): New static functions. (apply_macro_to_string): Call map_attr_string. (apply_macro_to_rtx): Add mode_maps and infile parameters. Change all callers. (apply_macro_traverse): Expect data to point to a struct macro_traverse_data. (read_rtx): Add mode_maps local variable. Use mode_traverse_data to pass data through htab_traverse. (read_rtx_1): Add mode_maps parameter. Change all callers. Handle mode names which are attribute strings. * doc/md.texi (Substitutions): Rename from String Substitutions. Change references. Document using attributes as modes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99548 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 18 ++++++ gcc/doc/md.texi | 37 +++++++---- gcc/read-rtl.c | 198 +++++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 204 insertions(+), 49 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7699a48..8a1827f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2005-05-10 Ian Lance Taylor + + * read-rtl.c (struct macro_traverse_data): Define. + (map_attr_string): New static function, broken out of + apply_macro_to_string. + (mode_attr_index, apply_mode_maps): New static functions. + (apply_macro_to_string): Call map_attr_string. + (apply_macro_to_rtx): Add mode_maps and infile parameters. Change + all callers. + (apply_macro_traverse): Expect data to point to a struct + macro_traverse_data. + (read_rtx): Add mode_maps local variable. Use mode_traverse_data + to pass data through htab_traverse. + (read_rtx_1): Add mode_maps parameter. Change all callers. + Handle mode names which are attribute strings. + * doc/md.texi (Substitutions): Rename from String Substitutions. + Change references. Document using attributes as modes. + 2005-05-10 Zdenek Dvorak * tree-cfg.c (tree_duplicate_sese_region): Update profile. diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 61b8856..4feab32 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -6718,7 +6718,7 @@ rtx-based construct, such as a @code{define_insn}, @menu * Defining Mode Macros:: Defining a new mode macro. -* String Substitutions:: Combining mode macros with string substitutions +* Substitutions:: Combining mode macros with substitutions * Examples:: Examples @end menu @@ -6764,14 +6764,15 @@ but that the @code{:SI} expansion has no such constraint. Macros are applied in the order they are defined. This can be significant if two macros are used in a construct that requires -string substitutions. @xref{String Substitutions}. +substitutions. @xref{Substitutions}. -@node String Substitutions -@subsubsection String Substitution in Mode Macros +@node Substitutions +@subsubsection Substitution in Mode Macros @findex define_mode_attr If an @file{.md} file construct uses mode macros, each version of the -construct will often need slightly different strings. For example: +construct will often need slightly different strings or modes. For +example: @itemize @bullet @item @@ -6782,6 +6783,11 @@ appropriate mode name for @var{m}. @item When a @code{define_insn} defines several instruction patterns, each instruction will often use a different assembler mnemonic. + +@item +When a @code{define_insn} requires operands with different modes, +using a macro for one of the operand modes usually requires a specific +mode for the other operand(s). @end itemize GCC supports such variations through a system of ``mode attributes''. @@ -6796,12 +6802,12 @@ upper case. You can define other attributes using: where @var{name} is the name of the attribute and @var{valuei} is the value associated with @var{modei}. -When GCC replaces some @var{:macro} with @var{:mode}, it will -scan each string in the pattern for sequences of the form -@code{<@var{macro}:@var{attr}>}, where @var{attr} is the name of -a mode attribute. If the attribute is defined for @var{mode}, the -whole @code{<...>} sequence will be replaced by the appropriate -attribute value. +When GCC replaces some @var{:macro} with @var{:mode}, it will scan +each string and mode in the pattern for sequences of the form +@code{<@var{macro}:@var{attr}>}, where @var{attr} is the name of a +mode attribute. If the attribute is defined for @var{mode}, the whole +@code{<...>} sequence will be replaced by the appropriate attribute +value. For example, suppose an @file{.md} file has: @@ -6815,6 +6821,15 @@ If one of the patterns that uses @code{:P} contains the string will use @code{"lw\t%0,%1"} and the @code{DI} version will use @code{"ld\t%0,%1"}. +Here is an example of using an attribute for a mode: + +@smallexample +(define_mode_macro LONG [SI DI]) +(define_mode_attr SHORT [(SI "HI") (DI "SI")]) +(define_insn ... + (sign_extend:LONG (match_operand: ...)) ...) +@end smallexample + The @code{@var{macro}:} prefix may be omitted, in which case the substitution will be attempted for every macro expansion. diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index b9e0cb5..23db85b 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -87,6 +87,17 @@ struct ptr_loc { int lineno; }; +/* A structure used to pass data from read_rtx to apply_macro_traverse + via htab_traverse. */ +struct macro_traverse_data { + /* Instruction queue. */ + rtx queue; + /* Attributes seen for modes. */ + struct map_value *mode_maps; + /* Input file. */ + FILE *infile; +}; + /* If CODE is the number of a code macro, return a real rtx code that has the same format. Return CODE otherwise. */ #define BELLWETHER_CODE(CODE) \ @@ -102,7 +113,8 @@ static int find_code (const char *, FILE *); static bool uses_code_macro_p (rtx, int); static void apply_code_macro (rtx, int); static const char *apply_macro_to_string (const char *, struct mapping *, int); -static rtx apply_macro_to_rtx (rtx, struct mapping *, int); +static rtx apply_macro_to_rtx (rtx, struct mapping *, int, + struct map_value *, FILE *); static bool uses_macro_p (rtx, struct mapping *); static const char *add_condition_to_string (const char *, const char *); static void add_condition_to_rtx (rtx, const char *); @@ -128,7 +140,7 @@ static void validate_const_int (FILE *, const char *); static int find_macro (struct macro_group *, const char *, FILE *); static struct mapping *read_mapping (struct macro_group *, htab_t, FILE *); static void check_code_macro (struct mapping *, FILE *); -static rtx read_rtx_1 (FILE *); +static rtx read_rtx_1 (FILE *, struct map_value **); /* The mode and code macro structures. */ static struct macro_group modes, codes; @@ -258,6 +270,115 @@ apply_code_macro (rtx x, int code) PUT_CODE (x, code); } +/* Map a code or mode attribute string P to the underlying string for + MACRO and VALUE. */ + +static struct map_value * +map_attr_string (const char *p, struct mapping *macro, int value) +{ + const char *attr; + struct mapping *m; + struct map_value *v; + + /* If there's a "macro:" prefix, check whether the macro name matches. + Set ATTR to the start of the attribute name. */ + attr = strchr (p, ':'); + if (attr == 0) + attr = p; + else + { + if (strncmp (p, macro->name, attr - p) != 0 + || macro->name[attr - p] != 0) + return 0; + attr++; + } + + /* Find the attribute specification. */ + m = (struct mapping *) htab_find (macro->group->attrs, &attr); + if (m == 0) + return 0; + + /* Find the attribute value for VALUE. */ + for (v = m->values; v != 0; v = v->next) + if (v->number == value) + break; + + return v; +} + +/* Given an attribute string used as a machine mode, return an index + to store in the machine mode to be translated by + apply_macro_to_rtx. */ + +static unsigned int +mode_attr_index (struct map_value **mode_maps, const char *string, + FILE *infile) +{ + char *p; + char *attr; + struct map_value *mv; + + /* Copy the attribute string into permanent storage, without the + angle brackets around it. */ + obstack_grow (&string_obstack, string + 1, strlen (string) - 2); + p = (char *) obstack_finish (&string_obstack); + + /* Make sure the attribute is defined as either a code attribute or + a mode attribute. */ + attr = strchr (p, ':'); + if (attr == 0) + attr = p; + else + ++attr; + + if (!htab_find (modes.attrs, &attr) && !htab_find (codes.attrs, &attr)) + fatal_with_file_and_line (infile, + "undefined attribute '%s' used for mode", + p); + + mv = XNEW (struct map_value); + mv->number = *mode_maps == 0 ? 0 : (*mode_maps)->number + 1; + mv->string = p; + mv->next = *mode_maps; + *mode_maps = mv; + + /* We return a code which we can map back into this string: the + number of machine modes + the number of mode macros + the index + we just used. */ + return MAX_MACHINE_MODE + htab_elements (modes.macros) + mv->number; +} + +/* Apply MODE_MAPS to the top level of X. */ + +static void +apply_mode_maps (rtx x, struct map_value *mode_maps, struct mapping *macro, + int value, FILE *infile) +{ + unsigned int offset; + int indx; + struct map_value *pm; + + offset = MAX_MACHINE_MODE + htab_elements (modes.macros); + if (GET_MODE (x) < offset) + return; + + indx = GET_MODE (x) - offset; + for (pm = mode_maps; pm; pm = pm->next) + { + if (pm->number == indx) + { + struct map_value *v; + + v = map_attr_string (pm->string, macro, value); + if (v) + { + PUT_MODE (x, find_mode (v->string, infile)); + return; + } + } + } +} + /* Given that MACRO is being expanded as VALUE, apply the appropriate string substitutions to STRING. Return the new string if any changes were needed, otherwise return STRING itself. */ @@ -265,8 +386,7 @@ apply_code_macro (rtx x, int code) static const char * apply_macro_to_string (const char *string, struct mapping *macro, int value) { - char *base, *copy, *p, *attr, *start, *end; - struct mapping *m; + char *base, *copy, *p, *start, *end; struct map_value *v; if (string == 0) @@ -277,30 +397,9 @@ apply_macro_to_string (const char *string, struct mapping *macro, int value) { p = start + 1; - /* If there's a "macro:" prefix, check whether the macro name matches. - Set ATTR to the start of the attribute name. */ - attr = strchr (p, ':'); - if (attr == 0 || attr > end) - attr = p; - else - { - if (strncmp (p, macro->name, attr - p) != 0 - || macro->name[attr - p] != 0) - continue; - attr++; - } - - /* Find the attribute specification. */ *end = 0; - m = (struct mapping *) htab_find (macro->group->attrs, &attr); + v = map_attr_string (p, macro, value); *end = '>'; - if (m == 0) - continue; - - /* Find the attribute value for VALUE. */ - for (v = m->values; v != 0; v = v->next) - if (v->number == value) - break; if (v == 0) continue; @@ -324,7 +423,8 @@ apply_macro_to_string (const char *string, struct mapping *macro, int value) replaced by VALUE. */ static rtx -apply_macro_to_rtx (rtx original, struct mapping *macro, int value) +apply_macro_to_rtx (rtx original, struct mapping *macro, int value, + struct map_value *mode_maps, FILE *infile) { struct macro_group *group; const char *format_ptr; @@ -345,6 +445,9 @@ apply_macro_to_rtx (rtx original, struct mapping *macro, int value) if (group->uses_macro_p (x, macro->index + group->num_builtins)) group->apply_macro (x, value); + if (mode_maps) + apply_mode_maps (x, mode_maps, macro, value, infile); + /* Change each string and recursively change each rtx. */ format_ptr = GET_RTX_FORMAT (bellwether_code); for (i = 0; format_ptr[i] != 0; i++) @@ -360,7 +463,8 @@ apply_macro_to_rtx (rtx original, struct mapping *macro, int value) break; case 'e': - XEXP (x, i) = apply_macro_to_rtx (XEXP (x, i), macro, value); + XEXP (x, i) = apply_macro_to_rtx (XEXP (x, i), macro, value, + mode_maps, infile); break; case 'V': @@ -370,7 +474,8 @@ apply_macro_to_rtx (rtx original, struct mapping *macro, int value) XVEC (x, i) = rtvec_alloc (XVECLEN (original, i)); for (j = 0; j < XVECLEN (x, i); j++) XVECEXP (x, i, j) = apply_macro_to_rtx (XVECEXP (original, i, j), - macro, value); + macro, value, mode_maps, + infile); } break; @@ -467,18 +572,20 @@ add_condition_to_rtx (rtx x, const char *extra) static int apply_macro_traverse (void **slot, void *data) { + struct macro_traverse_data *mtd = (struct macro_traverse_data *) data; struct mapping *macro; struct map_value *v; rtx elem, new_elem, original, x; macro = (struct mapping *) *slot; - for (elem = (rtx) data; elem != 0; elem = XEXP (elem, 1)) + for (elem = mtd->queue; elem != 0; elem = XEXP (elem, 1)) if (uses_macro_p (XEXP (elem, 0), macro)) { original = XEXP (elem, 0); for (v = macro->values; v != 0; v = v->next) { - x = apply_macro_to_rtx (original, macro, v->number); + x = apply_macro_to_rtx (original, macro, v->number, + mtd->mode_maps, mtd->infile); add_condition_to_rtx (x, v->string); if (v != macro->values) { @@ -1238,6 +1345,9 @@ read_rtx (FILE *infile, rtx *x, int *lineno) if (queue_next == 0) { + struct map_value *mode_maps; + struct macro_traverse_data mtd; + c = read_skip_spaces (infile); if (c == EOF) return false; @@ -1245,11 +1355,15 @@ read_rtx (FILE *infile, rtx *x, int *lineno) queue_next = queue_head; queue_lineno = read_rtx_lineno; - XEXP (queue_next, 0) = read_rtx_1 (infile); + mode_maps = 0; + XEXP (queue_next, 0) = read_rtx_1 (infile, &mode_maps); XEXP (queue_next, 1) = 0; - htab_traverse (modes.macros, apply_macro_traverse, queue_next); - htab_traverse (codes.macros, apply_macro_traverse, queue_next); + mtd.queue = queue_next; + mtd.mode_maps = mode_maps; + mtd.infile = infile; + htab_traverse (modes.macros, apply_macro_traverse, &mtd); + htab_traverse (codes.macros, apply_macro_traverse, &mtd); } *x = XEXP (queue_next, 0); @@ -1263,7 +1377,7 @@ read_rtx (FILE *infile, rtx *x, int *lineno) doesn't apply any macros. */ static rtx -read_rtx_1 (FILE *infile) +read_rtx_1 (FILE *infile, struct map_value **mode_maps) { int i; RTX_CODE real_code, bellwether_code; @@ -1337,8 +1451,16 @@ read_rtx_1 (FILE *infile) i = read_skip_spaces (infile); if (i == ':') { + unsigned int mode; + read_name (tmp_char, infile); - PUT_MODE (return_rtx, find_macro (&modes, tmp_char, infile)); + if (tmp_char[0] != '<' || tmp_char[strlen (tmp_char) - 1] != '>') + mode = find_macro (&modes, tmp_char, infile); + else + mode = mode_attr_index (mode_maps, tmp_char, infile); + PUT_MODE (return_rtx, mode); + if (GET_MODE (return_rtx) != mode) + fatal_with_file_and_line (infile, "mode too large"); } else ungetc (i, infile); @@ -1353,7 +1475,7 @@ read_rtx_1 (FILE *infile) case 'e': case 'u': - XEXP (return_rtx, i) = read_rtx_1 (infile); + XEXP (return_rtx, i) = read_rtx_1 (infile, mode_maps); break; case 'V': @@ -1385,7 +1507,7 @@ read_rtx_1 (FILE *infile) { ungetc (c, infile); list_counter++; - obstack_ptr_grow (&vector_stack, read_rtx_1 (infile)); + obstack_ptr_grow (&vector_stack, read_rtx_1 (infile, mode_maps)); } if (list_counter > 0) { -- 2.7.4