diff options
Diffstat (limited to 'gcc/read-rtl.c')
-rw-r--r-- | gcc/read-rtl.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index 79f4050..b4b1051 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -31,6 +31,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "rtl.h" #include "obstack.h" #include "hashtab.h" +#include "gensupport.h" static htab_t md_constants; @@ -138,6 +139,7 @@ static void read_escape (FILE *); 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 read_conditions (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 *); @@ -1205,6 +1207,58 @@ traverse_md_constants (htab_trav callback, void *info) if (md_constants) htab_traverse (md_constants, callback, info); } + +/* INFILE is a FILE pointer to read text from. TMP_CHAR is a buffer + suitable to read a name or number into. Process a + define_conditions directive, starting with the optional space after + the "define_conditions". The directive looks like this: + + (define_conditions [ + (number "string") + (number "string") + ... + ]) + + It's not intended to appear in machine descriptions. It is + generated by (the program generated by) genconditions.c, and + slipped in at the beginning of the sequence of MD files read by + most of the other generators. */ +static void +read_conditions (FILE *infile, char *tmp_char) +{ + int c; + + c = read_skip_spaces (infile); + if (c != '[') + fatal_expected_char (infile, '[', c); + + while ( (c = read_skip_spaces (infile)) != ']') + { + char *expr; + int value; + + if (c != '(') + fatal_expected_char (infile, '(', c); + + read_name (tmp_char, infile); + validate_const_int (infile, tmp_char); + value = atoi (tmp_char); + + c = read_skip_spaces (infile); + if (c != '"') + fatal_expected_char (infile, '"', c); + expr = read_quoted_string (infile); + + c = read_skip_spaces (infile); + if (c != ')') + fatal_expected_char (infile, ')', c); + + add_c_test (expr, value); + } + c = read_skip_spaces (infile); + if (c != ')') + fatal_expected_char (infile, ')', c); +} static void validate_const_int (FILE *infile, const char *string) @@ -1354,16 +1408,23 @@ read_rtx (FILE *infile, rtx *x, int *lineno) { struct map_value *mode_maps; struct macro_traverse_data mtd; + rtx from_file; c = read_skip_spaces (infile); if (c == EOF) return false; ungetc (c, infile); - queue_next = queue_head; queue_lineno = read_rtx_lineno; mode_maps = 0; - XEXP (queue_next, 0) = read_rtx_1 (infile, &mode_maps); + from_file = read_rtx_1 (infile, &mode_maps); + if (from_file == 0) + return false; /* This confuses a top level (nil) with end of + file, but a top level (nil) would have + crashed our caller anyway. */ + + queue_next = queue_head; + XEXP (queue_next, 0) = from_file; XEXP (queue_next, 1) = 0; mtd.queue = queue_next; @@ -1412,6 +1473,10 @@ read_rtx_1 (FILE *infile, struct map_value **mode_maps) again: c = read_skip_spaces (infile); /* Should be open paren. */ + + if (c == EOF) + return 0; + if (c != '(') fatal_expected_char (infile, '(', c); @@ -1429,6 +1494,11 @@ read_rtx_1 (FILE *infile, struct map_value **mode_maps) read_constants (infile, tmp_char); goto again; } + if (strcmp (tmp_char, "define_conditions") == 0) + { + read_conditions (infile, tmp_char); + goto again; + } if (strcmp (tmp_char, "define_mode_attr") == 0) { read_mapping (&modes, modes.attrs, infile); |