Mercurial > hg > CbC > CbC_gcc
comparison gcc/genrecog.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Generate code from machine description to recognize rtl as insns. | 1 /* Generate code from machine description to recognize rtl as insns. |
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1997, 1998, | 2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1997, 1998, |
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 | 3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 |
4 Free Software Foundation, Inc. | 4 Free Software Foundation, Inc. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it | 8 GCC is free software; you can redistribute it and/or modify it |
54 #include "system.h" | 54 #include "system.h" |
55 #include "coretypes.h" | 55 #include "coretypes.h" |
56 #include "tm.h" | 56 #include "tm.h" |
57 #include "rtl.h" | 57 #include "rtl.h" |
58 #include "errors.h" | 58 #include "errors.h" |
59 #include "read-md.h" | |
59 #include "gensupport.h" | 60 #include "gensupport.h" |
60 | 61 |
61 #define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \ | 62 #define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \ |
62 printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER)) | 63 printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER)) |
63 | 64 |
167 | 168 |
168 static int max_depth; | 169 static int max_depth; |
169 | 170 |
170 /* The line number of the start of the pattern currently being processed. */ | 171 /* The line number of the start of the pattern currently being processed. */ |
171 static int pattern_lineno; | 172 static int pattern_lineno; |
172 | |
173 /* Count of errors. */ | |
174 static int error_count; | |
175 | 173 |
176 /* Predicate handling. | 174 /* Predicate handling. |
177 | 175 |
178 We construct from the machine description a table mapping each | 176 We construct from the machine description a table mapping each |
179 predicate to a list of the rtl codes it can possibly match. The | 177 predicate to a list of the rtl codes it can possibly match. The |
286 const char *next_code = XSTR (exp, 0); | 284 const char *next_code = XSTR (exp, 0); |
287 const char *code; | 285 const char *code; |
288 | 286 |
289 if (*next_code == '\0') | 287 if (*next_code == '\0') |
290 { | 288 { |
291 message_with_line (pattern_lineno, "empty match_code expression"); | 289 error_with_line (pattern_lineno, "empty match_code expression"); |
292 error_count++; | |
293 break; | 290 break; |
294 } | 291 } |
295 | 292 |
296 while ((code = scan_comma_elt (&next_code)) != 0) | 293 while ((code = scan_comma_elt (&next_code)) != 0) |
297 { | 294 { |
306 found_it = 1; | 303 found_it = 1; |
307 break; | 304 break; |
308 } | 305 } |
309 if (!found_it) | 306 if (!found_it) |
310 { | 307 { |
311 message_with_line (pattern_lineno, "match_code \"%.*s\" matches nothing", | 308 error_with_line (pattern_lineno, |
312 (int) n, code); | 309 "match_code \"%.*s\" matches nothing", |
313 error_count ++; | 310 (int) n, code); |
314 for (i = 0; i < NUM_RTX_CODE; i++) | 311 for (i = 0; i < NUM_RTX_CODE; i++) |
315 if (!strncasecmp (code, GET_RTX_NAME (i), n) | 312 if (!strncasecmp (code, GET_RTX_NAME (i), n) |
316 && GET_RTX_NAME (i)[n] == '\0' | 313 && GET_RTX_NAME (i)[n] == '\0' |
317 && !did_you_mean_codes[i]) | 314 && !did_you_mean_codes[i]) |
318 { | 315 { |
330 disallows, and is indeterminate for the codes that it does allow. */ | 327 disallows, and is indeterminate for the codes that it does allow. */ |
331 { | 328 { |
332 struct pred_data *p = lookup_predicate (XSTR (exp, 1)); | 329 struct pred_data *p = lookup_predicate (XSTR (exp, 1)); |
333 if (!p) | 330 if (!p) |
334 { | 331 { |
335 message_with_line (pattern_lineno, | 332 error_with_line (pattern_lineno, |
336 "reference to unknown predicate '%s'", | 333 "reference to unknown predicate '%s'", |
337 XSTR (exp, 1)); | 334 XSTR (exp, 1)); |
338 error_count++; | |
339 break; | 335 break; |
340 } | 336 } |
341 for (i = 0; i < NUM_RTX_CODE; i++) | 337 for (i = 0; i < NUM_RTX_CODE; i++) |
342 codes[i] = p->codes[i] ? I : N; | 338 codes[i] = p->codes[i] ? I : N; |
343 } | 339 } |
348 /* (match_test WHATEVER) is completely indeterminate. */ | 344 /* (match_test WHATEVER) is completely indeterminate. */ |
349 memset (codes, I, NUM_RTX_CODE); | 345 memset (codes, I, NUM_RTX_CODE); |
350 break; | 346 break; |
351 | 347 |
352 default: | 348 default: |
353 message_with_line (pattern_lineno, | 349 error_with_line (pattern_lineno, |
354 "'%s' cannot be used in a define_predicate expression", | 350 "'%s' cannot be used in a define_predicate expression", |
355 GET_RTX_NAME (GET_CODE (exp))); | 351 GET_RTX_NAME (GET_CODE (exp))); |
356 error_count++; | |
357 memset (codes, I, NUM_RTX_CODE); | 352 memset (codes, I, NUM_RTX_CODE); |
358 break; | 353 break; |
359 } | 354 } |
360 } | 355 } |
361 | 356 |
631 return; | 626 return; |
632 case MATCH_DUP: | 627 case MATCH_DUP: |
633 case MATCH_OP_DUP: | 628 case MATCH_OP_DUP: |
634 case MATCH_PAR_DUP: | 629 case MATCH_PAR_DUP: |
635 if (find_operand (insn, XINT (pattern, 0), pattern) == pattern) | 630 if (find_operand (insn, XINT (pattern, 0), pattern) == pattern) |
636 { | 631 error_with_line (pattern_lineno, |
637 message_with_line (pattern_lineno, | 632 "operand %i duplicated before defined", |
638 "operand %i duplicated before defined", | 633 XINT (pattern, 0)); |
639 XINT (pattern, 0)); | |
640 error_count++; | |
641 } | |
642 break; | 634 break; |
643 case MATCH_OPERAND: | 635 case MATCH_OPERAND: |
644 case MATCH_OPERATOR: | 636 case MATCH_OPERATOR: |
645 { | 637 { |
646 const char *pred_name = XSTR (pattern, 1); | 638 const char *pred_name = XSTR (pattern, 1); |
692 we'd better have a matching input operand. */ | 684 we'd better have a matching input operand. */ |
693 else if (constraints0 == '=' | 685 else if (constraints0 == '=' |
694 && find_matching_operand (insn, XINT (pattern, 0))) | 686 && find_matching_operand (insn, XINT (pattern, 0))) |
695 ; | 687 ; |
696 else | 688 else |
697 { | 689 error_with_line (pattern_lineno, |
698 message_with_line (pattern_lineno, | 690 "operand %d missing in-out reload", |
699 "operand %d missing in-out reload", | 691 XINT (pattern, 0)); |
700 XINT (pattern, 0)); | |
701 error_count++; | |
702 } | |
703 } | 692 } |
704 else if (constraints0 != '=' && constraints0 != '+') | 693 else if (constraints0 != '=' && constraints0 != '+') |
705 { | 694 error_with_line (pattern_lineno, |
706 message_with_line (pattern_lineno, | 695 "operand %d missing output reload", |
707 "operand %d missing output reload", | 696 XINT (pattern, 0)); |
708 XINT (pattern, 0)); | |
709 error_count++; | |
710 } | |
711 } | 697 } |
712 } | 698 } |
713 | 699 |
714 /* Allowing non-lvalues in destinations -- particularly CONST_INT -- | 700 /* Allowing non-lvalues in destinations -- particularly CONST_INT -- |
715 while not likely to occur at runtime, results in less efficient | 701 while not likely to occur at runtime, results in less efficient |
779 ; | 765 ; |
780 | 766 |
781 /* The operands of a SET must have the same mode unless one | 767 /* The operands of a SET must have the same mode unless one |
782 is VOIDmode. */ | 768 is VOIDmode. */ |
783 else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode) | 769 else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode) |
784 { | 770 error_with_line (pattern_lineno, |
785 message_with_line (pattern_lineno, | 771 "mode mismatch in set: %smode vs %smode", |
786 "mode mismatch in set: %smode vs %smode", | 772 GET_MODE_NAME (dmode), GET_MODE_NAME (smode)); |
787 GET_MODE_NAME (dmode), GET_MODE_NAME (smode)); | |
788 error_count++; | |
789 } | |
790 | 773 |
791 /* If only one of the operands is VOIDmode, and PC or CC0 is | 774 /* If only one of the operands is VOIDmode, and PC or CC0 is |
792 not involved, it's probably a mistake. */ | 775 not involved, it's probably a mistake. */ |
793 else if (dmode != smode | 776 else if (dmode != smode |
794 && GET_CODE (dest) != PC | 777 && GET_CODE (dest) != PC |
825 validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0); | 808 validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0); |
826 return; | 809 return; |
827 | 810 |
828 case LABEL_REF: | 811 case LABEL_REF: |
829 if (GET_MODE (XEXP (pattern, 0)) != VOIDmode) | 812 if (GET_MODE (XEXP (pattern, 0)) != VOIDmode) |
830 { | 813 error_with_line (pattern_lineno, |
831 message_with_line (pattern_lineno, | 814 "operand to label_ref %smode not VOIDmode", |
832 "operand to label_ref %smode not VOIDmode", | 815 GET_MODE_NAME (GET_MODE (XEXP (pattern, 0)))); |
833 GET_MODE_NAME (GET_MODE (XEXP (pattern, 0)))); | |
834 error_count++; | |
835 } | |
836 break; | 816 break; |
837 | 817 |
838 default: | 818 default: |
839 break; | 819 break; |
840 } | 820 } |
1491 /* In this case, replace OLD with ADD. */ | 1471 /* In this case, replace OLD with ADD. */ |
1492 old->u.insn = add->u.insn; | 1472 old->u.insn = add->u.insn; |
1493 } | 1473 } |
1494 else | 1474 else |
1495 { | 1475 { |
1496 message_with_line (add->u.insn.lineno, "`%s' matches `%s'", | 1476 error_with_line (add->u.insn.lineno, "`%s' matches `%s'", |
1497 get_insn_name (add->u.insn.code_number), | 1477 get_insn_name (add->u.insn.code_number), |
1498 get_insn_name (old->u.insn.code_number)); | 1478 get_insn_name (old->u.insn.code_number)); |
1499 message_with_line (old->u.insn.lineno, "previous definition of `%s'", | 1479 message_with_line (old->u.insn.lineno, "previous definition of `%s'", |
1500 get_insn_name (old->u.insn.code_number)); | 1480 get_insn_name (old->u.insn.code_number)); |
1501 error_count++; | |
1502 } | 1481 } |
1503 } | 1482 } |
1504 | 1483 |
1505 /* Merge two decision trees OLDH and ADDH, modifying OLDH destructively. */ | 1484 /* Merge two decision trees OLDH and ADDH, modifying OLDH destructively. */ |
1506 | 1485 |
1780 change_state (const char *oldpos, const char *newpos, const char *indent) | 1759 change_state (const char *oldpos, const char *newpos, const char *indent) |
1781 { | 1760 { |
1782 int odepth = strlen (oldpos); | 1761 int odepth = strlen (oldpos); |
1783 int ndepth = strlen (newpos); | 1762 int ndepth = strlen (newpos); |
1784 int depth; | 1763 int depth; |
1785 int old_has_insn, new_has_insn; | |
1786 | 1764 |
1787 /* Pop up as many levels as necessary. */ | 1765 /* Pop up as many levels as necessary. */ |
1788 for (depth = odepth; strncmp (oldpos, newpos, depth) != 0; --depth) | 1766 for (depth = odepth; strncmp (oldpos, newpos, depth) != 0; --depth) |
1789 continue; | 1767 continue; |
1790 | |
1791 /* Hunt for the last [A-Z] in both strings. */ | |
1792 for (old_has_insn = odepth - 1; old_has_insn >= 0; --old_has_insn) | |
1793 if (ISUPPER (oldpos[old_has_insn])) | |
1794 break; | |
1795 for (new_has_insn = ndepth - 1; new_has_insn >= 0; --new_has_insn) | |
1796 if (ISUPPER (newpos[new_has_insn])) | |
1797 break; | |
1798 | 1768 |
1799 /* Go down to desired level. */ | 1769 /* Go down to desired level. */ |
1800 while (depth < ndepth) | 1770 while (depth < ndepth) |
1801 { | 1771 { |
1802 /* It's a different insn from the first one. */ | 1772 /* It's a different insn from the first one. */ |
2476 #include \"recog.h\"\n\ | 2446 #include \"recog.h\"\n\ |
2477 #include \"output.h\"\n\ | 2447 #include \"output.h\"\n\ |
2478 #include \"flags.h\"\n\ | 2448 #include \"flags.h\"\n\ |
2479 #include \"hard-reg-set.h\"\n\ | 2449 #include \"hard-reg-set.h\"\n\ |
2480 #include \"resource.h\"\n\ | 2450 #include \"resource.h\"\n\ |
2481 #include \"toplev.h\"\n\ | 2451 #include \"diagnostic-core.h\"\n\ |
2482 #include \"reload.h\"\n\ | 2452 #include \"reload.h\"\n\ |
2483 #include \"regs.h\"\n\ | 2453 #include \"regs.h\"\n\ |
2484 #include \"tm-constrs.h\"\n\ | 2454 #include \"tm-constrs.h\"\n\ |
2485 \n"); | 2455 \n"); |
2486 | 2456 |
2727 | 2697 |
2728 memset (&recog_tree, 0, sizeof recog_tree); | 2698 memset (&recog_tree, 0, sizeof recog_tree); |
2729 memset (&split_tree, 0, sizeof split_tree); | 2699 memset (&split_tree, 0, sizeof split_tree); |
2730 memset (&peephole2_tree, 0, sizeof peephole2_tree); | 2700 memset (&peephole2_tree, 0, sizeof peephole2_tree); |
2731 | 2701 |
2732 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) | 2702 if (!init_rtx_reader_args (argc, argv)) |
2733 return (FATAL_EXIT_CODE); | 2703 return (FATAL_EXIT_CODE); |
2734 | 2704 |
2735 next_insn_code = 0; | 2705 next_insn_code = 0; |
2736 | 2706 |
2737 write_header (); | 2707 write_header (); |
2768 default: | 2738 default: |
2769 /* do nothing */; | 2739 /* do nothing */; |
2770 } | 2740 } |
2771 } | 2741 } |
2772 | 2742 |
2773 if (error_count || have_error) | 2743 if (have_error) |
2774 return FATAL_EXIT_CODE; | 2744 return FATAL_EXIT_CODE; |
2775 | 2745 |
2776 puts ("\n\n"); | 2746 puts ("\n\n"); |
2777 | 2747 |
2778 process_tree (&recog_tree, RECOG); | 2748 process_tree (&recog_tree, RECOG); |
2895 debug_decision_1 (d, indent); | 2865 debug_decision_1 (d, indent); |
2896 for (n = d->success.first; n ; n = n->next) | 2866 for (n = d->success.first; n ; n = n->next) |
2897 debug_decision_0 (n, indent + 2, maxdepth - 1); | 2867 debug_decision_0 (n, indent + 2, maxdepth - 1); |
2898 } | 2868 } |
2899 | 2869 |
2900 void | 2870 DEBUG_FUNCTION void |
2901 debug_decision (struct decision *d) | 2871 debug_decision (struct decision *d) |
2902 { | 2872 { |
2903 debug_decision_0 (d, 0, 1000000); | 2873 debug_decision_0 (d, 0, 1000000); |
2904 } | 2874 } |
2905 | 2875 |
2906 void | 2876 DEBUG_FUNCTION void |
2907 debug_decision_list (struct decision *d) | 2877 debug_decision_list (struct decision *d) |
2908 { | 2878 { |
2909 while (d) | 2879 while (d) |
2910 { | 2880 { |
2911 debug_decision_0 (d, 0, 0); | 2881 debug_decision_0 (d, 0, 0); |