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

Revision 8834, 7.4 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, 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 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
50/* Names for patterns.  Non-zero only when linked with insn-output.c.  */
51
52extern char **insn_name_ptr;
53
54/* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */
55
56static void
57print_rtx (in_rtx)
58     register rtx in_rtx;
59{
60  static int indent;
61  register int i, j;
62  register char *format_ptr;
63  register int is_insn;
64
65  if (sawclose)
66    {
67      fprintf (outfile, "\n%s",
68               (spaces + (sizeof spaces - 1 - indent * 2)));
69      sawclose = 0;
70    }
71
72  if (in_rtx == 0)
73    {
74      fprintf (outfile, "(nil)");
75      sawclose = 1;
76      return;
77    }
78
79  /* print name of expression code */
80  fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
81
82  if (in_rtx->in_struct)
83    fprintf (outfile, "/s");
84
85  if (in_rtx->volatil)
86    fprintf (outfile, "/v");
87
88  if (in_rtx->unchanging)
89    fprintf (outfile, "/u");
90
91  if (in_rtx->integrated)
92    fprintf (outfile, "/i");
93
94  if (GET_MODE (in_rtx) != VOIDmode)
95    {
96      /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
97      if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)
98        fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
99      else
100        fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
101    }
102
103  is_insn = (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i');
104  format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
105
106  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
107    switch (*format_ptr++)
108      {
109      case 'S':
110      case 's':
111        if (XSTR (in_rtx, i) == 0)
112          fprintf (outfile, " \"\"");
113        else
114          fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));
115        sawclose = 1;
116        break;
117
118        /* 0 indicates a field for internal use that should not be printed.  */
119      case '0':
120        break;
121
122      case 'e':
123        indent += 2;
124        if (!sawclose)
125          fprintf (outfile, " ");
126        print_rtx (XEXP (in_rtx, i));
127        indent -= 2;
128        break;
129
130      case 'E':
131      case 'V':
132        indent += 2;
133        if (sawclose)
134          {
135            fprintf (outfile, "\n%s",
136                     (spaces + (sizeof spaces - 1 - indent * 2)));
137            sawclose = 0;
138          }
139        fprintf (outfile, "[ ");
140        if (NULL != XVEC (in_rtx, i))
141          {
142            indent += 2;
143            if (XVECLEN (in_rtx, i))
144              sawclose = 1;
145
146            for (j = 0; j < XVECLEN (in_rtx, i); j++)
147              print_rtx (XVECEXP (in_rtx, i, j));
148
149            indent -= 2;
150          }
151        if (sawclose)
152          fprintf (outfile, "\n%s",
153                   (spaces + (sizeof spaces - 1 - indent * 2)));
154
155        fprintf (outfile, "] ");
156        sawclose = 1;
157        indent -= 2;
158        break;
159
160      case 'w':
161        fprintf (outfile,
162#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
163                 " %d",
164#else
165                 " %ld",
166#endif
167                 XWINT (in_rtx, i));
168        break;
169
170      case 'i':
171        {
172          register int value = XINT (in_rtx, i);
173
174          if (GET_CODE (in_rtx) == REG && value < FIRST_PSEUDO_REGISTER)
175            {
176              fputc (' ', outfile);
177              DEBUG_PRINT_REG (in_rtx, 0, outfile);
178            }
179          else
180            fprintf (outfile, " %d", value);
181        }
182        if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
183            && insn_name_ptr
184            && XINT (in_rtx, i) >= 0)
185          fprintf (outfile, " {%s}", insn_name_ptr[XINT (in_rtx, i)]);
186        sawclose = 0;
187        break;
188
189      /* Print NOTE_INSN names rather than integer codes.  */
190
191      case 'n':
192        if (XINT (in_rtx, i) <= 0)
193          fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
194        else
195          fprintf (outfile, " %d", XINT (in_rtx, i));
196        sawclose = 0;
197        break;
198
199      case 'u':
200        if (XEXP (in_rtx, i) != NULL)
201          fprintf (outfile, " %d", INSN_UID (XEXP (in_rtx, i)));
202        else
203          fprintf (outfile, " 0");
204        sawclose = 0;
205        break;
206
207      case '*':
208        fprintf (outfile, " Unknown");
209        sawclose = 0;
210        break;
211
212      default:
213        fprintf (stderr,
214                 "switch format wrong in rtl.print_rtx(). format was: %c.\n",
215                 format_ptr[-1]);
216        abort ();
217      }
218
219  fprintf (outfile, ")");
220  sawclose = 1;
221}
222
223/* Call this function from the debugger to see what X looks like.  */
224
225void
226debug_rtx (x)
227     rtx x;
228{
229  outfile = stderr;
230  print_rtx (x);
231  fprintf (stderr, "\n");
232}
233
234/* Count of rtx's to print with debug_rtx_list.
235   This global exists because gdb user defined commands have no arguments.  */
236
237int debug_rtx_count = 0;        /* 0 is treated as equivalent to 1 */
238
239/* Call this function to print list from X on.
240
241   N is a count of the rtx's to print. Positive values print from the specified
242   rtx on.  Negative values print a window around the rtx.
243   EG: -5 prints 2 rtx's on either side (in addition to the specified rtx).  */
244
245void
246debug_rtx_list (x, n)
247     rtx x;
248     int n;
249{
250  int i,count;
251  rtx insn;
252
253  count = n == 0 ? 1 : n < 0 ? -n : n;
254
255  /* If we are printing a window, back up to the start.  */
256
257  if (n < 0)
258    for (i = count / 2; i > 0; i--)
259      {
260        if (PREV_INSN (x) == 0)
261          break;
262        x = PREV_INSN (x);
263      }
264
265  for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
266    debug_rtx (insn);
267}
268
269/* Call this function to search an rtx list to find one with insn uid UID,
270   and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
271   The found insn is returned to enable further debugging analysis.  */
272
273rtx
274debug_rtx_find(x, uid)
275     rtx x;
276     int uid;
277{
278  while (x != 0 && INSN_UID (x) != uid)
279    x = NEXT_INSN (x);
280  if (x != 0)
281    {
282      debug_rtx_list (x, debug_rtx_count);
283      return x;
284    }
285  else
286    {
287      fprintf (stderr, "insn uid %d not found\n", uid);
288      return 0;
289    }
290}
291
292/* External entry point for printing a chain of insns
293   starting with RTX_FIRST onto file OUTF.
294   A blank line separates insns.
295
296   If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
297
298void
299print_rtl (outf, rtx_first)
300     FILE *outf;
301     rtx rtx_first;
302{
303  register rtx tmp_rtx;
304
305  outfile = outf;
306  sawclose = 0;
307
308  if (rtx_first == 0)
309    fprintf (outf, "(nil)\n");
310  else
311    switch (GET_CODE (rtx_first))
312      {
313      case INSN:
314      case JUMP_INSN:
315      case CALL_INSN:
316      case NOTE:
317      case CODE_LABEL:
318      case BARRIER:
319        for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx))
320          {
321            print_rtx (tmp_rtx);
322            fprintf (outfile, "\n");
323          }
324        break;
325
326      default:
327        print_rtx (rtx_first);
328      }
329}
Note: See TracBrowser for help on using the repository browser.