Mercurial > hg > CbC > CbC_gcc
comparison gcc/genattrtab.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Generate code from machine description to compute values of attributes. | 1 /* Generate code from machine description to compute values of attributes. |
2 Copyright (C) 1991-2018 Free Software Foundation, Inc. | 2 Copyright (C) 1991-2020 Free Software Foundation, Inc. |
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) | 3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
131 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is | 131 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is |
132 encountered, we store all the relevant information into a | 132 encountered, we store all the relevant information into a |
133 `struct insn_def'. This is done to allow attribute definitions to occur | 133 `struct insn_def'. This is done to allow attribute definitions to occur |
134 anywhere in the file. */ | 134 anywhere in the file. */ |
135 | 135 |
136 struct insn_def | 136 class insn_def |
137 { | 137 { |
138 struct insn_def *next; /* Next insn in chain. */ | 138 public: |
139 class insn_def *next; /* Next insn in chain. */ | |
139 rtx def; /* The DEFINE_... */ | 140 rtx def; /* The DEFINE_... */ |
140 int insn_code; /* Instruction number. */ | 141 int insn_code; /* Instruction number. */ |
141 int insn_index; /* Expression number in file, for errors. */ | 142 int insn_index; /* Expression number in file, for errors. */ |
142 file_location loc; /* Where in the .md files it occurs. */ | 143 file_location loc; /* Where in the .md files it occurs. */ |
143 int num_alternatives; /* Number of alternatives. */ | 144 int num_alternatives; /* Number of alternatives. */ |
149 list. */ | 150 list. */ |
150 | 151 |
151 struct insn_ent | 152 struct insn_ent |
152 { | 153 { |
153 struct insn_ent *next; /* Next in chain. */ | 154 struct insn_ent *next; /* Next in chain. */ |
154 struct insn_def *def; /* Instruction definition. */ | 155 class insn_def *def; /* Instruction definition. */ |
155 }; | 156 }; |
156 | 157 |
157 /* Each value of an attribute (either constant or computed) is assigned a | 158 /* Each value of an attribute (either constant or computed) is assigned a |
158 structure which is used as the listhead of the insns that have that | 159 structure which is used as the listhead of the insns that have that |
159 value. */ | 160 value. */ |
167 int has_asm_insn; /* True if this value used for `asm' insns */ | 168 int has_asm_insn; /* True if this value used for `asm' insns */ |
168 }; | 169 }; |
169 | 170 |
170 /* Structure for each attribute. */ | 171 /* Structure for each attribute. */ |
171 | 172 |
172 struct attr_desc | 173 class attr_desc |
173 { | 174 { |
175 public: | |
174 char *name; /* Name of attribute. */ | 176 char *name; /* Name of attribute. */ |
175 const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */ | 177 const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */ |
176 struct attr_desc *next; /* Next attribute. */ | 178 class attr_desc *next; /* Next attribute. */ |
177 struct attr_value *first_value; /* First value of this attribute. */ | 179 struct attr_value *first_value; /* First value of this attribute. */ |
178 struct attr_value *default_val; /* Default value for this attribute. */ | 180 struct attr_value *default_val; /* Default value for this attribute. */ |
179 file_location loc; /* Where in the .md files it occurs. */ | 181 file_location loc; /* Where in the .md files it occurs. */ |
180 unsigned is_numeric : 1; /* Values of this attribute are numeric. */ | 182 unsigned is_numeric : 1; /* Values of this attribute are numeric. */ |
181 unsigned is_const : 1; /* Attribute value constant for each run. */ | 183 unsigned is_const : 1; /* Attribute value constant for each run. */ |
182 unsigned is_special : 1; /* Don't call `write_attr_set'. */ | 184 unsigned is_special : 1; /* Don't call `write_attr_set'. */ |
183 }; | 185 }; |
184 | 186 |
185 /* Structure for each DEFINE_DELAY. */ | 187 /* Structure for each DEFINE_DELAY. */ |
186 | 188 |
187 struct delay_desc | 189 class delay_desc |
188 { | 190 { |
191 public: | |
189 rtx def; /* DEFINE_DELAY expression. */ | 192 rtx def; /* DEFINE_DELAY expression. */ |
190 struct delay_desc *next; /* Next DEFINE_DELAY. */ | 193 class delay_desc *next; /* Next DEFINE_DELAY. */ |
191 file_location loc; /* Where in the .md files it occurs. */ | 194 file_location loc; /* Where in the .md files it occurs. */ |
192 int num; /* Number of DEFINE_DELAY, starting at 1. */ | 195 int num; /* Number of DEFINE_DELAY, starting at 1. */ |
193 }; | 196 }; |
194 | 197 |
195 struct attr_value_list | 198 struct attr_value_list |
196 { | 199 { |
197 struct attr_value *av; | 200 struct attr_value *av; |
198 struct insn_ent *ie; | 201 struct insn_ent *ie; |
199 struct attr_desc *attr; | 202 class attr_desc *attr; |
200 struct attr_value_list *next; | 203 struct attr_value_list *next; |
201 }; | 204 }; |
202 | 205 |
203 /* Listheads of above structures. */ | 206 /* Listheads of above structures. */ |
204 | 207 |
205 /* This one is indexed by the first character of the attribute name. */ | 208 /* This one is indexed by the first character of the attribute name. */ |
206 #define MAX_ATTRS_INDEX 256 | 209 #define MAX_ATTRS_INDEX 256 |
207 static struct attr_desc *attrs[MAX_ATTRS_INDEX]; | 210 static class attr_desc *attrs[MAX_ATTRS_INDEX]; |
208 static struct insn_def *defs; | 211 static class insn_def *defs; |
209 static struct delay_desc *delays; | 212 static class delay_desc *delays; |
210 struct attr_value_list **insn_code_values; | 213 struct attr_value_list **insn_code_values; |
211 | 214 |
212 /* Other variables. */ | 215 /* Other variables. */ |
213 | 216 |
214 static int insn_index_number; | 217 static int insn_index_number; |
255 /* Forward declarations of functions used before their definitions, only. */ | 258 /* Forward declarations of functions used before their definitions, only. */ |
256 static char *attr_string (const char *, int); | 259 static char *attr_string (const char *, int); |
257 static char *attr_printf (unsigned int, const char *, ...) | 260 static char *attr_printf (unsigned int, const char *, ...) |
258 ATTRIBUTE_PRINTF_2; | 261 ATTRIBUTE_PRINTF_2; |
259 static rtx make_numeric_value (int); | 262 static rtx make_numeric_value (int); |
260 static struct attr_desc *find_attr (const char **, int); | 263 static class attr_desc *find_attr (const char **, int); |
261 static rtx mk_attr_alt (alternative_mask); | 264 static rtx mk_attr_alt (alternative_mask); |
262 static char *next_comma_elt (const char **); | 265 static char *next_comma_elt (const char **); |
263 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int); | 266 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int); |
264 static rtx copy_boolean (rtx); | 267 static rtx copy_boolean (rtx); |
265 static int compares_alternatives_p (rtx); | 268 static int compares_alternatives_p (rtx); |
266 static void make_internal_attr (const char *, rtx, int); | 269 static void make_internal_attr (const char *, rtx, int); |
267 static void insert_insn_ent (struct attr_value *, struct insn_ent *); | 270 static void insert_insn_ent (struct attr_value *, struct insn_ent *); |
268 static void walk_attr_value (rtx); | 271 static void walk_attr_value (rtx); |
269 static int max_attr_value (rtx, int*); | 272 static int max_attr_value (rtx); |
270 static int min_attr_value (rtx, int*); | 273 static int min_attr_value (rtx); |
271 static int or_attr_value (rtx, int*); | 274 static unsigned int attr_value_alignment (rtx); |
272 static rtx simplify_test_exp (rtx, int, int); | 275 static rtx simplify_test_exp (rtx, int, int); |
273 static rtx simplify_test_exp_in_temp (rtx, int, int); | 276 static rtx simplify_test_exp_in_temp (rtx, int, int); |
274 static rtx copy_rtx_unchanging (rtx); | 277 static rtx copy_rtx_unchanging (rtx); |
275 static bool attr_alt_subset_p (rtx, rtx); | 278 static bool attr_alt_subset_p (rtx, rtx); |
276 static bool attr_alt_subset_of_compl_p (rtx, rtx); | 279 static bool attr_alt_subset_of_compl_p (rtx, rtx); |
277 static void clear_struct_flag (rtx); | 280 static void clear_struct_flag (rtx); |
278 static void write_attr_valueq (FILE *, struct attr_desc *, const char *); | 281 static void write_attr_valueq (FILE *, class attr_desc *, const char *); |
279 static struct attr_value *find_most_used (struct attr_desc *); | 282 static struct attr_value *find_most_used (class attr_desc *); |
280 static void write_attr_set (FILE *, struct attr_desc *, int, rtx, | 283 static void write_attr_set (FILE *, class attr_desc *, int, rtx, |
281 const char *, const char *, rtx, | 284 const char *, const char *, rtx, |
282 int, int, unsigned int); | 285 int, int, unsigned int); |
283 static void write_attr_case (FILE *, struct attr_desc *, | 286 static void write_attr_case (FILE *, class attr_desc *, |
284 struct attr_value *, | 287 struct attr_value *, |
285 int, const char *, const char *, int, rtx); | 288 int, const char *, const char *, int, rtx); |
286 static void write_attr_value (FILE *, struct attr_desc *, rtx); | 289 static void write_attr_value (FILE *, class attr_desc *, rtx); |
287 static void write_upcase (FILE *, const char *); | 290 static void write_upcase (FILE *, const char *); |
288 static void write_indent (FILE *, int); | 291 static void write_indent (FILE *, int); |
289 static rtx identity_fn (rtx); | 292 static rtx identity_fn (rtx); |
290 static rtx zero_fn (rtx); | 293 static rtx zero_fn (rtx); |
291 static rtx one_fn (rtx); | 294 static rtx one_fn (rtx); |
842 LOC is the location of the .md construct that contains EXP. | 845 LOC is the location of the .md construct that contains EXP. |
843 | 846 |
844 Return a perhaps modified replacement expression for the value. */ | 847 Return a perhaps modified replacement expression for the value. */ |
845 | 848 |
846 static rtx | 849 static rtx |
847 check_attr_value (file_location loc, rtx exp, struct attr_desc *attr) | 850 check_attr_value (file_location loc, rtx exp, class attr_desc *attr) |
848 { | 851 { |
849 struct attr_value *av; | 852 struct attr_value *av; |
850 const char *p; | 853 const char *p; |
851 int i; | 854 int i; |
852 | 855 |
952 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr); | 955 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr); |
953 break; | 956 break; |
954 | 957 |
955 case ATTR: | 958 case ATTR: |
956 { | 959 { |
957 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0); | 960 class attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0); |
958 if (attr2 == NULL) | 961 if (attr2 == NULL) |
959 error_at (loc, "unknown attribute `%s' in ATTR", | 962 error_at (loc, "unknown attribute `%s' in ATTR", |
960 XSTR (exp, 0)); | 963 XSTR (exp, 0)); |
961 else if (attr->is_const && ! attr2->is_const) | 964 else if (attr->is_const && ! attr2->is_const) |
962 error_at (attr->loc, | 965 error_at (attr->loc, |
986 | 989 |
987 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET. | 990 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET. |
988 It becomes a COND with each test being (eq_attr "alternative" "n") */ | 991 It becomes a COND with each test being (eq_attr "alternative" "n") */ |
989 | 992 |
990 static rtx | 993 static rtx |
991 convert_set_attr_alternative (rtx exp, struct insn_def *id) | 994 convert_set_attr_alternative (rtx exp, class insn_def *id) |
992 { | 995 { |
993 int num_alt = id->num_alternatives; | 996 int num_alt = id->num_alternatives; |
994 rtx condexp; | 997 rtx condexp; |
995 int i; | 998 int i; |
996 | 999 |
1022 | 1025 |
1023 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated | 1026 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated |
1024 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */ | 1027 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */ |
1025 | 1028 |
1026 static rtx | 1029 static rtx |
1027 convert_set_attr (rtx exp, struct insn_def *id) | 1030 convert_set_attr (rtx exp, class insn_def *id) |
1028 { | 1031 { |
1029 rtx newexp; | 1032 rtx newexp; |
1030 const char *name_ptr; | 1033 const char *name_ptr; |
1031 char *p; | 1034 char *p; |
1032 int n; | 1035 int n; |
1056 expressions. */ | 1059 expressions. */ |
1057 | 1060 |
1058 static void | 1061 static void |
1059 check_defs (void) | 1062 check_defs (void) |
1060 { | 1063 { |
1061 struct insn_def *id; | 1064 class insn_def *id; |
1062 struct attr_desc *attr; | 1065 class attr_desc *attr; |
1063 int i; | 1066 int i; |
1064 rtx value; | 1067 rtx value; |
1065 | 1068 |
1066 for (id = defs; id; id = id->next) | 1069 for (id = defs; id; id = id->next) |
1067 { | 1070 { |
1114 expressions by converting them into a COND. This removes cases from this | 1117 expressions by converting them into a COND. This removes cases from this |
1115 program. Also, replace an attribute value of "*" with the default attribute | 1118 program. Also, replace an attribute value of "*" with the default attribute |
1116 value. LOC is the location to use for error reporting. */ | 1119 value. LOC is the location to use for error reporting. */ |
1117 | 1120 |
1118 static rtx | 1121 static rtx |
1119 make_canonical (file_location loc, struct attr_desc *attr, rtx exp) | 1122 make_canonical (file_location loc, class attr_desc *attr, rtx exp) |
1120 { | 1123 { |
1121 int i; | 1124 int i; |
1122 rtx newexp; | 1125 rtx newexp; |
1123 | 1126 |
1124 switch (GET_CODE (exp)) | 1127 switch (GET_CODE (exp)) |
1221 value (-2 if not processing an insn). We ensure that all insns for | 1224 value (-2 if not processing an insn). We ensure that all insns for |
1222 a given value have the same number of alternatives if the value checks | 1225 a given value have the same number of alternatives if the value checks |
1223 alternatives. LOC is the location to use for error reporting. */ | 1226 alternatives. LOC is the location to use for error reporting. */ |
1224 | 1227 |
1225 static struct attr_value * | 1228 static struct attr_value * |
1226 get_attr_value (file_location loc, rtx value, struct attr_desc *attr, | 1229 get_attr_value (file_location loc, rtx value, class attr_desc *attr, |
1227 int insn_code) | 1230 int insn_code) |
1228 { | 1231 { |
1229 struct attr_value *av; | 1232 struct attr_value *av; |
1230 alternative_mask num_alt = 0; | 1233 alternative_mask num_alt = 0; |
1231 | 1234 |
1271 information needed to handle delay slots. */ | 1274 information needed to handle delay slots. */ |
1272 | 1275 |
1273 static void | 1276 static void |
1274 expand_delays (void) | 1277 expand_delays (void) |
1275 { | 1278 { |
1276 struct delay_desc *delay; | 1279 class delay_desc *delay; |
1277 rtx condexp; | 1280 rtx condexp; |
1278 rtx newexp; | 1281 rtx newexp; |
1279 int i; | 1282 int i; |
1280 char *p; | 1283 char *p; |
1281 | 1284 |
1357 /* Once all attributes and insns have been read and checked, we construct for | 1360 /* Once all attributes and insns have been read and checked, we construct for |
1358 each attribute value a list of all the insns that have that value for | 1361 each attribute value a list of all the insns that have that value for |
1359 the attribute. */ | 1362 the attribute. */ |
1360 | 1363 |
1361 static void | 1364 static void |
1362 fill_attr (struct attr_desc *attr) | 1365 fill_attr (class attr_desc *attr) |
1363 { | 1366 { |
1364 struct attr_value *av; | 1367 struct attr_value *av; |
1365 struct insn_ent *ie; | 1368 struct insn_ent *ie; |
1366 struct insn_def *id; | 1369 class insn_def *id; |
1367 int i; | 1370 int i; |
1368 rtx value; | 1371 rtx value; |
1369 | 1372 |
1370 /* Don't fill constant attributes. The value is independent of | 1373 /* Don't fill constant attributes. The value is independent of |
1371 any particular insn. */ | 1374 any particular insn. */ |
1486 static rtx (*const no_address_fn[]) (rtx) | 1489 static rtx (*const no_address_fn[]) (rtx) |
1487 = {identity_fn,identity_fn, zero_fn, zero_fn}; | 1490 = {identity_fn,identity_fn, zero_fn, zero_fn}; |
1488 static rtx (*const address_fn[]) (rtx) | 1491 static rtx (*const address_fn[]) (rtx) |
1489 = {max_fn, min_fn, one_fn, identity_fn}; | 1492 = {max_fn, min_fn, one_fn, identity_fn}; |
1490 size_t i; | 1493 size_t i; |
1491 struct attr_desc *length_attr, *new_attr; | 1494 class attr_desc *length_attr, *new_attr; |
1492 struct attr_value *av, *new_av; | 1495 struct attr_value *av, *new_av; |
1493 struct insn_ent *ie, *new_ie; | 1496 struct insn_ent *ie, *new_ie; |
1494 | 1497 |
1495 /* See if length attribute is defined. If so, it must be numeric. Make | 1498 /* See if length attribute is defined. If so, it must be numeric. Make |
1496 it special so we don't output anything for it. */ | 1499 it special so we don't output anything for it. */ |
1548 } | 1551 } |
1549 | 1552 |
1550 static rtx | 1553 static rtx |
1551 max_fn (rtx exp) | 1554 max_fn (rtx exp) |
1552 { | 1555 { |
1553 int unknown; | 1556 return make_numeric_value (max_attr_value (exp)); |
1554 return make_numeric_value (max_attr_value (exp, &unknown)); | |
1555 } | 1557 } |
1556 | 1558 |
1557 static rtx | 1559 static rtx |
1558 min_fn (rtx exp) | 1560 min_fn (rtx exp) |
1559 { | 1561 { |
1560 int unknown; | 1562 return make_numeric_value (min_attr_value (exp)); |
1561 return make_numeric_value (min_attr_value (exp, &unknown)); | |
1562 } | 1563 } |
1563 | 1564 |
1564 static void | 1565 static void |
1565 write_length_unit_log (FILE *outf) | 1566 write_length_unit_log (FILE *outf) |
1566 { | 1567 { |
1567 struct attr_desc *length_attr = find_attr (&length_str, 0); | 1568 class attr_desc *length_attr = find_attr (&length_str, 0); |
1568 struct attr_value *av; | 1569 struct attr_value *av; |
1569 struct insn_ent *ie; | 1570 struct insn_ent *ie; |
1570 unsigned int length_unit_log, length_or; | 1571 unsigned int length_unit_log, length_or; |
1571 int unknown = 0; | |
1572 | 1572 |
1573 if (length_attr) | 1573 if (length_attr) |
1574 { | 1574 { |
1575 length_or = or_attr_value (length_attr->default_val->value, &unknown); | 1575 length_or = attr_value_alignment (length_attr->default_val->value); |
1576 for (av = length_attr->first_value; av; av = av->next) | 1576 for (av = length_attr->first_value; av; av = av->next) |
1577 for (ie = av->first_insn; ie; ie = ie->next) | 1577 for (ie = av->first_insn; ie; ie = ie->next) |
1578 length_or |= or_attr_value (av->value, &unknown); | 1578 length_or |= attr_value_alignment (av->value); |
1579 } | 1579 |
1580 | |
1581 if (length_attr == NULL || unknown) | |
1582 length_unit_log = 0; | |
1583 else | |
1584 { | |
1585 length_or = ~length_or; | 1580 length_or = ~length_or; |
1586 for (length_unit_log = 0; length_or & 1; length_or >>= 1) | 1581 for (length_unit_log = 0; length_or & 1; length_or >>= 1) |
1587 length_unit_log++; | 1582 length_unit_log++; |
1588 } | 1583 } |
1584 else | |
1585 length_unit_log = 0; | |
1586 | |
1589 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log); | 1587 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log); |
1590 } | 1588 } |
1591 | 1589 |
1592 /* Compute approximate cost of the expression. Used to decide whether | 1590 /* Compute approximate cost of the expression. Used to decide whether |
1593 expression is cheap enough for inline. */ | 1591 expression is cheap enough for inline. */ |
1924 EXP is the EQ_ATTR expression and ATTR is the attribute to which | 1922 EXP is the EQ_ATTR expression and ATTR is the attribute to which |
1925 it refers. VALUE is the value of that attribute for the insn | 1923 it refers. VALUE is the value of that attribute for the insn |
1926 corresponding to INSN_CODE and INSN_INDEX. */ | 1924 corresponding to INSN_CODE and INSN_INDEX. */ |
1927 | 1925 |
1928 static rtx | 1926 static rtx |
1929 evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value, | 1927 evaluate_eq_attr (rtx exp, class attr_desc *attr, rtx value, |
1930 int insn_code, int insn_index) | 1928 int insn_code, int insn_index) |
1931 { | 1929 { |
1932 rtx orexp, andexp; | 1930 rtx orexp, andexp; |
1933 rtx right; | 1931 rtx right; |
1934 rtx newexp; | 1932 rtx newexp; |
2417 | 2415 |
2418 static rtx | 2416 static rtx |
2419 simplify_test_exp (rtx exp, int insn_code, int insn_index) | 2417 simplify_test_exp (rtx exp, int insn_code, int insn_index) |
2420 { | 2418 { |
2421 rtx left, right; | 2419 rtx left, right; |
2422 struct attr_desc *attr; | 2420 class attr_desc *attr; |
2423 struct attr_value *av; | 2421 struct attr_value *av; |
2424 struct insn_ent *ie; | 2422 struct insn_ent *ie; |
2425 struct attr_value_list *iv; | 2423 struct attr_value_list *iv; |
2426 alternative_mask i; | 2424 alternative_mask i; |
2427 rtx newexp = exp; | 2425 rtx newexp = exp; |
2758 | 2756 |
2759 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR, | 2757 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR, |
2760 otherwise return 0. */ | 2758 otherwise return 0. */ |
2761 | 2759 |
2762 static int | 2760 static int |
2763 tests_attr_p (rtx p, struct attr_desc *attr) | 2761 tests_attr_p (rtx p, class attr_desc *attr) |
2764 { | 2762 { |
2765 const char *fmt; | 2763 const char *fmt; |
2766 int i, ie, j, je; | 2764 int i, ie, j, je; |
2767 | 2765 |
2768 if (GET_CODE (p) == EQ_ATTR) | 2766 if (GET_CODE (p) == EQ_ATTR) |
2799 all attributes only depend on attributes in front of it. | 2797 all attributes only depend on attributes in front of it. |
2800 Place the result in *RET (which is a pointer to an array of | 2798 Place the result in *RET (which is a pointer to an array of |
2801 attr_desc pointers), and return the size of that array. */ | 2799 attr_desc pointers), and return the size of that array. */ |
2802 | 2800 |
2803 static int | 2801 static int |
2804 get_attr_order (struct attr_desc ***ret) | 2802 get_attr_order (class attr_desc ***ret) |
2805 { | 2803 { |
2806 int i, j; | 2804 int i, j; |
2807 int num = 0; | 2805 int num = 0; |
2808 struct attr_desc *attr; | 2806 class attr_desc *attr; |
2809 struct attr_desc **all, **sorted; | 2807 class attr_desc **all, **sorted; |
2810 char *handled; | 2808 char *handled; |
2811 for (i = 0; i < MAX_ATTRS_INDEX; i++) | 2809 for (i = 0; i < MAX_ATTRS_INDEX; i++) |
2812 for (attr = attrs[i]; attr; attr = attr->next) | 2810 for (attr = attrs[i]; attr; attr = attr->next) |
2813 num++; | 2811 num++; |
2814 all = XNEWVEC (struct attr_desc *, num); | 2812 all = XNEWVEC (class attr_desc *, num); |
2815 sorted = XNEWVEC (struct attr_desc *, num); | 2813 sorted = XNEWVEC (class attr_desc *, num); |
2816 handled = XCNEWVEC (char, num); | 2814 handled = XCNEWVEC (char, num); |
2817 num = 0; | 2815 num = 0; |
2818 for (i = 0; i < MAX_ATTRS_INDEX; i++) | 2816 for (i = 0; i < MAX_ATTRS_INDEX; i++) |
2819 for (attr = attrs[i]; attr; attr = attr->next) | 2817 for (attr = attrs[i]; attr; attr = attr->next) |
2820 all[num++] = attr; | 2818 all[num++] = attr; |
2858 } | 2856 } |
2859 | 2857 |
2860 if (DEBUG) | 2858 if (DEBUG) |
2861 for (j = 0; j < num; j++) | 2859 for (j = 0; j < num; j++) |
2862 { | 2860 { |
2863 struct attr_desc *attr2; | 2861 class attr_desc *attr2; |
2864 struct attr_value *av; | 2862 struct attr_value *av; |
2865 | 2863 |
2866 attr = sorted[j]; | 2864 attr = sorted[j]; |
2867 fprintf (stderr, "%s depends on: ", attr->name); | 2865 fprintf (stderr, "%s depends on: ", attr->name); |
2868 for (i = 0; i < MAX_ATTRS_INDEX; ++i) | 2866 for (i = 0; i < MAX_ATTRS_INDEX; ++i) |
2889 instruction codes. */ | 2887 instruction codes. */ |
2890 | 2888 |
2891 static void | 2889 static void |
2892 optimize_attrs (int num_insn_codes) | 2890 optimize_attrs (int num_insn_codes) |
2893 { | 2891 { |
2894 struct attr_desc *attr; | 2892 class attr_desc *attr; |
2895 struct attr_value *av; | 2893 struct attr_value *av; |
2896 struct insn_ent *ie; | 2894 struct insn_ent *ie; |
2897 rtx newexp; | 2895 rtx newexp; |
2898 int i; | 2896 int i; |
2899 struct attr_value_list *ivbuf; | 2897 struct attr_value_list *ivbuf; |
2900 struct attr_value_list *iv; | 2898 struct attr_value_list *iv; |
2901 struct attr_desc **topsort; | 2899 class attr_desc **topsort; |
2902 int topnum; | 2900 int topnum; |
2903 | 2901 |
2904 /* For each insn code, make a list of all the insn_ent's for it, | 2902 /* For each insn code, make a list of all the insn_ent's for it, |
2905 for all values for all attributes. */ | 2903 for all values for all attributes. */ |
2906 | 2904 |
3044 } | 3042 } |
3045 | 3043 |
3046 /* Add attribute value NAME to the beginning of ATTR's list. */ | 3044 /* Add attribute value NAME to the beginning of ATTR's list. */ |
3047 | 3045 |
3048 static void | 3046 static void |
3049 add_attr_value (struct attr_desc *attr, const char *name) | 3047 add_attr_value (class attr_desc *attr, const char *name) |
3050 { | 3048 { |
3051 struct attr_value *av; | 3049 struct attr_value *av; |
3052 | 3050 |
3053 av = oballoc (struct attr_value); | 3051 av = oballoc (struct attr_value); |
3054 av->value = attr_rtx (CONST_STRING, name); | 3052 av->value = attr_rtx (CONST_STRING, name); |
3064 static void | 3062 static void |
3065 gen_attr (md_rtx_info *info) | 3063 gen_attr (md_rtx_info *info) |
3066 { | 3064 { |
3067 struct enum_type *et; | 3065 struct enum_type *et; |
3068 struct enum_value *ev; | 3066 struct enum_value *ev; |
3069 struct attr_desc *attr; | 3067 class attr_desc *attr; |
3070 const char *name_ptr; | 3068 const char *name_ptr; |
3071 char *p; | 3069 char *p; |
3072 rtx def = info->def; | 3070 rtx def = info->def; |
3073 | 3071 |
3074 /* Make a new attribute structure. Check for duplicate by looking at | 3072 /* Make a new attribute structure. Check for duplicate by looking at |
3195 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */ | 3193 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */ |
3196 | 3194 |
3197 static void | 3195 static void |
3198 gen_insn (md_rtx_info *info) | 3196 gen_insn (md_rtx_info *info) |
3199 { | 3197 { |
3200 struct insn_def *id; | 3198 class insn_def *id; |
3201 rtx def = info->def; | 3199 rtx def = info->def; |
3202 | 3200 |
3203 id = oballoc (struct insn_def); | 3201 id = oballoc (class insn_def); |
3204 id->next = defs; | 3202 id->next = defs; |
3205 defs = id; | 3203 defs = id; |
3206 id->def = def; | 3204 id->def = def; |
3207 id->loc = info->loc; | 3205 id->loc = info->loc; |
3208 | 3206 |
3243 true or annul false is specified, and make a `struct delay_desc'. */ | 3241 true or annul false is specified, and make a `struct delay_desc'. */ |
3244 | 3242 |
3245 static void | 3243 static void |
3246 gen_delay (md_rtx_info *info) | 3244 gen_delay (md_rtx_info *info) |
3247 { | 3245 { |
3248 struct delay_desc *delay; | 3246 class delay_desc *delay; |
3249 int i; | 3247 int i; |
3250 | 3248 |
3251 rtx def = info->def; | 3249 rtx def = info->def; |
3252 if (XVECLEN (def, 1) % 3 != 0) | 3250 if (XVECLEN (def, 1) % 3 != 0) |
3253 { | 3251 { |
3262 have_annul_true = 1; | 3260 have_annul_true = 1; |
3263 if (XVECEXP (def, 1, i + 2)) | 3261 if (XVECEXP (def, 1, i + 2)) |
3264 have_annul_false = 1; | 3262 have_annul_false = 1; |
3265 } | 3263 } |
3266 | 3264 |
3267 delay = oballoc (struct delay_desc); | 3265 delay = oballoc (class delay_desc); |
3268 delay->def = def; | 3266 delay->def = def; |
3269 delay->num = ++num_delays; | 3267 delay->num = ++num_delays; |
3270 delay->next = delays; | 3268 delay->next = delays; |
3271 delay->loc = info->loc; | 3269 delay->loc = info->loc; |
3272 delays = delay; | 3270 delays = delay; |
3289 static void | 3287 static void |
3290 find_attrs_to_cache (rtx exp, bool create) | 3288 find_attrs_to_cache (rtx exp, bool create) |
3291 { | 3289 { |
3292 int i; | 3290 int i; |
3293 const char *name; | 3291 const char *name; |
3294 struct attr_desc *attr; | 3292 class attr_desc *attr; |
3295 | 3293 |
3296 if (exp == NULL) | 3294 if (exp == NULL) |
3297 return; | 3295 return; |
3298 | 3296 |
3299 switch (GET_CODE (exp)) | 3297 switch (GET_CODE (exp)) |
3369 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags, | 3367 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags, |
3370 bool emit_parens = true) | 3368 bool emit_parens = true) |
3371 { | 3369 { |
3372 int comparison_operator = 0; | 3370 int comparison_operator = 0; |
3373 RTX_CODE code; | 3371 RTX_CODE code; |
3374 struct attr_desc *attr; | 3372 class attr_desc *attr; |
3375 | 3373 |
3376 if (emit_parens) | 3374 if (emit_parens) |
3377 fprintf (outf, "("); | 3375 fprintf (outf, "("); |
3378 | 3376 |
3379 code = GET_CODE (exp); | 3377 code = GET_CODE (exp); |
3751 fprintf (outf, ")"); | 3749 fprintf (outf, ")"); |
3752 | 3750 |
3753 return attrs_cached; | 3751 return attrs_cached; |
3754 } | 3752 } |
3755 | 3753 |
3756 /* Given an attribute value, return the maximum CONST_STRING argument | 3754 /* Given an attribute value expression, return the maximum value that |
3757 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */ | 3755 might be evaluated. Return INT_MAX if the value can't be |
3756 calculated by this function. */ | |
3758 | 3757 |
3759 static int | 3758 static int |
3760 max_attr_value (rtx exp, int *unknownp) | 3759 max_attr_value (rtx exp) |
3761 { | 3760 { |
3762 int current_max; | 3761 int current_max; |
3763 int i, n; | 3762 int i, n; |
3764 | 3763 |
3765 switch (GET_CODE (exp)) | 3764 switch (GET_CODE (exp)) |
3766 { | 3765 { |
3767 case CONST_STRING: | 3766 case CONST_STRING: |
3768 current_max = atoi (XSTR (exp, 0)); | 3767 current_max = atoi (XSTR (exp, 0)); |
3769 break; | 3768 break; |
3770 | 3769 |
3770 case CONST_INT: | |
3771 current_max = INTVAL (exp); | |
3772 break; | |
3773 | |
3774 case PLUS: | |
3775 current_max = max_attr_value (XEXP (exp, 0)); | |
3776 if (current_max != INT_MAX) | |
3777 { | |
3778 n = current_max; | |
3779 current_max = max_attr_value (XEXP (exp, 1)); | |
3780 if (current_max != INT_MAX) | |
3781 current_max += n; | |
3782 } | |
3783 break; | |
3784 | |
3785 case MINUS: | |
3786 current_max = max_attr_value (XEXP (exp, 0)); | |
3787 if (current_max != INT_MAX) | |
3788 { | |
3789 n = current_max; | |
3790 current_max = min_attr_value (XEXP (exp, 1)); | |
3791 if (current_max != INT_MAX) | |
3792 current_max = n - current_max; | |
3793 } | |
3794 break; | |
3795 | |
3796 case MULT: | |
3797 current_max = max_attr_value (XEXP (exp, 0)); | |
3798 if (current_max != INT_MAX) | |
3799 { | |
3800 n = current_max; | |
3801 current_max = max_attr_value (XEXP (exp, 1)); | |
3802 if (current_max != INT_MAX) | |
3803 current_max *= n; | |
3804 } | |
3805 break; | |
3806 | |
3771 case COND: | 3807 case COND: |
3772 current_max = max_attr_value (XEXP (exp, 1), unknownp); | 3808 current_max = max_attr_value (XEXP (exp, 1)); |
3773 for (i = 0; i < XVECLEN (exp, 0); i += 2) | 3809 for (i = 0; i < XVECLEN (exp, 0); i += 2) |
3774 { | 3810 { |
3775 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp); | 3811 n = max_attr_value (XVECEXP (exp, 0, i + 1)); |
3776 if (n > current_max) | 3812 if (n > current_max) |
3777 current_max = n; | 3813 current_max = n; |
3778 } | 3814 } |
3779 break; | 3815 break; |
3780 | 3816 |
3781 case IF_THEN_ELSE: | 3817 case IF_THEN_ELSE: |
3782 current_max = max_attr_value (XEXP (exp, 1), unknownp); | 3818 current_max = max_attr_value (XEXP (exp, 1)); |
3783 n = max_attr_value (XEXP (exp, 2), unknownp); | 3819 n = max_attr_value (XEXP (exp, 2)); |
3784 if (n > current_max) | 3820 if (n > current_max) |
3785 current_max = n; | 3821 current_max = n; |
3786 break; | 3822 break; |
3787 | 3823 |
3788 default: | 3824 default: |
3789 *unknownp = 1; | |
3790 current_max = INT_MAX; | 3825 current_max = INT_MAX; |
3791 break; | 3826 break; |
3792 } | 3827 } |
3793 | 3828 |
3794 return current_max; | 3829 return current_max; |
3795 } | 3830 } |
3796 | 3831 |
3797 /* Given an attribute value, return the minimum CONST_STRING argument | 3832 /* Given an attribute value expression, return the minimum value that |
3798 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */ | 3833 might be evaluated. Return INT_MAX if the value can't be |
3834 calculated by this function. Note that when this function can | |
3835 calculate one value inside IF_THEN_ELSE or some but not all values | |
3836 inside COND, then it returns the minimum among those values it can | |
3837 calculate. */ | |
3799 | 3838 |
3800 static int | 3839 static int |
3801 min_attr_value (rtx exp, int *unknownp) | 3840 min_attr_value (rtx exp) |
3802 { | 3841 { |
3803 int current_min; | 3842 int current_min; |
3804 int i, n; | 3843 int i, n; |
3805 | 3844 |
3806 switch (GET_CODE (exp)) | 3845 switch (GET_CODE (exp)) |
3807 { | 3846 { |
3808 case CONST_STRING: | 3847 case CONST_STRING: |
3809 current_min = atoi (XSTR (exp, 0)); | 3848 current_min = atoi (XSTR (exp, 0)); |
3810 break; | 3849 break; |
3811 | 3850 |
3851 case CONST_INT: | |
3852 current_min = INTVAL (exp); | |
3853 break; | |
3854 | |
3855 case PLUS: | |
3856 current_min = min_attr_value (XEXP (exp, 0)); | |
3857 if (current_min != INT_MAX) | |
3858 { | |
3859 n = current_min; | |
3860 current_min = min_attr_value (XEXP (exp, 1)); | |
3861 if (current_min != INT_MAX) | |
3862 current_min += n; | |
3863 } | |
3864 break; | |
3865 | |
3866 case MINUS: | |
3867 current_min = min_attr_value (XEXP (exp, 0)); | |
3868 if (current_min != INT_MAX) | |
3869 { | |
3870 n = current_min; | |
3871 current_min = max_attr_value (XEXP (exp, 1)); | |
3872 if (current_min != INT_MAX) | |
3873 current_min = n - current_min; | |
3874 } | |
3875 break; | |
3876 | |
3877 case MULT: | |
3878 current_min = min_attr_value (XEXP (exp, 0)); | |
3879 if (current_min != INT_MAX) | |
3880 { | |
3881 n = current_min; | |
3882 current_min = min_attr_value (XEXP (exp, 1)); | |
3883 if (current_min != INT_MAX) | |
3884 current_min *= n; | |
3885 } | |
3886 break; | |
3887 | |
3812 case COND: | 3888 case COND: |
3813 current_min = min_attr_value (XEXP (exp, 1), unknownp); | 3889 current_min = min_attr_value (XEXP (exp, 1)); |
3814 for (i = 0; i < XVECLEN (exp, 0); i += 2) | 3890 for (i = 0; i < XVECLEN (exp, 0); i += 2) |
3815 { | 3891 { |
3816 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp); | 3892 n = min_attr_value (XVECEXP (exp, 0, i + 1)); |
3817 if (n < current_min) | 3893 if (n < current_min) |
3818 current_min = n; | 3894 current_min = n; |
3819 } | 3895 } |
3820 break; | 3896 break; |
3821 | 3897 |
3822 case IF_THEN_ELSE: | 3898 case IF_THEN_ELSE: |
3823 current_min = min_attr_value (XEXP (exp, 1), unknownp); | 3899 current_min = min_attr_value (XEXP (exp, 1)); |
3824 n = min_attr_value (XEXP (exp, 2), unknownp); | 3900 n = min_attr_value (XEXP (exp, 2)); |
3825 if (n < current_min) | 3901 if (n < current_min) |
3826 current_min = n; | 3902 current_min = n; |
3827 break; | 3903 break; |
3828 | 3904 |
3829 default: | 3905 default: |
3830 *unknownp = 1; | |
3831 current_min = INT_MAX; | 3906 current_min = INT_MAX; |
3832 break; | 3907 break; |
3833 } | 3908 } |
3834 | 3909 |
3835 return current_min; | 3910 return current_min; |
3836 } | 3911 } |
3837 | 3912 |
3838 /* Given an attribute value, return the result of ORing together all | 3913 /* Given an attribute value expression, return the alignment of values. |
3839 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1 | 3914 Return 0 if EXP is known to be zero, and 1 if the value can't be |
3840 if the numeric value is not known. */ | 3915 calculated by this function. */ |
3841 | 3916 |
3842 static int | 3917 static unsigned int |
3843 or_attr_value (rtx exp, int *unknownp) | 3918 attr_value_alignment (rtx exp) |
3844 { | 3919 { |
3845 int current_or; | 3920 unsigned int current_or; |
3846 int i; | 3921 int i; |
3847 | 3922 |
3848 switch (GET_CODE (exp)) | 3923 switch (GET_CODE (exp)) |
3849 { | 3924 { |
3850 case CONST_STRING: | 3925 case CONST_STRING: |
3851 current_or = atoi (XSTR (exp, 0)); | 3926 current_or = atoi (XSTR (exp, 0)); |
3852 break; | 3927 break; |
3853 | 3928 |
3929 case CONST_INT: | |
3930 current_or = INTVAL (exp); | |
3931 break; | |
3932 | |
3933 case PLUS: | |
3934 case MINUS: | |
3935 current_or = attr_value_alignment (XEXP (exp, 0)); | |
3936 current_or |= attr_value_alignment (XEXP (exp, 1)); | |
3937 break; | |
3938 | |
3939 case MULT: | |
3940 current_or = attr_value_alignment (XEXP (exp, 0)); | |
3941 current_or *= attr_value_alignment (XEXP (exp, 1)); | |
3942 break; | |
3943 | |
3854 case COND: | 3944 case COND: |
3855 current_or = or_attr_value (XEXP (exp, 1), unknownp); | 3945 current_or = attr_value_alignment (XEXP (exp, 1)); |
3856 for (i = 0; i < XVECLEN (exp, 0); i += 2) | 3946 for (i = 0; i < XVECLEN (exp, 0); i += 2) |
3857 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp); | 3947 current_or |= attr_value_alignment (XVECEXP (exp, 0, i + 1)); |
3858 break; | 3948 break; |
3859 | 3949 |
3860 case IF_THEN_ELSE: | 3950 case IF_THEN_ELSE: |
3861 current_or = or_attr_value (XEXP (exp, 1), unknownp); | 3951 current_or = attr_value_alignment (XEXP (exp, 1)); |
3862 current_or |= or_attr_value (XEXP (exp, 2), unknownp); | 3952 current_or |= attr_value_alignment (XEXP (exp, 2)); |
3863 break; | 3953 break; |
3864 | 3954 |
3865 default: | 3955 default: |
3866 *unknownp = 1; | 3956 current_or = 1; |
3867 current_or = -1; | 3957 break; |
3868 break; | 3958 } |
3869 } | 3959 |
3870 | 3960 return current_or & -current_or; |
3871 return current_or; | |
3872 } | 3961 } |
3873 | 3962 |
3874 /* Scan an attribute value, possibly a conditional, and record what actions | 3963 /* Scan an attribute value, possibly a conditional, and record what actions |
3875 will be required to do any conditional tests in it. | 3964 will be required to do any conditional tests in it. |
3876 | 3965 |
3951 } | 4040 } |
3952 | 4041 |
3953 /* Write out a function to obtain the attribute for a given INSN. */ | 4042 /* Write out a function to obtain the attribute for a given INSN. */ |
3954 | 4043 |
3955 static void | 4044 static void |
3956 write_attr_get (FILE *outf, struct attr_desc *attr) | 4045 write_attr_get (FILE *outf, class attr_desc *attr) |
3957 { | 4046 { |
3958 struct attr_value *av, *common_av; | 4047 struct attr_value *av, *common_av; |
3959 int i, j; | 4048 int i, j; |
3960 | 4049 |
3961 /* Find the most used attribute value. Handle that as the `default' of the | 4050 /* Find the most used attribute value. Handle that as the `default' of the |
4008 /* Remove those that aren't worth caching from the array. */ | 4097 /* Remove those that aren't worth caching from the array. */ |
4009 for (i = 0, j = 0; i < cached_attr_count; i++) | 4098 for (i = 0, j = 0; i < cached_attr_count; i++) |
4010 if ((attrs_seen_more_than_once & (1U << i)) != 0) | 4099 if ((attrs_seen_more_than_once & (1U << i)) != 0) |
4011 { | 4100 { |
4012 const char *name = cached_attrs[i]; | 4101 const char *name = cached_attrs[i]; |
4013 struct attr_desc *cached_attr; | 4102 class attr_desc *cached_attr; |
4014 if (i != j) | 4103 if (i != j) |
4015 cached_attrs[j] = name; | 4104 cached_attrs[j] = name; |
4016 cached_attr = find_attr (&name, 0); | 4105 cached_attr = find_attr (&name, 0); |
4017 gcc_assert (cached_attr && cached_attr->is_const == 0); | 4106 gcc_assert (cached_attr && cached_attr->is_const == 0); |
4018 if (cached_attr->enum_name) | 4107 if (cached_attr->enum_name) |
4072 sets of an attribute value. We are passed an indentation amount and prefix | 4161 sets of an attribute value. We are passed an indentation amount and prefix |
4073 and suffix strings to write around each attribute value (e.g., "return" | 4162 and suffix strings to write around each attribute value (e.g., "return" |
4074 and ";"). */ | 4163 and ";"). */ |
4075 | 4164 |
4076 static void | 4165 static void |
4077 write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value, | 4166 write_attr_set (FILE *outf, class attr_desc *attr, int indent, rtx value, |
4078 const char *prefix, const char *suffix, rtx known_true, | 4167 const char *prefix, const char *suffix, rtx known_true, |
4079 int insn_code, int insn_index, unsigned int attrs_cached) | 4168 int insn_code, int insn_index, unsigned int attrs_cached) |
4080 { | 4169 { |
4081 if (GET_CODE (value) == COND) | 4170 if (GET_CODE (value) == COND) |
4082 { | 4171 { |
4200 } | 4289 } |
4201 | 4290 |
4202 /* Write out the computation for one attribute value. */ | 4291 /* Write out the computation for one attribute value. */ |
4203 | 4292 |
4204 static void | 4293 static void |
4205 write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av, | 4294 write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av, |
4206 int write_case_lines, const char *prefix, const char *suffix, | 4295 int write_case_lines, const char *prefix, const char *suffix, |
4207 int indent, rtx known_true) | 4296 int indent, rtx known_true) |
4208 { | 4297 { |
4209 if (av->num_insns == 0) | 4298 if (av->num_insns == 0) |
4210 return; | 4299 return; |
4264 } | 4353 } |
4265 | 4354 |
4266 /* Utilities to write in various forms. */ | 4355 /* Utilities to write in various forms. */ |
4267 | 4356 |
4268 static void | 4357 static void |
4269 write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s) | 4358 write_attr_valueq (FILE *outf, class attr_desc *attr, const char *s) |
4270 { | 4359 { |
4271 if (attr->is_numeric) | 4360 if (attr->is_numeric) |
4272 { | 4361 { |
4273 int num = atoi (s); | 4362 int num = atoi (s); |
4274 | 4363 |
4284 write_upcase (outf, s); | 4373 write_upcase (outf, s); |
4285 } | 4374 } |
4286 } | 4375 } |
4287 | 4376 |
4288 static void | 4377 static void |
4289 write_attr_value (FILE *outf, struct attr_desc *attr, rtx value) | 4378 write_attr_value (FILE *outf, class attr_desc *attr, rtx value) |
4290 { | 4379 { |
4291 int op; | 4380 int op; |
4292 | 4381 |
4293 switch (GET_CODE (value)) | 4382 switch (GET_CODE (value)) |
4294 { | 4383 { |
4304 rtx_reader_ptr->fprint_c_condition (outf, XSTR (value, 0)); | 4393 rtx_reader_ptr->fprint_c_condition (outf, XSTR (value, 0)); |
4305 break; | 4394 break; |
4306 | 4395 |
4307 case ATTR: | 4396 case ATTR: |
4308 { | 4397 { |
4309 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0); | 4398 class attr_desc *attr2 = find_attr (&XSTR (value, 0), 0); |
4310 if (attr->enum_name) | 4399 if (attr->enum_name) |
4311 fprintf (outf, "(enum %s)", attr->enum_name); | 4400 fprintf (outf, "(enum %s)", attr->enum_name); |
4312 else if (!attr->is_numeric) | 4401 else if (!attr->is_numeric) |
4313 fprintf (outf, "(enum attr_%s)", attr->name); | 4402 fprintf (outf, "(enum attr_%s)", attr->name); |
4314 else if (!attr2->is_numeric) | 4403 else if (!attr2->is_numeric) |
4334 case MOD: | 4423 case MOD: |
4335 op = '%'; | 4424 op = '%'; |
4336 goto do_operator; | 4425 goto do_operator; |
4337 | 4426 |
4338 do_operator: | 4427 do_operator: |
4428 fprintf (outf, "("); | |
4339 write_attr_value (outf, attr, XEXP (value, 0)); | 4429 write_attr_value (outf, attr, XEXP (value, 0)); |
4340 fputc (' ', outf); | 4430 fprintf (outf, " %c ", op); |
4341 fputc (op, outf); | |
4342 fputc (' ', outf); | |
4343 write_attr_value (outf, attr, XEXP (value, 1)); | 4431 write_attr_value (outf, attr, XEXP (value, 1)); |
4432 fprintf (outf, ")"); | |
4433 break; | |
4434 | |
4435 case IF_THEN_ELSE: | |
4436 fprintf (outf, "("); | |
4437 write_test_expr (outf, XEXP (value, 0), 0, 0, false); | |
4438 fprintf (outf, " ? "); | |
4439 write_attr_value (outf, attr, XEXP (value, 1)); | |
4440 fprintf (outf, " : "); | |
4441 write_attr_value (outf, attr, XEXP (value, 2)); | |
4442 fprintf (outf, ")"); | |
4344 break; | 4443 break; |
4345 | 4444 |
4346 default: | 4445 default: |
4347 gcc_unreachable (); | 4446 gcc_unreachable (); |
4348 } | 4447 } |
4402 or "annul_false"). */ | 4501 or "annul_false"). */ |
4403 | 4502 |
4404 static void | 4503 static void |
4405 write_eligible_delay (FILE *outf, const char *kind) | 4504 write_eligible_delay (FILE *outf, const char *kind) |
4406 { | 4505 { |
4407 struct delay_desc *delay; | 4506 class delay_desc *delay; |
4408 int max_slots; | 4507 int max_slots; |
4409 char str[50]; | 4508 char str[50]; |
4410 const char *pstr; | 4509 const char *pstr; |
4411 struct attr_desc *attr; | 4510 class attr_desc *attr; |
4412 struct attr_value *av, *common_av; | 4511 struct attr_value *av, *common_av; |
4413 int i; | 4512 int i; |
4414 | 4513 |
4415 /* Compute the maximum number of delay slots required. We use the delay | 4514 /* Compute the maximum number of delay slots required. We use the delay |
4416 ordinal times this number plus one, plus the slot number as an index into | 4515 ordinal times this number plus one, plus the slot number as an index into |
4538 return NULL; | 4637 return NULL; |
4539 | 4638 |
4540 return attr_string (start, *pstr - start); | 4639 return attr_string (start, *pstr - start); |
4541 } | 4640 } |
4542 | 4641 |
4543 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE | 4642 /* Return a `class attr_desc' pointer for a given named attribute. If CREATE |
4544 is nonzero, build a new attribute, if one does not exist. *NAME_P is | 4643 is nonzero, build a new attribute, if one does not exist. *NAME_P is |
4545 replaced by a pointer to a canonical copy of the string. */ | 4644 replaced by a pointer to a canonical copy of the string. */ |
4546 | 4645 |
4547 static struct attr_desc * | 4646 static class attr_desc * |
4548 find_attr (const char **name_p, int create) | 4647 find_attr (const char **name_p, int create) |
4549 { | 4648 { |
4550 struct attr_desc *attr; | 4649 class attr_desc *attr; |
4551 int index; | 4650 int index; |
4552 const char *name = *name_p; | 4651 const char *name = *name_p; |
4553 | 4652 |
4554 /* Before we resort to using `strcmp', see if the string address matches | 4653 /* Before we resort to using `strcmp', see if the string address matches |
4555 anywhere. In most cases, it should have been canonicalized to do so. */ | 4654 anywhere. In most cases, it should have been canonicalized to do so. */ |
4570 } | 4669 } |
4571 | 4670 |
4572 if (! create) | 4671 if (! create) |
4573 return NULL; | 4672 return NULL; |
4574 | 4673 |
4575 attr = oballoc (struct attr_desc); | 4674 attr = oballoc (class attr_desc); |
4576 attr->name = DEF_ATTR_STRING (name); | 4675 attr->name = DEF_ATTR_STRING (name); |
4577 attr->enum_name = 0; | 4676 attr->enum_name = 0; |
4578 attr->first_value = attr->default_val = NULL; | 4677 attr->first_value = attr->default_val = NULL; |
4579 attr->is_numeric = attr->is_const = attr->is_special = 0; | 4678 attr->is_numeric = attr->is_const = attr->is_special = 0; |
4580 attr->next = attrs[index]; | 4679 attr->next = attrs[index]; |
4588 /* Create internal attribute with the given default value. */ | 4687 /* Create internal attribute with the given default value. */ |
4589 | 4688 |
4590 static void | 4689 static void |
4591 make_internal_attr (const char *name, rtx value, int special) | 4690 make_internal_attr (const char *name, rtx value, int special) |
4592 { | 4691 { |
4593 struct attr_desc *attr; | 4692 class attr_desc *attr; |
4594 | 4693 |
4595 attr = find_attr (&name, 1); | 4694 attr = find_attr (&name, 1); |
4596 gcc_assert (!attr->default_val); | 4695 gcc_assert (!attr->default_val); |
4597 | 4696 |
4598 attr->is_numeric = 1; | 4697 attr->is_numeric = 1; |
4603 } | 4702 } |
4604 | 4703 |
4605 /* Find the most used value of an attribute. */ | 4704 /* Find the most used value of an attribute. */ |
4606 | 4705 |
4607 static struct attr_value * | 4706 static struct attr_value * |
4608 find_most_used (struct attr_desc *attr) | 4707 find_most_used (class attr_desc *attr) |
4609 { | 4708 { |
4610 struct attr_value *av; | 4709 struct attr_value *av; |
4611 struct attr_value *most_used; | 4710 struct attr_value *most_used; |
4612 int nuses; | 4711 int nuses; |
4613 | 4712 |
4658 number of delay slots is not a function of the length of the insn. */ | 4757 number of delay slots is not a function of the length of the insn. */ |
4659 | 4758 |
4660 static void | 4759 static void |
4661 write_const_num_delay_slots (FILE *outf) | 4760 write_const_num_delay_slots (FILE *outf) |
4662 { | 4761 { |
4663 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0); | 4762 class attr_desc *attr = find_attr (&num_delay_slots_str, 0); |
4664 struct attr_value *av; | 4763 struct attr_value *av; |
4665 | 4764 |
4666 if (attr) | 4765 if (attr) |
4667 { | 4766 { |
4668 fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n"); | 4767 fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n"); |
4714 gen_insn_reserv (md_rtx_info *info) | 4813 gen_insn_reserv (md_rtx_info *info) |
4715 { | 4814 { |
4716 struct insn_reserv *decl = oballoc (struct insn_reserv); | 4815 struct insn_reserv *decl = oballoc (struct insn_reserv); |
4717 rtx def = info->def; | 4816 rtx def = info->def; |
4718 | 4817 |
4719 struct attr_desc attr = { }; | 4818 class attr_desc attr = { }; |
4720 | 4819 |
4721 attr.name = DEF_ATTR_STRING (XSTR (def, 0)); | 4820 attr.name = DEF_ATTR_STRING (XSTR (def, 0)); |
4722 attr.loc = info->loc; | 4821 attr.loc = info->loc; |
4723 | 4822 |
4724 decl->name = DEF_ATTR_STRING (XSTR (def, 0)); | 4823 decl->name = DEF_ATTR_STRING (XSTR (def, 0)); |
4831 } | 4930 } |
4832 } | 4931 } |
4833 | 4932 |
4834 /* Try to find a const attribute (usually cpu or tune) that is used | 4933 /* Try to find a const attribute (usually cpu or tune) that is used |
4835 in all define_insn_reservation conditions. */ | 4934 in all define_insn_reservation conditions. */ |
4836 static struct attr_desc * | 4935 static class attr_desc * |
4837 find_tune_attr (rtx exp) | 4936 find_tune_attr (rtx exp) |
4838 { | 4937 { |
4839 struct attr_desc *attr; | 4938 class attr_desc *attr; |
4840 | 4939 |
4841 switch (GET_CODE (exp)) | 4940 switch (GET_CODE (exp)) |
4842 { | 4941 { |
4843 case AND: | 4942 case AND: |
4844 case IOR: | 4943 case IOR: |
4878 make_automaton_attrs (void) | 4977 make_automaton_attrs (void) |
4879 { | 4978 { |
4880 int i; | 4979 int i; |
4881 struct insn_reserv *decl; | 4980 struct insn_reserv *decl; |
4882 rtx code_exp, lats_exp, byps_exp; | 4981 rtx code_exp, lats_exp, byps_exp; |
4883 struct attr_desc *tune_attr; | 4982 class attr_desc *tune_attr; |
4884 | 4983 |
4885 if (n_insn_reservs == 0) | 4984 if (n_insn_reservs == 0) |
4886 return; | 4985 return; |
4887 | 4986 |
4888 tune_attr = find_tune_attr (all_insn_reservs->condexp); | 4987 tune_attr = find_tune_attr (all_insn_reservs->condexp); |
5144 } | 5243 } |
5145 | 5244 |
5146 int | 5245 int |
5147 main (int argc, const char **argv) | 5246 main (int argc, const char **argv) |
5148 { | 5247 { |
5149 struct attr_desc *attr; | 5248 class attr_desc *attr; |
5150 struct insn_def *id; | 5249 class insn_def *id; |
5151 int i; | 5250 int i; |
5152 | 5251 |
5153 progname = "genattrtab"; | 5252 progname = "genattrtab"; |
5154 | 5253 |
5155 if (!init_rtx_reader_args_cb (argc, argv, handle_arg)) | 5254 if (!init_rtx_reader_args_cb (argc, argv, handle_arg)) |