⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genoutput.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 2 页
字号:
      return;    case MATCH_DUP:    case MATCH_OP_DUP:    case MATCH_PAR_DUP:      ++num_dups;      return;    case ADDRESS:      scan_operands (XEXP (part, 0), 1, 0);      return;    case 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;      }}/* Process an assembler template from a define_insn or a define_peephole.   It is either the assembler code template, a list of assembler code   templates, or C code to generate the assembler code template.  */static voidprocess_template (d, template)    struct data *d;    char *template;{  register char *cp;  register int i;  /* We need to consider only the instructions whose assembler code template     starts with a * or @.  These are the ones where C code is run to decide     on a template to use.  So for all others just return now.  */  if (template[0] != '*' && template[0] != '@')    {      d->template = template;      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");  /* If the assembler code template starts with a @ it is a newline-separated     list of assembler code templates, one for each alternative.  So produce     a routine to select the correct one.  */  if (template[0] == '@')    {      printf ("  static /*const*/ char *const strings_%d[] = {\n",	      d->code_number);      for (i = 0, cp = &template[1]; *cp; )	{	  while (*cp == '\n' || *cp == ' ' || *cp== '\t')	    cp++;	  printf ("    \"");	  while (*cp != '\n' && *cp != '\0')	    putchar (*cp++);	  printf ("\",\n");	  i++;	}      printf ("  };\n");      printf ("  return strings_%d[which_alternative];\n", d->code_number);      if (i != d->n_alternatives)	fatal ("Insn pattern %d has %d alternatives but %d assembler choices",	       d->index_number, d->n_alternatives, i);    }  else    {       /* 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", &template[1])); */      cp = &template[1];      while (*cp) putchar (*cp++);      putchar ('\n');    }  printf ("}\n");}/* Check insn D for consistency in number of constraint alternatives.  */static voidvalidate_insn_alternatives (d)     struct data *d;{  register int n = 0, start;  /* Make sure all the operands have the same number of     alternatives in their constraints.     Let N be that number.  */  for (start = 0; start < d->n_operands; start++)    if (d->op_n_alternatives[start] > 0)      {	if (n == 0)	  n = d->op_n_alternatives[start];	else if (n != d->op_n_alternatives[start])	  error ("wrong number of alternatives in operand %d of insn number %d",		 start, d->index_number);      }  /* Record the insn's overall number of alternatives.  */  d->n_alternatives = n;}/* 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.  */static voidgen_insn (insn)     rtx insn;{  register struct data *d = (struct data *) xmalloc (sizeof (struct data));  register int i;  d->code_number = next_code_number++;  d->index_number = next_index_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);  mybzero (seen, sizeof seen);  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);  validate_insn_alternatives (d);  process_template (d, XSTR (insn, 3));}/* 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.  */static 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->index_number = next_index_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);  mybzero (predicates, sizeof predicates);  mybzero (address_p, sizeof address_p);  mybzero (modes, sizeof modes);  mybzero (strict_low, sizeof strict_low);  mybzero (seen, sizeof seen);  /* 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);  validate_insn_alternatives (d);  process_template (d, XSTR (peep, 2));}/* Process a define_expand just read.  Assign its code number,   only for the purposes of `insn_gen_function'.  */static voidgen_expand (insn)     rtx insn;{  register struct data *d = (struct data *) xmalloc (sizeof (struct data));  register int i;  d->code_number = next_code_number++;  d->index_number = next_index_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 (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);  mybzero (seen, sizeof seen);  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;  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->template = 0;  d->outfun = 0;  validate_insn_alternatives (d);}/* Process a define_split just read.  Assign its code number,   only for reasons of consistency and to simplify genrecog.  */static voidgen_split (split)     rtx split;{  register struct data *d = (struct data *) xmalloc (sizeof (struct data));  register int i;  d->code_number = next_code_number++;  d->index_number = next_index_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;  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);  mybzero (seen, sizeof seen);  /* Get the number of operands by scanning all the     patterns of the split patterns.     But ignore all the rest of the information thus obtained.  */  for (i = 0; i < XVECLEN (split, 0); i++)    scan_operands (XVECEXP (split, 0, i), 0, 0);  d->n_operands = max_opno + 1;  mybzero (d->constraints, sizeof constraints);  mybzero (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->n_dups = 0;  d->n_alternatives = 0;  d->template = 0;  d->outfun = 0;}char *xmalloc (size)     unsigned size;{  register char *val = (char *) malloc (size);  if (val == 0)    fatal ("virtual memory exhausted");  return val;}char *xrealloc (ptr, size)     char *ptr;     unsigned size;{  char *result = (char *) realloc (ptr, size);  if (!result)    fatal ("virtual memory exhausted");  return result;}static voidmybzero (b, length)     register char *b;     register unsigned length;{  while (length-- > 0)    *b++ = 0;}static voidmybcopy (b1, b2, length)     register char *b1;     register char *b2;     register unsigned length;{  while (length-- > 0)    *b2++ = *b1++;}static voidfatal (s, a1, a2, a3, a4)     char *s;{  fprintf (stderr, "genoutput: ");  fprintf (stderr, s, a1, a2, a3, a4);  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.");}static voiderror (s, a1, a2)     char *s;{  fprintf (stderr, "genoutput: ");  fprintf (stderr, s, a1, a2);  fprintf (stderr, "\n");  have_error = 1;}intmain (argc, argv)     int argc;     char **argv;{  rtx desc;  FILE *infile;  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;  next_index_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);      if (GET_CODE (desc) == DEFINE_SPLIT)	gen_split (desc);      next_index_number++;    }  output_epilogue ();  fflush (stdout);  exit (ferror (stdout) != 0 || have_error	? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);  /* NOTREACHED */  return 0;}static intn_occurrences (c, s)     int c;     char *s;{  int n = 0;  while (*s)    n += (*s++ == c);  return n;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -