diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-23 05:55:50 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-23 05:55:50 +0000 |
commit | 4a29322997e997eae9e018c3d3a8b5c0d13694da (patch) | |
tree | 955515c44f9df08d27a02dff75b1f77772daaa98 /gcc/read-rtl.c | |
parent | 6f7111d236be1c7d97f3f9d8d1bc1bfa1c4c387e (diff) | |
download | gcc-4a29322997e997eae9e018c3d3a8b5c0d13694da.tar.gz |
* read-rtl.c (map_value, mapping, macro_group): New structures.
(BELLWETHER_CODE): New macro.
(modes, codes, bellwether_codes): New variables.
(find_mode, uses_mode_macro_p, apply_mode_macro, find_code)
(uses_code_macro_p, apply_code_macro, apply_macro_to_string)
(apply_macro_to_rtx, uses_macro_p, add_condition_to_string)
(add_condition_to_rtx, apply_macro_traverse, add_mapping)
(add_map_value, initialize_macros): New functions.
(def_hash, def_hash_eq_p): Generalize to anything that points to,
or starts with, a char * field.
(find_macro, read_mapping, check_code_macro): New functions.
(read_rtx_1): New, split out from read_rtx. Handle the new
define_{mode,code}_{macro,attr} constructs. Use find_macro
to parse the name of a code or mode. Use BELLWETHER_CODE to
extract the format and to choose a suitable code for rtx_alloc.
Modify recursive invocations to use read_rtx_1.
(read_rtx): Call initialize_macros. Apply code and mode macros
to the rtx returned by read_rtx_1. Cache everything after the
first macro expansion for subsequent read_rtx calls.
* doc/md.texi: Document new .md constructs.
* config/mips/mips.md (GPR): New mode macro.
(d, si8_di5): New mode attributes.
(any_cond): New code macro.
(add[sd]i3): Redefine using :GPR.
(*add[sd]i3): Likewise, renaming from add[sd]i3_internal.
(*add[sd]i3_sp[12], *add<mode>3_mips16): Redefine using :GPR, naming
previously unnamed MIPS16 patterns.
(*addsi3_extended): Renamed from addsi3_internal_2. Fix overly long
lines. Don't match (plus (const_int 0) ...).
(*addsi3_extended_mips16): Name previously unnamed MIPS16 pattern.
Use a define_split to generate the addition.
(sub[sd]i3): Redefine using :GPR. Turn subsi3 into a define_insn.
(subsi3_internal): Delete.
(*subsi3_extended): Renamed from subsi3_internal_2.
(bunordered, bordered, bunlt, bunge, buneq, bltgt, bunle, bungt)
(beq, bne, bgt, bge, blt, ble, bgtu, bgeu, bltu, bleu): Redefine
using an any_cond template.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@86404 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/read-rtl.c')
-rw-r--r-- | gcc/read-rtl.c | 698 |
1 files changed, 643 insertions, 55 deletions
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index 2b9bd915d23..fe0c7a4044a 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -30,9 +30,76 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA static htab_t md_constants; +/* One element in a singly-linked list of (integer, string) pairs. */ +struct map_value { + struct map_value *next; + int number; + const char *string; +}; + +/* Maps a macro or attribute name to a list of (integer, string) pairs. + The integers are mode or code values; the strings are either C conditions + or attribute values. */ +struct mapping { + /* The name of the macro or attribute. */ + const char *name; + + /* The group (modes or codes) to which the macro or attribute belongs. */ + struct macro_group *group; + + /* Gives a unique number to the attribute or macro. Numbers are + allocated consecutively, starting at 0. */ + int index; + + /* The list of (integer, string) pairs. */ + struct map_value *values; +}; + +/* A structure for abstracting the common parts of code and mode macros. */ +struct macro_group { + /* Tables of "mapping" structures, one for attributes and one for macros. */ + htab_t attrs, macros; + + /* The number of "real" modes or codes (and by extension, the first + number available for use as a macro placeholder). */ + int num_builtins; + + /* Treat the given string as the name of a standard mode or code and + return its integer value. Use the given file for error reporting. */ + int (*find_builtin) (const char *, FILE *); + + /* Return true if the given rtx uses the given mode or code. */ + bool (*uses_macro_p) (rtx, int); + + /* Make the given rtx use the given mode or code. */ + void (*apply_macro) (rtx, int); +}; + +/* 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) \ + ((CODE) < NUM_RTX_CODE ? CODE : bellwether_codes[CODE - NUM_RTX_CODE]) + static void fatal_with_file_and_line (FILE *, const char *, ...) ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN; static void fatal_expected_char (FILE *, int, int) ATTRIBUTE_NORETURN; +static int find_mode (const char *, FILE *); +static bool uses_mode_macro_p (rtx, int); +static void apply_mode_macro (rtx, int); +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 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 *); +static int apply_macro_traverse (void **, void *); +static struct mapping *add_mapping (struct macro_group *, htab_t t, + const char *, FILE *); +static struct map_value **add_map_value (struct map_value **, + int, const char *); +static void initialize_macros (void); static void read_name (char *, FILE *); static char *read_string (FILE *, int); static char *read_quoted_string (FILE *); @@ -42,6 +109,16 @@ static hashval_t def_hash (const void *); static int def_name_eq_p (const void *, const void *); static void read_constants (FILE *infile, char *tmp_char); 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 *); + +/* The mode and code macro structures. */ +static struct macro_group modes, codes; + +/* Index I is the value of BELLWETHER_CODE (I + NUM_RTX_CODE). */ +static enum rtx_code *bellwether_codes; /* Obstack used for allocating RTL strings. */ static struct obstack string_obstack; @@ -97,6 +174,393 @@ fatal_expected_char (FILE *infile, int expected_c, int actual_c) expected_c, actual_c); } +/* Implementations of the macro_group callbacks for modes. */ + +static int +find_mode (const char *name, FILE *infile) +{ + int i; + + for (i = 0; i < NUM_MACHINE_MODES; i++) + if (strcmp (GET_MODE_NAME (i), name) == 0) + return i; + + fatal_with_file_and_line (infile, "unknown mode `%s'", name); +} + +static bool +uses_mode_macro_p (rtx x, int mode) +{ + return (int) GET_MODE (x) == mode; +} + +static void +apply_mode_macro (rtx x, int mode) +{ + PUT_MODE (x, mode); +} + +/* Implementations of the macro_group callbacks for codes. */ + +static int +find_code (const char *name, FILE *infile) +{ + int i; + + for (i = 0; i < NUM_RTX_CODE; i++) + if (strcmp (GET_RTX_NAME (i), name) == 0) + return i; + + fatal_with_file_and_line (infile, "unknown rtx code `%s'", name); +} + +static bool +uses_code_macro_p (rtx x, int code) +{ + return (int) GET_CODE (x) == code; +} + +static void +apply_code_macro (rtx x, int code) +{ + PUT_CODE (x, code); +} + +/* 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. */ + +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; + struct map_value *v; + + if (string == 0) + return string; + + base = p = copy = ASTRDUP (string); + while ((start = index (p, '<')) && (end = index (start, '>'))) + { + 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 = index (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); + *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; + + /* Add everything between the last copied byte and the '<', + then add in the attribute value. */ + obstack_grow (&string_obstack, base, start - base); + obstack_grow (&string_obstack, v->string, strlen (v->string)); + base = end + 1; + } + if (base != copy) + { + obstack_grow (&string_obstack, base, strlen (base) + 1); + return (char *) obstack_finish (&string_obstack); + } + return string; +} + +/* Return a copy of ORIGINAL in which all uses of MACRO have been + replaced by VALUE. */ + +static rtx +apply_macro_to_rtx (rtx original, struct mapping *macro, int value) +{ + struct macro_group *group; + const char *format_ptr; + int i, j; + rtx x; + enum rtx_code bellwether_code; + + if (original == 0) + return original; + + /* Create a shallow copy of ORIGINAL. */ + bellwether_code = BELLWETHER_CODE (GET_CODE (original)); + x = rtx_alloc (bellwether_code); + memcpy (x, original, RTX_SIZE (bellwether_code)); + + /* Change the mode or code itself. */ + group = macro->group; + if (group->uses_macro_p (x, macro->index + group->num_builtins)) + group->apply_macro (x, value); + + /* Change each string and recursively change each rtx. */ + format_ptr = GET_RTX_FORMAT (bellwether_code); + for (i = 0; format_ptr[i] != 0; i++) + switch (format_ptr[i]) + { + case 'S': + case 'T': + case 's': + XSTR (x, i) = apply_macro_to_string (XSTR (x, i), macro, value); + break; + + case 'e': + XEXP (x, i) = apply_macro_to_rtx (XEXP (x, i), macro, value); + break; + + case 'V': + case 'E': + if (XVEC (original, i)) + { + 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); + } + break; + + default: + break; + } + return x; +} + +/* Return true if X (or some subexpression of X) uses macro MACRO. */ + +static bool +uses_macro_p (rtx x, struct mapping *macro) +{ + struct macro_group *group; + const char *format_ptr; + int i, j; + + if (x == 0) + return false; + + group = macro->group; + if (group->uses_macro_p (x, macro->index + group->num_builtins)) + return true; + + format_ptr = GET_RTX_FORMAT (BELLWETHER_CODE (GET_CODE (x))); + for (i = 0; format_ptr[i] != 0; i++) + switch (format_ptr[i]) + { + case 'e': + if (uses_macro_p (XEXP (x, i), macro)) + return true; + break; + + case 'V': + case 'E': + if (XVEC (x, i)) + for (j = 0; j < XVECLEN (x, i); j++) + if (uses_macro_p (XVECEXP (x, i, j), macro)) + return true; + break; + + default: + break; + } + return false; +} + +/* Return a condition that must satisfy both ORIGINAL and EXTRA. If ORIGINAL + has the form "&& ..." (as used in define_insn_and_splits), assume that + EXTRA is already satisfied. Empty strings are treated like "true". */ + +static const char * +add_condition_to_string (const char *original, const char *extra) +{ + char *result; + + if (original == 0 || original[0] == 0) + return extra; + + if ((original[0] == '&' && original[1] == '&') || extra[0] == 0) + return original; + + asprintf (&result, "(%s) && (%s)", original, extra); + return result; +} + +/* Like add_condition, but applied to all conditions in rtx X. */ + +static void +add_condition_to_rtx (rtx x, const char *extra) +{ + switch (GET_CODE (x)) + { + case DEFINE_INSN: + case DEFINE_EXPAND: + XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra); + break; + + case DEFINE_SPLIT: + case DEFINE_PEEPHOLE: + case DEFINE_PEEPHOLE2: + case DEFINE_COND_EXEC: + XSTR (x, 1) = add_condition_to_string (XSTR (x, 1), extra); + break; + + case DEFINE_INSN_AND_SPLIT: + XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra); + XSTR (x, 4) = add_condition_to_string (XSTR (x, 4), extra); + break; + + default: + break; + } +} + +/* A htab_traverse callback. Search the EXPR_LIST given by DATA + for rtxes that use the macro in *SLOT. Replace each such rtx + with a list of expansions. */ + +static int +apply_macro_traverse (void **slot, void *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)) + 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); + add_condition_to_rtx (x, v->string); + if (v != macro->values) + { + /* Insert a new EXPR_LIST node after ELEM and put the + new expansion there. */ + new_elem = rtx_alloc (EXPR_LIST); + XEXP (new_elem, 1) = XEXP (elem, 1); + XEXP (elem, 1) = new_elem; + elem = new_elem; + } + XEXP (elem, 0) = x; + } + } + return 1; +} + +/* Add a new "mapping" structure to hashtable TABLE. NAME is the name + of the mapping, GROUP is the group to which it belongs, and INFILE + is the file that defined the mapping. */ + +static struct mapping * +add_mapping (struct macro_group *group, htab_t table, + const char *name, FILE *infile) +{ + struct mapping *m; + void **slot; + + m = XNEW (struct mapping); + m->name = xstrdup (name); + m->group = group; + m->index = htab_elements (table); + m->values = 0; + + slot = htab_find_slot (table, m, INSERT); + if (*slot != 0) + fatal_with_file_and_line (infile, "`%s' already defined", name); + + *slot = m; + return m; +} + +/* Add the pair (NUMBER, STRING) to a list of map_value structures. + END_PTR points to the current null terminator for the list; return + a pointer the new null terminator. */ + +static struct map_value ** +add_map_value (struct map_value **end_ptr, int number, const char *string) +{ + struct map_value *value; + + value = XNEW (struct map_value); + value->next = 0; + value->number = number; + value->string = string; + + *end_ptr = value; + return &value->next; +} + +/* Do one-time initialization of the mode and code attributes. */ + +static void +initialize_macros (void) +{ + struct mapping *lower, *upper; + struct map_value **lower_ptr, **upper_ptr; + char *copy, *p; + int i; + + modes.attrs = htab_create (13, def_hash, def_name_eq_p, 0); + modes.macros = htab_create (13, def_hash, def_name_eq_p, 0); + modes.num_builtins = MAX_MACHINE_MODE; + modes.find_builtin = find_mode; + modes.uses_macro_p = uses_mode_macro_p; + modes.apply_macro = apply_mode_macro; + + codes.attrs = htab_create (13, def_hash, def_name_eq_p, 0); + codes.macros = htab_create (13, def_hash, def_name_eq_p, 0); + codes.num_builtins = NUM_RTX_CODE; + codes.find_builtin = find_code; + codes.uses_macro_p = uses_code_macro_p; + codes.apply_macro = apply_code_macro; + + lower = add_mapping (&modes, modes.attrs, "mode", 0); + upper = add_mapping (&modes, modes.attrs, "MODE", 0); + lower_ptr = &lower->values; + upper_ptr = &upper->values; + for (i = 0; i < MAX_MACHINE_MODE; i++) + { + copy = xstrdup (GET_MODE_NAME (i)); + for (p = copy; *p != 0; p++) + *p = TOLOWER (*p); + + upper_ptr = add_map_value (upper_ptr, i, GET_MODE_NAME (i)); + lower_ptr = add_map_value (lower_ptr, i, copy); + } + + lower = add_mapping (&codes, codes.attrs, "code", 0); + upper = add_mapping (&codes, codes.attrs, "CODE", 0); + lower_ptr = &lower->values; + upper_ptr = &upper->values; + for (i = 0; i < NUM_RTX_CODE; i++) + { + copy = xstrdup (GET_RTX_NAME (i)); + for (p = copy; *p != 0; p++) + *p = TOUPPER (*p); + + lower_ptr = add_map_value (lower_ptr, i, GET_RTX_NAME (i)); + upper_ptr = add_map_value (upper_ptr, i, copy); + } +} + /* Read chars from INFILE until a non-whitespace char and return that. Comments, both Lisp style and C style, are treated as whitespace. @@ -398,24 +862,26 @@ atoll (const char *p) } #endif -/* Given a constant definition, return a hash code for its name. */ +/* Given an object that starts with a char * name field, return a hash + code for its name. */ static hashval_t def_hash (const void *def) { unsigned result, i; - const char *string = ((const struct md_constant *) def)->name; + const char *string = *(const char *const *) def; - for (result = i = 0;*string++ != '\0'; i++) + for (result = i = 0; *string++ != '\0'; i++) result += ((unsigned char) *string << (i % CHAR_BIT)); return result; } -/* Given two constant definitions, return true if they have the same name. */ +/* Given two objects that start with char * name fields, return true if + they have the same name. */ static int def_name_eq_p (const void *def1, const void *def2) { - return ! strcmp (((const struct md_constant *) def1)->name, - ((const struct md_constant *) def2)->name); + return ! strcmp (*(const char *const *) def1, + *(const char *const *) def2); } /* INFILE is a FILE pointer to read text from. TMP_CHAR is a buffer suitable @@ -504,6 +970,102 @@ validate_const_int (FILE *infile, const char *string) fatal_with_file_and_line (infile, "invalid decimal constant \"%s\"\n", string); } +/* Search GROUP for a mode or code called NAME and return its numerical + identifier. INFILE is the file that contained NAME. */ + +static int +find_macro (struct macro_group *group, const char *name, FILE *infile) +{ + struct mapping *m; + + m = (struct mapping *) htab_find (group->macros, &name); + if (m != 0) + return m->index + group->num_builtins; + return group->find_builtin (name, infile); +} + +/* Finish reading a declaration of the form: + + (define... <name> [<value1> ... <valuen>]) + + from INFILE, where each <valuei> is either a bare symbol name or a + "(<name> <string>)" pair. The "(define..." part has already been read. + + Represent the declaration as a "mapping" structure; add it to TABLE + (which belongs to GROUP) and return it. */ + +static struct mapping * +read_mapping (struct macro_group *group, htab_t table, FILE *infile) +{ + char tmp_char[256]; + struct mapping *m; + struct map_value **end_ptr; + const char *string; + int number, c; + + /* Read the mapping name and create a structure for it. */ + read_name (tmp_char, infile); + m = add_mapping (group, table, tmp_char, infile); + + c = read_skip_spaces (infile); + if (c != '[') + fatal_expected_char (infile, '[', c); + + /* Read each value. */ + end_ptr = &m->values; + c = read_skip_spaces (infile); + do + { + if (c != '(') + { + /* A bare symbol name that is implicitly paired to an + empty string. */ + ungetc (c, infile); + read_name (tmp_char, infile); + string = ""; + } + else + { + /* A "(name string)" pair. */ + read_name (tmp_char, infile); + string = read_string (infile, false); + c = read_skip_spaces (infile); + if (c != ')') + fatal_expected_char (infile, ')', c); + } + number = group->find_builtin (tmp_char, infile); + end_ptr = add_map_value (end_ptr, number, string); + c = read_skip_spaces (infile); + } + while (c != ']'); + + c = read_skip_spaces (infile); + if (c != ')') + fatal_expected_char (infile, ')', c); + + return m; +} + +/* Check newly-created code macro MACRO to see whether every code has the + same format. Initialize the macro's entry in bellwether_codes. */ + +static void +check_code_macro (struct mapping *macro, FILE *infile) +{ + struct map_value *v; + enum rtx_code bellwether; + + bellwether = macro->values->number; + for (v = macro->values->next; v != 0; v = v->next) + if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0) + fatal_with_file_and_line (infile, "code macro `%s' combines " + "different rtx formats", macro->name); + + bellwether_codes = XRESIZEVEC (enum rtx_code, bellwether_codes, + macro->index + 1); + bellwether_codes[macro->index] = bellwether; +} + /* Read an rtx in printed representation from INFILE and return an actual rtx in core constructed accordingly. read_rtx is not used in the compiler proper, but rather in @@ -512,8 +1074,42 @@ validate_const_int (FILE *infile, const char *string) rtx read_rtx (FILE *infile) { - int i, j; - RTX_CODE tmp_code; + static rtx queue_head, queue_next; + rtx return_rtx; + + /* Do one-time initialization. */ + if (queue_head == 0) + { + initialize_macros (); + obstack_init (&string_obstack); + queue_head = rtx_alloc (EXPR_LIST); + } + + if (queue_next == 0) + { + queue_next = queue_head; + + XEXP (queue_next, 0) = read_rtx_1 (infile); + XEXP (queue_next, 1) = 0; + + htab_traverse (modes.macros, apply_macro_traverse, queue_next); + htab_traverse (codes.macros, apply_macro_traverse, queue_next); + } + + return_rtx = XEXP (queue_next, 0); + queue_next = XEXP (queue_next, 1); + + return return_rtx; +} + +/* Subroutine of read_rtx that reads one construct from INFILE but + doesn't apply any macros. */ + +static rtx +read_rtx_1 (FILE *infile) +{ + int i; + RTX_CODE real_code, bellwether_code; const char *format_ptr; /* tmp_char is a buffer used for reading decimal integers and names of rtx types and machine modes. @@ -524,8 +1120,6 @@ read_rtx (FILE *infile) int tmp_int; HOST_WIDE_INT tmp_wide; - static int initialized; - /* Linked list structure for making RTXs: */ struct rtx_list { @@ -533,51 +1127,52 @@ read_rtx (FILE *infile) rtx value; /* Value of this node. */ }; - if (!initialized) - { - obstack_init (&string_obstack); - initialized = 1; - } - -again: + again: c = read_skip_spaces (infile); /* Should be open paren. */ if (c != '(') fatal_expected_char (infile, '(', c); read_name (tmp_char, infile); - - tmp_code = UNKNOWN; - for (i = 0; i < NUM_RTX_CODE; i++) - if (! strcmp (tmp_char, GET_RTX_NAME (i))) - { - tmp_code = (RTX_CODE) i; /* get value for name */ - break; - } - - if (tmp_code == UNKNOWN) + if (strcmp (tmp_char, "nil") == 0) { /* (nil) stands for an expression that isn't there. */ - if (! strcmp (tmp_char, "nil")) - { - /* Discard the closeparen. */ - c = read_skip_spaces (infile); - if (c != ')') - fatal_expected_char (infile, ')', c); - return 0; - } - /* (define_constants ...) has special syntax. */ - else if (! strcmp (tmp_char, "define_constants")) - { - read_constants (infile, tmp_char); - goto again; - } - else - fatal_with_file_and_line (infile, "unknown rtx code `%s'", tmp_char); + c = read_skip_spaces (infile); + if (c != ')') + fatal_expected_char (infile, ')', c); + return 0; + } + if (strcmp (tmp_char, "define_constants") == 0) + { + read_constants (infile, tmp_char); + goto again; + } + if (strcmp (tmp_char, "define_mode_attr") == 0) + { + read_mapping (&modes, modes.attrs, infile); + goto again; + } + if (strcmp (tmp_char, "define_mode_macro") == 0) + { + read_mapping (&modes, modes.macros, infile); + goto again; + } + if (strcmp (tmp_char, "define_code_attr") == 0) + { + read_mapping (&codes, codes.attrs, infile); + goto again; + } + if (strcmp (tmp_char, "define_code_macro") == 0) + { + check_code_macro (read_mapping (&codes, codes.macros, infile), infile); + goto again; } + real_code = find_macro (&codes, tmp_char, infile); + bellwether_code = BELLWETHER_CODE (real_code); /* If we end up with an insn expression then we free this space below. */ - return_rtx = rtx_alloc (tmp_code); - format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx)); + return_rtx = rtx_alloc (bellwether_code); + format_ptr = GET_RTX_FORMAT (bellwether_code); + PUT_CODE (return_rtx, real_code); /* If what follows is `: mode ', read it and store the mode in the rtx. */ @@ -586,14 +1181,7 @@ again: if (i == ':') { read_name (tmp_char, infile); - for (j = 0; j < NUM_MACHINE_MODES; j++) - if (! strcmp (GET_MODE_NAME (j), tmp_char)) - break; - - if (j == MAX_MACHINE_MODE) - fatal_with_file_and_line (infile, "unknown mode `%s'", tmp_char); - - PUT_MODE (return_rtx, (enum machine_mode) j); + PUT_MODE (return_rtx, find_macro (&modes, tmp_char, infile)); } else ungetc (i, infile); @@ -608,7 +1196,7 @@ again: case 'e': case 'u': - XEXP (return_rtx, i) = read_rtx (infile); + XEXP (return_rtx, i) = read_rtx_1 (infile); break; case 'V': @@ -640,7 +1228,7 @@ again: { ungetc (c, infile); list_counter++; - obstack_ptr_grow (&vector_stack, read_rtx (infile)); + obstack_ptr_grow (&vector_stack, read_rtx_1 (infile)); } if (list_counter > 0) { |