source: trunk/third/gcc/print-rtl.c @ 11288

Revision 11288, 8.1 KB checked in by ghudson, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r11287, which included commits to RCS files with non-trunk default branches.
Line 
1/* Print RTL for GNU C Compiler.
2   Copyright (C) 1987, 1988, 1992, 1997 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21
22#include "config.h"
23#include <ctype.h>
24#include <stdio.h>
25#include "rtl.h"
26
27
28/* How to print out a register name.
29   We don't use PRINT_REG because some definitions of PRINT_REG
30   don't work here.  */
31#ifndef DEBUG_PRINT_REG
32#define DEBUG_PRINT_REG(RTX, CODE, FILE) \
33  fprintf ((FILE), "%d %s", REGNO (RTX), reg_names[REGNO (RTX)])
34#endif
35
36/* Array containing all of the register names */
37
38#ifdef DEBUG_REGISTER_NAMES
39static char *reg_names[] = DEBUG_REGISTER_NAMES;
40#else
41static char *reg_names[] = REGISTER_NAMES;
42#endif
43
44static FILE *outfile;
45
46char spaces[] = "                                                                                                                                                                ";
47
48static int sawclose = 0;
49
50static int indent;
51
52/* Names for patterns.  Non-zero only when linked with insn-output.c.  */
53
54extern char **insn_name_ptr;
55
56/* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */
57
58static void
59print_rtx (in_rtx)
60     register rtx in_rtx;
61{
62  register int i, j;
63  register char *format_ptr;
64  register int is_insn;
65
66  if (sawclose)
67    {
68      fprintf (outfile, "\n%s",
69               (spaces + (sizeof spaces - 1 - indent * 2)));
70      sawclose = 0;
71    }
72
73  if (in_rtx == 0)
74    {
75      fprintf (outfile, "(nil)");
76      sawclose = 1;
77      return;
78    }
79
80  /* print name of expression code */
81  fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
82
83  if (in_rtx->in_struct)
84    fprintf (outfile, "/s");
85
86  if (in_rtx->volatil)
87    fprintf (outfile, "/v");
88
89  if (in_rtx->unchanging)
90    fprintf (outfile, "/u");
91
92  if (in_rtx->integrated)
93    fprintf (outfile, "/i");
94
95  if (GET_MODE (in_rtx) != VOIDmode)
96    {
97      /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
98      if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)
99        fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
100      else
101        fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
102    }
103
104  is_insn = (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i');
105  format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
106
107  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
108    switch (*format_ptr++)
109      {
110      case 'S':
111      case 's':
112        if (i == 3 && GET_CODE (in_rtx) == NOTE
113            && (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_BEG
114                || NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_END))
115          {
116            fprintf (outfile, " %d", NOTE_BLOCK_NUMBER (in_rtx));
117            sawclose = 1;
118            break;
119          }
120        if (XSTR (in_rtx, i) == 0)
121          fprintf (outfile, " \"\"");
122        else
123          fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));
124        sawclose = 1;
125        break;
126
127        /* 0 indicates a field for internal use that should not be printed.  */
128      case '0':
129        break;
130
131      case 'e':
132        indent += 2;
133        if (!sawclose)
134          fprintf (outfile, " ");
135        print_rtx (XEXP (in_rtx, i));
136        indent -= 2;
137        break;
138
139      case 'E':
140      case 'V':
141        indent += 2;
142        if (sawclose)
143          {
144            fprintf (outfile, "\n%s",
145                     (spaces + (sizeof spaces - 1 - indent * 2)));
146            sawclose = 0;
147          }
148        fprintf (outfile, "[ ");
149        if (NULL != XVEC (in_rtx, i))
150          {
151            indent += 2;
152            if (XVECLEN (in_rtx, i))
153              sawclose = 1;
154
155            for (j = 0; j < XVECLEN (in_rtx, i); j++)
156              print_rtx (XVECEXP (in_rtx, i, j));
157
158            indent -= 2;
159          }
160        if (sawclose)
161          fprintf (outfile, "\n%s",
162                   (spaces + (sizeof spaces - 1 - indent * 2)));
163
164        fprintf (outfile, "] ");
165        sawclose = 1;
166        indent -= 2;
167        break;
168
169      case 'w':
170        fprintf (outfile, " ");
171        fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
172        break;
173
174      case 'i':
175        {
176          register int value = XINT (in_rtx, i);
177
178          if (GET_CODE (in_rtx) == REG && value < FIRST_PSEUDO_REGISTER)
179            {
180              fputc (' ', outfile);
181              DEBUG_PRINT_REG (in_rtx, 0, outfile);
182            }
183          else
184            fprintf (outfile, " %d", value);
185        }
186        if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
187            && insn_name_ptr
188            && XINT (in_rtx, i) >= 0)
189          fprintf (outfile, " {%s}", insn_name_ptr[XINT (in_rtx, i)]);
190        sawclose = 0;
191        break;
192
193      /* Print NOTE_INSN names rather than integer codes.  */
194
195      case 'n':
196        if (XINT (in_rtx, i) <= 0)
197          fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
198        else
199          fprintf (outfile, " %d", XINT (in_rtx, i));
200        sawclose = 0;
201        break;
202
203      case 'u':
204        if (XEXP (in_rtx, i) != NULL)
205          fprintf (outfile, " %d", INSN_UID (XEXP (in_rtx, i)));
206        else
207          fprintf (outfile, " 0");
208        sawclose = 0;
209        break;
210
211      case '*':
212        fprintf (outfile, " Unknown");
213        sawclose = 0;
214        break;
215
216      default:
217        fprintf (stderr,
218                 "switch format wrong in rtl.print_rtx(). format was: %c.\n",
219                 format_ptr[-1]);
220        abort ();
221      }
222
223  fprintf (outfile, ")");
224  sawclose = 1;
225}
226
227/* Print an rtx on the current line of FILE.  Initially indent IND
228   characters.  */
229
230void
231print_inline_rtx (outf, x, ind)
232     FILE *outf;
233     rtx x;
234{
235  int oldsaw = sawclose;
236  int oldindent = indent;
237
238  sawclose = 0;
239  indent = ind;
240  outfile = outf;
241  print_rtx (x);
242  sawclose = oldsaw;
243  indent = oldindent;
244}
245
246/* Call this function from the debugger to see what X looks like.  */
247
248void
249debug_rtx (x)
250     rtx x;
251{
252  outfile = stderr;
253  print_rtx (x);
254  fprintf (stderr, "\n");
255}
256
257/* Count of rtx's to print with debug_rtx_list.
258   This global exists because gdb user defined commands have no arguments.  */
259
260int debug_rtx_count = 0;        /* 0 is treated as equivalent to 1 */
261
262/* Call this function to print list from X on.
263
264   N is a count of the rtx's to print. Positive values print from the specified
265   rtx on.  Negative values print a window around the rtx.
266   EG: -5 prints 2 rtx's on either side (in addition to the specified rtx).  */
267
268void
269debug_rtx_list (x, n)
270     rtx x;
271     int n;
272{
273  int i,count;
274  rtx insn;
275
276  count = n == 0 ? 1 : n < 0 ? -n : n;
277
278  /* If we are printing a window, back up to the start.  */
279
280  if (n < 0)
281    for (i = count / 2; i > 0; i--)
282      {
283        if (PREV_INSN (x) == 0)
284          break;
285        x = PREV_INSN (x);
286      }
287
288  for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
289    debug_rtx (insn);
290}
291
292/* Call this function to search an rtx list to find one with insn uid UID,
293   and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
294   The found insn is returned to enable further debugging analysis.  */
295
296rtx
297debug_rtx_find (x, uid)
298     rtx x;
299     int uid;
300{
301  while (x != 0 && INSN_UID (x) != uid)
302    x = NEXT_INSN (x);
303  if (x != 0)
304    {
305      debug_rtx_list (x, debug_rtx_count);
306      return x;
307    }
308  else
309    {
310      fprintf (stderr, "insn uid %d not found\n", uid);
311      return 0;
312    }
313}
314
315/* External entry point for printing a chain of insns
316   starting with RTX_FIRST onto file OUTF.
317   A blank line separates insns.
318
319   If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
320
321void
322print_rtl (outf, rtx_first)
323     FILE *outf;
324     rtx rtx_first;
325{
326  register rtx tmp_rtx;
327
328  outfile = outf;
329  sawclose = 0;
330
331  if (rtx_first == 0)
332    fprintf (outf, "(nil)\n");
333  else
334    switch (GET_CODE (rtx_first))
335      {
336      case INSN:
337      case JUMP_INSN:
338      case CALL_INSN:
339      case NOTE:
340      case CODE_LABEL:
341      case BARRIER:
342        for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx))
343          {
344            print_rtx (tmp_rtx);
345            fprintf (outfile, "\n");
346          }
347        break;
348
349      default:
350        print_rtx (rtx_first);
351      }
352}
353
354/* Like print_rtx, except specify a file.  */
355
356void
357print_rtl_single (outf, x)
358     FILE *outf;
359     rtx x;
360{
361  outfile = outf;
362  sawclose = 0;
363  print_rtx (x);
364  putc ('\n', outf);
365}
Note: See TracBrowser for help on using the repository browser.