]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/avr/avr-log.c
NEXT_INSN and PREV_INSN take a const rtx_insn
[thirdparty/gcc.git] / gcc / config / avr / avr-log.c
CommitLineData
6c7dfafe 1/* Subroutines for log output for Atmel AVR back end.
23a5b65a 2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
6c7dfafe
GJL
3 Contributed by Georg-Johann Lay (avr@gjlay.de)
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "rtl.h"
26#include "tree.h"
d8a2d370 27#include "print-tree.h"
6c7dfafe
GJL
28#include "output.h"
29#include "input.h"
30#include "function.h"
31#include "tm_p.h"
7ee2468b 32#include "tree-pass.h" /* for current_pass */
6c7dfafe
GJL
33
34/* This file supplies some functions for AVR back-end developers
35 with a printf-like interface. The functions are called through
36 macros avr_edump or avr_fdump from avr-protos.h:
37
9ee5885b 38 avr_edump (const char *fmt, ...);
6c7dfafe 39
9ee5885b 40 avr_fdump (FILE *stream, const char *fmt, ...);
6c7dfafe
GJL
41
42 avr_edump (fmt, ...) is a shortcut for avr_fdump (stderr, fmt, ...)
43
44 == known %-codes ==
00892272
GJL
45
46 b: bool
6c7dfafe
GJL
47 r: rtx
48 t: tree
49 T: tree (brief)
50 C: enum rtx_code
51 m: enum machine_mode
52 R: enum reg_class
53 L: insn list
54 H: location_t
55
56 == no arguments ==
00892272 57
6c7dfafe
GJL
58 A: call abort()
59 f: current_function_name()
60 F: caller (via __FUNCTION__)
61 P: Pass name and number
62 ?: Print caller, current function and pass info
7c209481
GJL
63 !: Ditto, but only print if in a pass with static pass number,
64 else return.
6c7dfafe
GJL
65
66 == same as printf ==
00892272 67
6c7dfafe
GJL
68 %: %
69 c: char
70 s: string
71 d: int (decimal)
72 x: int (hex)
73*/
74
75/* Set according to -mlog= option. */
76avr_log_t avr_log;
77
78/* The caller as of __FUNCTION__ */
79static const char *avr_log_caller = "?";
80
81/* The worker function implementing the %-codes */
82static void avr_log_vadump (FILE*, const char*, va_list);
83
84/* As we have no variadic macros, avr_edump maps to a call to
85 avr_log_set_caller_e which saves __FUNCTION__ to avr_log_caller and
b5e35770 86 returns a function pointer to avr_log_fdump_e. avr_log_fdump_e
6c7dfafe 87 gets the printf-like arguments and calls avr_log_vadump, the
b5e35770 88 worker function. avr_fdump works the same way. */
6c7dfafe
GJL
89
90/* Provide avr_log_fdump_e/f so that avr_log_set_caller_e/_f can return
91 their address. */
92
93static int
94avr_log_fdump_e (const char *fmt, ...)
95{
96 va_list ap;
00892272 97
6c7dfafe
GJL
98 va_start (ap, fmt);
99 avr_log_vadump (stderr, fmt, ap);
100 va_end (ap);
00892272 101
6c7dfafe
GJL
102 return 1;
103}
104
105static int
106avr_log_fdump_f (FILE *stream, const char *fmt, ...)
107{
108 va_list ap;
00892272 109
6c7dfafe
GJL
110 va_start (ap, fmt);
111 if (stream)
112 avr_log_vadump (stream, fmt, ap);
113 va_end (ap);
00892272 114
6c7dfafe
GJL
115 return 1;
116}
117
118/* Macros avr_edump/avr_fdump map to calls of the following two functions,
119 respectively. You don't need to call them directly. */
120
121int (*
122avr_log_set_caller_e (const char *caller)
123 )(const char*, ...)
124{
125 avr_log_caller = caller;
00892272 126
6c7dfafe
GJL
127 return avr_log_fdump_e;
128}
129
130int (*
131avr_log_set_caller_f (const char *caller)
132 )(FILE*, const char*, ...)
133{
134 avr_log_caller = caller;
135
136 return avr_log_fdump_f;
137}
138
b5e35770 139
ab758510 140/* Worker function implementing the %-codes and forwarding to
6c7dfafe
GJL
141 respective print/dump function. */
142
143static void
144avr_log_vadump (FILE *file, const char *fmt, va_list ap)
145{
146 char bs[3] = {'\\', '?', '\0'};
147
148 while (*fmt)
149 {
150 switch (*fmt++)
151 {
152 default:
153 fputc (*(fmt-1), file);
154 break;
00892272 155
6c7dfafe
GJL
156 case '\\':
157 bs[1] = *fmt++;
158 fputs (bs, file);
159 break;
00892272 160
6c7dfafe
GJL
161 case '%':
162 switch (*fmt++)
163 {
164 case '%':
165 fputc ('%', file);
166 break;
00892272 167
6c7dfafe
GJL
168 case 't':
169 {
170 tree t = va_arg (ap, tree);
171 if (NULL_TREE == t)
172 fprintf (file, "<NULL-TREE>");
173 else
174 {
175 if (stderr == file)
176 debug_tree (t);
177 else
178 {
179 print_node (file, "", t, 0);
180 putc ('\n', file);
181 }
182 }
183 break;
184 }
00892272 185
6c7dfafe
GJL
186 case 'T':
187 print_node_brief (file, "", va_arg (ap, tree), 3);
188 break;
00892272 189
6c7dfafe
GJL
190 case 'd':
191 fprintf (file, "%d", va_arg (ap, int));
192 break;
00892272 193
6c7dfafe
GJL
194 case 'x':
195 fprintf (file, "%x", va_arg (ap, int));
196 break;
00892272 197
ab758510
GJL
198 case 'b':
199 fprintf (file, "%s", va_arg (ap, int) ? "true" : "false");
200 break;
00892272 201
6c7dfafe
GJL
202 case 'c':
203 fputc (va_arg (ap, int), file);
204 break;
00892272 205
6c7dfafe
GJL
206 case 'r':
207 print_inline_rtx (file, va_arg (ap, rtx), 0);
208 break;
00892272 209
6c7dfafe
GJL
210 case 'L':
211 {
b32d5189 212 rtx_insn *insn = safe_as_a <rtx_insn *> (va_arg (ap, rtx));
6c7dfafe
GJL
213
214 while (insn)
215 {
216 print_inline_rtx (file, insn, 0);
217 fprintf (file, "\n");
218 insn = NEXT_INSN (insn);
219 }
220 break;
221 }
00892272 222
6c7dfafe
GJL
223 case 'f':
224 if (cfun && cfun->decl)
225 fputs (current_function_name(), file);
226 break;
00892272 227
6c7dfafe
GJL
228 case 's':
229 {
230 const char *str = va_arg (ap, char*);
231 fputs (str ? str : "(null)", file);
232 }
233 break;
00892272 234
6c7dfafe 235 case 'm':
00892272
GJL
236 fputs (GET_MODE_NAME ((enum machine_mode) va_arg (ap, int)),
237 file);
6c7dfafe 238 break;
00892272 239
6c7dfafe 240 case 'C':
92f7f5fd 241 fputs (rtx_name[va_arg (ap, int)], file);
6c7dfafe 242 break;
00892272 243
6c7dfafe 244 case 'R':
92f7f5fd 245 fputs (reg_class_names[va_arg (ap, int)], file);
6c7dfafe 246 break;
00892272 247
6c7dfafe
GJL
248 case 'F':
249 fputs (avr_log_caller, file);
250 break;
00892272 251
6c7dfafe
GJL
252 case 'H':
253 {
254 location_t loc = va_arg (ap, location_t);
00892272 255
6c7dfafe 256 if (BUILTINS_LOCATION == loc)
b5e35770 257 fprintf (file, "<BUILTIN-LOCATION>");
6c7dfafe
GJL
258 else if (UNKNOWN_LOCATION == loc)
259 fprintf (file, "<UNKNOWN-LOCATION>");
260 else
261 fprintf (file, "%s:%d",
262 LOCATION_FILE (loc), LOCATION_LINE (loc));
00892272 263
6c7dfafe
GJL
264 break;
265 }
00892272 266
6c7dfafe
GJL
267 case '!':
268 if (!current_pass)
269 return;
270 /* FALLTHRU */
00892272 271
6c7dfafe
GJL
272 case '?':
273 avr_log_fdump_f (file, "%F[%f:%P]");
274 break;
00892272 275
6c7dfafe
GJL
276 case 'P':
277 if (current_pass)
00892272 278 fprintf (file, "%s(%d)",
6c7dfafe
GJL
279 current_pass->name,
280 current_pass->static_pass_number);
281 else
282 fprintf (file, "pass=?");
00892272 283
6c7dfafe 284 break;
00892272 285
6c7dfafe
GJL
286 case 'A':
287 fflush (file);
288 abort();
00892272 289
6c7dfafe 290 default:
fe780c13 291 /* Unknown %-code: Stop printing */
00892272 292
fe780c13
GJL
293 fprintf (file, "??? %%%c ???%s\n", *(fmt-1), fmt);
294 fmt = "";
00892272 295
fe780c13 296 break;
6c7dfafe
GJL
297 }
298 break; /* % */
299 }
300 }
00892272 301
6c7dfafe
GJL
302 fflush (file);
303}
304
305
306/* Called from avr.c:avr_option_override().
307 Parse argument of -mlog= and set respective fields in avr_log. */
308
309void
310avr_log_set_avr_log (void)
311{
b5e35770 312 bool all = TARGET_ALL_DEBUG != 0;
00892272 313
b5e35770 314 if (all || avr_log_details)
6c7dfafe
GJL
315 {
316 /* Adding , at beginning and end of string makes searching easier. */
00892272 317
6c7dfafe 318 char *str = (char*) alloca (3 + strlen (avr_log_details));
b5e35770 319 bool info;
00892272 320
6c7dfafe
GJL
321 str[0] = ',';
322 strcat (stpcpy (str+1, avr_log_details), ",");
b5e35770
GJL
323
324 all |= NULL != strstr (str, ",all,");
325 info = NULL != strstr (str, ",?,");
326
327 if (info)
328 fprintf (stderr, "\n-mlog=");
329
330#define SET_DUMP_DETAIL(S) \
331 do { \
332 avr_log.S = (all || NULL != strstr (str, "," #S ",")); \
333 if (info) \
334 fprintf (stderr, #S ","); \
335 } while (0)
6c7dfafe 336
7c209481 337 SET_DUMP_DETAIL (address_cost);
b5e35770 338 SET_DUMP_DETAIL (builtin);
7c209481 339 SET_DUMP_DETAIL (constraints);
6c7dfafe
GJL
340 SET_DUMP_DETAIL (legitimate_address_p);
341 SET_DUMP_DETAIL (legitimize_address);
342 SET_DUMP_DETAIL (legitimize_reload_address);
7c209481
GJL
343 SET_DUMP_DETAIL (progmem);
344 SET_DUMP_DETAIL (rtx_costs);
6c7dfafe
GJL
345
346#undef SET_DUMP_DETAIL
b5e35770
GJL
347
348 if (info)
349 fprintf (stderr, "?\n\n");
6c7dfafe
GJL
350 }
351}