OSDN Git Service

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