Fix comments
[official-gcc.git] / gcc / config / avr / avr-log.c
blob828c5effb3813916d5b4248229af58c7c1a2afa1
1 /* Subroutines for log output for Atmel AVR back end.
2 Copyright (C) 2011 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 "output.h"
28 #include "input.h"
29 #include "function.h"
30 #include "tm_p.h"
31 #include "tree-pass.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_edump or avr_fdump from avr-protos.h:
37 avr_edump (const char *fmt, ...);
39 avr_fdump (FILE *stream, const char *fmt, ...);
41 avr_edump (fmt, ...) is a shortcut for avr_fdump (stderr, fmt, ...)
43 == known %-codes ==
45 b: bool
46 r: rtx
47 t: tree
48 T: tree (brief)
49 C: enum rtx_code
50 m: enum machine_mode
51 R: enum reg_class
52 D: double_int (signed decimal)
53 X: double_int (unsigned hex)
54 L: insn list
55 H: location_t
57 == no arguments ==
59 A: call abort()
60 f: current_function_name()
61 F: caller (via __FUNCTION__)
62 P: Pass name and number
63 ?: Print caller, current function and pass info
64 !: Ditto, but only print if in a pass with static pass number,
65 else return.
67 == same as printf ==
69 %: %
70 c: char
71 s: string
72 d: int (decimal)
73 x: int (hex)
76 /* Set according to -mlog= option. */
77 avr_log_t avr_log;
79 /* The caller as of __FUNCTION__ */
80 static const char *avr_log_caller = "?";
82 /* The worker function implementing the %-codes */
83 static void avr_log_vadump (FILE*, const char*, va_list);
85 /* As we have no variadic macros, avr_edump maps to a call to
86 avr_log_set_caller_e which saves __FUNCTION__ to avr_log_caller and
87 returns a function pointer to avr_log_fdump_e. avr_log_fdump_e
88 gets the printf-like arguments and calls avr_log_vadump, the
89 worker function. avr_fdump works the same way. */
91 /* Provide avr_log_fdump_e/f so that avr_log_set_caller_e/_f can return
92 their address. */
94 static int
95 avr_log_fdump_e (const char *fmt, ...)
97 va_list ap;
99 va_start (ap, fmt);
100 avr_log_vadump (stderr, fmt, ap);
101 va_end (ap);
103 return 1;
106 static int
107 avr_log_fdump_f (FILE *stream, const char *fmt, ...)
109 va_list ap;
111 va_start (ap, fmt);
112 if (stream)
113 avr_log_vadump (stream, fmt, ap);
114 va_end (ap);
116 return 1;
119 /* Macros avr_edump/avr_fdump map to calls of the following two functions,
120 respectively. You don't need to call them directly. */
122 int (*
123 avr_log_set_caller_e (const char *caller)
124 )(const char*, ...)
126 avr_log_caller = caller;
128 return avr_log_fdump_e;
131 int (*
132 avr_log_set_caller_f (const char *caller)
133 )(FILE*, const char*, ...)
135 avr_log_caller = caller;
137 return avr_log_fdump_f;
141 /* Copy-paste from double-int.c:double_int_split_digit (it's static there).
142 Splits last digit of *CST (taken as unsigned) in BASE and returns it. */
144 static unsigned
145 avr_double_int_pop_digit (double_int *cst, unsigned base)
147 unsigned HOST_WIDE_INT resl, reml;
148 HOST_WIDE_INT resh, remh;
150 div_and_round_double (FLOOR_DIV_EXPR, true, cst->low, cst->high, base, 0,
151 &resl, &resh, &reml, &remh);
152 cst->high = resh;
153 cst->low = resl;
155 return reml;
159 /* Dump VAL as hex value to FILE. */
161 static void
162 avr_dump_double_int_hex (FILE *file, double_int val)
164 unsigned digit[4];
166 digit[0] = avr_double_int_pop_digit (&val, 1 << 16);
167 digit[1] = avr_double_int_pop_digit (&val, 1 << 16);
168 digit[2] = avr_double_int_pop_digit (&val, 1 << 16);
169 digit[3] = avr_double_int_pop_digit (&val, 1 << 16);
171 fprintf (file, "0x");
173 if (digit[3] | digit[2])
174 fprintf (file, "%04x%04x", digit[3], digit[2]);
176 if (digit[3] | digit[2] | digit[1] | digit[0])
177 fprintf (file, "%04x%04x", digit[1], digit[0]);
178 else
179 fprintf (file, "0");
183 /* Worker function implementing the %-codes and forwarding to
184 respective print/dump function. */
186 static void
187 avr_log_vadump (FILE *file, const char *fmt, va_list ap)
189 char bs[3] = {'\\', '?', '\0'};
191 while (*fmt)
193 switch (*fmt++)
195 default:
196 fputc (*(fmt-1), file);
197 break;
199 case '\\':
200 bs[1] = *fmt++;
201 fputs (bs, file);
202 break;
204 case '%':
205 switch (*fmt++)
207 case '%':
208 fputc ('%', file);
209 break;
211 case 't':
213 tree t = va_arg (ap, tree);
214 if (NULL_TREE == t)
215 fprintf (file, "<NULL-TREE>");
216 else
218 if (stderr == file)
219 debug_tree (t);
220 else
222 print_node (file, "", t, 0);
223 putc ('\n', file);
226 break;
229 case 'T':
230 print_node_brief (file, "", va_arg (ap, tree), 3);
231 break;
233 case 'd':
234 fprintf (file, "%d", va_arg (ap, int));
235 break;
237 case 'D':
238 dump_double_int (file, va_arg (ap, double_int), false);
239 break;
241 case 'X':
242 avr_dump_double_int_hex (file, va_arg (ap, double_int));
243 break;
245 case 'x':
246 fprintf (file, "%x", va_arg (ap, int));
247 break;
249 case 'b':
250 fprintf (file, "%s", va_arg (ap, int) ? "true" : "false");
251 break;
253 case 'c':
254 fputc (va_arg (ap, int), file);
255 break;
257 case 'r':
258 print_inline_rtx (file, va_arg (ap, rtx), 0);
259 break;
261 case 'L':
263 rtx insn = va_arg (ap, rtx);
265 while (insn)
267 print_inline_rtx (file, insn, 0);
268 fprintf (file, "\n");
269 insn = NEXT_INSN (insn);
271 break;
274 case 'f':
275 if (cfun && cfun->decl)
276 fputs (current_function_name(), file);
277 break;
279 case 's':
281 const char *str = va_arg (ap, char*);
282 fputs (str ? str : "(null)", file);
284 break;
286 case 'm':
287 fputs (GET_MODE_NAME (va_arg (ap, enum machine_mode)), file);
288 break;
290 case 'C':
291 fputs (rtx_name[va_arg (ap, enum rtx_code)], file);
292 break;
294 case 'R':
295 fputs (reg_class_names[va_arg (ap, enum reg_class)], file);
296 break;
298 case 'F':
299 fputs (avr_log_caller, file);
300 break;
302 case 'H':
304 location_t loc = va_arg (ap, location_t);
306 if (BUILTINS_LOCATION == loc)
307 fprintf (file, "<BUILTIN-LOCATION>");
308 else if (UNKNOWN_LOCATION == loc)
309 fprintf (file, "<UNKNOWN-LOCATION>");
310 else
311 fprintf (file, "%s:%d",
312 LOCATION_FILE (loc), LOCATION_LINE (loc));
314 break;
317 case '!':
318 if (!current_pass)
319 return;
320 /* FALLTHRU */
322 case '?':
323 avr_log_fdump_f (file, "%F[%f:%P]");
324 break;
326 case 'P':
327 if (current_pass)
328 fprintf (file, "%s(%d)",
329 current_pass->name,
330 current_pass->static_pass_number);
331 else
332 fprintf (file, "pass=?");
334 break;
336 case 'A':
337 fflush (file);
338 abort();
340 default:
341 /* Unknown %-code: Stop printing */
343 fprintf (file, "??? %%%c ???%s\n", *(fmt-1), fmt);
344 fmt = "";
346 break;
348 break; /* % */
352 fflush (file);
356 /* Called from avr.c:avr_option_override().
357 Parse argument of -mlog= and set respective fields in avr_log. */
359 void
360 avr_log_set_avr_log (void)
362 bool all = TARGET_ALL_DEBUG != 0;
364 if (all || avr_log_details)
366 /* Adding , at beginning and end of string makes searching easier. */
368 char *str = (char*) alloca (3 + strlen (avr_log_details));
369 bool info;
371 str[0] = ',';
372 strcat (stpcpy (str+1, avr_log_details), ",");
374 all |= NULL != strstr (str, ",all,");
375 info = NULL != strstr (str, ",?,");
377 if (info)
378 fprintf (stderr, "\n-mlog=");
380 #define SET_DUMP_DETAIL(S) \
381 do { \
382 avr_log.S = (all || NULL != strstr (str, "," #S ",")); \
383 if (info) \
384 fprintf (stderr, #S ","); \
385 } while (0)
387 SET_DUMP_DETAIL (address_cost);
388 SET_DUMP_DETAIL (builtin);
389 SET_DUMP_DETAIL (constraints);
390 SET_DUMP_DETAIL (legitimate_address_p);
391 SET_DUMP_DETAIL (legitimize_address);
392 SET_DUMP_DETAIL (legitimize_reload_address);
393 SET_DUMP_DETAIL (progmem);
394 SET_DUMP_DETAIL (rtx_costs);
396 #undef SET_DUMP_DETAIL
398 if (info)
399 fprintf (stderr, "?\n\n");