[gcc/testsuite]
[official-gcc.git] / gcc / config / avr / avr-log.c
blobaacaed04ef116e2bc69ff1810fb2e41a5e538f36
1 /* Subroutines for log output for Atmel AVR back end.
2 Copyright (C) 2011-2017 Free Software Foundation, Inc.
3 Contributed by Georg-Johann Lay (avr@gjlay.de)
5 This file is part of GCC.
7 GCC 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 3, or (at your option)
10 any later version.
12 GCC 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.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "function.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "tree-pass.h" /* for current_pass */
29 #include "memmodel.h"
30 #include "tm_p.h"
31 #include "print-tree.h"
33 /* This file supplies some functions for AVR back-end developers
34 with a printf-like interface. The functions are called through
35 macros `avr_dump', `avr_edump' or `avr_fdump' from avr-protos.h:
37 avr_fdump (FILE *stream, const char *fmt, ...);
38 avr_edump (fmt, ...) is a shortcut for avr_fdump (stderr, fmt, ...)
39 avr_dump (fmt, ...) is a shortcut for avr_fdump (dump_file, fmt, ...)
41 == known %-codes ==
43 b: bool
44 r: rtx
45 t: tree
46 T: tree (brief)
47 C: enum rtx_code
48 m: machine_mode
49 R: enum reg_class
50 L: insn list
51 H: location_t
53 == no arguments ==
55 A: call abort()
56 f: current_function_name()
57 F: caller (via __FUNCTION__)
58 P: Pass name and number
59 ?: Print caller, current function and pass info
60 !: Ditto, but only print if in a pass with static pass number,
61 else return.
63 == same as printf ==
65 %: %
66 c: char
67 s: string
68 d: int (decimal)
69 x: int (hex)
72 /* Set according to -mlog= option. */
73 avr_log_t avr_log;
75 /* The worker function implementing the %-codes */
76 static void avr_log_vadump (FILE*, const char*, va_list);
78 /* Wrapper for avr_log_vadump. If STREAM is NULL we are called by avr_dump,
79 i.e. output to dump_file if available. The 2nd argument is __FUNCTION__.
80 The 3rd argument is the format string. */
82 int
83 avr_vdump (FILE *stream, const char *caller, ...)
85 va_list ap;
87 if (NULL == stream && dump_file)
88 stream = dump_file;
90 va_start (ap, caller);
91 if (stream)
92 avr_log_vadump (stream, caller, ap);
93 va_end (ap);
95 return 1;
99 /* Worker function implementing the %-codes and forwarding to
100 respective print/dump function. */
102 static void
103 avr_log_vadump (FILE *file, const char *caller, va_list ap)
105 char bs[3] = {'\\', '?', '\0'};
107 /* 3rd proper argument is always the format string. */
108 const char *fmt = va_arg (ap, const char*);
110 while (*fmt)
112 switch (*fmt++)
114 default:
115 fputc (*(fmt-1), file);
116 break;
118 case '\\':
119 bs[1] = *fmt++;
120 fputs (bs, file);
121 break;
123 case '%':
124 switch (*fmt++)
126 case '%':
127 fputc ('%', file);
128 break;
130 case 't':
132 tree t = va_arg (ap, tree);
133 if (NULL_TREE == t)
134 fprintf (file, "<NULL-TREE>");
135 else
137 if (stderr == file)
138 debug_tree (t);
139 else
141 print_node (file, "", t, 0);
142 putc ('\n', file);
145 break;
148 case 'T':
150 tree t = va_arg (ap, tree);
151 if (NULL_TREE == t)
152 fprintf (file, "<NULL-TREE>");
153 else
154 print_node_brief (file, "", t, 3);
156 break;
158 case 'd':
159 fprintf (file, "%d", va_arg (ap, int));
160 break;
162 case 'x':
163 fprintf (file, "%x", va_arg (ap, int));
164 break;
166 case 'b':
167 fprintf (file, "%s", va_arg (ap, int) ? "true" : "false");
168 break;
170 case 'c':
171 fputc (va_arg (ap, int), file);
172 break;
174 case 'r':
175 print_inline_rtx (file, va_arg (ap, rtx), 0);
176 break;
178 case 'L':
180 rtx_insn *insn = safe_as_a <rtx_insn *> (va_arg (ap, rtx));
182 while (insn)
184 print_inline_rtx (file, insn, 0);
185 fprintf (file, "\n");
186 insn = NEXT_INSN (insn);
188 break;
191 case 'f':
192 if (cfun && cfun->decl)
193 fputs (current_function_name(), file);
194 break;
196 case 's':
198 const char *str = va_arg (ap, char*);
199 fputs (str ? str : "(null)", file);
201 break;
203 case 'm':
204 fputs (GET_MODE_NAME ((machine_mode) va_arg (ap, int)),
205 file);
206 break;
208 case 'C':
209 fputs (rtx_name[va_arg (ap, int)], file);
210 break;
212 case 'R':
213 fputs (reg_class_names[va_arg (ap, int)], file);
214 break;
216 case 'F':
217 fputs (caller, file);
218 break;
220 case 'H':
222 location_t loc = va_arg (ap, location_t);
224 if (BUILTINS_LOCATION == loc)
225 fprintf (file, "<BUILTIN-LOCATION>");
226 else if (UNKNOWN_LOCATION == loc)
227 fprintf (file, "<UNKNOWN-LOCATION>");
228 else
229 fprintf (file, "%s:%d",
230 LOCATION_FILE (loc), LOCATION_LINE (loc));
232 break;
235 case '!':
236 if (!current_pass)
237 return;
238 /* FALLTHRU */
240 case '?':
241 avr_vdump (file, caller, "%F[%f:%P]");
242 break;
244 case 'P':
245 if (current_pass)
246 fprintf (file, "%s(%d)",
247 current_pass->name,
248 current_pass->static_pass_number);
249 else
250 fprintf (file, "pass=?");
252 break;
254 case 'A':
255 fflush (file);
256 abort();
258 default:
259 /* Unknown %-code: Stop printing */
261 fprintf (file, "??? %%%c ???%s\n", *(fmt-1), fmt);
262 fmt = "";
264 break;
266 break; /* % */
270 fflush (file);
274 /* Called from avr.c:avr_option_override().
275 Parse argument of -mlog= and set respective fields in avr_log. */
277 void
278 avr_log_set_avr_log (void)
280 bool all = TARGET_ALL_DEBUG != 0;
282 if (all)
283 avr_log_details = "all";
285 if (all || avr_log_details)
287 /* Adding , at beginning and end of string makes searching easier. */
289 char *str = (char*) alloca (3 + strlen (avr_log_details));
290 bool info;
292 str[0] = ',';
293 strcat (stpcpy (str+1, avr_log_details), ",");
295 all |= NULL != strstr (str, ",all,");
296 info = NULL != strstr (str, ",?,");
298 if (info)
299 fprintf (stderr, "\n-mlog=");
301 #define SET_DUMP_DETAIL(S) \
302 do { \
303 avr_log.S = (all || NULL != strstr (str, "," #S ",")); \
304 if (info) \
305 fprintf (stderr, #S ","); \
306 } while (0)
308 SET_DUMP_DETAIL (address_cost);
309 SET_DUMP_DETAIL (builtin);
310 SET_DUMP_DETAIL (constraints);
311 SET_DUMP_DETAIL (insn_addresses);
312 SET_DUMP_DETAIL (legitimate_address_p);
313 SET_DUMP_DETAIL (legitimize_address);
314 SET_DUMP_DETAIL (legitimize_reload_address);
315 SET_DUMP_DETAIL (progmem);
316 SET_DUMP_DETAIL (rtx_costs);
318 #undef SET_DUMP_DETAIL
320 if (info)
321 fprintf (stderr, "?\n\n");