OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [avr/] [avr-log.c] - Blame information for rev 713

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
/* 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)
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"
27
#include "output.h"
28
#include "input.h"
29
#include "function.h"
30
#include "tm_p.h"
31
#include "tree-pass.h"
32
 
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:
36
 
37
      avr_edump (const char * fmt, ...);
38
 
39
      avr_fdump (FILE * stream, const char * fmt, ...);
40
 
41
   avr_edump (fmt, ...) is a shortcut for avr_fdump (stderr, fmt, ...)
42
 
43
  == known %-codes ==
44
 
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
56
 
57
  == no arguments ==
58
 
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.
66
 
67
  == same as printf ==
68
 
69
  %: %
70
  c: char
71
  s: string
72
  d: int (decimal)
73
  x: int (hex)
74
*/
75
 
76
/* Set according to -mlog= option.  */
77
avr_log_t avr_log;
78
 
79
/* The caller as of __FUNCTION__ */
80
static const char *avr_log_caller = "?";
81
 
82
/* The worker function implementing the %-codes */
83
static void avr_log_vadump (FILE*, const char*, va_list);
84
 
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.  */
90
 
91
/* Provide avr_log_fdump_e/f so that avr_log_set_caller_e/_f can return
92
   their address.  */
93
 
94
static int
95
avr_log_fdump_e (const char *fmt, ...)
96
{
97
  va_list ap;
98
 
99
  va_start (ap, fmt);
100
  avr_log_vadump (stderr, fmt, ap);
101
  va_end (ap);
102
 
103
  return 1;
104
}
105
 
106
static int
107
avr_log_fdump_f (FILE *stream, const char *fmt, ...)
108
{
109
  va_list ap;
110
 
111
  va_start (ap, fmt);
112
  if (stream)
113
    avr_log_vadump (stream, fmt, ap);
114
  va_end (ap);
115
 
116
  return 1;
117
}
118
 
119
/* Macros avr_edump/avr_fdump map to calls of the following two functions,
120
   respectively.  You don't need to call them directly.  */
121
 
122
int (*
123
avr_log_set_caller_e (const char *caller)
124
     )(const char*, ...)
125
{
126
  avr_log_caller = caller;
127
 
128
  return avr_log_fdump_e;
129
}
130
 
131
int (*
132
avr_log_set_caller_f (const char *caller)
133
     )(FILE*, const char*, ...)
134
{
135
  avr_log_caller = caller;
136
 
137
  return avr_log_fdump_f;
138
}
139
 
140
 
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.  */
143
 
144
static unsigned
145
avr_double_int_pop_digit (double_int *cst, unsigned base)
146
{
147
  unsigned HOST_WIDE_INT resl, reml;
148
  HOST_WIDE_INT resh, remh;
149
 
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;
154
 
155
  return reml;
156
}
157
 
158
 
159
/* Dump VAL as hex value to FILE.  */
160
 
161
static void
162
avr_dump_double_int_hex (FILE *file, double_int val)
163
{
164
  unsigned digit[4];
165
 
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);
170
 
171
  fprintf (file, "0x");
172
 
173
  if (digit[3] | digit[2])
174
    fprintf (file, "%04x%04x", digit[3], digit[2]);
175
 
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");
180
}
181
 
182
 
183
/* Worker function implementing the %-codes and forwarding to
184
   respective print/dump function.  */
185
 
186
static void
187
avr_log_vadump (FILE *file, const char *fmt, va_list ap)
188
{
189
  char bs[3] = {'\\', '?', '\0'};
190
 
191
  while (*fmt)
192
    {
193
      switch (*fmt++)
194
        {
195
        default:
196
          fputc (*(fmt-1), file);
197
          break;
198
 
199
        case '\\':
200
          bs[1] = *fmt++;
201
          fputs (bs, file);
202
          break;
203
 
204
        case '%':
205
          switch (*fmt++)
206
            {
207
            case '%':
208
              fputc ('%', file);
209
              break;
210
 
211
            case 't':
212
              {
213
                tree t = va_arg (ap, tree);
214
                if (NULL_TREE == t)
215
                  fprintf (file, "<NULL-TREE>");
216
                else
217
                  {
218
                    if (stderr == file)
219
                      debug_tree (t);
220
                    else
221
                      {
222
                        print_node (file, "", t, 0);
223
                        putc ('\n', file);
224
                      }
225
                  }
226
                break;
227
              }
228
 
229
            case 'T':
230
              print_node_brief (file, "", va_arg (ap, tree), 3);
231
              break;
232
 
233
            case 'd':
234
              fprintf (file, "%d", va_arg (ap, int));
235
              break;
236
 
237
            case 'D':
238
              dump_double_int (file, va_arg (ap, double_int), false);
239
              break;
240
 
241
            case 'X':
242
              avr_dump_double_int_hex (file, va_arg (ap, double_int));
243
              break;
244
 
245
            case 'x':
246
              fprintf (file, "%x", va_arg (ap, int));
247
              break;
248
 
249
            case 'b':
250
              fprintf (file, "%s", va_arg (ap, int) ? "true" : "false");
251
              break;
252
 
253
            case 'c':
254
              fputc (va_arg (ap, int), file);
255
              break;
256
 
257
            case 'r':
258
              print_inline_rtx (file, va_arg (ap, rtx), 0);
259
              break;
260
 
261
            case 'L':
262
              {
263
                rtx insn = va_arg (ap, rtx);
264
 
265
                while (insn)
266
                  {
267
                    print_inline_rtx (file, insn, 0);
268
                    fprintf (file, "\n");
269
                    insn = NEXT_INSN (insn);
270
                  }
271
                break;
272
              }
273
 
274
            case 'f':
275
              if (cfun && cfun->decl)
276
                fputs (current_function_name(), file);
277
              break;
278
 
279
            case 's':
280
              {
281
                const char *str = va_arg (ap, char*);
282
                fputs (str ? str : "(null)", file);
283
              }
284
              break;
285
 
286
            case 'm':
287
              fputs (GET_MODE_NAME (va_arg (ap, enum machine_mode)), file);
288
              break;
289
 
290
            case 'C':
291
              fputs (rtx_name[va_arg (ap, enum rtx_code)], file);
292
              break;
293
 
294
            case 'R':
295
              fputs (reg_class_names[va_arg (ap, enum reg_class)], file);
296
              break;
297
 
298
            case 'F':
299
              fputs (avr_log_caller, file);
300
              break;
301
 
302
            case 'H':
303
              {
304
                location_t loc = va_arg (ap, location_t);
305
 
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));
313
 
314
                break;
315
              }
316
 
317
            case '!':
318
              if (!current_pass)
319
                return;
320
              /* FALLTHRU */
321
 
322
            case '?':
323
              avr_log_fdump_f (file, "%F[%f:%P]");
324
              break;
325
 
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=?");
333
 
334
              break;
335
 
336
            case 'A':
337
              fflush (file);
338
              abort();
339
 
340
            default:
341
              /* Unknown %-code: Stop printing */
342
 
343
              fprintf (file, "??? %%%c ???%s\n", *(fmt-1), fmt);
344
              fmt = "";
345
 
346
              break;
347
            }
348
          break; /* % */
349
        }
350
    }
351
 
352
  fflush (file);
353
}
354
 
355
 
356
/* Called from avr.c:avr_option_override().
357
   Parse argument of -mlog= and set respective fields in avr_log.  */
358
 
359
void
360
avr_log_set_avr_log (void)
361
{
362
  bool all = TARGET_ALL_DEBUG != 0;
363
 
364
  if (all || avr_log_details)
365
    {
366
      /* Adding , at beginning and end of string makes searching easier.  */
367
 
368
      char *str = (char*) alloca (3 + strlen (avr_log_details));
369
      bool info;
370
 
371
      str[0] = ',';
372
      strcat (stpcpy (str+1, avr_log_details), ",");
373
 
374
      all |= NULL != strstr (str, ",all,");
375
      info = NULL != strstr (str, ",?,");
376
 
377
      if (info)
378
        fprintf (stderr, "\n-mlog=");
379
 
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)
386
 
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);
395
 
396
#undef SET_DUMP_DETAIL
397
 
398
      if (info)
399
        fprintf (stderr, "?\n\n");
400
    }
401
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.