xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/avr/avr-log.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Subroutines for log output for Atmel AVR back end.
2*8feb0f0bSmrg    Copyright (C) 2011-2020 Free Software Foundation, Inc.
31debfc3dSmrg    Contributed by Georg-Johann Lay (avr@gjlay.de)
41debfc3dSmrg 
51debfc3dSmrg    This file is part of GCC.
61debfc3dSmrg 
71debfc3dSmrg    GCC is free software; you can redistribute it and/or modify
81debfc3dSmrg    it under the terms of the GNU General Public License as published by
91debfc3dSmrg    the Free Software Foundation; either version 3, or (at your option)
101debfc3dSmrg    any later version.
111debfc3dSmrg 
121debfc3dSmrg    GCC is distributed in the hope that it will be useful,
131debfc3dSmrg    but WITHOUT ANY WARRANTY; without even the implied warranty of
141debfc3dSmrg    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
151debfc3dSmrg    GNU General Public License for more details.
161debfc3dSmrg 
171debfc3dSmrg    You should have received a copy of the GNU General Public License
181debfc3dSmrg    along with GCC; see the file COPYING3.  If not see
191debfc3dSmrg    <http://www.gnu.org/licenses/>.  */
201debfc3dSmrg 
21a2dc1f3fSmrg #define IN_TARGET_CODE 1
22a2dc1f3fSmrg 
231debfc3dSmrg #include "config.h"
241debfc3dSmrg #include "system.h"
251debfc3dSmrg #include "coretypes.h"
261debfc3dSmrg #include "tm.h"
271debfc3dSmrg #include "function.h"
281debfc3dSmrg #include "rtl.h"
291debfc3dSmrg #include "tree.h"
301debfc3dSmrg #include "tree-pass.h"	/* for current_pass */
311debfc3dSmrg #include "memmodel.h"
321debfc3dSmrg #include "tm_p.h"
331debfc3dSmrg #include "print-tree.h"
341debfc3dSmrg 
351debfc3dSmrg /* This file supplies some functions for AVR back-end developers
361debfc3dSmrg    with a printf-like interface.  The functions are called through
371debfc3dSmrg    macros `avr_dump', `avr_edump' or `avr_fdump' from avr-protos.h:
381debfc3dSmrg 
391debfc3dSmrg    avr_fdump (FILE *stream, const char *fmt, ...);
401debfc3dSmrg    avr_edump (fmt, ...) is a shortcut for avr_fdump (stderr, fmt, ...)
411debfc3dSmrg    avr_dump (fmt, ...)  is a shortcut for avr_fdump (dump_file, fmt, ...)
421debfc3dSmrg 
431debfc3dSmrg   == known %-codes ==
441debfc3dSmrg 
451debfc3dSmrg   b: bool
461debfc3dSmrg   r: rtx
471debfc3dSmrg   t: tree
481debfc3dSmrg   T: tree (brief)
491debfc3dSmrg   C: enum rtx_code
501debfc3dSmrg   m: machine_mode
511debfc3dSmrg   R: enum reg_class
521debfc3dSmrg   L: insn list
531debfc3dSmrg   H: location_t
541debfc3dSmrg 
551debfc3dSmrg   == no arguments ==
561debfc3dSmrg 
571debfc3dSmrg   A: call abort()
581debfc3dSmrg   f: current_function_name()
591debfc3dSmrg   F: caller (via __FUNCTION__)
601debfc3dSmrg   P: Pass name and number
611debfc3dSmrg   ?: Print caller, current function and pass info
621debfc3dSmrg   !: Ditto, but only print if in a pass with static pass number,
631debfc3dSmrg      else return.
641debfc3dSmrg 
651debfc3dSmrg   == same as printf ==
661debfc3dSmrg 
671debfc3dSmrg   %: %
681debfc3dSmrg   c: char
691debfc3dSmrg   s: string
701debfc3dSmrg   d: int (decimal)
711debfc3dSmrg   x: int (hex)
721debfc3dSmrg */
731debfc3dSmrg 
741debfc3dSmrg /* Set according to -mlog= option.  */
751debfc3dSmrg avr_log_t avr_log;
761debfc3dSmrg 
771debfc3dSmrg /* The worker function implementing the %-codes */
781debfc3dSmrg static void avr_log_vadump (FILE*, const char*, va_list);
791debfc3dSmrg 
801debfc3dSmrg /* Wrapper for avr_log_vadump.  If STREAM is NULL we are called by avr_dump,
811debfc3dSmrg    i.e. output to dump_file if available.  The 2nd argument is __FUNCTION__.
821debfc3dSmrg    The 3rd argument is the format string. */
831debfc3dSmrg 
841debfc3dSmrg int
avr_vdump(FILE * stream,const char * caller,...)851debfc3dSmrg avr_vdump (FILE *stream, const char *caller, ...)
861debfc3dSmrg {
871debfc3dSmrg   va_list ap;
881debfc3dSmrg 
89a2dc1f3fSmrg   if (stream == NULL && dump_file)
901debfc3dSmrg     stream = dump_file;
911debfc3dSmrg 
921debfc3dSmrg   va_start (ap, caller);
931debfc3dSmrg   if (stream)
941debfc3dSmrg     avr_log_vadump (stream, caller, ap);
951debfc3dSmrg   va_end (ap);
961debfc3dSmrg 
971debfc3dSmrg   return 1;
981debfc3dSmrg }
991debfc3dSmrg 
1001debfc3dSmrg 
1011debfc3dSmrg /* Worker function implementing the %-codes and forwarding to
1021debfc3dSmrg    respective print/dump function.  */
1031debfc3dSmrg 
1041debfc3dSmrg static void
avr_log_vadump(FILE * file,const char * caller,va_list ap)1051debfc3dSmrg avr_log_vadump (FILE *file, const char *caller, va_list ap)
1061debfc3dSmrg {
1071debfc3dSmrg   char bs[3] = {'\\', '?', '\0'};
1081debfc3dSmrg 
1091debfc3dSmrg   /* 3rd proper argument is always the format string.  */
1101debfc3dSmrg   const char *fmt = va_arg (ap, const char*);
1111debfc3dSmrg 
1121debfc3dSmrg   while (*fmt)
1131debfc3dSmrg     {
1141debfc3dSmrg       switch (*fmt++)
1151debfc3dSmrg         {
1161debfc3dSmrg         default:
1171debfc3dSmrg           fputc (*(fmt-1), file);
1181debfc3dSmrg           break;
1191debfc3dSmrg 
1201debfc3dSmrg         case '\\':
1211debfc3dSmrg           bs[1] = *fmt++;
1221debfc3dSmrg           fputs (bs, file);
1231debfc3dSmrg           break;
1241debfc3dSmrg 
1251debfc3dSmrg         case '%':
1261debfc3dSmrg           switch (*fmt++)
1271debfc3dSmrg             {
1281debfc3dSmrg             case '%':
1291debfc3dSmrg               fputc ('%', file);
1301debfc3dSmrg               break;
1311debfc3dSmrg 
1321debfc3dSmrg             case 't':
1331debfc3dSmrg               {
1341debfc3dSmrg                 tree t = va_arg (ap, tree);
1351debfc3dSmrg                 if (NULL_TREE == t)
1361debfc3dSmrg                   fprintf (file, "<NULL-TREE>");
1371debfc3dSmrg                 else
1381debfc3dSmrg                   {
1391debfc3dSmrg                     if (stderr == file)
1401debfc3dSmrg                       debug_tree (t);
1411debfc3dSmrg                     else
1421debfc3dSmrg                       {
1431debfc3dSmrg                         print_node (file, "", t, 0);
1441debfc3dSmrg                         putc ('\n', file);
1451debfc3dSmrg                       }
1461debfc3dSmrg                   }
1471debfc3dSmrg                 break;
1481debfc3dSmrg               }
1491debfc3dSmrg 
1501debfc3dSmrg             case 'T':
151a2dc1f3fSmrg               {
152a2dc1f3fSmrg                 tree t = va_arg (ap, tree);
153a2dc1f3fSmrg                 if (NULL_TREE == t)
154a2dc1f3fSmrg                   fprintf (file, "<NULL-TREE>");
155a2dc1f3fSmrg                 else
156a2dc1f3fSmrg                   print_node_brief (file, "", t, 3);
157a2dc1f3fSmrg               }
1581debfc3dSmrg               break;
1591debfc3dSmrg 
1601debfc3dSmrg             case 'd':
1611debfc3dSmrg               fprintf (file, "%d", va_arg (ap, int));
1621debfc3dSmrg               break;
1631debfc3dSmrg 
1641debfc3dSmrg             case 'x':
1651debfc3dSmrg               fprintf (file, "%x", va_arg (ap, int));
1661debfc3dSmrg               break;
1671debfc3dSmrg 
1681debfc3dSmrg             case 'b':
1691debfc3dSmrg               fprintf (file, "%s", va_arg (ap, int) ? "true" : "false");
1701debfc3dSmrg               break;
1711debfc3dSmrg 
1721debfc3dSmrg             case 'c':
1731debfc3dSmrg               fputc (va_arg (ap, int), file);
1741debfc3dSmrg               break;
1751debfc3dSmrg 
1761debfc3dSmrg             case 'r':
1771debfc3dSmrg               print_inline_rtx (file, va_arg (ap, rtx), 0);
1781debfc3dSmrg               break;
1791debfc3dSmrg 
1801debfc3dSmrg             case 'L':
1811debfc3dSmrg               {
1821debfc3dSmrg                 rtx_insn *insn = safe_as_a <rtx_insn *> (va_arg (ap, rtx));
1831debfc3dSmrg 
1841debfc3dSmrg                 while (insn)
1851debfc3dSmrg                   {
1861debfc3dSmrg                     print_inline_rtx (file, insn, 0);
1871debfc3dSmrg                     fprintf (file, "\n");
1881debfc3dSmrg                     insn = NEXT_INSN (insn);
1891debfc3dSmrg                   }
1901debfc3dSmrg                 break;
1911debfc3dSmrg               }
1921debfc3dSmrg 
1931debfc3dSmrg             case 'f':
1941debfc3dSmrg               if (cfun && cfun->decl)
1951debfc3dSmrg                 fputs (current_function_name(), file);
1961debfc3dSmrg               break;
1971debfc3dSmrg 
1981debfc3dSmrg             case 's':
1991debfc3dSmrg               {
2001debfc3dSmrg                 const char *str = va_arg (ap, char*);
2011debfc3dSmrg                 fputs (str ? str : "(null)", file);
2021debfc3dSmrg               }
2031debfc3dSmrg               break;
2041debfc3dSmrg 
2051debfc3dSmrg             case 'm':
2061debfc3dSmrg               fputs (GET_MODE_NAME ((machine_mode) va_arg (ap, int)),
2071debfc3dSmrg                      file);
2081debfc3dSmrg               break;
2091debfc3dSmrg 
2101debfc3dSmrg             case 'C':
2111debfc3dSmrg               fputs (rtx_name[va_arg (ap, int)], file);
2121debfc3dSmrg               break;
2131debfc3dSmrg 
2141debfc3dSmrg             case 'R':
2151debfc3dSmrg               fputs (reg_class_names[va_arg (ap, int)], file);
2161debfc3dSmrg               break;
2171debfc3dSmrg 
2181debfc3dSmrg             case 'F':
2191debfc3dSmrg               fputs (caller, file);
2201debfc3dSmrg               break;
2211debfc3dSmrg 
2221debfc3dSmrg             case 'H':
2231debfc3dSmrg               {
2241debfc3dSmrg                 location_t loc = va_arg (ap, location_t);
2251debfc3dSmrg 
2261debfc3dSmrg                 if (BUILTINS_LOCATION == loc)
2271debfc3dSmrg                   fprintf (file, "<BUILTIN-LOCATION>");
2281debfc3dSmrg                 else if (UNKNOWN_LOCATION == loc)
2291debfc3dSmrg                   fprintf (file, "<UNKNOWN-LOCATION>");
2301debfc3dSmrg                 else
2311debfc3dSmrg                   fprintf (file, "%s:%d",
2321debfc3dSmrg                            LOCATION_FILE (loc), LOCATION_LINE (loc));
2331debfc3dSmrg 
2341debfc3dSmrg                 break;
2351debfc3dSmrg               }
2361debfc3dSmrg 
2371debfc3dSmrg             case '!':
2381debfc3dSmrg               if (!current_pass)
2391debfc3dSmrg                 return;
2401debfc3dSmrg               /* FALLTHRU */
2411debfc3dSmrg 
2421debfc3dSmrg             case '?':
2431debfc3dSmrg               avr_vdump (file, caller, "%F[%f:%P]");
2441debfc3dSmrg               break;
2451debfc3dSmrg 
2461debfc3dSmrg             case 'P':
2471debfc3dSmrg               if (current_pass)
2481debfc3dSmrg                 fprintf (file, "%s(%d)",
2491debfc3dSmrg                          current_pass->name,
2501debfc3dSmrg                          current_pass->static_pass_number);
2511debfc3dSmrg               else
2521debfc3dSmrg                 fprintf (file, "pass=?");
2531debfc3dSmrg 
2541debfc3dSmrg               break;
2551debfc3dSmrg 
2561debfc3dSmrg             case 'A':
2571debfc3dSmrg               fflush (file);
2581debfc3dSmrg               abort();
2591debfc3dSmrg 
2601debfc3dSmrg             default:
2611debfc3dSmrg               /* Unknown %-code: Stop printing */
2621debfc3dSmrg 
2631debfc3dSmrg               fprintf (file, "??? %%%c ???%s\n", *(fmt-1), fmt);
2641debfc3dSmrg               fmt = "";
2651debfc3dSmrg 
2661debfc3dSmrg               break;
2671debfc3dSmrg             }
2681debfc3dSmrg           break; /* % */
2691debfc3dSmrg         }
2701debfc3dSmrg     }
2711debfc3dSmrg 
2721debfc3dSmrg   fflush (file);
2731debfc3dSmrg }
2741debfc3dSmrg 
2751debfc3dSmrg 
2761debfc3dSmrg /* Called from avr.c:avr_option_override().
2771debfc3dSmrg    Parse argument of -mlog= and set respective fields in avr_log.  */
2781debfc3dSmrg 
2791debfc3dSmrg void
avr_log_set_avr_log(void)2801debfc3dSmrg avr_log_set_avr_log (void)
2811debfc3dSmrg {
2821debfc3dSmrg   bool all = TARGET_ALL_DEBUG != 0;
2831debfc3dSmrg 
2841debfc3dSmrg   if (all)
2851debfc3dSmrg     avr_log_details = "all";
2861debfc3dSmrg 
2871debfc3dSmrg   if (all || avr_log_details)
2881debfc3dSmrg     {
2891debfc3dSmrg       /* Adding , at beginning and end of string makes searching easier.  */
2901debfc3dSmrg 
2911debfc3dSmrg       char *str = (char*) alloca (3 + strlen (avr_log_details));
2921debfc3dSmrg       bool info;
2931debfc3dSmrg 
2941debfc3dSmrg       str[0] = ',';
2951debfc3dSmrg       strcat (stpcpy (str+1, avr_log_details), ",");
2961debfc3dSmrg 
297a2dc1f3fSmrg       all |= strstr (str, ",all,") != NULL;
298a2dc1f3fSmrg       info = strstr (str, ",?,") != NULL;
2991debfc3dSmrg 
3001debfc3dSmrg       if (info)
3011debfc3dSmrg         fprintf (stderr, "\n-mlog=");
3021debfc3dSmrg 
3031debfc3dSmrg #define SET_DUMP_DETAIL(S)                                       \
3041debfc3dSmrg       do {                                                       \
305a2dc1f3fSmrg 	avr_log.S = (all || strstr (str, "," #S ",") != NULL);   \
3061debfc3dSmrg         if (info)                                                \
3071debfc3dSmrg           fprintf (stderr, #S ",");                              \
3081debfc3dSmrg       } while (0)
3091debfc3dSmrg 
3101debfc3dSmrg       SET_DUMP_DETAIL (address_cost);
3111debfc3dSmrg       SET_DUMP_DETAIL (builtin);
3121debfc3dSmrg       SET_DUMP_DETAIL (constraints);
313a2dc1f3fSmrg       SET_DUMP_DETAIL (insn_addresses);
3141debfc3dSmrg       SET_DUMP_DETAIL (legitimate_address_p);
3151debfc3dSmrg       SET_DUMP_DETAIL (legitimize_address);
3161debfc3dSmrg       SET_DUMP_DETAIL (legitimize_reload_address);
3171debfc3dSmrg       SET_DUMP_DETAIL (progmem);
3181debfc3dSmrg       SET_DUMP_DETAIL (rtx_costs);
3191debfc3dSmrg 
3201debfc3dSmrg #undef SET_DUMP_DETAIL
3211debfc3dSmrg 
3221debfc3dSmrg       if (info)
3231debfc3dSmrg         fprintf (stderr, "?\n\n");
3241debfc3dSmrg     }
3251debfc3dSmrg }
326