gcc/ada/
[official-gcc.git] / gcc / config / avr / avr-log.c
blob68d5cbe0b1327481e72b0231d85a9cf2ce1a66d8
1 /* Subroutines for log output for Atmel AVR back end.
2 Copyright (C) 2011-2014 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 "rtl.h"
26 #include "tree.h"
27 #include "print-tree.h"
28 #include "output.h"
29 #include "input.h"
30 #include "hashtab.h"
31 #include "hash-set.h"
32 #include "vec.h"
33 #include "machmode.h"
34 #include "hard-reg-set.h"
35 #include "function.h"
36 #include "tm_p.h"
37 #include "tree-pass.h" /* for current_pass */
39 /* This file supplies some functions for AVR back-end developers
40 with a printf-like interface. The functions are called through
41 macros avr_edump or avr_fdump from avr-protos.h:
43 avr_edump (const char *fmt, ...);
45 avr_fdump (FILE *stream, const char *fmt, ...);
47 avr_edump (fmt, ...) is a shortcut for avr_fdump (stderr, fmt, ...)
49 == known %-codes ==
51 b: bool
52 r: rtx
53 t: tree
54 T: tree (brief)
55 C: enum rtx_code
56 m: machine_mode
57 R: enum reg_class
58 L: insn list
59 H: location_t
61 == no arguments ==
63 A: call abort()
64 f: current_function_name()
65 F: caller (via __FUNCTION__)
66 P: Pass name and number
67 ?: Print caller, current function and pass info
68 !: Ditto, but only print if in a pass with static pass number,
69 else return.
71 == same as printf ==
73 %: %
74 c: char
75 s: string
76 d: int (decimal)
77 x: int (hex)
80 /* Set according to -mlog= option. */
81 avr_log_t avr_log;
83 /* The caller as of __FUNCTION__ */
84 static const char *avr_log_caller = "?";
86 /* The worker function implementing the %-codes */
87 static void avr_log_vadump (FILE*, const char*, va_list);
89 /* As we have no variadic macros, avr_edump maps to a call to
90 avr_log_set_caller_e which saves __FUNCTION__ to avr_log_caller and
91 returns a function pointer to avr_log_fdump_e. avr_log_fdump_e
92 gets the printf-like arguments and calls avr_log_vadump, the
93 worker function. avr_fdump works the same way. */
95 /* Provide avr_log_fdump_e/f so that avr_log_set_caller_e/_f can return
96 their address. */
98 static int
99 avr_log_fdump_e (const char *fmt, ...)
101 va_list ap;
103 va_start (ap, fmt);
104 avr_log_vadump (stderr, fmt, ap);
105 va_end (ap);
107 return 1;
110 static int
111 avr_log_fdump_f (FILE *stream, const char *fmt, ...)
113 va_list ap;
115 va_start (ap, fmt);
116 if (stream)
117 avr_log_vadump (stream, fmt, ap);
118 va_end (ap);
120 return 1;
123 /* Macros avr_edump/avr_fdump map to calls of the following two functions,
124 respectively. You don't need to call them directly. */
126 int (*
127 avr_log_set_caller_e (const char *caller)
128 )(const char*, ...)
130 avr_log_caller = caller;
132 return avr_log_fdump_e;
135 int (*
136 avr_log_set_caller_f (const char *caller)
137 )(FILE*, const char*, ...)
139 avr_log_caller = caller;
141 return avr_log_fdump_f;
145 /* Worker function implementing the %-codes and forwarding to
146 respective print/dump function. */
148 static void
149 avr_log_vadump (FILE *file, const char *fmt, va_list ap)
151 char bs[3] = {'\\', '?', '\0'};
153 while (*fmt)
155 switch (*fmt++)
157 default:
158 fputc (*(fmt-1), file);
159 break;
161 case '\\':
162 bs[1] = *fmt++;
163 fputs (bs, file);
164 break;
166 case '%':
167 switch (*fmt++)
169 case '%':
170 fputc ('%', file);
171 break;
173 case 't':
175 tree t = va_arg (ap, tree);
176 if (NULL_TREE == t)
177 fprintf (file, "<NULL-TREE>");
178 else
180 if (stderr == file)
181 debug_tree (t);
182 else
184 print_node (file, "", t, 0);
185 putc ('\n', file);
188 break;
191 case 'T':
192 print_node_brief (file, "", va_arg (ap, tree), 3);
193 break;
195 case 'd':
196 fprintf (file, "%d", va_arg (ap, int));
197 break;
199 case 'x':
200 fprintf (file, "%x", va_arg (ap, int));
201 break;
203 case 'b':
204 fprintf (file, "%s", va_arg (ap, int) ? "true" : "false");
205 break;
207 case 'c':
208 fputc (va_arg (ap, int), file);
209 break;
211 case 'r':
212 print_inline_rtx (file, va_arg (ap, rtx), 0);
213 break;
215 case 'L':
217 rtx_insn *insn = safe_as_a <rtx_insn *> (va_arg (ap, rtx));
219 while (insn)
221 print_inline_rtx (file, insn, 0);
222 fprintf (file, "\n");
223 insn = NEXT_INSN (insn);
225 break;
228 case 'f':
229 if (cfun && cfun->decl)
230 fputs (current_function_name(), file);
231 break;
233 case 's':
235 const char *str = va_arg (ap, char*);
236 fputs (str ? str : "(null)", file);
238 break;
240 case 'm':
241 fputs (GET_MODE_NAME ((machine_mode) va_arg (ap, int)),
242 file);
243 break;
245 case 'C':
246 fputs (rtx_name[va_arg (ap, int)], file);
247 break;
249 case 'R':
250 fputs (reg_class_names[va_arg (ap, int)], file);
251 break;
253 case 'F':
254 fputs (avr_log_caller, file);
255 break;
257 case 'H':
259 location_t loc = va_arg (ap, location_t);
261 if (BUILTINS_LOCATION == loc)
262 fprintf (file, "<BUILTIN-LOCATION>");
263 else if (UNKNOWN_LOCATION == loc)
264 fprintf (file, "<UNKNOWN-LOCATION>");
265 else
266 fprintf (file, "%s:%d",
267 LOCATION_FILE (loc), LOCATION_LINE (loc));
269 break;
272 case '!':
273 if (!current_pass)
274 return;
275 /* FALLTHRU */
277 case '?':
278 avr_log_fdump_f (file, "%F[%f:%P]");
279 break;
281 case 'P':
282 if (current_pass)
283 fprintf (file, "%s(%d)",
284 current_pass->name,
285 current_pass->static_pass_number);
286 else
287 fprintf (file, "pass=?");
289 break;
291 case 'A':
292 fflush (file);
293 abort();
295 default:
296 /* Unknown %-code: Stop printing */
298 fprintf (file, "??? %%%c ???%s\n", *(fmt-1), fmt);
299 fmt = "";
301 break;
303 break; /* % */
307 fflush (file);
311 /* Called from avr.c:avr_option_override().
312 Parse argument of -mlog= and set respective fields in avr_log. */
314 void
315 avr_log_set_avr_log (void)
317 bool all = TARGET_ALL_DEBUG != 0;
319 if (all || avr_log_details)
321 /* Adding , at beginning and end of string makes searching easier. */
323 char *str = (char*) alloca (3 + strlen (avr_log_details));
324 bool info;
326 str[0] = ',';
327 strcat (stpcpy (str+1, avr_log_details), ",");
329 all |= NULL != strstr (str, ",all,");
330 info = NULL != strstr (str, ",?,");
332 if (info)
333 fprintf (stderr, "\n-mlog=");
335 #define SET_DUMP_DETAIL(S) \
336 do { \
337 avr_log.S = (all || NULL != strstr (str, "," #S ",")); \
338 if (info) \
339 fprintf (stderr, #S ","); \
340 } while (0)
342 SET_DUMP_DETAIL (address_cost);
343 SET_DUMP_DETAIL (builtin);
344 SET_DUMP_DETAIL (constraints);
345 SET_DUMP_DETAIL (legitimate_address_p);
346 SET_DUMP_DETAIL (legitimize_address);
347 SET_DUMP_DETAIL (legitimize_reload_address);
348 SET_DUMP_DETAIL (progmem);
349 SET_DUMP_DETAIL (rtx_costs);
351 #undef SET_DUMP_DETAIL
353 if (info)
354 fprintf (stderr, "?\n\n");