]>
Commit | Line | Data |
---|---|---|
5e6908ea | 1 | /* Print RTL for GCC. |
fe9565ed | 2 | Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002, 2003, |
2b1c5433 | 3 | 2004, 2005, 2007, 2008, 2009, 2010, 2011 |
c5c76735 | 4 | Free Software Foundation, Inc. |
e1a79915 | 5 | |
1322177d | 6 | This file is part of GCC. |
e1a79915 | 7 | |
1322177d LB |
8 | GCC is free software; you can redistribute it and/or modify it under |
9 | the terms of the GNU General Public License as published by the Free | |
9dcd6f09 | 10 | Software Foundation; either version 3, or (at your option) any later |
1322177d | 11 | version. |
e1a79915 | 12 | |
1322177d LB |
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | for more details. | |
e1a79915 RS |
17 | |
18 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
e1a79915 | 21 | |
45c8116d ZW |
22 | /* This file is compiled twice: once for the generator programs, |
23 | once for the compiler. */ | |
24 | #ifdef GENERATOR_FILE | |
25 | #include "bconfig.h" | |
26 | #else | |
e1a79915 | 27 | #include "config.h" |
45c8116d ZW |
28 | #endif |
29 | ||
670ee920 | 30 | #include "system.h" |
4977bab6 ZW |
31 | #include "coretypes.h" |
32 | #include "tm.h" | |
e1a79915 | 33 | #include "rtl.h" |
738cc472 | 34 | |
45c8116d ZW |
35 | /* These headers all define things which are not available in |
36 | generator programs. */ | |
37 | #ifndef GENERATOR_FILE | |
738cc472 | 38 | #include "tree.h" |
b707b450 | 39 | #include "flags.h" |
efc9bd41 | 40 | #include "hard-reg-set.h" |
e881bb1b | 41 | #include "basic-block.h" |
55b34b5f | 42 | #include "diagnostic.h" |
cf835838 | 43 | #include "tree-pretty-print.h" |
b5b8b0ac | 44 | #include "cselib.h" |
7ee2468b | 45 | #include "dumpfile.h" /* for dump_flags */ |
2867fa7c | 46 | #include "dwarf2out.h" |
45c8116d | 47 | #endif |
cf99a734 | 48 | |
e1a79915 RS |
49 | static FILE *outfile; |
50 | ||
e1a79915 RS |
51 | static int sawclose = 0; |
52 | ||
1d79197a RK |
53 | static int indent; |
54 | ||
f7d504c2 | 55 | static void print_rtx (const_rtx); |
5edc9230 | 56 | |
c349e40b SC |
57 | /* String printed at beginning of each RTL when it is dumped. |
58 | This string is set to ASM_COMMENT_START when the RTL is dumped in | |
59 | the assembly output file. */ | |
47c10e9b | 60 | const char *print_rtx_head = ""; |
c349e40b | 61 | |
e90afde6 JM |
62 | #ifdef GENERATOR_FILE |
63 | /* These are defined from the .opt file when not used in generator | |
64 | programs. */ | |
65 | ||
9dbe7947 JH |
66 | /* Nonzero means suppress output of instruction numbers |
67 | in debugging dumps. | |
b707b450 | 68 | This must be defined here so that programs like gencodes can be linked. */ |
9ec36da5 | 69 | int flag_dump_unnumbered = 0; |
b707b450 | 70 | |
2aa7c49b AO |
71 | /* Nonzero means suppress output of instruction numbers for previous |
72 | and next insns in debugging dumps. | |
73 | This must be defined here so that programs like gencodes can be linked. */ | |
74 | int flag_dump_unnumbered_links = 0; | |
e90afde6 | 75 | #endif |
2aa7c49b | 76 | |
75b7557d MH |
77 | /* Nonzero means use simplified format without flags, modes, etc. */ |
78 | int flag_simple = 0; | |
79 | ||
735a0e33 UD |
80 | /* Nonzero if we are dumping graphical description. */ |
81 | int dump_for_graph; | |
82 | ||
45c8116d | 83 | #ifndef GENERATOR_FILE |
998d7deb | 84 | void |
f7d504c2 | 85 | print_mem_expr (FILE *outfile, const_tree expr) |
998d7deb | 86 | { |
55b34b5f | 87 | fputc (' ', outfile); |
831b9ef8 | 88 | print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags); |
998d7deb | 89 | } |
45c8116d | 90 | #endif |
998d7deb | 91 | |
e1a79915 RS |
92 | /* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */ |
93 | ||
94 | static void | |
f7d504c2 | 95 | print_rtx (const_rtx in_rtx) |
e1a79915 | 96 | { |
b3694847 SS |
97 | int i = 0; |
98 | int j; | |
99 | const char *format_ptr; | |
100 | int is_insn; | |
e1a79915 RS |
101 | |
102 | if (sawclose) | |
103 | { | |
75b7557d MH |
104 | if (flag_simple) |
105 | fputc (' ', outfile); | |
106 | else | |
5e74f966 | 107 | fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, ""); |
e1a79915 RS |
108 | sawclose = 0; |
109 | } | |
110 | ||
111 | if (in_rtx == 0) | |
112 | { | |
735a0e33 | 113 | fputs ("(nil)", outfile); |
e1a79915 RS |
114 | sawclose = 1; |
115 | return; | |
116 | } | |
5e74f966 RK |
117 | else if (GET_CODE (in_rtx) > NUM_RTX_CODE) |
118 | { | |
8a2bbeef JJ |
119 | fprintf (outfile, "(??? bad code %d\n%s%*s)", GET_CODE (in_rtx), |
120 | print_rtx_head, indent * 2, ""); | |
5e74f966 RK |
121 | sawclose = 1; |
122 | return; | |
123 | } | |
e1a79915 | 124 | |
5e74f966 | 125 | is_insn = INSN_P (in_rtx); |
735a0e33 UD |
126 | |
127 | /* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER | |
128 | in separate nodes and therefore have to handle them special here. */ | |
5e74f966 | 129 | if (dump_for_graph |
4b4bf941 JQ |
130 | && (is_insn || NOTE_P (in_rtx) |
131 | || LABEL_P (in_rtx) || BARRIER_P (in_rtx))) | |
735a0e33 UD |
132 | { |
133 | i = 3; | |
134 | indent = 0; | |
135 | } | |
136 | else | |
137 | { | |
5e74f966 | 138 | /* Print name of expression code. */ |
481683e1 | 139 | if (flag_simple && CONST_INT_P (in_rtx)) |
75b7557d MH |
140 | fputc ('(', outfile); |
141 | else | |
142 | fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx))); | |
6a4d6760 | 143 | |
75b7557d | 144 | if (! flag_simple) |
735a0e33 | 145 | { |
2adc7f12 | 146 | if (RTX_FLAG (in_rtx, in_struct)) |
75b7557d MH |
147 | fputs ("/s", outfile); |
148 | ||
2adc7f12 | 149 | if (RTX_FLAG (in_rtx, volatil)) |
75b7557d | 150 | fputs ("/v", outfile); |
6a4d6760 | 151 | |
2adc7f12 | 152 | if (RTX_FLAG (in_rtx, unchanging)) |
75b7557d | 153 | fputs ("/u", outfile); |
6a4d6760 | 154 | |
2adc7f12 | 155 | if (RTX_FLAG (in_rtx, frame_related)) |
75b7557d | 156 | fputs ("/f", outfile); |
6a4d6760 | 157 | |
2adc7f12 | 158 | if (RTX_FLAG (in_rtx, jump)) |
75b7557d | 159 | fputs ("/j", outfile); |
6a4d6760 | 160 | |
2adc7f12 | 161 | if (RTX_FLAG (in_rtx, call)) |
75b7557d MH |
162 | fputs ("/c", outfile); |
163 | ||
6de9cd9a DN |
164 | if (RTX_FLAG (in_rtx, return_val)) |
165 | fputs ("/i", outfile); | |
166 | ||
52c5701b | 167 | /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */ |
9e74b7d2 AO |
168 | if ((GET_CODE (in_rtx) == EXPR_LIST |
169 | || GET_CODE (in_rtx) == INSN_LIST) | |
170 | && (int)GET_MODE (in_rtx) < REG_NOTE_MAX) | |
52c5701b ZW |
171 | fprintf (outfile, ":%s", |
172 | GET_REG_NOTE_NAME (GET_MODE (in_rtx))); | |
173 | ||
174 | /* For other rtl, print the mode if it's not VOID. */ | |
175 | else if (GET_MODE (in_rtx) != VOIDmode) | |
176 | fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx))); | |
b5b8b0ac AO |
177 | |
178 | #ifndef GENERATOR_FILE | |
179 | if (GET_CODE (in_rtx) == VAR_LOCATION) | |
180 | { | |
181 | if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST) | |
182 | fputs (" <debug string placeholder>", outfile); | |
183 | else | |
184 | print_mem_expr (outfile, PAT_VAR_LOCATION_DECL (in_rtx)); | |
185 | fputc (' ', outfile); | |
186 | print_rtx (PAT_VAR_LOCATION_LOC (in_rtx)); | |
187 | if (PAT_VAR_LOCATION_STATUS (in_rtx) | |
188 | == VAR_INIT_STATUS_UNINITIALIZED) | |
189 | fprintf (outfile, " [uninit]"); | |
190 | sawclose = 1; | |
191 | i = GET_RTX_LENGTH (VAR_LOCATION); | |
192 | } | |
193 | #endif | |
735a0e33 | 194 | } |
e1a79915 RS |
195 | } |
196 | ||
69bd00e6 | 197 | #ifndef GENERATOR_FILE |
48175537 | 198 | if (CONST_DOUBLE_AS_FLOAT_P (in_rtx)) |
69bd00e6 RH |
199 | i = 5; |
200 | #endif | |
201 | ||
735a0e33 UD |
202 | /* Get the format string and skip the first elements if we have handled |
203 | them already. */ | |
204 | format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i; | |
735a0e33 | 205 | for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++) |
e1a79915 RS |
206 | switch (*format_ptr++) |
207 | { | |
3b324340 ZW |
208 | const char *str; |
209 | ||
210 | case 'T': | |
211 | str = XTMPL (in_rtx, i); | |
212 | goto string; | |
213 | ||
e1a79915 RS |
214 | case 'S': |
215 | case 's': | |
3b324340 ZW |
216 | str = XSTR (in_rtx, i); |
217 | string: | |
218 | ||
219 | if (str == 0) | |
735a0e33 | 220 | fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile); |
e1a79915 | 221 | else |
913d0833 KG |
222 | { |
223 | if (dump_for_graph) | |
3b324340 | 224 | fprintf (outfile, " (\\\"%s\\\")", str); |
913d0833 | 225 | else |
3b324340 | 226 | fprintf (outfile, " (\"%s\")", str); |
913d0833 | 227 | } |
e1a79915 RS |
228 | sawclose = 1; |
229 | break; | |
230 | ||
8f985ec4 ZW |
231 | /* 0 indicates a field for internal use that should not be printed. |
232 | An exception is the third field of a NOTE, where it indicates | |
233 | that the field has several different valid contents. */ | |
e1a79915 | 234 | case '0': |
f8cfc6aa | 235 | if (i == 1 && REG_P (in_rtx)) |
08394eef BS |
236 | { |
237 | if (REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx)) | |
238 | fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx)); | |
08394eef | 239 | } |
52859c77 RH |
240 | #ifndef GENERATOR_FILE |
241 | else if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF) | |
242 | { | |
243 | int flags = SYMBOL_REF_FLAGS (in_rtx); | |
244 | if (flags) | |
a3f1cee4 | 245 | fprintf (outfile, " [flags %#x]", flags); |
52859c77 RH |
246 | } |
247 | else if (i == 2 && GET_CODE (in_rtx) == SYMBOL_REF) | |
248 | { | |
249 | tree decl = SYMBOL_REF_DECL (in_rtx); | |
250 | if (decl) | |
831b9ef8 | 251 | print_node_brief (outfile, "", decl, dump_flags); |
52859c77 RH |
252 | } |
253 | #endif | |
4b4bf941 | 254 | else if (i == 4 && NOTE_P (in_rtx)) |
8f985ec4 | 255 | { |
a38e7aa5 | 256 | switch (NOTE_KIND (in_rtx)) |
bf43101e | 257 | { |
994a57cd RH |
258 | case NOTE_INSN_EH_REGION_BEG: |
259 | case NOTE_INSN_EH_REGION_END: | |
f76ca83c GK |
260 | if (flag_dump_unnumbered) |
261 | fprintf (outfile, " #"); | |
262 | else | |
263 | fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx)); | |
bf43101e | 264 | sawclose = 1; |
994a57cd RH |
265 | break; |
266 | ||
267 | case NOTE_INSN_BLOCK_BEG: | |
268 | case NOTE_INSN_BLOCK_END: | |
24a7799e R |
269 | #ifndef GENERATOR_FILE |
270 | dump_addr (outfile, " ", NOTE_BLOCK (in_rtx)); | |
271 | #endif | |
8f985ec4 | 272 | sawclose = 1; |
994a57cd RH |
273 | break; |
274 | ||
994a57cd RH |
275 | case NOTE_INSN_BASIC_BLOCK: |
276 | { | |
45c8116d | 277 | #ifndef GENERATOR_FILE |
994a57cd RH |
278 | basic_block bb = NOTE_BASIC_BLOCK (in_rtx); |
279 | if (bb != 0) | |
0b17ab2f | 280 | fprintf (outfile, " [bb %d]", bb->index); |
45c8116d | 281 | #endif |
994a57cd RH |
282 | break; |
283 | } | |
284 | ||
be1bb652 | 285 | case NOTE_INSN_DELETED_LABEL: |
5619e52c | 286 | case NOTE_INSN_DELETED_DEBUG_LABEL: |
6773e15f PB |
287 | { |
288 | const char *label = NOTE_DELETED_LABEL_NAME (in_rtx); | |
289 | if (label) | |
290 | fprintf (outfile, " (\"%s\")", label); | |
291 | else | |
292 | fprintf (outfile, " \"\""); | |
293 | } | |
be1bb652 RH |
294 | break; |
295 | ||
87c8b4be | 296 | case NOTE_INSN_SWITCH_TEXT_SECTIONS: |
750054a2 | 297 | { |
45c8116d | 298 | #ifndef GENERATOR_FILE |
750054a2 CT |
299 | basic_block bb = NOTE_BASIC_BLOCK (in_rtx); |
300 | if (bb != 0) | |
301 | fprintf (outfile, " [bb %d]", bb->index); | |
45c8116d | 302 | #endif |
750054a2 CT |
303 | break; |
304 | } | |
b8698a0f | 305 | |
014a1138 | 306 | case NOTE_INSN_VAR_LOCATION: |
2b1c5433 | 307 | case NOTE_INSN_CALL_ARG_LOCATION: |
45c8116d | 308 | #ifndef GENERATOR_FILE |
b5b8b0ac AO |
309 | fputc (' ', outfile); |
310 | print_rtx (NOTE_VAR_LOCATION (in_rtx)); | |
45c8116d | 311 | #endif |
014a1138 JZ |
312 | break; |
313 | ||
2867fa7c RH |
314 | case NOTE_INSN_CFI: |
315 | #ifndef GENERATOR_FILE | |
316 | fputc ('\n', outfile); | |
317 | output_cfi_directive (outfile, NOTE_CFI (in_rtx)); | |
318 | fputc ('\t', outfile); | |
319 | #endif | |
320 | break; | |
321 | ||
994a57cd | 322 | default: |
a38e7aa5 | 323 | break; |
8f985ec4 ZW |
324 | } |
325 | } | |
137a05d3 | 326 | else if (i == 8 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL) |
dc0ff1c8 BS |
327 | { |
328 | /* Output the JUMP_LABEL reference. */ | |
329 | fprintf (outfile, "\n%s%*s -> ", print_rtx_head, indent * 2, ""); | |
330 | if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN) | |
331 | fprintf (outfile, "return"); | |
26898771 BS |
332 | else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN) |
333 | fprintf (outfile, "simple_return"); | |
dc0ff1c8 BS |
334 | else |
335 | fprintf (outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx))); | |
336 | } | |
b5b8b0ac AO |
337 | else if (i == 0 && GET_CODE (in_rtx) == VALUE) |
338 | { | |
339 | #ifndef GENERATOR_FILE | |
340 | cselib_val *val = CSELIB_VAL_PTR (in_rtx); | |
341 | ||
5440c0e7 | 342 | fprintf (outfile, " %u:%u", val->uid, val->hash); |
b5b8b0ac AO |
343 | dump_addr (outfile, " @", in_rtx); |
344 | dump_addr (outfile, "/", (void*)val); | |
0ca5af51 AO |
345 | #endif |
346 | } | |
347 | else if (i == 0 && GET_CODE (in_rtx) == DEBUG_EXPR) | |
348 | { | |
349 | #ifndef GENERATOR_FILE | |
e4fb38bd JJ |
350 | fprintf (outfile, " D#%i", |
351 | DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx))); | |
b5b8b0ac AO |
352 | #endif |
353 | } | |
a58a8e4b JJ |
354 | else if (i == 0 && GET_CODE (in_rtx) == ENTRY_VALUE) |
355 | { | |
356 | indent += 2; | |
357 | if (!sawclose) | |
358 | fprintf (outfile, " "); | |
359 | print_rtx (ENTRY_VALUE_EXP (in_rtx)); | |
360 | indent -= 2; | |
361 | } | |
e1a79915 RS |
362 | break; |
363 | ||
364 | case 'e': | |
bcdaba58 | 365 | do_e: |
e1a79915 | 366 | indent += 2; |
418e920f BS |
367 | if (i == 7 && INSN_P (in_rtx)) |
368 | /* Put REG_NOTES on their own line. */ | |
369 | fprintf (outfile, "\n%s%*s", | |
370 | print_rtx_head, indent * 2, ""); | |
e1a79915 RS |
371 | if (!sawclose) |
372 | fprintf (outfile, " "); | |
373 | print_rtx (XEXP (in_rtx, i)); | |
374 | indent -= 2; | |
375 | break; | |
376 | ||
377 | case 'E': | |
378 | case 'V': | |
379 | indent += 2; | |
380 | if (sawclose) | |
381 | { | |
d558416e | 382 | fprintf (outfile, "\n%s%*s", |
6a4d6760 | 383 | print_rtx_head, indent * 2, ""); |
e1a79915 RS |
384 | sawclose = 0; |
385 | } | |
7f11f1f9 | 386 | fputs (" [", outfile); |
e1a79915 RS |
387 | if (NULL != XVEC (in_rtx, i)) |
388 | { | |
389 | indent += 2; | |
390 | if (XVECLEN (in_rtx, i)) | |
391 | sawclose = 1; | |
392 | ||
393 | for (j = 0; j < XVECLEN (in_rtx, i); j++) | |
394 | print_rtx (XVECEXP (in_rtx, i, j)); | |
395 | ||
396 | indent -= 2; | |
397 | } | |
398 | if (sawclose) | |
5e74f966 | 399 | fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, ""); |
e1a79915 | 400 | |
7f11f1f9 | 401 | fputs ("]", outfile); |
e1a79915 RS |
402 | sawclose = 1; |
403 | indent -= 2; | |
404 | break; | |
405 | ||
5bf665df | 406 | case 'w': |
75b7557d MH |
407 | if (! flag_simple) |
408 | fprintf (outfile, " "); | |
734de8c8 | 409 | fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i)); |
75b7557d | 410 | if (! flag_simple) |
90ff44cf | 411 | fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]", |
3d57d7ce | 412 | (unsigned HOST_WIDE_INT) XWINT (in_rtx, i)); |
5bf665df RK |
413 | break; |
414 | ||
e1a79915 | 415 | case 'i': |
418e920f | 416 | if (i == 5 && INSN_P (in_rtx)) |
0435312e JH |
417 | { |
418 | #ifndef GENERATOR_FILE | |
419 | /* Pretty-print insn locators. Ignore scoping as it is mostly | |
420 | redundant with line number information and do not print anything | |
421 | when there is no location information available. */ | |
422 | if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx)) | |
423 | fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx)); | |
da1e1503 AO |
424 | #endif |
425 | } | |
426 | else if (i == 6 && GET_CODE (in_rtx) == ASM_OPERANDS) | |
427 | { | |
428 | #ifndef GENERATOR_FILE | |
429 | fprintf (outfile, " %s:%i", | |
430 | locator_file (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)), | |
431 | locator_line (ASM_OPERANDS_SOURCE_LOCATION (in_rtx))); | |
432 | #endif | |
433 | } | |
434 | else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT) | |
435 | { | |
436 | #ifndef GENERATOR_FILE | |
437 | fprintf (outfile, " %s:%i", | |
438 | locator_file (ASM_INPUT_SOURCE_LOCATION (in_rtx)), | |
439 | locator_line (ASM_INPUT_SOURCE_LOCATION (in_rtx))); | |
0435312e JH |
440 | #endif |
441 | } | |
4b4bf941 | 442 | else if (i == 6 && NOTE_P (in_rtx)) |
25cff714 RH |
443 | { |
444 | /* This field is only used for NOTE_INSN_DELETED_LABEL, and | |
445 | other times often contains garbage from INSN->NOTE death. */ | |
5619e52c JJ |
446 | if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL |
447 | || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL) | |
25cff714 RH |
448 | fprintf (outfile, " %d", XINT (in_rtx, i)); |
449 | } | |
0fe60a1b RS |
450 | #if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0 |
451 | else if (i == 1 | |
452 | && GET_CODE (in_rtx) == UNSPEC_VOLATILE | |
453 | && XINT (in_rtx, 1) >= 0 | |
454 | && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES) | |
455 | fprintf (outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]); | |
456 | #endif | |
457 | #if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0 | |
458 | else if (i == 1 | |
459 | && (GET_CODE (in_rtx) == UNSPEC | |
460 | || GET_CODE (in_rtx) == UNSPEC_VOLATILE) | |
461 | && XINT (in_rtx, 1) >= 0 | |
462 | && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES) | |
463 | fprintf (outfile, " %s", unspec_strings[XINT (in_rtx, 1)]); | |
464 | #endif | |
25cff714 RH |
465 | else |
466 | { | |
b3694847 | 467 | int value = XINT (in_rtx, i); |
25cff714 | 468 | const char *name; |
cf99a734 | 469 | |
94134f42 | 470 | #ifndef GENERATOR_FILE |
c62c5441 AM |
471 | if (REG_P (in_rtx) && (unsigned) value < FIRST_PSEUDO_REGISTER) |
472 | fprintf (outfile, " %d %s", value, reg_names[value]); | |
f8cfc6aa | 473 | else if (REG_P (in_rtx) |
c62c5441 | 474 | && (unsigned) value <= LAST_VIRTUAL_REGISTER) |
25cff714 RH |
475 | { |
476 | if (value == VIRTUAL_INCOMING_ARGS_REGNUM) | |
477 | fprintf (outfile, " %d virtual-incoming-args", value); | |
478 | else if (value == VIRTUAL_STACK_VARS_REGNUM) | |
479 | fprintf (outfile, " %d virtual-stack-vars", value); | |
480 | else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM) | |
481 | fprintf (outfile, " %d virtual-stack-dynamic", value); | |
482 | else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM) | |
483 | fprintf (outfile, " %d virtual-outgoing-args", value); | |
484 | else if (value == VIRTUAL_CFA_REGNUM) | |
485 | fprintf (outfile, " %d virtual-cfa", value); | |
32990d5b JJ |
486 | else if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM) |
487 | fprintf (outfile, " %d virtual-preferred-stack-boundary", | |
488 | value); | |
25cff714 RH |
489 | else |
490 | fprintf (outfile, " %d virtual-reg-%d", value, | |
491 | value-FIRST_VIRTUAL_REGISTER); | |
492 | } | |
94134f42 ZW |
493 | else |
494 | #endif | |
495 | if (flag_dump_unnumbered | |
4b4bf941 | 496 | && (is_insn || NOTE_P (in_rtx))) |
25cff714 RH |
497 | fputc ('#', outfile); |
498 | else | |
499 | fprintf (outfile, " %d", value); | |
500 | ||
45c8116d | 501 | #ifndef GENERATOR_FILE |
f8cfc6aa | 502 | if (REG_P (in_rtx) && REG_ATTRS (in_rtx)) |
a560d4d4 JH |
503 | { |
504 | fputs (" [", outfile); | |
505 | if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx)) | |
506 | fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx)); | |
507 | if (REG_EXPR (in_rtx)) | |
508 | print_mem_expr (outfile, REG_EXPR (in_rtx)); | |
509 | ||
510 | if (REG_OFFSET (in_rtx)) | |
90ff44cf KG |
511 | fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, |
512 | REG_OFFSET (in_rtx)); | |
a560d4d4 JH |
513 | fputs (" ]", outfile); |
514 | } | |
45c8116d | 515 | #endif |
a560d4d4 | 516 | |
25cff714 RH |
517 | if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i) |
518 | && XINT (in_rtx, i) >= 0 | |
519 | && (name = get_insn_name (XINT (in_rtx, i))) != NULL) | |
520 | fprintf (outfile, " {%s}", name); | |
521 | sawclose = 0; | |
522 | } | |
e1a79915 RS |
523 | break; |
524 | ||
525 | /* Print NOTE_INSN names rather than integer codes. */ | |
526 | ||
527 | case 'n': | |
a38e7aa5 | 528 | fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i))); |
e1a79915 RS |
529 | sawclose = 0; |
530 | break; | |
531 | ||
532 | case 'u': | |
533 | if (XEXP (in_rtx, i) != NULL) | |
9ec36da5 | 534 | { |
556ffcc5 RH |
535 | rtx sub = XEXP (in_rtx, i); |
536 | enum rtx_code subc = GET_CODE (sub); | |
537 | ||
be1bb652 RH |
538 | if (GET_CODE (in_rtx) == LABEL_REF) |
539 | { | |
540 | if (subc == NOTE | |
a38e7aa5 | 541 | && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL) |
be1bb652 RH |
542 | { |
543 | if (flag_dump_unnumbered) | |
544 | fprintf (outfile, " [# deleted]"); | |
545 | else | |
546 | fprintf (outfile, " [%d deleted]", INSN_UID (sub)); | |
547 | sawclose = 0; | |
548 | break; | |
549 | } | |
550 | ||
551 | if (subc != CODE_LABEL) | |
552 | goto do_e; | |
553 | } | |
bcdaba58 | 554 | |
2aa7c49b AO |
555 | if (flag_dump_unnumbered |
556 | || (flag_dump_unnumbered_links && (i == 1 || i == 2) | |
557 | && (INSN_P (in_rtx) || NOTE_P (in_rtx) | |
558 | || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))) | |
be1bb652 | 559 | fputs (" #", outfile); |
9ec36da5 | 560 | else |
556ffcc5 | 561 | fprintf (outfile, " %d", INSN_UID (sub)); |
9ec36da5 | 562 | } |
e1a79915 | 563 | else |
d5e3e85b | 564 | fputs (" 0", outfile); |
d64be5ec CH |
565 | sawclose = 0; |
566 | break; | |
567 | ||
0dfa1860 | 568 | case 't': |
24a7799e | 569 | #ifndef GENERATOR_FILE |
c8a27c40 JJ |
570 | if (i == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR) |
571 | print_mem_expr (outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx)); | |
ddb555ed JJ |
572 | else if (i == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF) |
573 | print_mem_expr (outfile, DEBUG_PARAMETER_REF_DECL (in_rtx)); | |
c8a27c40 JJ |
574 | else |
575 | dump_addr (outfile, " ", XTREE (in_rtx, i)); | |
24a7799e | 576 | #endif |
0dfa1860 MM |
577 | break; |
578 | ||
d64be5ec | 579 | case '*': |
735a0e33 | 580 | fputs (" Unknown", outfile); |
e1a79915 RS |
581 | sawclose = 0; |
582 | break; | |
583 | ||
ba4f7968 | 584 | case 'B': |
45c8116d | 585 | #ifndef GENERATOR_FILE |
ba4f7968 JH |
586 | if (XBBDEF (in_rtx, i)) |
587 | fprintf (outfile, " %i", XBBDEF (in_rtx, i)->index); | |
45c8116d | 588 | #endif |
ba4f7968 JH |
589 | break; |
590 | ||
e1a79915 | 591 | default: |
0e61db61 | 592 | gcc_unreachable (); |
e1a79915 RS |
593 | } |
594 | ||
be1bb652 RH |
595 | switch (GET_CODE (in_rtx)) |
596 | { | |
6ebd2ef4 | 597 | #ifndef GENERATOR_FILE |
be1bb652 | 598 | case MEM: |
6ca5d1f6 JJ |
599 | if (__builtin_expect (final_insns_dump_p, false)) |
600 | fprintf (outfile, " ["); | |
601 | else | |
602 | fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC, | |
603 | (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx)); | |
998d7deb RH |
604 | |
605 | if (MEM_EXPR (in_rtx)) | |
606 | print_mem_expr (outfile, MEM_EXPR (in_rtx)); | |
738cc472 | 607 | |
527210c4 RS |
608 | if (MEM_OFFSET_KNOWN_P (in_rtx)) |
609 | fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx)); | |
738cc472 | 610 | |
f5541398 RS |
611 | if (MEM_SIZE_KNOWN_P (in_rtx)) |
612 | fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx)); | |
738cc472 RK |
613 | |
614 | if (MEM_ALIGN (in_rtx) != 1) | |
615 | fprintf (outfile, " A%u", MEM_ALIGN (in_rtx)); | |
616 | ||
09e881c9 BE |
617 | if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx))) |
618 | fprintf (outfile, " AS%u", MEM_ADDR_SPACE (in_rtx)); | |
619 | ||
738cc472 | 620 | fputc (']', outfile); |
be1bb652 | 621 | break; |
5a0a1a66 | 622 | |
be1bb652 RH |
623 | case CONST_DOUBLE: |
624 | if (FLOAT_MODE_P (GET_MODE (in_rtx))) | |
625 | { | |
4fdbcfb2 | 626 | char s[60]; |
b216cd4a | 627 | |
da6eec72 RH |
628 | real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx), |
629 | sizeof (s), 0, 1); | |
69bd00e6 RH |
630 | fprintf (outfile, " %s", s); |
631 | ||
da6eec72 RH |
632 | real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx), |
633 | sizeof (s), 0, 1); | |
b216cd4a | 634 | fprintf (outfile, " [%s]", s); |
be1bb652 RH |
635 | } |
636 | break; | |
800d5c9e RH |
637 | #endif |
638 | ||
be1bb652 | 639 | case CODE_LABEL: |
c3c63936 | 640 | fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx)); |
0dc36574 ZW |
641 | switch (LABEL_KIND (in_rtx)) |
642 | { | |
643 | case LABEL_NORMAL: break; | |
644 | case LABEL_STATIC_ENTRY: fputs (" [entry]", outfile); break; | |
645 | case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", outfile); break; | |
646 | case LABEL_WEAK_ENTRY: fputs (" [weak entry]", outfile); break; | |
e16acfcd | 647 | default: gcc_unreachable (); |
0dc36574 | 648 | } |
be1bb652 RH |
649 | break; |
650 | ||
be1bb652 RH |
651 | default: |
652 | break; | |
8cd0faaf | 653 | } |
c3c63936 | 654 | |
735a0e33 | 655 | if (dump_for_graph |
4b4bf941 JQ |
656 | && (is_insn || NOTE_P (in_rtx) |
657 | || LABEL_P (in_rtx) || BARRIER_P (in_rtx))) | |
735a0e33 UD |
658 | sawclose = 0; |
659 | else | |
660 | { | |
661 | fputc (')', outfile); | |
662 | sawclose = 1; | |
663 | } | |
e1a79915 RS |
664 | } |
665 | ||
1d79197a RK |
666 | /* Print an rtx on the current line of FILE. Initially indent IND |
667 | characters. */ | |
668 | ||
669 | void | |
f7d504c2 | 670 | print_inline_rtx (FILE *outf, const_rtx x, int ind) |
1d79197a | 671 | { |
956d6950 JL |
672 | int oldsaw = sawclose; |
673 | int oldindent = indent; | |
674 | ||
1d79197a RK |
675 | sawclose = 0; |
676 | indent = ind; | |
677 | outfile = outf; | |
678 | print_rtx (x); | |
956d6950 JL |
679 | sawclose = oldsaw; |
680 | indent = oldindent; | |
1d79197a RK |
681 | } |
682 | ||
e1a79915 RS |
683 | /* Call this function from the debugger to see what X looks like. */ |
684 | ||
24e47c76 | 685 | DEBUG_FUNCTION void |
f7d504c2 | 686 | debug_rtx (const_rtx x) |
e1a79915 RS |
687 | { |
688 | outfile = stderr; | |
7f11f1f9 | 689 | sawclose = 0; |
e1a79915 RS |
690 | print_rtx (x); |
691 | fprintf (stderr, "\n"); | |
692 | } | |
693 | ||
716f003f DE |
694 | /* Count of rtx's to print with debug_rtx_list. |
695 | This global exists because gdb user defined commands have no arguments. */ | |
696 | ||
24e47c76 | 697 | DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */ |
716f003f DE |
698 | |
699 | /* Call this function to print list from X on. | |
700 | ||
701 | N is a count of the rtx's to print. Positive values print from the specified | |
702 | rtx on. Negative values print a window around the rtx. | |
703 | EG: -5 prints 2 rtx's on either side (in addition to the specified rtx). */ | |
704 | ||
24e47c76 | 705 | DEBUG_FUNCTION void |
f7d504c2 | 706 | debug_rtx_list (const_rtx x, int n) |
716f003f DE |
707 | { |
708 | int i,count; | |
f7d504c2 | 709 | const_rtx insn; |
716f003f DE |
710 | |
711 | count = n == 0 ? 1 : n < 0 ? -n : n; | |
712 | ||
713 | /* If we are printing a window, back up to the start. */ | |
714 | ||
715 | if (n < 0) | |
716 | for (i = count / 2; i > 0; i--) | |
717 | { | |
718 | if (PREV_INSN (x) == 0) | |
719 | break; | |
720 | x = PREV_INSN (x); | |
721 | } | |
722 | ||
723 | for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn)) | |
7f11f1f9 AS |
724 | { |
725 | debug_rtx (insn); | |
726 | fprintf (stderr, "\n"); | |
727 | } | |
716f003f DE |
728 | } |
729 | ||
4c85a96d RH |
730 | /* Call this function to print an rtx list from START to END inclusive. */ |
731 | ||
24e47c76 | 732 | DEBUG_FUNCTION void |
f7d504c2 | 733 | debug_rtx_range (const_rtx start, const_rtx end) |
4c85a96d RH |
734 | { |
735 | while (1) | |
736 | { | |
737 | debug_rtx (start); | |
7f11f1f9 | 738 | fprintf (stderr, "\n"); |
4c85a96d RH |
739 | if (!start || start == end) |
740 | break; | |
741 | start = NEXT_INSN (start); | |
742 | } | |
743 | } | |
744 | ||
716f003f DE |
745 | /* Call this function to search an rtx list to find one with insn uid UID, |
746 | and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT. | |
747 | The found insn is returned to enable further debugging analysis. */ | |
748 | ||
24e47c76 | 749 | DEBUG_FUNCTION const_rtx |
f7d504c2 | 750 | debug_rtx_find (const_rtx x, int uid) |
716f003f DE |
751 | { |
752 | while (x != 0 && INSN_UID (x) != uid) | |
753 | x = NEXT_INSN (x); | |
754 | if (x != 0) | |
755 | { | |
756 | debug_rtx_list (x, debug_rtx_count); | |
757 | return x; | |
758 | } | |
759 | else | |
760 | { | |
761 | fprintf (stderr, "insn uid %d not found\n", uid); | |
762 | return 0; | |
763 | } | |
764 | } | |
765 | ||
e1a79915 RS |
766 | /* External entry point for printing a chain of insns |
767 | starting with RTX_FIRST onto file OUTF. | |
768 | A blank line separates insns. | |
769 | ||
770 | If RTX_FIRST is not an insn, then it alone is printed, with no newline. */ | |
771 | ||
772 | void | |
f7d504c2 | 773 | print_rtl (FILE *outf, const_rtx rtx_first) |
e1a79915 | 774 | { |
f7d504c2 | 775 | const_rtx tmp_rtx; |
9dbe7947 | 776 | |
e1a79915 RS |
777 | outfile = outf; |
778 | sawclose = 0; | |
779 | ||
780 | if (rtx_first == 0) | |
c349e40b SC |
781 | { |
782 | fputs (print_rtx_head, outf); | |
783 | fputs ("(nil)\n", outf); | |
784 | } | |
e1a79915 RS |
785 | else |
786 | switch (GET_CODE (rtx_first)) | |
787 | { | |
788 | case INSN: | |
789 | case JUMP_INSN: | |
790 | case CALL_INSN: | |
791 | case NOTE: | |
792 | case CODE_LABEL: | |
793 | case BARRIER: | |
9dbe7947 JH |
794 | for (tmp_rtx = rtx_first; tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx)) |
795 | { | |
796 | fputs (print_rtx_head, outfile); | |
797 | print_rtx (tmp_rtx); | |
798 | fprintf (outfile, "\n"); | |
799 | } | |
e1a79915 RS |
800 | break; |
801 | ||
802 | default: | |
6a4d6760 | 803 | fputs (print_rtx_head, outfile); |
e1a79915 RS |
804 | print_rtx (rtx_first); |
805 | } | |
806 | } | |
3e28fe44 MM |
807 | |
808 | /* Like print_rtx, except specify a file. */ | |
b707b450 | 809 | /* Return nonzero if we actually printed anything. */ |
3e28fe44 | 810 | |
b707b450 | 811 | int |
f7d504c2 | 812 | print_rtl_single (FILE *outf, const_rtx x) |
3e28fe44 MM |
813 | { |
814 | outfile = outf; | |
815 | sawclose = 0; | |
297e9b46 KZ |
816 | fputs (print_rtx_head, outfile); |
817 | print_rtx (x); | |
818 | putc ('\n', outf); | |
819 | return 1; | |
3e28fe44 | 820 | } |
75b7557d MH |
821 | |
822 | ||
823 | /* Like print_rtl except without all the detail; for example, | |
824 | if RTX is a CONST_INT then print in decimal format. */ | |
825 | ||
826 | void | |
f7d504c2 | 827 | print_simple_rtl (FILE *outf, const_rtx x) |
75b7557d MH |
828 | { |
829 | flag_simple = 1; | |
830 | print_rtl (outf, x); | |
831 | flag_simple = 0; | |
832 | } |