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

📄 genrecog.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* Write out C code to perform the decisions in the tree.  */voidwrite_tree (tree, prevpos, afterward, afterpos, initial)     struct decision *tree;     char *prevpos;     int afterward;     char *afterpos;     int initial;{  register struct decision *p, *p1;  char *pos;  register int depth;  int ignmode;  enum anon1 { NO_SWITCH, CODE_SWITCH, MODE_SWITCH } in_switch = NO_SWITCH;  char modemap[NUM_MACHINE_MODES];  char codemap[NUM_RTX_CODE];  pos = prevpos;  if (tree->subroutine_number > 0 && ! initial)    {      printf (" L%d:\n", tree->number);      if (afterward)	{	  printf ("  tem = recog_%d (x0, insn);\n",		  tree->subroutine_number);	  printf ("  if (tem >= 0) return tem;\n");	  change_state (pos, afterpos);	  printf ("  goto L%d;\n", afterward);	}      else	printf ("  return recog_%d (x0, insn);\n",		tree->subroutine_number);      return;    }  tree->label_needed = 1;  for (p = tree; p; p = p->next)    {      /* Find the next alternative to p	 that might be true when p is true.	 Test that one next if p's successors fail.	 Note that when the `tests' field is nonzero	 it is up to the specified test-function to compare machine modes	 and some (such as general_operand) don't always do so.	 But when inside a switch-on-modes we ignore this and	 consider all modes mutually exclusive.  */      for (p1 = p->next; p1; p1 = p1->next)	if (((p->code == UNKNOWN || p1->code == UNKNOWN || p->code == p1->code)	     && (p->mode == VOIDmode || p1->mode == VOIDmode		 || p->mode == p1->mode		 || (in_switch != MODE_SWITCH && (p->tests || p1->tests))))	    || strcmp (p1->position, p->position))	  break;      p->afterward = p1;      if (p1) p1->label_needed = 1;      if (in_switch == MODE_SWITCH	  && (p->mode == VOIDmode || (! p->enforce_mode && p->tests != 0)))	{	  in_switch = NO_SWITCH;	  printf ("  }\n");	}      if (in_switch == CODE_SWITCH && p->code == UNKNOWN)	{	  in_switch = NO_SWITCH;	  printf ("  }\n");	}      if (p->label_needed)	printf (" L%d:\n", p->number);      if (p->success == 0 && p->insn_code_number < 0)	abort ();      change_state (pos, p->position);      pos = p->position;      depth = strlen (pos);      ignmode = p->ignmode || pos[depth - 1] == '*' || p->tests;      if (in_switch == NO_SWITCH)	{	  /* If p and its alternatives all want the same mode,	     reject all others at once, first, then ignore the mode.  */	  if (!ignmode && p->mode != VOIDmode && p->next && same_modes (p, p->mode))	    {	      printf ("  if (GET_MODE (x%d) != %smode)\n",		      depth, GET_MODE_NAME (p->mode));	      if (afterward)		{		  printf ("    {\n    ");		  change_state (pos, afterpos);		  printf ("      goto L%d;\n    }\n", afterward);		}	      else		printf ("    goto ret0;\n");	      clear_modes (p);	      ignmode = 1;	    }	  /* If p and its alternatives all want the same code,	     reject all others at once, first, then ignore the code.  */	  if (p->code != UNKNOWN && p->next && same_codes (p, p->code))	    {	      printf ("  if (GET_CODE (x%d) != ", depth);	      print_code (p->code);	      printf (")\n");	      if (afterward)		{		  printf ("    {");		  change_state (pos, afterpos);		  printf ("    goto L%d; }\n", afterward);		}	      else		printf ("    goto ret0;\n");	      clear_codes (p);	    }	}      /* If p and its alternatives all have different modes	 and there are at least 4 of them, make a switch.  */      if (in_switch == NO_SWITCH && pos[depth-1] != '*')	{	  register int i;	  int lose = 0;	  mybzero (modemap, sizeof modemap);	  for (p1 = p, i = 0;	       (p1 && p1->mode != VOIDmode		&& (p1->tests == 0 || p1->enforce_mode));	       p1 = p1->next, i++)	    {	      if (! p->enforce_mode && modemap[(int) p1->mode])		{		  lose = 1;		  break;		}	      modemap[(int) p1->mode] = 1;	    }	  if (!lose && i >= 4)	    {	      in_switch = MODE_SWITCH;	      printf (" switch (GET_MODE (x%d))\n  {\n", depth);	    }	}      if (in_switch == NO_SWITCH)	{	  register int i;	  mybzero (codemap, sizeof codemap);	  for (p1 = p, i = 0; p1 && p1->code != UNKNOWN; p1 = p1->next, i++)	    {	      if (codemap[(int) p1->code])		break;	      codemap[(int) p1->code] = 1;	    }	  if ((p1 == 0 || p1->code == UNKNOWN) && i >= 4)	    {	      in_switch = CODE_SWITCH;	      printf (" switch (GET_CODE (x%d))\n  {\n", depth);	    }	}      if (in_switch == MODE_SWITCH)	{	  if (modemap[(int) p->mode])	    {	      printf ("  case %smode:\n", GET_MODE_NAME (p->mode));	      modemap[(int) p->mode] = 0;	    }	}      if (in_switch == CODE_SWITCH)	{	  if (codemap[(int) p->code])	    {	      printf ("  case ");	      print_code (p->code);	      printf (":\n");	      codemap[(int) p->code] = 0;	    }	}      printf ("  if (");      if (p->exact || (p->code != UNKNOWN && in_switch != CODE_SWITCH))	{	  if (p->exact)	    printf ("x%d == %s", depth, p->exact);	  else	    {	      printf ("GET_CODE (x%d) == ", depth);	      print_code (p->code);	    }	  printf (" && ");	}      if (p->mode != VOIDmode && !ignmode && in_switch != MODE_SWITCH)	printf ("GET_MODE (x%d) == %smode && ",		depth, GET_MODE_NAME (p->mode));      if (p->test_elt_zero_int)	printf ("XINT (x%d, 0) == %d && ", depth, p->elt_zero_int);      if (p->veclen)	printf ("XVECLEN (x%d, 0) == %d && ", depth, p->veclen);      if (p->test_elt_one_int)	printf ("XINT (x%d, 1) == %d && ", depth, p->elt_one_int);      if (p->dupno >= 0)	printf ("rtx_equal_p (x%d, recog_operand[%d]) && ", depth, p->dupno);      if (p->tests)	printf ("%s (x%d, %smode)", p->tests, depth,		GET_MODE_NAME (p->mode));      else	printf ("1");      if (p->opno >= 0)	printf (")\n    { recog_operand[%d] = x%d; ",		p->opno, depth);      else	printf (")\n    ");      if (p->c_test)	printf ("if (%s) ", p->c_test);      if (p->insn_code_number >= 0)	printf ("return %d;", p->insn_code_number);      else	printf ("goto L%d;", p->success->number);      if (p->opno >= 0)	printf (" }\n");      else	printf ("\n");      /* Now, if inside a switch, branch to next switch member	 that might also need to be tested if this one fails.  */      if (in_switch == CODE_SWITCH)	{	  /* Find the next alternative to p	     that might be applicable if p was applicable.  */	  for (p1 = p->next; p1; p1 = p1->next)	    if (p1->code == UNKNOWN || p->code == p1->code)	      break;	  if (p1 == 0 || p1->code == UNKNOWN)	    printf ("  break;\n");	  else if (p1 != p->next)	    {	      printf (" goto L%d;\n", p1->number);	      p1->label_needed = 1;	    }	}      if (in_switch == MODE_SWITCH)	{	  /* Find the next alternative to p	     that might be applicable if p was applicable.  */	  for (p1 = p->next; p1; p1 = p1->next)	    if (p1->mode == VOIDmode || p->mode == p1->mode)	      break;	  if (p1 == 0 || p1->mode == VOIDmode)	    printf ("  break;\n");	  else if (p1 != p->next)	    {	      printf (" goto L%d;\n", p1->number);	      p1->label_needed = 1;	    }	}    }  if (in_switch != NO_SWITCH)    printf ("  }\n");  if (afterward)    {      change_state (pos, afterpos);      printf ("  goto L%d;\n", afterward);    }  else    printf ("  goto ret0;\n");  for (p = tree; p; p = p->next)    if (p->success)      {	  {	    pos = p->position;	    write_tree (p->success, pos,			p->afterward ? p->afterward->number : afterward,			p->afterward ? pos : afterpos,			0);	  }      }}voidprint_code (code)     RTX_CODE code;{  register char *p1;  for (p1 = GET_RTX_NAME (code); *p1; p1++)    {      if (*p1 >= 'a' && *p1 <= 'z')	putchar (*p1 + 'A' - 'a');      else	putchar (*p1);    }}intsame_codes (p, code)     register struct decision *p;     register RTX_CODE code;{  for (; p; p = p->next)    if (p->code != code)      return 0;  return 1;}voidclear_codes (p)     register struct decision *p;{  for (; p; p = p->next)    p->code = UNKNOWN;}intsame_modes (p, mode)     register struct decision *p;     register enum machine_mode mode;{  for (; p; p = p->next)    if (p->mode != mode || p->tests)      return 0;  return 1;}voidclear_modes (p)     register struct decision *p;{  for (; p; p = p->next)    p->ignmode = 1;}voidchange_state (oldpos, newpos)     char *oldpos;     char *newpos;{  int odepth = strlen (oldpos);  int depth = odepth;  int ndepth = strlen (newpos);  /* Pop up as many levels as necessary.  */  while (strncmp (oldpos, newpos, depth))    --depth;  /* Go down to desired level.  */  while (depth < ndepth)    {      if (newpos[depth] == '*')	printf ("  x%d = recog_addr_dummy;\n  XEXP (x%d, 0) = x%d;\n",		depth + 1, depth + 1, depth);      else if (newpos[depth] >= 'a' && newpos[depth] <= 'z')	printf ("  x%d = XVECEXP (x%d, 0, %d);\n",		depth + 1, depth, newpos[depth] - 'a');      else	printf ("  x%d = XEXP (x%d, %c);\n",		depth + 1, depth, newpos[depth]);      ++depth;    }}char *copystr (s1)     char *s1;{  register char *tem;  if (s1 == 0)    return 0;  tem = (char *) xmalloc (strlen (s1) + 1);  strcpy (tem, s1);  return tem;}voidmybzero (b, length)     register char *b;     register int length;{  while (length-- > 0)    *b++ = 0;}char *concat (s1, s2)     char *s1, *s2;{  register char *tem;  if (s1 == 0)    return s2;  if (s2 == 0)    return s1;  tem = (char *) xmalloc (strlen (s1) + strlen (s2) + 2);  strcpy (tem, s1);  strcat (tem, " ");  strcat (tem, s2);  return tem;}intxrealloc (ptr, size)     char *ptr;     int size;{  int result = realloc (ptr, size);  if (!result)    fatal ("virtual memory exhausted");  return result;}intxmalloc (size){  register int val = malloc (size);  if (val == 0)    fatal ("virtual memory exhausted");  return val;}voidfatal (s, a1, a2)     char *s;{  fprintf (stderr, "genrecog: ");  fprintf (stderr, s, a1, a2);  fprintf (stderr, "\n");  fprintf (stderr, "after %d instruction definitions\n",	   next_insn_code);  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.");}intmain (argc, argv)     int argc;     char **argv;{  rtx desc;  struct decision *tree = 0;  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 ();  next_insn_code = 0;  printf ("/* Generated automatically by the program `genrecog'\n\from the machine description file `md'.  */\n\n");  /* 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)	tree = merge_trees (tree, make_insn_sequence (desc));      if (GET_CODE (desc) == DEFINE_PEEPHOLE	  || GET_CODE (desc) == DEFINE_EXPAND)	next_insn_code++;    }  printf ("#include \"config.h\"\n");  printf ("#include \"rtl.h\"\n");  printf ("#include \"insn-config.h\"\n");  printf ("#include \"recog.h\"\n");  printf ("#include \"real.h\"\n");  printf ("\n\/* `recog' contains a decision tree\n\   that recognizes whether the rtx X0 is a valid instruction.\n\\n\   recog returns -1 if the rtx is not valid.\n\   If the rtx is valid, recog returns a nonnegative number\n\   which is the insn code number for the pattern that matched.\n");  printf ("   This is the same as the order in the machine description of\n\   the entry that matched.  This number can be used as an index into\n\   insn_templates and insn_n_operands (found in insn-output.c)\n\   or as an argument to output_insn_hairy (also in insn-output.c).  */\n\n");  printf ("rtx recog_operand[MAX_RECOG_OPERANDS];\n\n");  printf ("rtx *recog_operand_loc[MAX_RECOG_OPERANDS];\n\n");  printf ("rtx *recog_dup_loc[MAX_DUP_OPERANDS];\n\n");  printf ("char recog_dup_num[MAX_DUP_OPERANDS];\n\n");  printf ("extern rtx recog_addr_dummy;\n\n");  printf ("#define operands recog_operand\n\n");  break_out_subroutines (tree);  printf ("int\nrecog (x0, insn)\n     register rtx x0;\n     rtx insn;\n{\n");  printf ("  register rtx x1, x2, x3, x4, x5;\n  rtx x6, x7, x8, x9, x10, x11;\n");  printf ("  int tem;\n");  write_tree (tree, "", 0, "", 1);  printf (" ret0: return -1;\n}\n");  fflush (stdout);  exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);}

⌨️ 快捷键说明

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