📄 genoutput.c
字号:
predicates[opno] = XSTR (part, 1); constraints[opno] = XSTR (part, 2); if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0) { op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1; have_constraints = 1; } address_p[opno] = this_address_p; return; } if (code == MATCH_OPERATOR) { int opno = XINT (part, 0); if (opno > max_opno) max_opno = opno; if (max_opno >= MAX_MAX_OPERANDS) error ("Too many operands (%d) in one instruction pattern.\n", max_opno + 1); modes[opno] = GET_MODE (part); strict_low[opno] = 0; predicates[opno] = XSTR (part, 1); constraints[opno] = 0; address_p[opno] = 0; for (i = 0; i < XVECLEN (part, 2); i++) scan_operands (XVECEXP (part, 2, i), 0, 0); return; } if (code == MATCH_DUP) { ++num_dups; return; } if (code == ADDRESS) { scan_operands (XEXP (part, 0), 1, 0); return; } if (code == STRICT_LOW_PART) { scan_operands (XEXP (part, 0), 0, 1); return; } format_ptr = GET_RTX_FORMAT (GET_CODE (part)); for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) switch (*format_ptr++) { case 'e': scan_operands (XEXP (part, i), 0, 0); break; case 'E': if (XVEC (part, i) != NULL) for (j = 0; j < XVECLEN (part, i); j++) scan_operands (XVECEXP (part, i, j), 0, 0); break; }}/* Look at a define_insn just read. Assign its code number. Record on insn_data the template and the number of arguments. If the insn has a hairy output action, output a function for now. */voidgen_insn (insn) rtx insn;{ register struct data *d = (struct data *) xmalloc (sizeof (struct data)); register int i; d->code_number = next_code_number++; if (XSTR (insn, 0)[0]) d->name = XSTR (insn, 0); else d->name = 0; /* Build up the list in the same order as the insns are seen in the machine description. */ d->next = 0; if (end_of_insn_data) end_of_insn_data->next = d; else insn_data = d; end_of_insn_data = d; max_opno = -1; num_dups = 0; mybzero (constraints, sizeof constraints); mybzero (op_n_alternatives, sizeof op_n_alternatives); mybzero (predicates, sizeof predicates); mybzero (address_p, sizeof address_p); mybzero (modes, sizeof modes); mybzero (strict_low, sizeof strict_low); for (i = 0; i < XVECLEN (insn, 1); i++) scan_operands (XVECEXP (insn, 1, i), 0, 0); d->n_operands = max_opno + 1; d->n_dups = num_dups; mybcopy (constraints, d->constraints, sizeof constraints); mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives); mybcopy (predicates, d->predicates, sizeof predicates); mybcopy (address_p, d->address_p, sizeof address_p); mybcopy (modes, d->modes, sizeof modes); mybcopy (strict_low, d->strict_low, sizeof strict_low); d->machine_info = XSTR (insn, 4); /* We need to consider only the instructions whose assembler code template starts with a *. These are the ones where the template is really C code to run to decide on a template to use. So for all others just return now. */ if (XSTR (insn, 3)[0] != '*') { d->template = XSTR (insn, 3); d->outfun = 0; return; } d->template = 0; d->outfun = 1; printf ("\nstatic char *\n"); printf ("output_%d (operands, insn)\n", d->code_number); printf (" rtx *operands;\n"); printf (" rtx insn;\n"); printf ("{\n"); /* The following is done in a funny way to get around problems in VAX-11 "C" on VMS. It is the equivalent of: printf ("%s\n", &(XSTR (insn, 3)[1])); */ { register char *cp = &(XSTR (insn, 3)[1]); while (*cp) putchar (*cp++); putchar ('\n'); } printf ("}\n");}/* Look at a define_peephole just read. Assign its code number. Record on insn_data the template and the number of arguments. If the insn has a hairy output action, output it now. */voidgen_peephole (peep) rtx peep;{ register struct data *d = (struct data *) xmalloc (sizeof (struct data)); register int i; d->code_number = next_code_number++; d->name = 0; /* Build up the list in the same order as the insns are seen in the machine description. */ d->next = 0; if (end_of_insn_data) end_of_insn_data->next = d; else insn_data = d; end_of_insn_data = d; max_opno = -1; mybzero (constraints, sizeof constraints); mybzero (op_n_alternatives, sizeof op_n_alternatives); /* Get the number of operands by scanning all the patterns of the peephole optimizer. But ignore all the rest of the information thus obtained. */ for (i = 0; i < XVECLEN (peep, 0); i++) scan_operands (XVECEXP (peep, 0, i), 0, 0); d->n_operands = max_opno + 1; d->n_dups = 0; mybcopy (constraints, d->constraints, sizeof constraints); mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives); mybzero (d->predicates, sizeof predicates); mybzero (d->address_p, sizeof address_p); mybzero (d->modes, sizeof modes); mybzero (d->strict_low, sizeof strict_low); d->machine_info = XSTR (peep, 3); /* We need to consider only the instructions whose assembler code template starts with a *. These are the ones where the template is really C code to run to decide on a template to use. So for all others just return now. */ if (XSTR (peep, 2)[0] != '*') { d->template = XSTR (peep, 2); d->outfun = 0; return; } d->template = 0; d->outfun = 1; printf ("\nstatic char *\n"); printf ("output_%d (operands, insn)\n", d->code_number); printf (" rtx *operands;\n"); printf (" rtx insn;\n"); printf ("{\n"); printf ("%s\n", &(XSTR (peep, 2)[1])); printf ("}\n");}/* Process a define_expand just read. Assign its code number, only for the purposes of `insn_gen_function'. */voidgen_expand (insn) rtx insn;{ register struct data *d = (struct data *) xmalloc (sizeof (struct data)); register int i; d->code_number = next_code_number++; if (XSTR (insn, 0)[0]) d->name = XSTR (insn, 0); else d->name = 0; /* Build up the list in the same order as the insns are seen in the machine description. */ d->next = 0; if (end_of_insn_data) end_of_insn_data->next = d; else insn_data = d; end_of_insn_data = d; max_opno = -1; num_dups = 0; /* Scan the operands to get the specified predicates and modes, since expand_binop needs to know them. */ mybzero (predicates, sizeof predicates); mybzero (modes, sizeof modes); if (XVEC (insn, 1)) for (i = 0; i < XVECLEN (insn, 1); i++) scan_operands (XVECEXP (insn, 1, i), 0, 0); d->n_operands = max_opno + 1; mybcopy (predicates, d->predicates, sizeof predicates); mybcopy (modes, d->modes, sizeof modes); mybzero (d->constraints, sizeof constraints); mybzero (d->op_n_alternatives, sizeof op_n_alternatives); mybzero (d->address_p, sizeof address_p); mybzero (d->strict_low, sizeof strict_low); d->n_dups = 0; d->template = 0; d->outfun = 0; d->machine_info = 0;}intxmalloc (size){ register int val = malloc (size); if (val == 0) fatal ("virtual memory exhausted"); return val;}intxrealloc (ptr, size) char *ptr; int size;{ int result = realloc (ptr, size); if (!result) fatal ("virtual memory exhausted"); return result;}voidmybzero (b, length) register char *b; register int length;{ while (length-- > 0) *b++ = 0;}voidmybcopy (b1, b2, length) register char *b1; register char *b2; register int length;{ while (length-- > 0) *b2++ = *b1++;}voidfatal (s, a1, a2) char *s;{ fprintf (stderr, "genoutput: "); fprintf (stderr, s, a1, a2); fprintf (stderr, "\n"); exit (FATAL_EXIT_CODE);}/* More 'friendly' abort that prints the line and file. config.h can #define abort fancy_abort if you like that sort of thing. */voidfancy_abort (){ fatal ("Internal gcc abort.");}voiderror (s, a1, a2) char *s;{ fprintf (stderr, "genoutput: "); fprintf (stderr, s, a1, a2); fprintf (stderr, "\n");}intmain (argc, argv) int argc; char **argv;{ rtx desc; FILE *infile; extern rtx read_rtx (); register int c; obstack_init (rtl_obstack); if (argc <= 1) fatal ("No input file name."); infile = fopen (argv[1], "r"); if (infile == 0) { perror (argv[1]); exit (FATAL_EXIT_CODE); } init_rtl (); output_prologue (); next_code_number = 0; have_constraints = 0; /* Read the machine description. */ while (1) { c = read_skip_spaces (infile); if (c == EOF) break; ungetc (c, infile); desc = read_rtx (infile); if (GET_CODE (desc) == DEFINE_INSN) gen_insn (desc); if (GET_CODE (desc) == DEFINE_PEEPHOLE) gen_peephole (desc); if (GET_CODE (desc) == DEFINE_EXPAND) gen_expand (desc); } output_epilogue (); fflush (stdout); exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);}intn_occurrences (c, s) char c; char *s;{ int n = 0; while (*s) n += (*s++ == c); return n;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -