This tool outputs global array insn-output.c from md file. Insn-output.c produces assemble instructions for specified pattern.
967 int
968 main (int argc, char **argv) in genoutput.c
969 {
970 rtx desc;
971
972 progname = "genoutput";
973
974 if (argc <= 1)
975 fatal ("no input file name");
976
977 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
978 return (FATAL_EXIT_CODE);
979
980 output_prologue ();
981 next_code_number = 0;
982 next_index_number = 0;
983
984 /* Read the machine description. */
985
986 while (1)
987 {
988 int line_no;
989
990 desc = read_md_rtx (&line_no, &next_code_number );
991 if (desc == NULL)
992 break ;
993
994 if (GET_CODE (desc) == DEFINE_INSN)
995 gen_insn (desc, line_no);
996 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
997 gen_peephole (desc, line_no);
998 if (GET_CODE (desc) == DEFINE_EXPAND)
999 gen_expand (desc, line_no);
1000 if (GET_CODE (desc) == DEFINE_SPLIT
1001 || GET_CODE (desc) == DEFINE_PEEPHOLE2)
1002 gen_split (desc, line_no);
1003 next_index_number ++;
1004 }
1005
1006 printf("/n/n");
1007 output_operand_data ();
1008 output_insn_data ();
1009 output_get_insn_name ();
1010
1011 fflush (stdout);
1012 return (ferror (stdout) != 0 || have_error
1013 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
1014 }
All gen* tools have the similar beginning. Above at line 977, init_md_reader_args will read in the machine description file and create corresponding rtx object as we see before. For demonstration purpose, here we again use the define_insn_and_split pattern which we use in 2. Tool of genconditions as the example.
We already know that this pattern will be split into two patterns, one of define_insn, the other of define_split. For the define_insn pattern, at line 995 gen_insn will be invoked.
807 static void
808 gen_insn (rtx insn, int lineno) in genoutput.c
809 {
810 struct data *d = xmalloc (sizeof (struct data ));
811 int i;
812
813 d->code_number = next_code_number ;
814 d->index_number = next_index_number ;
815 d->lineno = lineno;
816 if (XSTR (insn, 0)[0])
817 d->name = XSTR (insn, 0);
818 else
819 d->name = 0;
820
821 /* Build up the list in the same order as the insns are seen
822 i n the machine description. */
823 d->next = 0;
824 *idata_end = d;
825 idata_end = &d->next;
826
827 max_opno = -1;
828 num_dups = 0;
829 memset (d->operand, 0, sizeof (d->operand));
830
831 for (i = 0; i < XVECLEN (insn, 1); i++)
832 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
833
834 d->n_operands = max_opno + 1;
835 d->n_dups = num_dups ;
836
837 check_constraint_len ();
838 validate_insn_operands (d);
839 validate_insn_alternatives (d);
840 place_operands (d);
841 process_template (d, XTMPL (insn, 3));
842 }
Above, at line 810, structure data records all information that will be outputed. This data will be linked into idata_end at line 824.
156 struct data in genoutput.c
157 {
158 struct data *next;
159 const char *name;
160 const char *template;
161 int code_number;
162 int index_number;
163 int lineno;
164 int n_operands; /* Number of operands this insn recognizes */
165 int n_dups; /* Number times match_dup appears in pattern */
166 int n_alternatives; /* Number of alternatives in each constraint */
167 int operand_number; /* Operand index in the big array. */
168 int output_format; /* INSN_OUTPUT_FORMAT_*. */
169 struct operand_data operand[MAX_MAX_OPERANDS];
170 };
122 struct operand_data in genoutput.c
123 {
124 struct operand_data *next;
125 int index;
126 const char *predicate;
127 const char *constraint;
128 enum machine_mode mode;
129 unsigned char n_alternatives;
130 char address_p;
131 char strict_low;
132 char eliminable;
133 char seen;
134 };
The define_insn pattern used as the example is as following. See that the second child of the pattern is the rtvec which has the size of 1. At line 831 above, scan_operands is invoked to check the number of operands each element of rtvec needs.
figure 31 : genouput - example of define_insn_and_split pattern – insn part
423 static void
424 scan_operands (struct data *d, rtx part, int this_address_p, in genoutput.c
425 int this_strict_low)
426 {
427 int i, j;
428 const char *format_ptr;
429 int opno;
430
431 if (part == 0)
432 return ;
433
434 switch (GET_CODE (part))
435 {
436 case MATCH_OPERAND:
437 opno = XINT (part, 0);
438 if (opno > max_opno )
439 max_opno = opno;
440 if (max_opno >= MAX_MAX_OPERANDS)
441 {
442 message_with_line (d->lineno,
443 "maximum number of operands exceeded");
444 have_error = 1;
445 return;
446 }
447 if (d->operand[opno].seen)
448 {
449 message_with_line (d->lineno,
450 "repeated operand number %d/n", opno);
451 have_error = 1;
452 }
453
454 d->operand[opno].seen = 1;
455 d->operand[opno].mode = GET_MODE (part);
456 d->operand[opno].strict_low = this_strict_low;
457 d->operand[opno].predicate = XSTR (part, 1);
458 d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
459 d->operand[opno].n_alternatives
460 = n_occurrences (',', d->operand[opno].constraint) + 1;
461 d->operand[opno].address_p = this_address_p;
462 d->operand[opno].eliminable = 1;
463 return ;
464
465 case MATCH_SCRATCH:
466 opno = XINT (part, 0);
467 if (opno > max_opno )
468 max_opno = opno;
469 if (max_opno >= MAX_MAX_OPERANDS)
470 {
471 message_with_line (d->lineno,
472 "maximum number of operands exceeded");
473 have_error = 1;
474 return ;
475 }
476 if (d->operand[opno].seen)
477 {
478 message_with_line (d->lineno,
479 "repeated operand number %d/n", opno);
480 have_error = 1;
481 }
482
483 d->operand[opno].seen = 1;
484 d->operand[opno].mode = GET_MODE (part);
485 d->operand[opno].strict_low = 0;
486 d->operand[opno].predicate = "scratch_operand";
487 d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
488 d->operand[opno].n_alternatives
489 = n_occurrences (',', d->operand[opno].constraint) + 1;
490 d->operand[opno].address_p = 0;
491 d->operand[opno].eliminable = 0;
492 return ;
493
494 case MATCH_OPERATOR:
495 case MATCH_PARALLEL:
496 opno = XINT (part, 0);
497 if (opno > max_opno )
498 max_opno = opno;
499 if (max_opno >= MAX_MAX_OPERANDS)
500 {
501 message_with_line (d->lineno,
502 "maximum number of operands exceeded");
503 have_error = 1;
504 return ;
505 }
506 if (d->operand[opno].seen)
507 {
508 message_with_line (d->lineno,
509 "repeated operand number %d/n", opno);
510 have_error = 1;
511 }
512
513 d->operand[opno].seen = 1;
514 d->operand[opno].mode = GET_MODE (part);
515 d->operand[opno].strict_low = 0;
516 d->operand[opno].predicate = XSTR (part, 1);
517 d->operand[opno].constraint = 0;
518 d->operand[opno].address_p = 0;
519 d->operand[opno].eliminable = 0;
520 for (i = 0; i < XVECLEN (part, 2); i++)
521 scan_operands (d, XVECEXP (part, 2, i), 0, 0);
522 return ;
523
524 case MATCH_DUP:
525 case MATCH_OP_DUP:
526 case MATCH_PAR_DUP:
527 ++num_dups ;
528 break ;
529
530 case ADDRESS:
531 scan_operands (d, XEXP (part, 0), 1, 0);
532 return ;
533
534 case STRICT_LOW_PART:
535 scan_operands (d, XEXP (part, 0), 0, 1);
536 return ;
537
538 default :
539 break ;
540 }
541
542 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
543
544 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
545 switch (*format_ptr++)
546 {
547 case 'e':
548 case 'u':
549 scan_operands (d, XEXP (part, i), 0, 0);
550 break ;
551 case 'E':
552 if (XVEC (part, i) != NULL)
553 for (j = 0; j < XVECLEN (part, i); j++)
554 scan_operands (d, XVECEXP (part, i, j), 0, 0);
555 break ;
556 }
557 }
For our example, the pattern has rtl code of set , then drops to line 542, and recurses for its two children at line 549. The code is quite easy. When it finishes we can get the data structure as following. data represents instruction pattern, and operand_data saves details of operands in the instruction.
figure 32 : genoutput – data produced for define_insn, figure 1
Back to gen_insn , now we have prepared the data from the rtx objects. We have seen that in pattern definition constraint can be used to describe the qualification of the register or memory to be selected to hold the parameter. Different chips can introduce new constraints or redefine existing ones. However some constrains are like reserve words in C or C++, they are not allowed to change the meaning. Function check_constraint_len tries to find out the tampering.
1057 static void
1058 check_constraint_len (void) in genoutput.c
1059 {
1060 const char *p;
1061 int d;
1062
1063 for (p = ",#*+=&%!1234567890"; *p; p++)
1064 for (d = -9; d < 9; d++)
1065 if (constraint_len (p, d) != d)
1066 abort ();
1067 }
From above, the constraints does not allow tampering is ‘,’, ‘#’, ‘*’, ‘+’, ‘=’, ‘&’, ‘%’, ‘!’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, and ‘0’. For their meaning please refer to reference [2].
1069 static int
1070 constraint_len (const char *p, int genoutput_default_constraint_len) in genoutput.c
1071 {
1072 /* Check that we still match defaults.h . First we do a generation-time
1073 check that fails if the value is not the expected one... */
1074 if (DEFAULT_CONSTRAINT_LEN (*p, p) != 1)
1075 abort ();
1076 /* And now a compile-time check that should give a diagnostic if the
1077 definition doesn't exactly match. */
1078 #define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1079 /* Now re-define DEFAULT_CONSTRAINT_LEN so that we can verify it is
1080 being used. */
1081 #undef DEFAULT_CONSTRAINT_LEN
1082 #define DEFAULT_CONSTRAINT_LEN(C,STR) /
1083 ((C) != *p || STR != p ? -1 : genoutput_default_constraint_len)
1084 return CONSTRAINT_LEN (*p, p);
1085 /* And set it back. */
1086 #undef DEFAULT_CONSTRAINT_LEN
1087 #define DEFAULT_CONSTRAINT_LEN(C,STR) 1
1088 }
Above at line 1074, DEFAULT_CONSTRAINT_LEN is defined in defaults.h as 1. This definition should not be changed except temper in this function. At line 1084, CONSTRAINT_LEN is also defined in defaults.h by DEFAULT_CONSTRAINT_LEN . This macro can be changed for different machines to accommodate customized constraints. Let’s see an example for Renesas SuperH.
1318 /* Overview of uppercase letter constraints:
1319 A: Addresses (constraint len == 3)
1320 A c4: sh4 cache operations
1321 A c5: sh5 cache operations
1322 Bxx: miscellaneous constraints
1323 Bsc: SCRATCH - for the scratch register in movsi_ie in the
1324 fldi0 / fldi0 cases
1325 C: Constants other than only CONST_INT (constraint len == 3)
1326 C16: 16 bit constant, literal or symbolic
1327 Csy: label or symbol
1328 Cpg: non-explicit constants that can be directly loaded into a general
1329 purpose register in PIC code. like 's' except we don't allow
1330 PIC_DIRECT_ADDR_P
1331 IJKLMNOP: CONT_INT constants
1332 Ixx: signed xx bit
1333 J16: 0xffffffff00000000 | 0x00000000ffffffff
1334 Kxx: unsigned xx bit
1335 M: 1
1336 N: 0
1337 P27: 1 | 2 | 8 | 16
1338 Q: pc relative load operand
1339 Rxx: reserved for exotic register classes.
1340 S: extra memory (storage) constraints (constraint len == 3)
1341 Sua: unaligned memory operations
1342 W: vector
1343 Z: zero in any mode
1344
1345 unused CONST_INT constraint letters: LO
1346 unused EXTRA_CONSTRAINT letters: D T U Y */
1347
1348 #define CONSTRAINT_LEN(C,STR) /
1349 (((C) == 'A' || (C) == 'B' || (C) == 'C' /
1350 || (C) == 'I' || (C) == 'J' || (C) == 'K' || (C) == 'P' /
1351 || (C) == 'R' || (C) == 'S') /
1352 ? 3 : DEFAULT_CONSTRAINT_LEN ((C), (STR))) in sh.h
From the comment, can see that constraints begin with the specified character are of size 3, and DEFAULT_CONSTRAINT_LEN is expanded by definition at line 1082. Once one of above contraints is tampered, condition at line 1065 won’t be met; besides, if in CONSTRAINT_LEN changes constraint under processing, the definition at line 1082 returns -1. Note that before the definition at line 1078, #undef is not given, so if DEFAULT_CONSTRAINT_LEN has inconsist definitions, the compiler will give a warning. Following then we make sure all operands have been visited by scan_operands in validate_insn_operands .
790 static void
791 validate_insn_operands (struct data *d) in genoutput.c
792 {
793 int i;
794
795 for (i = 0; i < d->n_operands; ++i)
796 if (d->operand[i].seen == 0)
797 {
798 message_with_line (d->lineno, "missing operand %d", i);
799 have_error = 1;
800 }
801 }
Back to gen_insn , at line 839, validate_insn_alternatives again checks the validation of the constraints. Notice that “,”, “#”, “*” can’t be used to form the custom constraint.
719 static void
720 validate_insn_alternatives (struct data *d) in genoutput.c
721 {
722 int n = 0, start;
723
724 /* Make sure all the operands have the same number of alternatives
725 i n their constraints. Let N be that number. */
726 for (start = 0; start < d->n_operands; start++)
727 if (d->operand[start].n_alternatives > 0)
728 {
729 int len, i;
730 const char *p;
731 char c;
732 int which_alternative = 0;
733 int alternative_count_unsure = 0;
734
735 for (p = d->operand[start].constraint; (c = *p); p += len)
736 {
737 len = CONSTRAINT_LEN (c, p);
738
739 if (len < 1 || (len > 1 && strchr (",#*+=&%!0123456789", c)))
740 {
741 message_with_line (d->lineno,
742 "invalid length %d for char '%c' in alternative %d of operand %d",
743 len, c, which_alternative, start);
744 len = 1;
745 have_error = 1;
746 }
747
748 if (c == ',')
749 {
750 which_alternative++;
751 continue ;
752 }
753
754 for (i = 1; i < len; i++)
755 if (p[i] == '/0')
756 {
757 message_with_line (d->lineno,
758 "NUL in alternative %d of operand %d",
759 which_alternative, start);
760 alternative_count_unsure = 1;
761 break ;
762 }
763 else if (strchr (",#*", p[i]))
764 {
765 message_with_line (d->lineno,
766 "'%c' in alternative %d of operand %d",
767 p[i], which_alternative, start);
768 alternative_count_unsure = 1;
769 }
770 }
771 if (alternative_count_unsure)
772 have_error = 1;
773 else if (n == 0)
774 n = d->operand[start].n_alternatives;
775 else if (n != d->operand[start].n_alternatives)
776 {
777 message_with_line (d->lineno,
778 "wrong number of alternatives in operand %d",
779 start);
780 have_error = 1;
781 }
782 }
783
784 /* Record the insn's overall number of alternatives. */
785 d->n_alternatives = n;
786 }
Though every insn is distinct, it may share the same operands with others, and these data, in assemble code generation, is used as read-only. It is possible and should share them as possible. So, passing the sanity check, place_operands will maintain a singlton for the operand.
599 static void
600 place_operands (struct data *d) in genoutput.c
601 {
602 struct operand_data *od, *od2;
603 int i;
604
605 if (d->n_operands == 0)
606 {
607 d->operand_number = 0;
608 return ;
609 }
610
611 /* Brute force substring search. */
612 for (od = odata , i = 0; od; od = od->next, i = 0)
613 if (compare_operands (od, &d->operand[0]))
614 {
615 od2 = od->next;
616 i = 1;
617 while (1)
618 {
619 if (i == d->n_operands)
620 goto full_match;
621 if (od2 == NULL)
622 goto partial_match;
623 if (! compare_operands (od2, &d->operand[i]))
624 break ;
625 ++i, od2 = od2->next;
626 }
627 }
628
629 /* Either partial match at the end of the list, or no match. In either
630 case, we tack on what operands are remaining to the end of the list. */
631 partial_match:
632 d->operand_number = next_operand_number - i;
633 for (; i < d->n_operands; ++i)
634 {
635 od2 = &d->operand[i];
636 *odata_end = od2;
637 odata_end = &od2->next;
638 od2->index = next_operand_number ++;
639 }
640 *odata_end = NULL;
641 return ;
642
643 full_match:
644 d->operand_number = od->index;
645 return ;
646 }
Above at line 612, variable odata is of type operand_data which is part of data and forms a link. In FOR loop at line 612, it finds if the instance of d is present, if not, it will be added into this link. Notice that as all operand_datas are linked tegother, operand_number records the the index of the unique instance, and index records its positon is in the list. Then process_template is inovked to operate template part of the instruction pattern.
653 static void
654 process_template (struct data *d, const char *template) in genoutput.c
655 {
656 const char *cp;
657 int i;
658
659 /* Templates starting with * contain straight code to be run. */
660 if (template[0] == '*')
661 {
662 d->template = 0;
663 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
664
665 puts ("/nstatic const char *");
666 printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)/n",
667 d->code_number);
668 puts ("{");
669
670 puts (template + 1);
671 puts ("}");
672 }
673
674 /* If the assembler code template starts with a @ it is a newline-separated
675 list of assembler code templates, one for each alternative. */
676 else if (template[0] == '@')
677 {
678 d->template = 0;
679 d->output_format = INSN_OUTPUT_FORMAT_MULTI;
680
681 printf ("/nstatic const char * const output_%d[] = {/n", d->code_number);
682
683 for (i = 0, cp = &template[1]; *cp; )
684 {
685 while (ISSPACE (*cp))
686 cp++;
687
688 printf (" /"");
689 while (!IS_VSPACE (*cp) && *cp != '/0')
690 {
691 putchar (*cp);
692 cp++;
693 }
694
695 printf ("/",/n");
696 i++;
697 }
698 if (i == 1)
699 message_with_line (d->lineno,
700 "'@' is redundant for output template with single alternative");
701 if (i != d->n_alternatives)
702 {
703 message_with_line (d->lineno,
704 "wrong number of alternatives in the output template");
705 have_error = 1;
706 }
707
708 printf ("};/n");
709 }
710 else
711 {
712 d->template = template;
713 d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
714 }
715 }
Here process_template handles the output template in pattern, we can see the difference between ‘*’ ‘@’ and others. For former both types, output_* functions will be produced for reference by insn_data output later.