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

📄 genemit.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 2 页
字号:
  printf ("rtx\ngen_%s (", XSTR (expand, 0));  for (i = 0; i < operands; i++)    printf (i ? ", operand%d" : "operand%d", i);  printf (")\n");  for (i = 0; i < operands; i++)    printf ("     rtx operand%d;\n", i);  printf ("{\n");  /* If we don't have any C code to write, only one insn is being written,     and no MATCH_DUPs are present, we can just return the desired insn     like we do for a DEFINE_INSN.  This saves memory.  */  if ((XSTR (expand, 3) == 0 || *XSTR (expand, 3) == '\0')      && operands > max_dup_opno      && XVECLEN (expand, 1) == 1)    {      printf ("  return ");      gen_exp (XVECEXP (expand, 1, 0));      printf (";\n}\n\n");      return;    }  /* For each operand referred to only with MATCH_DUPs,     make a local variable.  */  for (i = operands; i <= max_dup_opno; i++)    printf ("  rtx operand%d;\n", i);  if (operands > 0 || max_dup_opno >= 0)    printf ("  rtx operands[%d];\n", MAX (operands, max_dup_opno + 1));  printf ("  rtx _val = 0;\n");  printf ("  start_sequence ();\n");  /* The fourth operand of DEFINE_EXPAND is some code to be executed     before the actual construction.     This code expects to refer to `operands'     just as the output-code in a DEFINE_INSN does,     but here `operands' is an automatic array.     So copy the operand values there before executing it.  */  if (XSTR (expand, 3) && *XSTR (expand, 3))    {      /* Output code to copy the arguments into `operands'.  */      for (i = 0; i < operands; i++)	printf ("  operands[%d] = operand%d;\n", i, i);      /* Output the special code to be executed before the sequence	 is generated.  */      printf ("%s\n", XSTR (expand, 3));      /* Output code to copy the arguments back out of `operands'	 (unless we aren't going to use them at all).  */      if (XVEC (expand, 1) != 0)	{	  for (i = 0; i < operands; i++)	    printf ("  operand%d = operands[%d];\n", i, i);	  for (; i <= max_dup_opno; i++)	    printf ("  operand%d = operands[%d];\n", i, i);	}    }  /* Output code to construct the rtl for the instruction bodies.     Use emit_insn to add them to the sequence being accumulated.     But don't do this if the user's code has set `no_more' nonzero.  */  for (i = 0; i < XVECLEN (expand, 1); i++)    {      rtx next = XVECEXP (expand, 1, i);      if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC)	  || (GET_CODE (next) == PARALLEL	      && GET_CODE (XVECEXP (next, 0, 0)) == SET	      && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)	  || GET_CODE (next) == RETURN)	printf ("  emit_jump_insn (");      else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL)	       || GET_CODE (next) == CALL	       || (GET_CODE (next) == PARALLEL		   && GET_CODE (XVECEXP (next, 0, 0)) == SET		   && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL)	       || (GET_CODE (next) == PARALLEL		   && GET_CODE (XVECEXP (next, 0, 0)) == CALL))	printf ("  emit_call_insn (");      else if (GET_CODE (next) == CODE_LABEL)	printf ("  emit_label (");      else if (GET_CODE (next) == MATCH_OPERAND	       || GET_CODE (next) == MATCH_OPERATOR	       || GET_CODE (next) == MATCH_PARALLEL	       || GET_CODE (next) == MATCH_OP_DUP	       || GET_CODE (next) == MATCH_DUP	       || GET_CODE (next) == PARALLEL)	printf ("  emit (");      else	printf ("  emit_insn (");      gen_exp (next);      printf (");\n");      if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC	  && GET_CODE (SET_SRC (next)) == LABEL_REF)	printf ("  emit_barrier ();");    }  /* Call `gen_sequence' to make a SEQUENCE out of all the     insns emitted within this gen_... function.  */  printf (" _done:\n");  printf ("  _val = gen_sequence ();\n");  printf (" _fail:\n");  printf ("  end_sequence ();\n");  printf ("  return _val;\n}\n\n");}/* Like gen_expand, but generates a SEQUENCE.  */static voidgen_split (split)     rtx split;{  register int i;  int operands;  if (XVEC (split, 0) == 0)    fatal ("define_split (definition %d) lacks a pattern", insn_index_number);  else if (XVEC (split, 2) == 0)    fatal ("define_split (definition %d) lacks a replacement pattern",	   insn_index_number);  /* Find out how many operands this function has.  */  max_operand_vec (split, 2);  operands = MAX (max_opno, max_dup_opno) + 1;  /* Output the function name and argument declarations.  */  printf ("rtx\ngen_split_%d (operands)\n     rtx *operands;\n",	  insn_code_number);  printf ("{\n");  /* Declare all local variables.  */  for (i = 0; i < operands; i++)    printf ("  rtx operand%d;\n", i);  printf ("  rtx _val = 0;\n");  printf ("  start_sequence ();\n");  /* The fourth operand of DEFINE_SPLIT is some code to be executed     before the actual construction.  */  if (XSTR (split, 3))    printf ("%s\n", XSTR (split, 3));  /* Output code to copy the arguments back out of `operands'  */  for (i = 0; i < operands; i++)    printf ("  operand%d = operands[%d];\n", i, i);  /* Output code to construct the rtl for the instruction bodies.     Use emit_insn to add them to the sequence being accumulated.     But don't do this if the user's code has set `no_more' nonzero.  */  for (i = 0; i < XVECLEN (split, 2); i++)    {      rtx next = XVECEXP (split, 2, i);      if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC)	  || (GET_CODE (next) == PARALLEL	      && GET_CODE (XVECEXP (next, 0, 0)) == SET	      && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)	  || GET_CODE (next) == RETURN)	printf ("  emit_jump_insn (");      else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL)	       || GET_CODE (next) == CALL	       || (GET_CODE (next) == PARALLEL		   && GET_CODE (XVECEXP (next, 0, 0)) == SET		   && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL)	       || (GET_CODE (next) == PARALLEL		   && GET_CODE (XVECEXP (next, 0, 0)) == CALL))	printf ("  emit_call_insn (");      else if (GET_CODE (next) == CODE_LABEL)	printf ("  emit_label (");      else if (GET_CODE (next) == MATCH_OPERAND	       || GET_CODE (next) == MATCH_OPERATOR	       || GET_CODE (next) == MATCH_PARALLEL	       || GET_CODE (next) == MATCH_OP_DUP	       || GET_CODE (next) == MATCH_DUP	       || GET_CODE (next) == PARALLEL)	printf ("  emit (");      else	printf ("  emit_insn (");      gen_exp (next);      printf (");\n");      if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC	  && GET_CODE (SET_SRC (next)) == LABEL_REF)	printf ("  emit_barrier ();");    }  /* Call `gen_sequence' to make a SEQUENCE out of all the     insns emitted within this gen_... function.  */  printf (" _done:\n");  printf ("  _val = gen_sequence ();\n");  printf (" _fail:\n");  printf ("  end_sequence ();\n");  printf ("  return _val;\n}\n\n");}/* Write a function, `add_clobbers', that is given a PARALLEL of sufficient   size for the insn and an INSN_CODE, and inserts the required CLOBBERs at   the end of the vector.  */static voidoutput_add_clobbers (){  struct clobber_pat *clobber;  struct clobber_ent *ent;  int i;  printf ("\n\nvoid\nadd_clobbers (pattern, insn_code_number)\n");  printf ("     rtx pattern;\n     int insn_code_number;\n");  printf ("{\n");  printf ("  int i;\n\n");  printf ("  switch (insn_code_number)\n");  printf ("    {\n");  for (clobber = clobber_list; clobber; clobber = clobber->next)    {      for (ent = clobber->insns; ent; ent = ent->next)	printf ("    case %d:\n", ent->code_number);      for (i = clobber->first_clobber; i < XVECLEN (clobber->pattern, 1); i++)	{	  printf ("      XVECEXP (pattern, 0, %d) = ", i);	  gen_exp (XVECEXP (clobber->pattern, 1, i));	  printf (";\n");	}      printf ("      break;\n\n");    }  printf ("    default:\n");  printf ("      abort ();\n");  printf ("    }\n");  printf ("}\n");}/* Write a function, init_mov_optab, that is called to set up entries   in mov_optab for EXTRA_CC_MODES.  */static voidoutput_init_mov_optab (){#ifdef EXTRA_CC_NAMES  static char *cc_names[] = { EXTRA_CC_NAMES };  char *p;  int i;  printf ("\nvoid\ninit_mov_optab ()\n{\n");  for (i = 0; i < sizeof cc_names / sizeof cc_names[0]; i++)    {      printf ("#ifdef HAVE_mov");      for (p = cc_names[i]; *p; p++)	printf ("%c", *p >= 'A' && *p <= 'Z' ? *p - 'A' + 'a' : *p);      printf ("\n");      printf ("  if (HAVE_mov");      for (p = cc_names[i]; *p; p++)	printf ("%c", *p >= 'A' && *p <= 'Z' ? *p - 'A' + 'a' : *p);      printf (")\n");      printf ("    mov_optab->handlers[(int) %smode].insn_code = CODE_FOR_mov",	      cc_names[i]);      for (p = cc_names[i]; *p; p++)	printf ("%c", *p >= 'A' && *p <= 'Z' ? *p - 'A' + 'a' : *p);      printf (";\n#endif\n");    }  printf ("}\n");#endif}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 voidfatal (s, a1, a2)     char *s;{  fprintf (stderr, "genemit: ");  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.");}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 ();  /* Assign sequential codes to all entries in the machine description     in parallel with the tables in insn-output.c.  */  insn_code_number = 0;  insn_index_number = 0;  printf ("/* Generated automatically by the program `genemit'\n\from the machine description file `md'.  */\n\n");  printf ("#include \"config.h\"\n");  printf ("#include \"rtl.h\"\n");  printf ("#include \"expr.h\"\n");  printf ("#include \"real.h\"\n");  printf ("#include \"output.h\"\n");  printf ("#include \"insn-config.h\"\n\n");  printf ("#include \"insn-flags.h\"\n\n");  printf ("#include \"insn-codes.h\"\n\n");  printf ("extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS];\n\n");  printf ("extern rtx recog_operand[];\n");  printf ("#define operands emit_operand\n\n");  printf ("#define FAIL goto _fail\n\n");  printf ("#define DONE goto _done\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)	{	  gen_insn (desc);	  ++insn_code_number;	}      if (GET_CODE (desc) == DEFINE_EXPAND)	{	  gen_expand (desc);	  ++insn_code_number;	}      if (GET_CODE (desc) == DEFINE_SPLIT)	{	  gen_split (desc);	  ++insn_code_number;	}      if (GET_CODE (desc) == DEFINE_PEEPHOLE)	{	  ++insn_code_number;	}      ++insn_index_number;    }  /* Write out the routine to add CLOBBERs to a pattern.  */  output_add_clobbers ();  /* Write the routine to initialize mov_optab for the EXTRA_CC_MODES.  */  output_init_mov_optab ();  fflush (stdout);  exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);  /* NOTREACHED */  return 0;}

⌨️ 快捷键说明

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