]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/avr/avr-log.c
2015-06-04 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / config / avr / avr-log.c
1 /* Subroutines for log output for Atmel AVR back end.
2 Copyright (C) 2011-2015 Free Software Foundation, Inc.
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 "hash-set.h"
27 #include "vec.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "inchash.h"
32 #include "tree.h"
33 #include "print-tree.h"
34 #include "output.h"
35 #include "input.h"
36 #include "hard-reg-set.h"
37 #include "function.h"
38 #include "tm_p.h"
39 #include "tree-pass.h" /* for current_pass */
40
41 /* This file supplies some functions for AVR back-end developers
42 with a printf-like interface. The functions are called through
43 macros `avr_dump', `avr_edump' or `avr_fdump' from avr-protos.h:
44
45 avr_fdump (FILE *stream, const char *fmt, ...);
46 avr_edump (fmt, ...) is a shortcut for avr_fdump (stderr, fmt, ...)
47 avr_dump (fmt, ...) is a shortcut for avr_fdump (dump_file, fmt, ...)
48
49 == known %-codes ==
50
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
60
61 == no arguments ==
62
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.
70
71 == same as printf ==
72
73 %: %
74 c: char
75 s: string
76 d: int (decimal)
77 x: int (hex)
78 */
79
80 /* Set according to -mlog= option. */
81 avr_log_t avr_log;
82
83 /* The worker function implementing the %-codes */
84 static void avr_log_vadump (FILE*, const char*, va_list);
85
86 /* Wrapper for avr_log_vadump. If STREAM is NULL we are called by avr_dump,
87 i.e. output to dump_file if available. The 2nd argument is __FUNCTION__.
88 The 3rd argument is the format string. */
89
90 int
91 avr_vdump (FILE *stream, const char *caller, ...)
92 {
93 va_list ap;
94
95 if (NULL == stream && dump_file)
96 stream = dump_file;
97
98 va_start (ap, caller);
99 if (stream)
100 avr_log_vadump (stream, caller, ap);
101 va_end (ap);
102
103 return 1;
104 }
105
106
107 /* Worker function implementing the %-codes and forwarding to
108 respective print/dump function. */
109
110 static void
111 avr_log_vadump (FILE *file, const char *caller, va_list ap)
112 {
113 char bs[3] = {'\\', '?', '\0'};
114
115 /* 3rd proper argument is always the format string. */
116 const char *fmt = va_arg (ap, const char*);
117
118 while (*fmt)
119 {
120 switch (*fmt++)
121 {
122 default:
123 fputc (*(fmt-1), file);
124 break;
125
126 case '\\':
127 bs[1] = *fmt++;
128 fputs (bs, file);
129 break;
130
131 case '%':
132 switch (*fmt++)
133 {
134 case '%':
135 fputc ('%', file);
136 break;
137
138 case 't':
139 {
140 tree t = va_arg (ap, tree);
141 if (NULL_TREE == t)
142 fprintf (file, "<NULL-TREE>");
143 else
144 {
145 if (stderr == file)
146 debug_tree (t);
147 else
148 {
149 print_node (file, "", t, 0);
150 putc ('\n', file);
151 }
152 }
153 break;
154 }
155
156 case 'T':
157 print_node_brief (file, "", va_arg (ap, tree), 3);
158 break;
159
160 case 'd':
161 fprintf (file, "%d", va_arg (ap, int));
162 break;
163
164 case 'x':
165 fprintf (file, "%x", va_arg (ap, int));
166 break;
167
168 case 'b':
169 fprintf (file, "%s", va_arg (ap, int) ? "true" : "false");
170 break;
171
172 case 'c':
173 fputc (va_arg (ap, int), file);
174 break;
175
176 case 'r':
177 print_inline_rtx (file, va_arg (ap, rtx), 0);
178 break;
179
180 case 'L':
181 {
182 rtx_insn *insn = safe_as_a <rtx_insn *> (va_arg (ap, rtx));
183
184 while (insn)
185 {
186 print_inline_rtx (file, insn, 0);
187 fprintf (file, "\n");
188 insn = NEXT_INSN (insn);
189 }
190 break;
191 }
192
193 case 'f':
194 if (cfun && cfun->decl)
195 fputs (current_function_name(), file);
196 break;
197
198 case 's':
199 {
200 const char *str = va_arg (ap, char*);
201 fputs (str ? str : "(null)", file);
202 }
203 break;
204
205 case 'm':
206 fputs (GET_MODE_NAME ((machine_mode) va_arg (ap, int)),
207 file);
208 break;
209
210 case 'C':
211 fputs (rtx_name[va_arg (ap, int)], file);
212 break;
213
214 case 'R':
215 fputs (reg_class_names[va_arg (ap, int)], file);
216 break;
217
218 case 'F':
219 fputs (caller, file);
220 break;
221
222 case 'H':
223 {
224 location_t loc = va_arg (ap, location_t);
225
226 if (BUILTINS_LOCATION == loc)
227 fprintf (file, "<BUILTIN-LOCATION>");
228 else if (UNKNOWN_LOCATION == loc)
229 fprintf (file, "<UNKNOWN-LOCATION>");
230 else
231 fprintf (file, "%s:%d",
232 LOCATION_FILE (loc), LOCATION_LINE (loc));
233
234 break;
235 }
236
237 case '!':
238 if (!current_pass)
239 return;
240 /* FALLTHRU */
241
242 case '?':
243 avr_vdump (file, caller, "%F[%f:%P]");
244 break;
245
246 case 'P':
247 if (current_pass)
248 fprintf (file, "%s(%d)",
249 current_pass->name,
250 current_pass->static_pass_number);
251 else
252 fprintf (file, "pass=?");
253
254 break;
255
256 case 'A':
257 fflush (file);
258 abort();
259
260 default:
261 /* Unknown %-code: Stop printing */
262
263 fprintf (file, "??? %%%c ???%s\n", *(fmt-1), fmt);
264 fmt = "";
265
266 break;
267 }
268 break; /* % */
269 }
270 }
271
272 fflush (file);
273 }
274
275
276 /* Called from avr.c:avr_option_override().
277 Parse argument of -mlog= and set respective fields in avr_log. */
278
279 void
280 avr_log_set_avr_log (void)
281 {
282 bool all = TARGET_ALL_DEBUG != 0;
283
284 if (all)
285 avr_log_details = "all";
286
287 if (all || avr_log_details)
288 {
289 /* Adding , at beginning and end of string makes searching easier. */
290
291 char *str = (char*) alloca (3 + strlen (avr_log_details));
292 bool info;
293
294 str[0] = ',';
295 strcat (stpcpy (str+1, avr_log_details), ",");
296
297 all |= NULL != strstr (str, ",all,");
298 info = NULL != strstr (str, ",?,");
299
300 if (info)
301 fprintf (stderr, "\n-mlog=");
302
303 #define SET_DUMP_DETAIL(S) \
304 do { \
305 avr_log.S = (all || NULL != strstr (str, "," #S ",")); \
306 if (info) \
307 fprintf (stderr, #S ","); \
308 } while (0)
309
310 SET_DUMP_DETAIL (address_cost);
311 SET_DUMP_DETAIL (builtin);
312 SET_DUMP_DETAIL (constraints);
313 SET_DUMP_DETAIL (legitimate_address_p);
314 SET_DUMP_DETAIL (legitimize_address);
315 SET_DUMP_DETAIL (legitimize_reload_address);
316 SET_DUMP_DETAIL (progmem);
317 SET_DUMP_DETAIL (rtx_costs);
318
319 #undef SET_DUMP_DETAIL
320
321 if (info)
322 fprintf (stderr, "?\n\n");
323 }
324 }