Mercurial > hg > CbC > CbC_gcc
comparison gcc/read-rtl.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 /* RTL reader for GCC. | 1 /* RTL reader for GCC. |
2 Copyright (C) 1987-2018 Free Software Foundation, Inc. | 2 Copyright (C) 1987-2020 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
103 /* Records one use of an attribute (the "<[iterator:]attribute>" syntax) | 103 /* Records one use of an attribute (the "<[iterator:]attribute>" syntax) |
104 in a non-string rtx field. */ | 104 in a non-string rtx field. */ |
105 struct attribute_use { | 105 struct attribute_use { |
106 /* The group that describes the use site. */ | 106 /* The group that describes the use site. */ |
107 struct iterator_group *group; | 107 struct iterator_group *group; |
108 | |
109 /* The location at which the use occurs. */ | |
110 file_location loc; | |
108 | 111 |
109 /* The name of the attribute, possibly with an "iterator:" prefix. */ | 112 /* The name of the attribute, possibly with an "iterator:" prefix. */ |
110 const char *value; | 113 const char *value; |
111 | 114 |
112 /* The location of the use, as passed to GROUP's apply_iterator callback. | 115 /* The location of the use, as passed to GROUP's apply_iterator callback. |
192 { BARRIER, "cbarrier" }, | 195 { BARRIER, "cbarrier" }, |
193 { CODE_LABEL, "clabel" }, | 196 { CODE_LABEL, "clabel" }, |
194 { NOTE, "cnote" } | 197 { NOTE, "cnote" } |
195 }; | 198 }; |
196 | 199 |
200 /* Return the rtx code for NAME, or UNKNOWN if NAME isn't a valid rtx code. */ | |
201 | |
202 static rtx_code | |
203 maybe_find_code (const char *name) | |
204 { | |
205 for (int i = 0; i < NUM_RTX_CODE; i++) | |
206 if (strcmp (GET_RTX_NAME (i), name) == 0) | |
207 return (rtx_code) i; | |
208 | |
209 for (int i = 0; i < (signed)ARRAY_SIZE (compact_insn_names); i++) | |
210 if (strcmp (compact_insn_names[i].name, name) == 0) | |
211 return compact_insn_names[i].code; | |
212 | |
213 return UNKNOWN; | |
214 } | |
215 | |
197 /* Implementations of the iterator_group callbacks for codes. */ | 216 /* Implementations of the iterator_group callbacks for codes. */ |
198 | 217 |
199 static int | 218 static int |
200 find_code (const char *name) | 219 find_code (const char *name) |
201 { | 220 { |
202 int i; | 221 rtx_code code = maybe_find_code (name); |
203 | 222 if (code == UNKNOWN) |
204 for (i = 0; i < NUM_RTX_CODE; i++) | 223 fatal_with_file_and_line ("unknown rtx code `%s'", name); |
205 if (strcmp (GET_RTX_NAME (i), name) == 0) | 224 return code; |
206 return i; | |
207 | |
208 for (i = 0; i < (signed)ARRAY_SIZE (compact_insn_names); i++) | |
209 if (strcmp (compact_insn_names[i].name, name) == 0) | |
210 return compact_insn_names[i].code; | |
211 | |
212 fatal_with_file_and_line ("unknown rtx code `%s'", name); | |
213 } | 225 } |
214 | 226 |
215 static void | 227 static void |
216 apply_code_iterator (rtx x, unsigned int, int code) | 228 apply_code_iterator (rtx x, unsigned int, int code) |
217 { | 229 { |
270 apply_subst_iterator (rtx rt, unsigned int, int value) | 282 apply_subst_iterator (rtx rt, unsigned int, int value) |
271 { | 283 { |
272 rtx new_attr; | 284 rtx new_attr; |
273 rtvec attrs_vec, new_attrs_vec; | 285 rtvec attrs_vec, new_attrs_vec; |
274 int i; | 286 int i; |
275 if (value == 1) | 287 /* define_split has no attributes. */ |
288 if (value == 1 || GET_CODE (rt) == DEFINE_SPLIT) | |
276 return; | 289 return; |
277 gcc_assert (GET_CODE (rt) == DEFINE_INSN | 290 gcc_assert (GET_CODE (rt) == DEFINE_INSN |
291 || GET_CODE (rt) == DEFINE_INSN_AND_SPLIT | |
292 || GET_CODE (rt) == DEFINE_INSN_AND_REWRITE | |
278 || GET_CODE (rt) == DEFINE_EXPAND); | 293 || GET_CODE (rt) == DEFINE_EXPAND); |
279 | 294 |
280 attrs_vec = XVEC (rt, 4); | 295 int attrs = (GET_CODE (rt) == DEFINE_INSN_AND_SPLIT ? 7 |
296 : GET_CODE (rt) == DEFINE_INSN_AND_REWRITE ? 6 : 4); | |
297 attrs_vec = XVEC (rt, attrs); | |
281 | 298 |
282 /* If we've already added attribute 'current_iterator_name', then we | 299 /* If we've already added attribute 'current_iterator_name', then we |
283 have nothing to do now. */ | 300 have nothing to do now. */ |
284 if (attrs_vec) | 301 if (attrs_vec) |
285 { | 302 { |
307 new_attrs_vec = rtvec_alloc (GET_NUM_ELEM (attrs_vec) + 1); | 324 new_attrs_vec = rtvec_alloc (GET_NUM_ELEM (attrs_vec) + 1); |
308 memcpy (&new_attrs_vec->elem[0], &attrs_vec->elem[0], | 325 memcpy (&new_attrs_vec->elem[0], &attrs_vec->elem[0], |
309 GET_NUM_ELEM (attrs_vec) * sizeof (rtx)); | 326 GET_NUM_ELEM (attrs_vec) * sizeof (rtx)); |
310 new_attrs_vec->elem[GET_NUM_ELEM (attrs_vec)] = new_attr; | 327 new_attrs_vec->elem[GET_NUM_ELEM (attrs_vec)] = new_attr; |
311 } | 328 } |
312 XVEC (rt, 4) = new_attrs_vec; | 329 XVEC (rt, attrs) = new_attrs_vec; |
313 } | 330 } |
314 | 331 |
315 /* Map subst-attribute ATTR to subst iterator ITER. */ | 332 /* Map subst-attribute ATTR to subst iterator ITER. */ |
316 | 333 |
317 static void | 334 static void |
345 return iter_name; | 362 return iter_name; |
346 } | 363 } |
347 | 364 |
348 /* Map attribute string P to its current value. Return null if the attribute | 365 /* Map attribute string P to its current value. Return null if the attribute |
349 isn't known. If ITERATOR_OUT is nonnull, store the associated iterator | 366 isn't known. If ITERATOR_OUT is nonnull, store the associated iterator |
350 there. */ | 367 there. Report any errors against location LOC. */ |
351 | 368 |
352 static struct map_value * | 369 static struct map_value * |
353 map_attr_string (const char *p, mapping **iterator_out = 0) | 370 map_attr_string (file_location loc, const char *p, mapping **iterator_out = 0) |
354 { | 371 { |
355 const char *attr; | 372 const char *attr; |
356 struct mapping *iterator; | 373 struct mapping *iterator; |
357 unsigned int i; | 374 unsigned int i; |
358 struct mapping *m; | 375 struct mapping *m; |
359 struct map_value *v; | 376 struct map_value *v; |
360 int iterator_name_len; | 377 int iterator_name_len; |
378 struct map_value *res = NULL; | |
379 struct mapping *prev = NULL; | |
361 | 380 |
362 /* Peel off any "iterator:" prefix. Set ATTR to the start of the | 381 /* Peel off any "iterator:" prefix. Set ATTR to the start of the |
363 attribute name. */ | 382 attribute name. */ |
364 attr = strchr (p, ':'); | 383 attr = strchr (p, ':'); |
365 if (attr == 0) | 384 if (attr == 0) |
398 /* Find the attribute value associated with the current | 417 /* Find the attribute value associated with the current |
399 iterator value. */ | 418 iterator value. */ |
400 for (v = m->values; v; v = v->next) | 419 for (v = m->values; v; v = v->next) |
401 if (v->number == iterator->current_value->number) | 420 if (v->number == iterator->current_value->number) |
402 { | 421 { |
422 if (res && strcmp (v->string, res->string) != 0) | |
423 { | |
424 error_at (loc, "ambiguous attribute '%s'; could be" | |
425 " '%s' (via '%s:%s') or '%s' (via '%s:%s')", | |
426 attr, res->string, prev->name, attr, | |
427 v->string, iterator->name, attr); | |
428 return v; | |
429 } | |
403 if (iterator_out) | 430 if (iterator_out) |
404 *iterator_out = iterator; | 431 *iterator_out = iterator; |
405 return v; | 432 prev = iterator; |
433 res = v; | |
406 } | 434 } |
407 } | 435 } |
408 } | 436 } |
409 return NULL; | 437 return res; |
410 } | 438 } |
411 | 439 |
412 /* Apply the current iterator values to STRING. Return the new string | 440 /* Apply the current iterator values to STRING. Return the new string |
413 if any changes were needed, otherwise return STRING itself. */ | 441 if any changes were needed, otherwise return STRING itself. */ |
414 | 442 |
416 md_reader::apply_iterator_to_string (const char *string) | 444 md_reader::apply_iterator_to_string (const char *string) |
417 { | 445 { |
418 char *base, *copy, *p, *start, *end; | 446 char *base, *copy, *p, *start, *end; |
419 struct map_value *v; | 447 struct map_value *v; |
420 | 448 |
421 if (string == 0) | 449 if (string == 0 || string[0] == 0) |
422 return string; | 450 return string; |
423 | 451 |
452 file_location loc = get_md_ptr_loc (string)->loc; | |
424 base = p = copy = ASTRDUP (string); | 453 base = p = copy = ASTRDUP (string); |
425 while ((start = strchr (p, '<')) && (end = strchr (start, '>'))) | 454 while ((start = strchr (p, '<')) && (end = strchr (start, '>'))) |
426 { | 455 { |
427 p = start + 1; | 456 p = start + 1; |
428 | 457 |
429 *end = 0; | 458 *end = 0; |
430 v = map_attr_string (p); | 459 v = map_attr_string (loc, p); |
431 *end = '>'; | 460 *end = '>'; |
432 if (v == 0) | 461 if (v == 0) |
433 continue; | 462 continue; |
434 | 463 |
435 /* Add everything between the last copied byte and the '<', | 464 /* Add everything between the last copied byte and the '<', |
535 case DEFINE_COND_EXEC: | 564 case DEFINE_COND_EXEC: |
536 XSTR (x, 1) = add_condition_to_string (XSTR (x, 1), extra); | 565 XSTR (x, 1) = add_condition_to_string (XSTR (x, 1), extra); |
537 break; | 566 break; |
538 | 567 |
539 case DEFINE_INSN_AND_SPLIT: | 568 case DEFINE_INSN_AND_SPLIT: |
569 case DEFINE_INSN_AND_REWRITE: | |
540 XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra); | 570 XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra); |
541 XSTR (x, 4) = add_condition_to_string (XSTR (x, 4), extra); | 571 XSTR (x, 4) = add_condition_to_string (XSTR (x, 4), extra); |
542 break; | 572 break; |
543 | 573 |
544 default: | 574 default: |
555 attribute_use *ause; | 585 attribute_use *ause; |
556 unsigned int i; | 586 unsigned int i; |
557 | 587 |
558 FOR_EACH_VEC_ELT (attribute_uses, i, ause) | 588 FOR_EACH_VEC_ELT (attribute_uses, i, ause) |
559 { | 589 { |
560 v = map_attr_string (ause->value); | 590 v = map_attr_string (ause->loc, ause->value); |
561 if (!v) | 591 if (!v) |
562 fatal_with_file_and_line ("unknown iterator value `%s'", ause->value); | 592 fatal_with_file_and_line ("unknown iterator value `%s'", ause->value); |
563 ause->group->apply_iterator (ause->x, ause->index, | 593 ause->group->apply_iterator (ause->x, ause->index, |
564 ause->group->find_builtin (v->string)); | 594 ause->group->find_builtin (v->string)); |
565 } | 595 } |
618 switch (GET_CODE (x)) | 648 switch (GET_CODE (x)) |
619 { | 649 { |
620 case DEFINE_EXPAND: | 650 case DEFINE_EXPAND: |
621 case DEFINE_INSN: | 651 case DEFINE_INSN: |
622 case DEFINE_INSN_AND_SPLIT: | 652 case DEFINE_INSN_AND_SPLIT: |
653 case DEFINE_INSN_AND_REWRITE: | |
623 return true; | 654 return true; |
624 | 655 |
625 default: | 656 default: |
626 return false; | 657 return false; |
627 } | 658 } |
638 if (!named_rtx_p (original) || XSTR (original, 0)[0] != '@') | 669 if (!named_rtx_p (original) || XSTR (original, 0)[0] != '@') |
639 return NULL; | 670 return NULL; |
640 | 671 |
641 /* Remove the '@', so that no other code needs to worry about it. */ | 672 /* Remove the '@', so that no other code needs to worry about it. */ |
642 const char *name = XSTR (original, 0); | 673 const char *name = XSTR (original, 0); |
674 file_location loc = get_md_ptr_loc (name)->loc; | |
643 copy_md_ptr_loc (name + 1, name); | 675 copy_md_ptr_loc (name + 1, name); |
644 name += 1; | 676 name += 1; |
645 XSTR (original, 0) = name; | 677 XSTR (original, 0) = name; |
646 | 678 |
647 /* Build a copy of the name without the '<...>' attribute strings. | 679 /* Build a copy of the name without the '<...>' attribute strings. |
654 bool pending_underscore_p = false; | 686 bool pending_underscore_p = false; |
655 while ((start = strchr (base, '<')) && (end = strchr (start, '>'))) | 687 while ((start = strchr (base, '<')) && (end = strchr (start, '>'))) |
656 { | 688 { |
657 *end = 0; | 689 *end = 0; |
658 mapping *iterator; | 690 mapping *iterator; |
659 if (!map_attr_string (start + 1, &iterator)) | 691 if (!map_attr_string (loc, start + 1, &iterator)) |
660 fatal_with_file_and_line ("unknown iterator `%s'", start + 1); | 692 fatal_with_file_and_line ("unknown iterator `%s'", start + 1); |
661 *end = '>'; | 693 *end = '>'; |
662 | 694 |
663 /* Remove a trailing underscore, so that we don't end a name | 695 /* Remove a trailing underscore, so that we don't end a name |
664 with "_" or turn "_<...>_" into "__". */ | 696 with "_" or turn "_<...>_" into "__". */ |
1108 { | 1140 { |
1109 struct iterator_use iuse = {iterator, x, index}; | 1141 struct iterator_use iuse = {iterator, x, index}; |
1110 iterator_uses.safe_push (iuse); | 1142 iterator_uses.safe_push (iuse); |
1111 } | 1143 } |
1112 | 1144 |
1113 /* Record that X uses attribute VALUE, which must match a built-in | 1145 /* Record that X uses attribute VALUE at location LOC, where VALUE must |
1114 value from group GROUP. If the use is in an operand of X, INDEX | 1146 match a built-in value from group GROUP. If the use is in an operand |
1115 is the index of that operand, otherwise it is ignored. */ | 1147 of X, INDEX is the index of that operand, otherwise it is ignored. */ |
1116 | 1148 |
1117 static void | 1149 static void |
1118 record_attribute_use (struct iterator_group *group, rtx x, | 1150 record_attribute_use (struct iterator_group *group, file_location loc, rtx x, |
1119 unsigned int index, const char *value) | 1151 unsigned int index, const char *value) |
1120 { | 1152 { |
1121 struct attribute_use ause = {group, value, x, index}; | 1153 struct attribute_use ause = {group, loc, value, x, index}; |
1122 attribute_uses.safe_push (ause); | 1154 attribute_uses.safe_push (ause); |
1123 } | 1155 } |
1124 | 1156 |
1125 /* Interpret NAME as either a built-in value, iterator or attribute | 1157 /* Interpret NAME as either a built-in value, iterator or attribute |
1126 for group GROUP. X and INDEX are the values to pass to GROUP's | 1158 for group GROUP. X and INDEX are the values to pass to GROUP's |
1127 apply_iterator callback. */ | 1159 apply_iterator callback. LOC is the location of the use. */ |
1128 | 1160 |
1129 void | 1161 void |
1130 md_reader::record_potential_iterator_use (struct iterator_group *group, | 1162 md_reader::record_potential_iterator_use (struct iterator_group *group, |
1163 file_location loc, | |
1131 rtx x, unsigned int index, | 1164 rtx x, unsigned int index, |
1132 const char *name) | 1165 const char *name) |
1133 { | 1166 { |
1134 struct mapping *m; | 1167 struct mapping *m; |
1135 size_t len; | 1168 size_t len; |
1138 if (name[0] == '<' && name[len - 1] == '>') | 1171 if (name[0] == '<' && name[len - 1] == '>') |
1139 { | 1172 { |
1140 /* Copy the attribute string into permanent storage, without the | 1173 /* Copy the attribute string into permanent storage, without the |
1141 angle brackets around it. */ | 1174 angle brackets around it. */ |
1142 obstack_grow0 (&m_string_obstack, name + 1, len - 2); | 1175 obstack_grow0 (&m_string_obstack, name + 1, len - 2); |
1143 record_attribute_use (group, x, index, | 1176 record_attribute_use (group, loc, x, index, |
1144 XOBFINISH (&m_string_obstack, char *)); | 1177 XOBFINISH (&m_string_obstack, char *)); |
1145 } | 1178 } |
1146 else | 1179 else |
1147 { | 1180 { |
1148 m = (struct mapping *) htab_find (group->iterators, &name); | 1181 m = (struct mapping *) htab_find (group->iterators, &name); |
1277 if (!m) | 1310 if (!m) |
1278 { | 1311 { |
1279 m = add_mapping (&substs, subst_iters_table, attr_operands[1]); | 1312 m = add_mapping (&substs, subst_iters_table, attr_operands[1]); |
1280 end_ptr = &m->values; | 1313 end_ptr = &m->values; |
1281 end_ptr = add_map_value (end_ptr, 1, ""); | 1314 end_ptr = add_map_value (end_ptr, 1, ""); |
1282 end_ptr = add_map_value (end_ptr, 2, ""); | 1315 add_map_value (end_ptr, 2, ""); |
1283 | 1316 |
1284 add_define_attr_for_define_subst (attr_operands[1], queue); | 1317 add_define_attr_for_define_subst (attr_operands[1], queue); |
1285 } | 1318 } |
1286 | 1319 |
1287 m = add_mapping (&substs, subst_attrs_table, attr_operands[0]); | 1320 m = add_mapping (&substs, subst_attrs_table, attr_operands[0]); |
1288 end_ptr = &m->values; | 1321 end_ptr = &m->values; |
1289 end_ptr = add_map_value (end_ptr, 1, attr_operands[2]); | 1322 end_ptr = add_map_value (end_ptr, 1, attr_operands[2]); |
1290 end_ptr = add_map_value (end_ptr, 2, attr_operands[3]); | 1323 add_map_value (end_ptr, 2, attr_operands[3]); |
1291 } | 1324 } |
1292 | 1325 |
1293 /* Check newly-created code iterator ITERATOR to see whether every code has the | 1326 /* Check newly-created code iterator ITERATOR to see whether every code has the |
1294 same format. */ | 1327 same format. */ |
1295 | 1328 |
1301 | 1334 |
1302 bellwether = (enum rtx_code) iterator->values->number; | 1335 bellwether = (enum rtx_code) iterator->values->number; |
1303 for (v = iterator->values->next; v != 0; v = v->next) | 1336 for (v = iterator->values->next; v != 0; v = v->next) |
1304 if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0) | 1337 if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0) |
1305 fatal_with_file_and_line ("code iterator `%s' combines " | 1338 fatal_with_file_and_line ("code iterator `%s' combines " |
1306 "different rtx formats", iterator->name); | 1339 "`%s' and `%s', which have different " |
1340 "rtx formats", iterator->name, | |
1341 GET_RTX_NAME (bellwether), | |
1342 GET_RTX_NAME (v->number)); | |
1343 } | |
1344 | |
1345 /* Check that all values of attribute ATTR are rtx codes that have a | |
1346 consistent format. Return a representative code. */ | |
1347 | |
1348 static rtx_code | |
1349 check_code_attribute (mapping *attr) | |
1350 { | |
1351 rtx_code bellwether = UNKNOWN; | |
1352 for (map_value *v = attr->values; v != 0; v = v->next) | |
1353 { | |
1354 rtx_code code = maybe_find_code (v->string); | |
1355 if (code == UNKNOWN) | |
1356 fatal_with_file_and_line ("code attribute `%s' contains " | |
1357 "unrecognized rtx code `%s'", | |
1358 attr->name, v->string); | |
1359 if (bellwether == UNKNOWN) | |
1360 bellwether = code; | |
1361 else if (strcmp (GET_RTX_FORMAT (bellwether), | |
1362 GET_RTX_FORMAT (code)) != 0) | |
1363 fatal_with_file_and_line ("code attribute `%s' combines " | |
1364 "`%s' and `%s', which have different " | |
1365 "rtx formats", attr->name, | |
1366 GET_RTX_NAME (bellwether), | |
1367 GET_RTX_NAME (code)); | |
1368 } | |
1369 return bellwether; | |
1307 } | 1370 } |
1308 | 1371 |
1309 /* Read an rtx-related declaration from the MD file, given that it | 1372 /* Read an rtx-related declaration from the MD file, given that it |
1310 starts with directive name RTX_NAME. Return true if it expands to | 1373 starts with directive name RTX_NAME. Return true if it expands to |
1311 one or more rtxes (as defined by rtx.def). When returning true, | 1374 one or more rtxes (as defined by rtx.def). When returning true, |
1462 if (strcmp (string, GET_REG_NOTE_NAME (i)) == 0) | 1525 if (strcmp (string, GET_REG_NOTE_NAME (i)) == 0) |
1463 return i; | 1526 return i; |
1464 fatal_with_file_and_line ("unrecognized REG_NOTE name: `%s'", string); | 1527 fatal_with_file_and_line ("unrecognized REG_NOTE name: `%s'", string); |
1465 } | 1528 } |
1466 | 1529 |
1530 /* Allocate an rtx for code NAME. If NAME is a code iterator or code | |
1531 attribute, record its use for later and use one of its possible | |
1532 values as an interim rtx code. */ | |
1533 | |
1534 rtx | |
1535 rtx_reader::rtx_alloc_for_name (const char *name) | |
1536 { | |
1537 #ifdef GENERATOR_FILE | |
1538 size_t len = strlen (name); | |
1539 if (name[0] == '<' && name[len - 1] == '>') | |
1540 { | |
1541 /* Copy the attribute string into permanent storage, without the | |
1542 angle brackets around it. */ | |
1543 obstack *strings = get_string_obstack (); | |
1544 obstack_grow0 (strings, name + 1, len - 2); | |
1545 char *deferred_name = XOBFINISH (strings, char *); | |
1546 | |
1547 /* Find the name of the attribute. */ | |
1548 const char *attr = strchr (deferred_name, ':'); | |
1549 if (!attr) | |
1550 attr = deferred_name; | |
1551 | |
1552 /* Find the attribute itself. */ | |
1553 mapping *m = (mapping *) htab_find (codes.attrs, &attr); | |
1554 if (!m) | |
1555 fatal_with_file_and_line ("unknown code attribute `%s'", attr); | |
1556 | |
1557 /* Pick the first possible code for now, and record the attribute | |
1558 use for later. */ | |
1559 rtx x = rtx_alloc (check_code_attribute (m)); | |
1560 record_attribute_use (&codes, get_current_location (), | |
1561 x, 0, deferred_name); | |
1562 return x; | |
1563 } | |
1564 | |
1565 mapping *iterator = (mapping *) htab_find (codes.iterators, &name); | |
1566 if (iterator != 0) | |
1567 { | |
1568 /* Pick the first possible code for now, and record the iterator | |
1569 use for later. */ | |
1570 rtx x = rtx_alloc (rtx_code (iterator->values->number)); | |
1571 record_iterator_use (iterator, x, 0); | |
1572 return x; | |
1573 } | |
1574 #endif | |
1575 | |
1576 return rtx_alloc (rtx_code (codes.find_builtin (name))); | |
1577 } | |
1578 | |
1467 /* Subroutine of read_rtx and read_nested_rtx. CODE_NAME is the name of | 1579 /* Subroutine of read_rtx and read_nested_rtx. CODE_NAME is the name of |
1468 either an rtx code or a code iterator. Parse the rest of the rtx and | 1580 either an rtx code or a code iterator. Parse the rest of the rtx and |
1469 return it. */ | 1581 return it. */ |
1470 | 1582 |
1471 rtx | 1583 rtx |
1472 rtx_reader::read_rtx_code (const char *code_name) | 1584 rtx_reader::read_rtx_code (const char *code_name) |
1473 { | 1585 { |
1474 RTX_CODE code; | 1586 RTX_CODE code; |
1475 struct mapping *iterator = NULL; | |
1476 const char *format_ptr; | 1587 const char *format_ptr; |
1477 struct md_name name; | 1588 struct md_name name; |
1478 rtx return_rtx; | 1589 rtx return_rtx; |
1479 int c; | 1590 int c; |
1480 long reuse_id = -1; | 1591 long reuse_id = -1; |
1504 gcc_assert (idx < m_reuse_rtx_by_id.length ()); | 1615 gcc_assert (idx < m_reuse_rtx_by_id.length ()); |
1505 return_rtx = m_reuse_rtx_by_id[idx]; | 1616 return_rtx = m_reuse_rtx_by_id[idx]; |
1506 return return_rtx; | 1617 return return_rtx; |
1507 } | 1618 } |
1508 | 1619 |
1509 /* If this code is an iterator, build the rtx using the iterator's | |
1510 first value. */ | |
1511 #ifdef GENERATOR_FILE | |
1512 iterator = (struct mapping *) htab_find (codes.iterators, &code_name); | |
1513 if (iterator != 0) | |
1514 code = (enum rtx_code) iterator->values->number; | |
1515 else | |
1516 code = (enum rtx_code) codes.find_builtin (code_name); | |
1517 #else | |
1518 code = (enum rtx_code) codes.find_builtin (code_name); | |
1519 #endif | |
1520 | |
1521 /* If we end up with an insn expression then we free this space below. */ | 1620 /* If we end up with an insn expression then we free this space below. */ |
1522 return_rtx = rtx_alloc (code); | 1621 return_rtx = rtx_alloc_for_name (code_name); |
1622 code = GET_CODE (return_rtx); | |
1523 format_ptr = GET_RTX_FORMAT (code); | 1623 format_ptr = GET_RTX_FORMAT (code); |
1524 memset (return_rtx, 0, RTX_CODE_SIZE (code)); | 1624 memset (return_rtx, 0, RTX_CODE_SIZE (code)); |
1525 PUT_CODE (return_rtx, code); | 1625 PUT_CODE (return_rtx, code); |
1526 | 1626 |
1527 if (reuse_id != -1) | 1627 if (reuse_id != -1) |
1528 { | 1628 { |
1529 /* Store away for later reuse. */ | 1629 /* Store away for later reuse. */ |
1530 m_reuse_rtx_by_id.safe_grow_cleared (reuse_id + 1); | 1630 m_reuse_rtx_by_id.safe_grow_cleared (reuse_id + 1); |
1531 m_reuse_rtx_by_id[reuse_id] = return_rtx; | 1631 m_reuse_rtx_by_id[reuse_id] = return_rtx; |
1532 } | 1632 } |
1533 | |
1534 if (iterator) | |
1535 record_iterator_use (iterator, return_rtx, 0); | |
1536 | 1633 |
1537 /* Check for flags. */ | 1634 /* Check for flags. */ |
1538 read_flags (return_rtx); | 1635 read_flags (return_rtx); |
1539 | 1636 |
1540 /* Read REG_NOTE names for EXPR_LIST and INSN_LIST. */ | 1637 /* Read REG_NOTE names for EXPR_LIST and INSN_LIST. */ |
1558 store the mode in the rtx. */ | 1655 store the mode in the rtx. */ |
1559 | 1656 |
1560 c = read_skip_spaces (); | 1657 c = read_skip_spaces (); |
1561 if (c == ':') | 1658 if (c == ':') |
1562 { | 1659 { |
1563 read_name (&name); | 1660 file_location loc = read_name (&name); |
1564 record_potential_iterator_use (&modes, return_rtx, 0, name.string); | 1661 record_potential_iterator_use (&modes, loc, return_rtx, 0, name.string); |
1565 } | 1662 } |
1566 else | 1663 else |
1567 unread_char (c); | 1664 unread_char (c); |
1568 | 1665 |
1569 if (INSN_CHAIN_CODE_P (code)) | 1666 if (INSN_CHAIN_CODE_P (code)) |
1760 omitted, treating them in the same way as empty strings. */ | 1857 omitted, treating them in the same way as empty strings. */ |
1761 XSTR (return_rtx, idx) = (format_ptr[idx] == 'S' ? NULL : ""); | 1858 XSTR (return_rtx, idx) = (format_ptr[idx] == 'S' ? NULL : ""); |
1762 break; | 1859 break; |
1763 } | 1860 } |
1764 | 1861 |
1765 /* The output template slot of a DEFINE_INSN, | 1862 /* The output template slot of a DEFINE_INSN, DEFINE_INSN_AND_SPLIT, |
1766 DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically | 1863 DEFINE_INSN_AND_REWRITE or DEFINE_PEEPHOLE automatically |
1767 gets a star inserted as its first character, if it is | 1864 gets a star inserted as its first character, if it is |
1768 written with a brace block instead of a string constant. */ | 1865 written with a brace block instead of a string constant. */ |
1769 star_if_braced = (format_ptr[idx] == 'T'); | 1866 star_if_braced = (format_ptr[idx] == 'T'); |
1770 | 1867 |
1771 stringbuf = read_string (star_if_braced); | 1868 stringbuf = read_string (star_if_braced); |
1778 given name is blank. These are only for define_insn and | 1875 given name is blank. These are only for define_insn and |
1779 define_insn_and_split, to aid debugging. */ | 1876 define_insn_and_split, to aid debugging. */ |
1780 if (*stringbuf == '\0' | 1877 if (*stringbuf == '\0' |
1781 && idx == 0 | 1878 && idx == 0 |
1782 && (GET_CODE (return_rtx) == DEFINE_INSN | 1879 && (GET_CODE (return_rtx) == DEFINE_INSN |
1783 || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT)) | 1880 || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT |
1881 || GET_CODE (return_rtx) == DEFINE_INSN_AND_REWRITE)) | |
1784 { | 1882 { |
1883 const char *old_stringbuf = stringbuf; | |
1785 struct obstack *string_obstack = get_string_obstack (); | 1884 struct obstack *string_obstack = get_string_obstack (); |
1786 char line_name[20]; | 1885 char line_name[20]; |
1787 const char *read_md_filename = get_filename (); | 1886 const char *read_md_filename = get_filename (); |
1788 const char *fn = (read_md_filename ? read_md_filename : "rtx"); | 1887 const char *fn = (read_md_filename ? read_md_filename : "rtx"); |
1789 const char *slash; | 1888 const char *slash; |
1793 obstack_1grow (string_obstack, '*'); | 1892 obstack_1grow (string_obstack, '*'); |
1794 obstack_grow (string_obstack, fn, strlen (fn)); | 1893 obstack_grow (string_obstack, fn, strlen (fn)); |
1795 sprintf (line_name, ":%d", get_lineno ()); | 1894 sprintf (line_name, ":%d", get_lineno ()); |
1796 obstack_grow (string_obstack, line_name, strlen (line_name)+1); | 1895 obstack_grow (string_obstack, line_name, strlen (line_name)+1); |
1797 stringbuf = XOBFINISH (string_obstack, char *); | 1896 stringbuf = XOBFINISH (string_obstack, char *); |
1897 copy_md_ptr_loc (stringbuf, old_stringbuf); | |
1798 } | 1898 } |
1799 | 1899 |
1800 /* Find attr-names in the string. */ | 1900 /* Find attr-names in the string. */ |
1801 char *str; | 1901 char *str; |
1802 char *start, *end, *ptr; | 1902 char *start, *end, *ptr; |
1864 break; | 1964 break; |
1865 | 1965 |
1866 case 'i': | 1966 case 'i': |
1867 case 'n': | 1967 case 'n': |
1868 case 'p': | 1968 case 'p': |
1869 /* Can be an iterator or an integer constant. */ | 1969 { |
1870 read_name (&name); | 1970 /* Can be an iterator or an integer constant. */ |
1871 record_potential_iterator_use (&ints, return_rtx, idx, name.string); | 1971 file_location loc = read_name (&name); |
1872 break; | 1972 record_potential_iterator_use (&ints, loc, return_rtx, idx, |
1973 name.string); | |
1974 break; | |
1975 } | |
1873 | 1976 |
1874 case 'r': | 1977 case 'r': |
1875 read_name (&name); | 1978 read_name (&name); |
1876 validate_const_int (name.string); | 1979 validate_const_int (name.string); |
1877 set_regno_raw (return_rtx, atoi (name.string), 1); | 1980 set_regno_raw (return_rtx, atoi (name.string), 1); |