Introduce ORIGINAL_REGNO macro
[platform/upstream/gcc.git] / gcc / print-rtl.c
1 /* Print RTL for GNU C Compiler.
2    Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000
3    Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "rtl.h"
26 #include "real.h"
27 #include "flags.h"
28 #include "hard-reg-set.h"
29 #include "basic-block.h"
30
31 /* How to print out a register name.
32    We don't use PRINT_REG because some definitions of PRINT_REG
33    don't work here.  */
34 #ifndef DEBUG_PRINT_REG
35 #define DEBUG_PRINT_REG(RTX, CODE, FILE) \
36   fprintf ((FILE), "%d %s", REGNO (RTX), reg_names[REGNO (RTX)])
37 #endif
38
39 /* Array containing all of the register names */
40
41 #ifdef DEBUG_REGISTER_NAMES
42 static const char * const debug_reg_names[] = DEBUG_REGISTER_NAMES;
43 #define reg_names debug_reg_names
44 #else
45 const char * reg_names[] = REGISTER_NAMES;
46 #endif
47
48 static FILE *outfile;
49
50 static const char xspaces[] = "                                                                                                                                                                ";
51
52 static int sawclose = 0;
53
54 static int indent;
55
56 static void print_rtx           PARAMS ((rtx));
57
58 /* String printed at beginning of each RTL when it is dumped.
59    This string is set to ASM_COMMENT_START when the RTL is dumped in
60    the assembly output file.  */
61 const char *print_rtx_head = "";
62
63 /* Nonzero means suppress output of instruction numbers and line number
64    notes in debugging dumps.
65    This must be defined here so that programs like gencodes can be linked.  */
66 int flag_dump_unnumbered = 0;
67
68 /* Nonzero if we are dumping graphical description.  */
69 int dump_for_graph;
70
71 /* Nonzero to dump all call_placeholder alternatives.  */
72 static int debug_call_placeholder_verbose;
73
74 /* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */
75
76 static void
77 print_rtx (in_rtx)
78      register rtx in_rtx;
79 {
80   register int i = 0;
81   register int j;
82   register const char *format_ptr;
83   register int is_insn;
84   rtx tem;
85
86   if (sawclose)
87     {
88       fprintf (outfile, "\n%s%s",
89                print_rtx_head,
90                (xspaces + (sizeof xspaces - 1 - indent * 2)));
91       sawclose = 0;
92     }
93
94   if (in_rtx == 0)
95     {
96       fputs ("(nil)", outfile);
97       sawclose = 1;
98       return;
99     }
100
101   is_insn = (INSN_P (in_rtx));
102
103   /* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER
104      in separate nodes and therefore have to handle them special here.  */
105   if (dump_for_graph &&
106       (is_insn || GET_CODE (in_rtx) == NOTE || GET_CODE (in_rtx) == CODE_LABEL
107        || GET_CODE (in_rtx) == BARRIER))
108     {
109       i = 3;
110       indent = 0;
111     }
112   else
113     {
114       /* print name of expression code */
115       fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
116
117       if (in_rtx->in_struct)
118         fputs ("/s", outfile);
119
120       if (in_rtx->volatil)
121         fputs ("/v", outfile);
122
123       if (in_rtx->unchanging)
124         fputs ("/u", outfile);
125
126       if (in_rtx->integrated)
127         fputs ("/i", outfile);
128
129       if (in_rtx->frame_related)
130         fputs ("/f", outfile);
131
132       if (in_rtx->jump)
133         fputs ("/j", outfile);
134
135       if (in_rtx->call)
136         fputs ("/c", outfile);
137
138       if (GET_MODE (in_rtx) != VOIDmode)
139         {
140           /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
141           if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)
142             fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
143           else
144             fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
145         }
146     }
147
148   /* Get the format string and skip the first elements if we have handled
149      them already.  */
150   format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i;
151
152   for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
153     switch (*format_ptr++)
154       {
155       case 'S':
156       case 's':
157         if (XSTR (in_rtx, i) == 0)
158           fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
159         else
160           {
161             if (dump_for_graph)
162               fprintf (outfile, " (\\\"%s\\\")", XSTR (in_rtx, i));
163             else
164               fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));
165           }
166         sawclose = 1;
167         break;
168
169         /* 0 indicates a field for internal use that should not be printed.
170            An exception is the third field of a NOTE, where it indicates
171            that the field has several different valid contents.  */
172       case '0':
173         if (i == 1 && GET_CODE (in_rtx) == REG)
174           {
175             if (REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
176               fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
177             break;
178           }
179         if (i == 3 && GET_CODE (in_rtx) == NOTE)
180           {
181             switch (NOTE_LINE_NUMBER (in_rtx))
182               {
183               case NOTE_INSN_EH_REGION_BEG:
184               case NOTE_INSN_EH_REGION_END:
185                 if (flag_dump_unnumbered)
186                   fprintf (outfile, " #");
187                 else
188                   fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx));
189                 sawclose = 1;
190                 break;
191
192               case NOTE_INSN_BLOCK_BEG:
193               case NOTE_INSN_BLOCK_END:
194                 fprintf (outfile, " ");
195                 if (flag_dump_unnumbered)
196                   fprintf (outfile, "#");
197                 else
198                   fprintf (outfile, HOST_PTR_PRINTF, 
199                            (char *) NOTE_BLOCK (in_rtx));
200                 sawclose = 1;
201                 break;
202
203               case NOTE_INSN_RANGE_BEG:
204               case NOTE_INSN_RANGE_END:
205               case NOTE_INSN_LIVE:
206                 indent += 2;
207                 if (!sawclose)
208                   fprintf (outfile, " ");
209                 print_rtx (NOTE_RANGE_INFO (in_rtx));
210                 indent -= 2;
211                 break;
212
213               case NOTE_INSN_BASIC_BLOCK:
214                 {
215                   basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
216                   if (bb != 0)
217                     fprintf (outfile, " [bb %d]", bb->index);
218                   break;
219                 }
220
221               case NOTE_INSN_EXPECTED_VALUE:
222                 indent += 2;
223                 if (!sawclose)
224                   fprintf (outfile, " ");
225                 print_rtx (NOTE_EXPECTED_VALUE (in_rtx));
226                 indent -= 2;
227                 break;
228
229               case NOTE_INSN_DELETED_LABEL:
230                 if (NOTE_SOURCE_FILE (in_rtx))
231                   fprintf (outfile, " (\"%s\")", NOTE_SOURCE_FILE (in_rtx));
232                 else
233                   fprintf (outfile, " \"\"");
234                 break;
235
236               default:
237                 {
238                   const char * const str = X0STR (in_rtx, i);
239
240                   if (NOTE_LINE_NUMBER (in_rtx) < 0)
241                     ;
242                   else if (str == 0)
243                     fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
244                   else
245                     {
246                       if (dump_for_graph)
247                         fprintf (outfile, " (\\\"%s\\\")", str);
248                       else
249                         fprintf (outfile, " (\"%s\")", str);
250                     }
251                   break;
252                 }
253               }
254           }
255         break;
256
257       case 'e':
258       do_e:
259         indent += 2;
260         if (!sawclose)
261           fprintf (outfile, " ");
262         print_rtx (XEXP (in_rtx, i));
263         indent -= 2;
264         break;
265
266       case 'E':
267       case 'V':
268         indent += 2;
269         if (sawclose)
270           {
271             fprintf (outfile, "\n%s%s",
272                      print_rtx_head,
273                      (xspaces + (sizeof xspaces - 1 - indent * 2)));
274             sawclose = 0;
275           }
276         fputs ("[ ", outfile);
277         if (NULL != XVEC (in_rtx, i))
278           {
279             indent += 2;
280             if (XVECLEN (in_rtx, i))
281               sawclose = 1;
282
283             for (j = 0; j < XVECLEN (in_rtx, i); j++)
284               print_rtx (XVECEXP (in_rtx, i, j));
285
286             indent -= 2;
287           }
288         if (sawclose)
289           fprintf (outfile, "\n%s%s",
290                    print_rtx_head,
291                    (xspaces + (sizeof xspaces - 1 - indent * 2)));
292
293         fputs ("] ", outfile);
294         sawclose = 1;
295         indent -= 2;
296         break;
297
298       case 'w':
299         fprintf (outfile, " ");
300         fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
301         fprintf (outfile, " [");
302         fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, XWINT (in_rtx, i));
303         fprintf (outfile, "]");
304         break;
305
306       case 'i':
307         {
308           register int value = XINT (in_rtx, i);
309           const char *name;
310
311           if (GET_CODE (in_rtx) == REG && value < FIRST_PSEUDO_REGISTER)
312             {
313               fputc (' ', outfile);
314               DEBUG_PRINT_REG (in_rtx, 0, outfile);
315             }
316           else if (GET_CODE (in_rtx) == REG && value <= LAST_VIRTUAL_REGISTER)
317             {
318               if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
319                 fprintf (outfile, " %d virtual-incoming-args", value);
320               else if (value == VIRTUAL_STACK_VARS_REGNUM)
321                 fprintf (outfile, " %d virtual-stack-vars", value);
322               else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM)
323                 fprintf (outfile, " %d virtual-stack-dynamic", value);
324               else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM)
325                 fprintf (outfile, " %d virtual-outgoing-args", value);
326               else if (value == VIRTUAL_CFA_REGNUM)
327                 fprintf (outfile, " %d virtual-cfa", value);
328               else
329                 fprintf (outfile, " %d virtual-reg-%d", value,
330                          value-FIRST_VIRTUAL_REGISTER);
331             }
332           else if (flag_dump_unnumbered
333                    && (is_insn || GET_CODE (in_rtx) == NOTE))
334             fputc ('#', outfile);
335           else
336             fprintf (outfile, " %d", value);
337
338           if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
339               && XINT (in_rtx, i) >= 0
340               && (name = get_insn_name (XINT (in_rtx, i))) != NULL)
341             fprintf (outfile, " {%s}", name);
342           sawclose = 0;
343         }
344         break;
345
346       /* Print NOTE_INSN names rather than integer codes.  */
347
348       case 'n':
349         if (XINT (in_rtx, i) >= NOTE_INSN_BIAS
350             && XINT (in_rtx, i) < NOTE_INSN_MAX)
351           fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
352         else
353           fprintf (outfile, " %d", XINT (in_rtx, i));
354         sawclose = 0;
355         break;
356
357       case 'u':
358         if (XEXP (in_rtx, i) != NULL)
359           {
360             rtx sub = XEXP (in_rtx, i);
361             enum rtx_code subc = GET_CODE (sub);
362
363             if (GET_CODE (in_rtx) == LABEL_REF)
364               {
365                 if (subc == NOTE
366                     && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL)
367                   {
368                     if (flag_dump_unnumbered)
369                       fprintf (outfile, " [# deleted]");
370                     else
371                       fprintf (outfile, " [%d deleted]", INSN_UID (sub));
372                     sawclose = 0;
373                     break;
374                   }
375
376                 if (subc != CODE_LABEL)
377                   goto do_e;
378               }
379
380             if (flag_dump_unnumbered)
381               fputs (" #", outfile);
382             else
383               fprintf (outfile, " %d", INSN_UID (sub));
384           }
385         else
386           fputs (" 0", outfile);
387         sawclose = 0;
388         break;
389
390       case 'b':
391         if (XBITMAP (in_rtx, i) == NULL)
392           fputs (" {null}", outfile);
393         else
394           bitmap_print (outfile, XBITMAP (in_rtx, i), " {", "}");
395         sawclose = 0;
396         break;
397
398       case 't':
399         putc (' ', outfile);
400         fprintf (outfile, HOST_PTR_PRINTF, (char *) XTREE (in_rtx, i));
401         break;
402
403       case '*':
404         fputs (" Unknown", outfile);
405         sawclose = 0;
406         break;
407
408       default:
409         fprintf (stderr,
410                  "switch format wrong in rtl.print_rtx(). format was: %c.\n",
411                  format_ptr[-1]);
412         abort ();
413       }
414
415   switch (GET_CODE (in_rtx))
416     {
417     case MEM:
418       fputc (' ', outfile);
419       fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx));
420       break;
421
422 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && MAX_LONG_DOUBLE_TYPE_SIZE == 64
423     case CONST_DOUBLE:
424       if (FLOAT_MODE_P (GET_MODE (in_rtx)))
425         {
426           double val;
427           REAL_VALUE_FROM_CONST_DOUBLE (val, in_rtx);
428           fprintf (outfile, " [%.16g]", val);
429         }
430       break;
431 #endif
432
433     case CODE_LABEL:
434       fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
435       if (LABEL_ALTERNATE_NAME (in_rtx))
436         fprintf (outfile, " [alternate name: %s]",
437                  LABEL_ALTERNATE_NAME (in_rtx));
438       break;
439
440     case CALL_PLACEHOLDER:
441       if (debug_call_placeholder_verbose)
442         {
443           fputs (" (cond [\n  (const_string \"normal\") (sequence [", outfile);
444           for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
445             {
446               fputs ("\n    ", outfile);
447               print_inline_rtx (outfile, tem, 4);
448             }
449
450           tem = XEXP (in_rtx, 1);
451           if (tem)
452             fputs ("\n    ])\n  (const_string \"tail_call\") (sequence [", outfile);
453           for (; tem != 0; tem = NEXT_INSN (tem))
454             {
455               fputs ("\n    ", outfile);
456               print_inline_rtx (outfile, tem, 4);
457             }
458
459           tem = XEXP (in_rtx, 2);
460           if (tem)
461             fputs ("\n    ])\n  (const_string \"tail_recursion\") (sequence [", outfile);
462           for (; tem != 0; tem = NEXT_INSN (tem))
463             {
464               fputs ("\n    ", outfile);
465               print_inline_rtx (outfile, tem, 4);
466             }
467
468           fputs ("\n    ])\n  ])", outfile);
469           break;
470         }
471
472       for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
473         if (GET_CODE (tem) == CALL_INSN)
474           {
475             fprintf (outfile, " ");
476             print_rtx (tem);
477             break;
478           }
479       break;
480
481     default:
482       break;
483     }
484
485   if (dump_for_graph
486       && (is_insn || GET_CODE (in_rtx) == NOTE
487           || GET_CODE (in_rtx) == CODE_LABEL || GET_CODE (in_rtx) == BARRIER))
488     sawclose = 0;
489   else
490     {
491       fputc (')', outfile);
492       sawclose = 1;
493     }
494 }
495
496 /* Print an rtx on the current line of FILE.  Initially indent IND
497    characters.  */
498
499 void
500 print_inline_rtx (outf, x, ind)
501      FILE *outf;
502      rtx x;
503      int ind;
504 {
505   int oldsaw = sawclose;
506   int oldindent = indent;
507
508   sawclose = 0;
509   indent = ind;
510   outfile = outf;
511   print_rtx (x);
512   sawclose = oldsaw;
513   indent = oldindent;
514 }
515
516 /* Call this function from the debugger to see what X looks like.  */
517
518 void
519 debug_rtx (x)
520      rtx x;
521 {
522   outfile = stderr;
523   print_rtx (x);
524   fprintf (stderr, "\n");
525 }
526
527 /* Count of rtx's to print with debug_rtx_list.
528    This global exists because gdb user defined commands have no arguments.  */
529
530 int debug_rtx_count = 0;        /* 0 is treated as equivalent to 1 */
531
532 /* Call this function to print list from X on.
533
534    N is a count of the rtx's to print. Positive values print from the specified
535    rtx on.  Negative values print a window around the rtx.
536    EG: -5 prints 2 rtx's on either side (in addition to the specified rtx).  */
537
538 void
539 debug_rtx_list (x, n)
540      rtx x;
541      int n;
542 {
543   int i,count;
544   rtx insn;
545
546   count = n == 0 ? 1 : n < 0 ? -n : n;
547
548   /* If we are printing a window, back up to the start.  */
549
550   if (n < 0)
551     for (i = count / 2; i > 0; i--)
552       {
553         if (PREV_INSN (x) == 0)
554           break;
555         x = PREV_INSN (x);
556       }
557
558   for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
559     debug_rtx (insn);
560 }
561
562 /* Call this function to print an rtx list from START to END inclusive.  */
563
564 void
565 debug_rtx_range (start, end)
566      rtx start, end;
567 {
568   while (1)
569     {
570       debug_rtx (start);
571       if (!start || start == end)
572         break;
573       start = NEXT_INSN (start);
574     }
575 }
576
577 /* Call this function to search an rtx list to find one with insn uid UID,
578    and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
579    The found insn is returned to enable further debugging analysis.  */
580
581 rtx
582 debug_rtx_find (x, uid)
583      rtx x;
584      int uid;
585 {
586   while (x != 0 && INSN_UID (x) != uid)
587     x = NEXT_INSN (x);
588   if (x != 0)
589     {
590       debug_rtx_list (x, debug_rtx_count);
591       return x;
592     }
593   else
594     {
595       fprintf (stderr, "insn uid %d not found\n", uid);
596       return 0;
597     }
598 }
599
600 /* External entry point for printing a chain of insns
601    starting with RTX_FIRST onto file OUTF.
602    A blank line separates insns.
603
604    If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
605
606 void
607 print_rtl (outf, rtx_first)
608      FILE *outf;
609      rtx rtx_first;
610 {
611   register rtx tmp_rtx;
612
613   outfile = outf;
614   sawclose = 0;
615
616   if (rtx_first == 0)
617     {
618       fputs (print_rtx_head, outf);
619       fputs ("(nil)\n", outf);
620     }
621   else
622     switch (GET_CODE (rtx_first))
623       {
624       case INSN:
625       case JUMP_INSN:
626       case CALL_INSN:
627       case NOTE:
628       case CODE_LABEL:
629       case BARRIER:
630         for (tmp_rtx = rtx_first; tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx))
631           if (! flag_dump_unnumbered
632               || GET_CODE (tmp_rtx) != NOTE || NOTE_LINE_NUMBER (tmp_rtx) < 0)
633             {
634               fputs (print_rtx_head, outfile);
635               print_rtx (tmp_rtx);
636               fprintf (outfile, "\n");
637             }
638         break;
639
640       default:
641         fputs (print_rtx_head, outfile);
642         print_rtx (rtx_first);
643       }
644 }
645
646 /* Like print_rtx, except specify a file.  */
647 /* Return nonzero if we actually printed anything.  */
648
649 int
650 print_rtl_single (outf, x)
651      FILE *outf;
652      rtx x;
653 {
654   outfile = outf;
655   sawclose = 0;
656   if (! flag_dump_unnumbered
657       || GET_CODE (x) != NOTE || NOTE_LINE_NUMBER (x) < 0)
658     {
659       fputs (print_rtx_head, outfile);
660       print_rtx (x);
661       putc ('\n', outf);
662       return 1;
663     }
664   return 0;
665 }