1 /* Generate code from machine description to recognize rtl as insns.
2 Copyright (C) 1987-1991 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* This program is used to produce insn-recog.c, which contains
22 a function called `recog' plus its subroutines.
23 These functions contain a decision tree
24 that recognizes whether an rtx, the argument given to recog,
25 is a valid instruction.
27 recog returns -1 if the rtx is not valid.
28 If the rtx is valid, recog returns a nonnegative number
29 which is the insn code number for the pattern that matched.
30 This is the same as the order in the machine description of the
31 entry that matched. This number can be used as an index into various
32 insn_* tables, such as insn_templates, insn_outfun, and insn_n_operands
33 (found in insn-output.c).
35 The third argument to recog is an optional pointer to an int.
36 If present, recog will accept a pattern if it matches except for
37 missing CLOBBER expressions at the end. In that case, the value
38 pointed to by the optional pointer will be set to the number of
39 CLOBBERs that need to be added (it should be initialized to zero by
40 the caller). If it is set nonzero, the caller should allocate a
41 PARALLEL of the appropriate size, copy the initial entries, and call
42 add_clobbers (found in insn-emit.c) to fill in the CLOBBERs.
44 This program also generates the function `split_insns',
45 which returns 0 if the rtl could not be split, or
46 it returns the split rtl in a SEQUENCE. */
53 static struct obstack obstack;
54 struct obstack *rtl_obstack = &obstack;
56 #define obstack_chunk_alloc xmalloc
57 #define obstack_chunk_free free
61 /* Data structure for decision tree for recognizing
62 legitimate instructions. */
70 enum machine_mode mode;
73 int num_clobbers_to_add;
74 struct decision *next;
75 struct decision *success;
78 int test_elt_zero_int;
83 struct decision *afterward;
88 int subroutine_number;
89 /* Used for DEFINE_SPLITs. */
94 #define SUBROUTINE_THRESHOLD 50
96 static int next_subroutine_number;
98 /* We can write two types of subroutines: One for insn recognition and
99 one to split insns. This defines which type is being written. */
101 enum routine_type {RECOG, SPLIT};
103 static int try_merge_1 ();
104 static int no_same_mode ();
105 static int same_codes ();
106 static int same_modes ();
113 x = XVECEXP (top, 0, 3);
114 if (test_code (GET_CODE (x))
115 && test_mode (MODE (x))
118 else if (next one...)
132 x = XEXP (stack[depth], 0);
136 x = XEXP (stack[depth], 1);
141 static int next_number;
143 static int next_insn_code;
145 static int next_index;
148 static struct decision *add_to_sequence ();
149 static struct decision *merge_trees ();
150 static struct decision *try_merge_2 ();
151 static void write_subroutine ();
152 static void print_code ();
153 static void clear_codes ();
154 static void clear_modes ();
155 static void change_state ();
156 static void write_tree ();
157 static char *copystr ();
158 static char *concat ();
159 static void fatal ();
161 static void mybzero ();
163 static struct decision *first;
165 /* Construct and return a sequence of decisions
166 that will recognize INSN. */
168 static struct decision *
169 make_insn_sequence (insn)
173 char *c_test = XSTR (insn, 2);
174 struct decision *last;
176 if (XVECLEN (insn, 1) == 1)
177 x = XVECEXP (insn, 1, 0);
180 x = rtx_alloc (PARALLEL);
181 XVEC (x, 0) = XVEC (insn, 1);
182 PUT_MODE (x, VOIDmode);
185 last = add_to_sequence (x, 0, "");
188 last->c_test = c_test;
189 last->insn_code_number = next_insn_code;
190 last->num_clobbers_to_add = 0;
192 /* If X is a PARALLEL, see if it ends with a group of CLOBBERs of (hard)
193 registers or MATCH_SCRATCHes. If so, set up to recognize the pattern
194 without these CLOBBERs. */
196 if (GET_CODE (x) == PARALLEL)
200 for (i = XVECLEN (x, 0); i > 0; i--)
201 if (GET_CODE (XVECEXP (x, 0, i - 1)) != CLOBBER
202 || (GET_CODE (XEXP (XVECEXP (x, 0, i - 1), 0)) != REG
203 && GET_CODE (XEXP (XVECEXP (x, 0, i - 1), 0)) != MATCH_SCRATCH))
206 if (i != XVECLEN (x, 0))
209 struct decision *previous_first = first;
212 new = XVECEXP (x, 0, 0);
217 new = rtx_alloc (PARALLEL);
218 XVEC (new, 0) = rtvec_alloc (i);
219 for (j = i - 1; j >= 0; j--)
220 XVECEXP (new, 0, j) = XVECEXP (x, 0, j);
223 last = add_to_sequence (new, 0, "");
226 last->c_test = c_test;
227 last->insn_code_number = next_insn_code;
228 last->num_clobbers_to_add = XVECLEN (x, 0) - i;
229 first = merge_trees (previous_first, first);
237 static struct decision *
238 make_split_sequence (insn)
242 char *c_test = XSTR (insn, 1);
243 char *c_hook = XSTR (insn, 3);
244 struct decision *last;
246 if (XVECLEN (insn, 0) == 1)
247 x = XVECEXP (insn, 0, 0);
250 x = rtx_alloc (PARALLEL);
251 XVEC (x, 0) = XVEC (insn, 0);
252 PUT_MODE (x, VOIDmode);
255 last = add_to_sequence (x, 0, "");
258 last->c_test = c_test;
259 if (c_hook != 0 && c_hook[0] != 0)
260 last->c_hook = c_hook;
261 last->split_sequence = XEXP (insn, 2);
262 last->insn_code_number = next_insn_code++;
264 /* Define the subroutine we will call below and emit in genemit. */
265 printf ("extern rtx gen_split_%d ();\n", last->insn_code_number);
270 static struct decision *
271 add_to_sequence (pattern, last, position)
273 struct decision *last;
276 register RTX_CODE code;
277 register struct decision *new
278 = (struct decision *) xmalloc (sizeof (struct decision));
279 struct decision *this;
286 new->number = next_number++;
287 new->position = copystr (position);
291 new->insn_code_number = -1;
292 new->num_clobbers_to_add = 0;
296 new->test_elt_zero_int = 0;
297 new->test_elt_one_int = 0;
298 new->elt_zero_int = 0;
299 new->elt_one_int = 0;
300 new->enforce_mode = 0;
303 new->label_needed = 0;
306 new->split_sequence = 0;
308 new->subroutine_number = 0;
317 depth = strlen (position);
318 newpos = (char *) alloca (depth + 2);
319 strcpy (newpos, position);
320 newpos[depth + 1] = 0;
328 new->mode = VOIDmode;
332 new->mode = GET_MODE (pattern);
333 new->code = code = GET_CODE (pattern);
338 new->opno = XINT (pattern, 0);
340 new->tests = XSTR (pattern, 1);
341 if (*new->tests == 0)
346 new->opno = XINT (pattern, 0);
348 new->tests = "scratch_operand";
349 if (*new->tests == 0)
354 new->opno = XINT (pattern, 0);
356 new->tests = XSTR (pattern, 1);
357 if (*new->tests == 0)
359 for (i = 0; i < XVECLEN (pattern, 2); i++)
361 newpos[depth] = i + '0';
362 new = add_to_sequence (XVECEXP (pattern, 2, i), new, newpos);
364 this->success->enforce_mode = 0;
368 new->opno = XINT (pattern, 0);
369 new->code = PARALLEL;
370 new->tests = XSTR (pattern, 1);
371 if (*new->tests == 0)
373 for (i = 0; i < XVECLEN (pattern, 2); i++)
375 newpos[depth] = i + 'a';
376 new = add_to_sequence (XVECEXP (pattern, 2, i), new, newpos);
378 this->success->enforce_mode = 0;
382 new->opno = XINT (pattern, 0);
383 new->dupno = XINT (pattern, 0);
386 for (i = 0; i < XVECLEN (pattern, 1); i++)
388 newpos[depth] = i + '0';
389 new = add_to_sequence (XVECEXP (pattern, 1, i), new, newpos);
391 this->success->enforce_mode = 0;
395 new->dupno = XINT (pattern, 0);
400 pattern = XEXP (pattern, 0);
404 new->exact = "pc_rtx";
408 new->exact = "cc0_rtx";
412 if (INTVAL (pattern) == 0)
414 new->exact = "const0_rtx";
417 if (INTVAL (pattern) == 1)
419 new->exact = "const1_rtx";
422 if (INTVAL (pattern) == -1)
424 new->exact = "constm1_rtx";
427 if (INTVAL (pattern) == STORE_FLAG_VALUE)
429 new->exact = "const_true_rtx";
436 new = add_to_sequence (SET_DEST (pattern), new, newpos);
437 this->success->enforce_mode = 1;
439 new = add_to_sequence (SET_SRC (pattern), new, newpos);
442 case STRICT_LOW_PART:
444 new = add_to_sequence (XEXP (pattern, 0), new, newpos);
445 this->success->enforce_mode = 1;
449 this->test_elt_one_int = 1;
450 this->elt_one_int = XINT (pattern, 1);
452 new = add_to_sequence (XEXP (pattern, 0), new, newpos);
453 this->success->enforce_mode = 1;
459 new = add_to_sequence (XEXP (pattern, 0), new, newpos);
460 this->success->enforce_mode = 1;
462 new = add_to_sequence (XEXP (pattern, 1), new, newpos);
464 new = add_to_sequence (XEXP (pattern, 2), new, newpos);
468 fmt = GET_RTX_FORMAT (code);
469 len = GET_RTX_LENGTH (code);
470 for (i = 0; i < len; i++)
472 newpos[depth] = '0' + i;
473 if (fmt[i] == 'e' || fmt[i] == 'u')
474 new = add_to_sequence (XEXP (pattern, i), new, newpos);
475 else if (fmt[i] == 'i' && i == 0)
477 this->test_elt_zero_int = 1;
478 this->elt_zero_int = XINT (pattern, i);
480 else if (fmt[i] == 'i' && i == 1)
482 this->test_elt_one_int = 1;
483 this->elt_one_int = XINT (pattern, i);
485 else if (fmt[i] == 'E')
488 /* We do not handle a vector appearing as other than
489 the first item, just because nothing uses them
490 and by handling only the special case
491 we can use one element in newpos for either
492 the item number of a subexpression
493 or the element number in a vector. */
496 this->veclen = XVECLEN (pattern, i);
497 for (j = 0; j < XVECLEN (pattern, i); j++)
499 newpos[depth] = 'a' + j;
500 new = add_to_sequence (XVECEXP (pattern, i, j),
504 else if (fmt[i] != '0')
510 /* Merge two decision trees OLD and ADD,
511 modifying OLD destructively,
512 and return the merged tree. */
514 static struct decision *
515 merge_trees (old, add)
516 register struct decision *old, *add;
520 register struct decision *next = add->next;
522 if (!try_merge_1 (old, add))
523 old = try_merge_2 (old, add);
529 /* Merge ADD into the next-chain starting with OLD
530 only if it overlaps a condition already tested in OLD.
531 Returns 1 if successful (OLD is modified),
532 0 if nothing has been done. */
535 try_merge_1 (old, add)
536 register struct decision *old, *add;
540 if ((old->position == add->position
541 || (old->position && add->position
542 && !strcmp (old->position, add->position)))
543 && (old->tests == add->tests
544 || (old->tests && add->tests && !strcmp (old->tests, add->tests)))
545 && (old->c_test == add->c_test
546 || (old->c_test && add->c_test && !strcmp (old->c_test, add->c_test)))
547 && (old->c_hook == add->c_hook
548 || (old->c_hook && add->c_hook && !strcmp (old->c_hook, add->c_hook)))
549 && old->test_elt_zero_int == add->test_elt_zero_int
550 && old->elt_zero_int == add->elt_zero_int
551 && old->test_elt_one_int == add->test_elt_one_int
552 && old->elt_one_int == add->elt_one_int
553 && old->veclen == add->veclen
554 && old->dupno == add->dupno
555 && old->opno == add->opno
556 /* In a collection of nodes that don't have predicates,
557 we can always merge a new one with any node that matches it.
558 This is because we know that two different nodes can't possibly match
559 the same RTL object. So we can reorder the tests to simplify the
560 whole collection of them.
562 But when predicates are involved, we have to preserve the order of
563 testing them. This means that a new node can only be merged with the
566 enforce_mode indicates that at this level each of the nodes
567 requires a particular mode. When this is true, then we know
568 that two nodes with different modes can't possibly both match.
569 Therefore, it is ok to merge a new node with the last node
570 that wants the same mode, even if other nodes for different modes
571 appear after it. no_same_mode tests for this condition. */
573 || (add->enforce_mode ? no_same_mode (old) : old->next == 0))
574 && old->code == add->code
575 && old->mode == add->mode
576 && (old->exact == add->exact
577 || (old->exact && add->exact && ! strcmp (old->exact, add->exact))))
579 old->success = merge_trees (old->success, add->success);
580 if (old->insn_code_number >= 0 && add->insn_code_number >= 0)
581 fatal ("Two actions at one point in tree");
582 if (old->insn_code_number == -1)
583 old->insn_code_number = add->insn_code_number;
591 /* Merge ADD into the next-chain that starts with OLD,
592 preferably after something that tests the same place
594 The next-chain of ADD itself is ignored, and it is set
595 up for entering ADD into the new chain.
596 Returns the new chain. */
598 static struct decision *
599 try_merge_2 (old, add)
600 struct decision *old, *add;
602 register struct decision *p;
603 struct decision *last = 0;
604 struct decision *last_same_place = 0;
606 /* Put this in after the others that test the same place,
607 if there are any. If not, find the last chain element
610 One modification: if this one is NOT a MATCH_OPERAND,
611 put it before any MATCH_OPERANDS that test the same place.
613 Another: if enforce_mode (i.e. this is first operand of a SET),
614 put this after the last thing that tests the same place for
618 int operand = 0 != add->tests;
621 for (p = old; p; p = p->next)
623 if (p->position == add->position
624 || (p->position && add->position
625 && !strcmp (p->position, add->position)))
628 /* If enforce_mode, segregate the modes in numerical order. */
629 if (p->enforce_mode && (int) add->mode < (int) p->mode)
632 /* Keep explicit decompositions before those that test predicates.
633 If enforce_mode, do this separately within each mode. */
634 if (! p->enforce_mode || p->mode == add->mode)
635 if (!operand && p->tests)
639 /* If this is past the end of the decisions at the same place as ADD,
640 stop looking now; add ADD before here. */
641 else if (last_same_place)
646 /* Insert before P, which means after LAST. */
650 add->next = last->next;
661 struct decision *node;
663 register struct decision *p;
664 register enum machine_mode mode = node->mode;
666 for (p = node->next; p; p = p->next)
673 /* Count the number of subnodes of node NODE, assumed to be the start
674 of a next-chain. If the number is high enough, make NODE start
675 a separate subroutine in the C code that is generated.
677 TYPE gives the type of routine we are writing. */
680 break_out_subroutines (node, type)
681 struct decision *node;
682 enum routine_type type;
685 struct decision *sub;
686 for (sub = node; sub; sub = sub->next)
687 size += 1 + break_out_subroutines (sub->success, type);
688 if (size > SUBROUTINE_THRESHOLD)
690 node->subroutine_number = ++next_subroutine_number;
691 write_subroutine (node, type);
698 write_subroutine (tree, type)
699 struct decision *tree;
700 enum routine_type type;
702 char *return_type = (type == SPLIT ? "rtx" : "int");
706 printf ("rtx\nsplit_%d (x0, insn)\n", tree->subroutine_number);
707 printf (" register rtx x0;\n rtx insn;\n");
711 printf ("int\nrecog_%d (x0, insn, pnum_clobbers)\n",
712 tree->subroutine_number);
713 printf (" register rtx x0;\n rtx insn;\n");
714 printf (" int *pnum_clobbers;\n");
718 printf (" register rtx *ro = &recog_operand[0];\n");
719 printf (" register rtx x1, x2, x3, x4, x5;\n rtx x6, x7, x8, x9, x10, x11;\n");
720 printf (" %s tem;\n", return_type);
721 write_tree (tree, "", 0, "", 1, type);
722 printf (" ret0: return %d;\n}\n\n", type == SPLIT ? 0 : -1);
725 /* Write out C code to perform the decisions in the tree. */
728 write_tree_1 (tree, prevpos, afterward, afterpos, initial, type)
729 struct decision *tree;
734 enum routine_type type;
736 register struct decision *p, *p1;
740 enum anon1 { NO_SWITCH, CODE_SWITCH, MODE_SWITCH } in_switch = NO_SWITCH;
741 char modemap[NUM_MACHINE_MODES];
742 char codemap[NUM_RTX_CODE];
746 tree->label_needed = 1;
747 for (p = tree; p; p = p->next)
749 /* Find the next alternative to p
750 that might be true when p is true.
751 Test that one next if p's successors fail.
752 Note that when the `tests' field is nonzero
753 it is up to the specified test-function to compare machine modes
754 and some (such as general_operand) don't always do so.
755 But when inside a switch-on-modes we ignore this and
756 consider all modes mutually exclusive. */
757 for (p1 = p->next; p1; p1 = p1->next)
758 if (((p->code == UNKNOWN || p1->code == UNKNOWN || p->code == p1->code)
759 && (p->mode == VOIDmode || p1->mode == VOIDmode
760 || p->mode == p1->mode
761 || (in_switch != MODE_SWITCH && (p->tests || p1->tests))))
762 || strcmp (p1->position, p->position))
765 if (p1) p1->label_needed = 1;
767 if (in_switch == MODE_SWITCH
768 && (p->mode == VOIDmode || (! p->enforce_mode && p->tests != 0)))
770 in_switch = NO_SWITCH;
773 if (in_switch == CODE_SWITCH && p->code == UNKNOWN)
775 in_switch = NO_SWITCH;
780 printf (" L%d:\n", p->number);
782 if (p->success == 0 && p->insn_code_number < 0)
785 change_state (pos, p->position);
787 depth = strlen (pos);
789 ignmode = (p->ignmode || p->tests);
791 if (in_switch == NO_SWITCH)
793 /* If p and its alternatives all want the same mode,
794 reject all others at once, first, then ignore the mode. */
795 if (!ignmode && p->mode != VOIDmode && p->next && same_modes (p, p->mode))
797 printf (" if (GET_MODE (x%d) != %smode)\n",
798 depth, GET_MODE_NAME (p->mode));
802 change_state (pos, afterpos);
803 printf (" goto L%d;\n }\n", afterward);
806 printf (" goto ret0;\n");
811 /* If p and its alternatives all want the same code,
812 reject all others at once, first, then ignore the code. */
813 if (p->code != UNKNOWN && p->next && same_codes (p, p->code))
815 printf (" if (GET_CODE (x%d) != ", depth);
816 print_code (p->code);
821 change_state (pos, afterpos);
822 printf (" goto L%d; }\n", afterward);
825 printf (" goto ret0;\n");
830 /* If p and its alternatives all have different modes
831 and there are at least 4 of them, make a switch. */
832 if (in_switch == NO_SWITCH)
837 mybzero (modemap, sizeof modemap);
839 (p1 && p1->mode != VOIDmode
840 && (p1->tests == 0 || p1->enforce_mode));
843 if (! p->enforce_mode && modemap[(int) p1->mode])
848 modemap[(int) p1->mode] = 1;
852 in_switch = MODE_SWITCH;
853 printf (" switch (GET_MODE (x%d))\n {\n", depth);
857 if (in_switch == NO_SWITCH)
860 mybzero (codemap, sizeof codemap);
861 for (p1 = p, i = 0; p1 && p1->code != UNKNOWN; p1 = p1->next, i++)
863 if (codemap[(int) p1->code])
865 codemap[(int) p1->code] = 1;
867 if ((p1 == 0 || p1->code == UNKNOWN) && i >= 4)
869 in_switch = CODE_SWITCH;
870 printf (" switch (GET_CODE (x%d))\n {\n", depth);
874 if (in_switch == MODE_SWITCH)
876 if (modemap[(int) p->mode])
878 printf (" case %smode:\n", GET_MODE_NAME (p->mode));
879 modemap[(int) p->mode] = 0;
882 if (in_switch == CODE_SWITCH)
884 if (codemap[(int) p->code])
887 print_code (p->code);
889 codemap[(int) p->code] = 0;
894 if (p->exact || (p->code != UNKNOWN && in_switch != CODE_SWITCH))
897 printf ("x%d == %s", depth, p->exact);
900 printf ("GET_CODE (x%d) == ", depth);
901 print_code (p->code);
905 if (p->mode != VOIDmode && !ignmode && in_switch != MODE_SWITCH)
906 printf ("GET_MODE (x%d) == %smode && ",
907 depth, GET_MODE_NAME (p->mode));
908 if (p->test_elt_zero_int)
909 printf ("XINT (x%d, 0) == %d && ", depth, p->elt_zero_int);
911 printf ("XVECLEN (x%d, 0) == %d && ", depth, p->veclen);
912 if (p->test_elt_one_int)
913 printf ("XINT (x%d, 1) == %d && ", depth, p->elt_one_int);
915 printf ("rtx_equal_p (x%d, ro[%d]) && ", depth, p->dupno);
917 printf ("%s (x%d, %smode)", p->tests, depth,
918 GET_MODE_NAME (p->mode));
923 printf (")\n { ro[%d] = x%d; ",
929 printf ("if (%s) ", p->c_test);
931 if (p->insn_code_number >= 0)
934 printf ("return gen_split_%d (operands);", p->insn_code_number);
937 if (p->num_clobbers_to_add)
940 printf ("\tif (pnum_clobbers == 0) goto ret0; ");
941 printf ("*pnum_clobbers = %d; ", p->num_clobbers_to_add);
942 printf ("return %d;\n }", p->insn_code_number);
945 printf ("return %d;", p->insn_code_number);
949 printf ("goto L%d;", p->success->number);
956 /* Now, if inside a switch, branch to next switch member
957 that might also need to be tested if this one fails. */
959 if (in_switch == CODE_SWITCH)
961 /* Find the next alternative to p
962 that might be applicable if p was applicable. */
963 for (p1 = p->next; p1; p1 = p1->next)
964 if (p1->code == UNKNOWN || p->code == p1->code)
966 if (p1 == 0 || p1->code == UNKNOWN)
967 printf (" break;\n");
968 else if (p1 != p->next)
970 printf (" goto L%d;\n", p1->number);
971 p1->label_needed = 1;
975 if (in_switch == MODE_SWITCH)
977 /* Find the next alternative to p
978 that might be applicable if p was applicable. */
979 for (p1 = p->next; p1; p1 = p1->next)
980 if (p1->mode == VOIDmode || p->mode == p1->mode)
982 if (p1 == 0 || p1->mode == VOIDmode)
983 printf (" break;\n");
984 else if (p1 != p->next)
986 printf (" goto L%d;\n", p1->number);
987 p1->label_needed = 1;
992 if (in_switch != NO_SWITCH)
997 change_state (pos, afterpos);
998 printf (" goto L%d;\n", afterward);
1001 printf (" goto ret0;\n");
1006 write_tree (tree, prevpos, afterward, afterpos, initial, type)
1007 struct decision *tree;
1012 enum routine_type type;
1014 register struct decision *p;
1015 char *pos = prevpos;
1016 char *name_prefix = (type == SPLIT ? "split" : "recog");
1017 char *call_suffix = (type == SPLIT ? "" : ", pnum_clobbers");
1019 if (tree->subroutine_number > 0 && ! initial)
1021 printf (" L%d:\n", tree->number);
1025 printf (" tem = %s_%d (x0, insn%s);\n",
1026 name_prefix, tree->subroutine_number, call_suffix);
1027 printf (" if (tem >= 0) return tem;\n");
1028 change_state (pos, afterpos);
1029 printf (" goto L%d;\n", afterward);
1032 printf (" return %s_%d (x0, insn%s);\n",
1033 name_prefix, tree->subroutine_number, call_suffix);
1037 pos = write_tree_1 (tree, prevpos, afterward, afterpos, initial, type);
1039 for (p = tree; p; p = p->next)
1043 write_tree (p->success, pos,
1044 p->afterward ? p->afterward->number : afterward,
1045 p->afterward ? pos : afterpos, 0, type);
1054 for (p1 = GET_RTX_NAME (code); *p1; p1++)
1056 if (*p1 >= 'a' && *p1 <= 'z')
1057 putchar (*p1 + 'A' - 'a');
1064 same_codes (p, code)
1065 register struct decision *p;
1066 register RTX_CODE code;
1068 for (; p; p = p->next)
1069 if (p->code != code)
1077 register struct decision *p;
1079 for (; p; p = p->next)
1084 same_modes (p, mode)
1085 register struct decision *p;
1086 register enum machine_mode mode;
1088 for (; p; p = p->next)
1089 if (p->mode != mode || p->tests)
1097 register struct decision *p;
1099 for (; p; p = p->next)
1104 change_state (oldpos, newpos)
1108 int odepth = strlen (oldpos);
1110 int ndepth = strlen (newpos);
1112 /* Pop up as many levels as necessary. */
1114 while (strncmp (oldpos, newpos, depth))
1117 /* Go down to desired level. */
1119 while (depth < ndepth)
1121 if (newpos[depth] >= 'a' && newpos[depth] <= 'z')
1122 printf (" x%d = XVECEXP (x%d, 0, %d);\n",
1123 depth + 1, depth, newpos[depth] - 'a');
1125 printf (" x%d = XEXP (x%d, %c);\n",
1126 depth + 1, depth, newpos[depth]);
1140 tem = (char *) xmalloc (strlen (s1) + 1);
1149 register unsigned length;
1151 while (length-- > 0)
1166 tem = (char *) xmalloc (strlen (s1) + strlen (s2) + 2);
1175 xrealloc (ptr, size)
1179 char *result = (char *) realloc (ptr, size);
1181 fatal ("virtual memory exhausted");
1189 register char *val = (char *) malloc (size);
1192 fatal ("virtual memory exhausted");
1200 fprintf (stderr, "genrecog: ");
1201 fprintf (stderr, s, a1, a2);
1202 fprintf (stderr, "\n");
1203 fprintf (stderr, "after %d instruction definitions\n", next_index);
1204 exit (FATAL_EXIT_CODE);
1207 /* More 'friendly' abort that prints the line and file.
1208 config.h can #define abort fancy_abort if you like that sort of thing. */
1213 fatal ("Internal gcc abort.");
1222 struct decision *tree = 0;
1223 struct decision *split_tree = 0;
1225 extern rtx read_rtx ();
1228 obstack_init (rtl_obstack);
1231 fatal ("No input file name.");
1233 infile = fopen (argv[1], "r");
1237 exit (FATAL_EXIT_CODE);
1244 printf ("/* Generated automatically by the program `genrecog'\n\
1245 from the machine description file `md'. */\n\n");
1247 printf ("#include \"config.h\"\n");
1248 printf ("#include \"rtl.h\"\n");
1249 printf ("#include \"insn-config.h\"\n");
1250 printf ("#include \"recog.h\"\n");
1251 printf ("#include \"real.h\"\n");
1252 printf ("#include \"output.h\"\n");
1253 printf ("#include \"flags.h\"\n");
1256 /* Read the machine description. */
1260 c = read_skip_spaces (infile);
1265 desc = read_rtx (infile);
1266 if (GET_CODE (desc) == DEFINE_INSN)
1267 tree = merge_trees (tree, make_insn_sequence (desc));
1268 else if (GET_CODE (desc) == DEFINE_SPLIT)
1269 split_tree = merge_trees (split_tree, make_split_sequence (desc));
1270 if (GET_CODE (desc) == DEFINE_PEEPHOLE
1271 || GET_CODE (desc) == DEFINE_EXPAND)
1277 /* `recog' contains a decision tree\n\
1278 that recognizes whether the rtx X0 is a valid instruction.\n\
1280 recog returns -1 if the rtx is not valid.\n\
1281 If the rtx is valid, recog returns a nonnegative number\n\
1282 which is the insn code number for the pattern that matched.\n");
1283 printf (" This is the same as the order in the machine description of\n\
1284 the entry that matched. This number can be used as an index into\n\
1285 entry that matched. This number can be used as an index into various\n\
1286 insn_* tables, such as insn_templates, insn_outfun, and insn_n_operands\n\
1287 (found in insn-output.c).\n\n");
1288 printf (" The third argument to recog is an optional pointer to an int.\n\
1289 If present, recog will accept a pattern if it matches except for\n\
1290 missing CLOBBER expressions at the end. In that case, the value\n\
1291 pointed to by the optional pointer will be set to the number of\n\
1292 CLOBBERs that need to be added (it should be initialized to zero by\n\
1293 the caller). If it is set nonzero, the caller should allocate a\n\
1294 PARALLEL of the appropriate size, copy the initial entries, and call\n\
1295 add_clobbers (found in insn-emit.c) to fill in the CLOBBERs.");
1298 printf ("\n\n The function split_insns returns 0 if the rtl could not\n\
1299 be split or the split rtl in a SEQUENCE if it can be.");
1303 printf ("rtx recog_operand[MAX_RECOG_OPERANDS];\n\n");
1304 printf ("rtx *recog_operand_loc[MAX_RECOG_OPERANDS];\n\n");
1305 printf ("rtx *recog_dup_loc[MAX_DUP_OPERANDS];\n\n");
1306 printf ("char recog_dup_num[MAX_DUP_OPERANDS];\n\n");
1307 printf ("#define operands recog_operand\n\n");
1309 next_subroutine_number = 0;
1310 break_out_subroutines (tree, RECOG);
1312 printf ("int\nrecog (x0, insn, pnum_clobbers)\n");
1313 printf (" register rtx x0;\n rtx insn;\n");
1314 printf (" int *pnum_clobbers;\n{\n");
1315 printf (" register rtx *ro = &recog_operand[0];\n");
1316 printf (" register rtx x1, x2, x3, x4, x5;\n rtx x6, x7, x8, x9, x10, x11;\n");
1317 printf (" int tem;\n");
1320 write_tree (tree, "", 0, "", 1, RECOG);
1321 printf (" ret0: return -1;\n}\n");
1323 next_subroutine_number = 0;
1324 break_out_subroutines (split_tree, SPLIT);
1326 printf ("rtx\nsplit_insns (x0, insn)\n register rtx x0;\n rtx insn;\n{\n");
1327 printf (" register rtx *ro = &recog_operand[0];\n");
1328 printf (" register rtx x1, x2, x3, x4, x5;\n rtx x6, x7, x8, x9, x10, x11;\n");
1329 printf (" rtx tem;\n");
1332 write_tree (split_tree, "", 0, "", 1, SPLIT);
1333 printf (" ret0: return 0;\n}\n");
1336 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);