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

📄 rtl.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Allocate, read and print RTL for C-Compiler   Copyright (C) 1987, 1988 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 1, 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.  */#include "config.h"#include <ctype.h>#include <stdio.h>#include "rtl.h"#include "obstack.h"#define	obstack_chunk_alloc	xmalloc#define	obstack_chunk_free	freeextern int xmalloc ();extern void free ();/* Obstack used for allocating RTL objects.   Between functions, this is the permanent_obstack.   While parsing and expanding a function, this is maybepermanent_obstack   so we can save it if it is an inline function.   During optimization and output, this is temporary_obstack.  */extern struct obstack *rtl_obstack;#define MIN(x,y) ((x < y) ? x : y)extern long ftell();/* Indexed by rtx code, gives number of operands for an rtx with that code.   Does NOT include rtx header data (code and links).   This array is initialized in init_rtl.  */int rtx_length[NUM_RTX_CODE + 1];/* Indexed by rtx code, gives the name of that kind of rtx, as a C string.  */#define DEF_RTL_EXPR(ENUM, NAME, FORMAT)   NAME ,char *rtx_name[] = {#include "rtl.def"		/* rtl expressions are documented here */};#undef DEF_RTL_EXPR/* Indexed by machine mode, gives the name of that machine mode.   This name does not include the letters "mode".  */#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  NAME,char *mode_name[] = {#include "machmode.def"};#undef DEF_MACHMODE/* Indexed by machine mode, gives the length of the mode, in bytes.   GET_MODE_CLASS uses this.  */#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  CLASS,enum mode_class mode_class[] = {#include "machmode.def"};#undef DEF_MACHMODE/* Indexed by machine mode, gives the length of the mode, in bytes.   GET_MODE_SIZE uses this.  */#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \  (SIZE*UNITS_PER_WORD+3)/4,int mode_size[] = {#include "machmode.def"};#undef DEF_MACHMODE/* Indexed by machine mode, gives the length of the mode's subunit.   GET_MODE_UNIT_SIZE uses this.  */#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \  (UNIT*UNITS_PER_WORD+3)/4,int mode_unit_size[] = {#include "machmode.def"		/* machine modes are documented here */};#undef DEF_MACHMODE/* Indexed by machine mode, gives next wider natural mode   (QI -> HI -> SI -> DI, etc.)  Widening multiply instructions   use this.  */#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \  (enum machine_mode) WIDER,enum machine_mode mode_wider_mode[] = {#include "machmode.def"		/* machine modes are documented here */};#undef DEF_MACHMODE/* Indexed by rtx code, gives a sequence of operand-types for   rtx's of that code.  The sequence is a C string in which   each charcter describes one operand.  */char *rtx_format[] = {  /* "*" undefined.         can cause a warning message     "0" field is unused (or used in a phase-dependent manner)         prints nothing     "i" an integer         prints the integer     "s" a pointer to a string         prints the string     "S" like "s", but optional:	 the containing rtx may end before this operand     "e" a pointer to an rtl expression         prints the expression     "E" a pointer to a vector that points to a number of rtl expressions         prints a list of the rtl expressions     "u" a pointer to another insn         prints the uid of the insn.  */#define DEF_RTL_EXPR(ENUM, NAME, FORMAT)   FORMAT ,#include "rtl.def"		/* rtl expressions are defined here */#undef DEF_RTL_EXPR};/* Names for kinds of NOTEs and REG_NOTEs.  */char *note_insn_name[] = { "NOTE_INSN_FUNCTION_BEG", "NOTE_INSN_DELETED",			   "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",			   "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",			   "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",			   "NOTE_INSN_LOOP_CONT" };char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",			  "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",			  "REG_NONNEG", "REG_UNSET" };/* Allocate an rtx vector of N elements.   Store the length, and initialize all elements to zero.  */rtvecrtvec_alloc (n)     int n;{  rtvec rt;  int i;  rt = (rtvec) obstack_alloc (rtl_obstack,			      sizeof (struct rtvec_def)			      + (( n - 1) * sizeof (rtunion)));  /* clear out the vector */  PUT_NUM_ELEM(rt, n);  for (i=0; i < n; i++)    rt->elem[i].rtvec = NULL;	/* @@ not portable due to rtunion */  return rt;}/* Allocate an rtx of code CODE.  The CODE is stored in the rtx;   all the rest is initialized to zero.  */rtxrtx_alloc (code)  RTX_CODE code;{  rtx rt;  register int nelts = GET_RTX_LENGTH (code);  register int length = sizeof (struct rtx_def)    + (nelts - 1) * sizeof (rtunion);  rt = (rtx) obstack_alloc (rtl_obstack, length);  * (int *) rt = 0;  PUT_CODE (rt, code);  return rt;}/* Create a new copy of an rtx.   Recursively copies the operands of the rtx,   except for those few rtx codes that are sharable.  */rtxcopy_rtx (orig)     register rtx orig;{  register rtx copy;  register int i, j;  register RTX_CODE code;  register char *format_ptr;  code = GET_CODE (orig);  switch (code)    {    case REG:    case QUEUED:    case CONST_INT:    case CONST_DOUBLE:    case SYMBOL_REF:    case CODE_LABEL:    case PC:    case CC0:      return orig;    }  copy = rtx_alloc (code);  PUT_MODE (copy, GET_MODE (orig));  copy->in_struct = orig->in_struct;  copy->volatil = orig->volatil;  copy->unchanging = orig->unchanging;  copy->integrated = orig->integrated;    format_ptr = GET_RTX_FORMAT (GET_CODE (copy));  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)    {      switch (*format_ptr++)	{	case 'e':	  XEXP (copy, i) = XEXP (orig, i);	  if (XEXP (orig, i) != NULL)	    XEXP (copy, i) = copy_rtx (XEXP (orig, i));	  break;	case 'E':	  XVEC (copy, i) = XVEC (orig, i);	  if (XVEC (orig, i) != NULL)	    {	      XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));	      for (j = 0; j < XVECLEN (copy, i); j++)		XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));	    }	  break;	default:	  XINT (copy, i) = XINT (orig, i);	  break;	}    }  return copy;}/* Printing rtl for debugging dumps.  */static FILE *outfile;char spaces[] = "                                                                                                                                                                ";static int sawclose = 0;/* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */static voidprint_rtx (in_rtx)     register rtx in_rtx;{  static int indent;  register int i, j;  register char *format_ptr;  if (sawclose)    {      fprintf (outfile, "\n%s",	       (spaces + (sizeof spaces - indent * 2)));      sawclose = 0;    }  if (in_rtx == 0)    {      fprintf (outfile, "(nil)");      sawclose = 1;      return;    }  /* print name of expression code */  fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));  if (in_rtx->in_struct)    fprintf (outfile, "/s");  if (in_rtx->volatil)    fprintf (outfile, "/v");  if (in_rtx->unchanging)    fprintf (outfile, "/u");  if (in_rtx->integrated)    fprintf (outfile, "/i");  if (GET_MODE (in_rtx) != VOIDmode)    {      /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */      if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)	fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));      else	fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));    }  format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)    switch (*format_ptr++)      {      case 'S':      case 's':	if (XSTR (in_rtx, i) == 0)	  fprintf (outfile, " \"\"");	else	  fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));	sawclose = 1;	break;	/* 0 indicates a field for internal use that should not be printed.  */      case '0':	break;      case 'e':	indent += 2;	if (!sawclose)	  fprintf (outfile, " ");	print_rtx (XEXP (in_rtx, i));	indent -= 2;	break;      case 'E':	indent += 2;	if (sawclose)	  {	    fprintf (outfile, "\n%s",		     (spaces + (sizeof spaces - indent * 2)));	    sawclose = 0;	  }	fprintf (outfile, "[ ");	if (NULL != XVEC (in_rtx, i))	  {	    indent += 2;	    if (XVECLEN (in_rtx, i))	      sawclose = 1;	    for (j = 0; j < XVECLEN (in_rtx, i); j++)	      print_rtx (XVECEXP (in_rtx, i, j));	    indent -= 2;	  }	if (sawclose)	  fprintf (outfile, "\n%s",		   (spaces + (sizeof spaces - indent * 2)));	fprintf (outfile, "] ");	sawclose = 1;	indent -= 2;	break;      case 'i':	fprintf (outfile, " %d", XINT (in_rtx, i));	sawclose = 0;	break;      /* Print NOTE_INSN names rather than integer codes.  */      case 'n':	if (XINT (in_rtx, i) <= 0)	  fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));	else	  fprintf (outfile, " %d", XINT (in_rtx, i));	sawclose = 0;	break;      case 'u':	if (XEXP (in_rtx, i) != NULL)	  fprintf(outfile, " %d", INSN_UID (XEXP (in_rtx, i)));	else	  fprintf(outfile, " 0");	sawclose = 0;	break;      default:	fprintf (stderr,		 "switch format wrong in rtl.print_rtx(). format was: %c.\n",		 format_ptr[-1]);	abort ();      }  fprintf (outfile, ")");

⌨️ 快捷键说明

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