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

📄 genoutput.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Generate code from to output assembler insns as recognized from rtl.   Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  *//* This program reads the machine description for the compiler target machine   and produces a file containing these things:   1. An array of strings `insn_template' which is indexed by insn code number   and contains the template for output of that insn,   2. An array of functions `insn_outfun' which, indexed by the insn code   number, gives the function that returns a template to use for output of   that insn.  This is used only in the cases where the template is not   constant.  These cases are specified by a * or @ at the beginning of the   template string in the machine description.  They are identified for the   sake of other parts of the compiler by a zero element in `insn_template'.     3. An array of functions `insn_gen_function' which, indexed   by insn code number, gives the function to generate a body   for that pattern, given operands as arguments.   4. An array of strings `insn_name' which, indexed by insn code number,   gives the name for that pattern.  Nameless patterns are given a name.   5. An array of ints `insn_n_operands' which is indexed by insn code number   and contains the number of distinct operands in the pattern for that insn,   6. An array of ints `insn_n_dups' which is indexed by insn code number   and contains the number of match_dup's that appear in the insn's pattern.   This says how many elements of `recog_dup_loc' are significant   after an insn has been recognized.   7. An array of arrays of operand constraint strings,   `insn_operand_constraint',   indexed first by insn code number and second by operand number,   containing the constraint for that operand.   This array is generated only if register constraints appear in    match_operand rtx's.   8. An array of arrays of chars which indicate which operands of   which insn patterns appear within ADDRESS rtx's.  This array is   called `insn_operand_address_p' and is generated only if there   are *no* register constraints in the match_operand rtx's.   9. An array of arrays of machine modes, `insn_operand_mode',   indexed first by insn code number and second by operand number,   containing the machine mode that that operand is supposed to have.   Also `insn_operand_strict_low', which is nonzero for operands   contained in a STRICT_LOW_PART.   10. An array of arrays of int-valued functions, `insn_operand_predicate',   indexed first by insn code number and second by operand number,   containing the match_operand predicate for this operand.   11. An array of ints, `insn_n_alternatives', that gives the number   of alternatives in the constraints of each pattern.The code number of an insn is simply its position in the machine description;code numbers are assigned sequentially to entries in the description,starting with code number 0.Thus, the following entry in the machine description    (define_insn "clrdf"      [(set (match_operand:DF 0 "general_operand" "")	    (const_int 0))]      ""      "clrd %0")assuming it is the 25th entry present, would causeinsn_template[24] to be "clrd %0", and insn_n_operands[24] to be 1.It would not make an case in output_insn_hairy because the templategiven in the entry is a constant (it does not start with `*').  */#include <stdio.h>#include "hconfig.h"#include "rtl.h"#include "obstack.h"/* No instruction can have more operands than this.   Sorry for this arbitrary limit, but what machine will   have an instruction with this many operands?  */#define MAX_MAX_OPERANDS 40static struct obstack obstack;struct obstack *rtl_obstack = &obstack;#define obstack_chunk_alloc xmalloc#define obstack_chunk_free freeextern void free ();extern rtx read_rtx ();char *xmalloc ();static void fatal ();void fancy_abort ();static void error ();static void mybcopy ();static void mybzero ();static int n_occurrences ();/* insns in the machine description are assigned sequential code numbers   that are used by insn-recog.c (produced by genrecog) to communicate   to insn-output.c (produced by this program).  */static int next_code_number;/* This counts all definitions in the md file,   for the sake of error messages.  */static int next_index_number;/* Record in this chain all information that we will output,   associated with the code number of the insn.  */struct data{  int code_number;  int index_number;  char *name;  char *template;		/* string such as "movl %1,%0" */  int n_operands;		/* Number of operands this insn recognizes */  int n_dups;			/* Number times match_dup appears in pattern */  int n_alternatives;		/* Number of alternatives in each constraint */  struct data *next;  char *constraints[MAX_MAX_OPERANDS];  /* Number of alternatives in constraints of operand N.  */  int op_n_alternatives[MAX_MAX_OPERANDS];  char *predicates[MAX_MAX_OPERANDS];  char address_p[MAX_MAX_OPERANDS];  enum machine_mode modes[MAX_MAX_OPERANDS];  char strict_low[MAX_MAX_OPERANDS];  char outfun;			/* Nonzero means this has an output function */};/* This variable points to the first link in the chain.  */struct data *insn_data;/* Pointer to the last link in the chain, so new elements   can be added at the end.  */struct data *end_of_insn_data;/* Nonzero if any match_operand has a constraint string;   implies that REGISTER_CONSTRAINTS will be defined   for this machine description.  */int have_constraints;static voidoutput_prologue (){  printf ("/* Generated automatically by the program `genoutput'\n\from the machine description file `md'.  */\n\n");  printf ("#include \"config.h\"\n");  printf ("#include \"rtl.h\"\n");  printf ("#include \"regs.h\"\n");  printf ("#include \"hard-reg-set.h\"\n");  printf ("#include \"real.h\"\n");  printf ("#include \"insn-config.h\"\n\n");  printf ("#include \"conditions.h\"\n");  printf ("#include \"insn-flags.h\"\n");  printf ("#include \"insn-attr.h\"\n\n");  printf ("#include \"insn-codes.h\"\n\n");  printf ("#include \"recog.h\"\n\n");  printf ("#include <stdio.h>\n");  printf ("#include \"output.h\"\n");}static voidoutput_epilogue (){  register struct data *d;  printf ("\nchar * const insn_template[] =\n  {\n");  for (d = insn_data; d; d = d->next)    {      if (d->template)	printf ("    \"%s\",\n", d->template);      else	printf ("    0,\n");    }  printf ("  };\n");  printf ("\nchar *(*const insn_outfun[])() =\n  {\n");  for (d = insn_data; d; d = d->next)    {      if (d->outfun)	printf ("    output_%d,\n", d->code_number);      else	printf ("    0,\n");    }  printf ("  };\n");  printf ("\nrtx (*const insn_gen_function[]) () =\n  {\n");  for (d = insn_data; d; d = d->next)    {      if (d->name)	printf ("    gen_%s,\n", d->name);      else	printf ("    0,\n");    }  printf ("  };\n");  printf ("\nchar *insn_name[] =\n  {\n");  {    int offset = 0;    int next;    char * last_name = 0;    char * next_name;    register struct data *n;    for (n = insn_data, next = 0; n; n = n->next, next++)      if (n->name)	{	  next_name = n->name;	  break;	}    for (d = insn_data; d; d = d->next)      {	if (d->name)	  {	    printf ("    \"%s\",\n", d->name);	    offset = 0;	    last_name = d->name;	    next_name = 0;	    for (n = d->next, next = 1; n; n = n->next, next++)	      if (n->name)		{		  next_name = n->name;		  break;		}	  }	else	  {	    offset++;	    if (next_name && (last_name == 0 || offset > next / 2))	      printf ("    \"%s-%d\",\n", next_name, next - offset);	    else	      printf ("    \"%s+%d\",\n", last_name, offset);	  }      }  }  printf ("  };\n");  printf ("char **insn_name_ptr = insn_name;\n");  printf ("\nconst int insn_n_operands[] =\n  {\n");  for (d = insn_data; d; d = d->next)    printf ("    %d,\n", d->n_operands);  printf ("  };\n");  printf ("\nconst int insn_n_dups[] =\n  {\n");  for (d = insn_data; d; d = d->next)    printf ("    %d,\n", d->n_dups);  printf ("  };\n");  if (have_constraints)    {      printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n  {\n");      for (d = insn_data; d; d = d->next)	{	  register int i;	  printf ("    {");	  for (i = 0; i < d->n_operands; i++)	    {	      if (d->constraints[i] == 0)		printf (" \"\",");	      else		printf (" \"%s\",", d->constraints[i]);	    }	  if (d->n_operands == 0)	    printf (" 0");	  printf (" },\n");	}      printf ("  };\n");    }  else    {      printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n  {\n");      for (d = insn_data; d; d = d->next)	{	  register int i;	  printf ("    {");	  for (i = 0; i < d->n_operands; i++)	    printf (" %d,", d->address_p[i]);	  if (d->n_operands == 0)	    printf (" 0");	  printf (" },\n");	}      printf ("  };\n");    }  printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n  {\n");  for (d = insn_data; d; d = d->next)    {      register int i;      printf ("    {");      for (i = 0; i < d->n_operands; i++)	printf (" %smode,", GET_MODE_NAME (d->modes[i]));      if (d->n_operands == 0)	printf (" VOIDmode");      printf (" },\n");    }  printf ("  };\n");  printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n  {\n");  for (d = insn_data; d; d = d->next)    {      register int i;      printf ("    {");      for (i = 0; i < d->n_operands; i++)	printf (" %d,", d->strict_low[i]);      if (d->n_operands == 0)	printf (" 0");      printf (" },\n");    }  printf ("  };\n");  {    /* We need to define all predicates used.  Keep a list of those we       have defined so far.  There normally aren't very many predicates used,       so a linked list should be fast enough.  */    struct predicate { char *name; struct predicate *next; } *predicates = 0;    struct predicate *p;    int i;    printf ("\n");    for (d = insn_data; d; d = d->next)      for (i = 0; i < d->n_operands; i++)	if (d->predicates[i] && d->predicates[i][0])	  {	    for (p = predicates; p; p = p->next)	      if (! strcmp (p->name, d->predicates[i]))		break;	    if (p == 0)	      {		printf ("extern int %s ();\n", d->predicates[i]);		p = (struct predicate *) alloca (sizeof (struct predicate));		p->name = d->predicates[i];		p->next = predicates;		predicates = p;	      }	  }        printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n  {\n");    for (d = insn_data; d; d = d->next)      {	printf ("    {");	for (i = 0; i < d->n_operands; i++)	  printf (" %s,", ((d->predicates[i] && d->predicates[i][0])			   ? d->predicates[i] : "0"));	if (d->n_operands == 0)	  printf (" 0");	printf (" },\n");      }    printf ("  };\n");  }  printf ("\nconst int insn_n_alternatives[] =\n  {\n");  for (d = insn_data; d; d = d->next)    printf ("    %d,\n", d->n_alternatives);  printf("  };\n");}/* scan_operands (X) stores in max_opno the largest operand   number present in X, if that is larger than the previous   value of max_opno.  It stores all the constraints in `constraints'   and all the machine modes in `modes'.   THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.   THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART.  */static int max_opno;static int num_dups;static char *constraints[MAX_MAX_OPERANDS];static int op_n_alternatives[MAX_MAX_OPERANDS];static char *predicates[MAX_MAX_OPERANDS];static char address_p[MAX_MAX_OPERANDS];static enum machine_mode modes[MAX_MAX_OPERANDS];static char strict_low[MAX_MAX_OPERANDS];static char seen[MAX_MAX_OPERANDS];static voidscan_operands (part, this_address_p, this_strict_low)     rtx part;     int this_address_p;     int this_strict_low;{  register int i, j;  register char *format_ptr;  int opno;  if (part == 0)    return;  switch (GET_CODE (part))    {    case MATCH_OPERAND:      opno = XINT (part, 0);      if (opno > max_opno)	max_opno = opno;      if (max_opno >= MAX_MAX_OPERANDS)	{	  error ("Too many operands (%d) in definition %d.\n",		 max_opno + 1, next_index_number);	  return;	}      if (seen[opno])	error ("Definition %d specified operand number %d more than once.\n",	       next_index_number, opno);      seen[opno] = 1;      modes[opno] = GET_MODE (part);      strict_low[opno] = this_strict_low;      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;    case MATCH_SCRATCH:      opno = XINT (part, 0);      if (opno > max_opno)	max_opno = opno;      if (max_opno >= MAX_MAX_OPERANDS)	{	  error ("Too many operands (%d) in definition %d.\n",		 max_opno + 1, next_index_number);	  return;	}      if (seen[opno])	error ("Definition %d specified operand number %d more than once.\n",	       next_index_number, opno);      seen[opno] = 1;      modes[opno] = GET_MODE (part);      strict_low[opno] = 0;      predicates[opno] = "scratch_operand";      constraints[opno] = XSTR (part, 1);      if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)	{	  op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;	  have_constraints = 1;	}      address_p[opno] = 0;      return;    case MATCH_OPERATOR:    case MATCH_PARALLEL:      opno = XINT (part, 0);      if (opno > max_opno)	max_opno = opno;      if (max_opno >= MAX_MAX_OPERANDS)	{	  error ("Too many operands (%d) in definition %d.\n",		 max_opno + 1, next_index_number);	  return;	}      if (seen[opno])	error ("Definition %d specified operand number %d more than once.\n",	       next_index_number, opno);      seen[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;

⌨️ 快捷键说明

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