]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/50566 ([avr]: Add support for better logging similar to -mdeb)
authorGeorg-Johann Lay <avr@gjlay.de>
Thu, 29 Sep 2011 11:51:59 +0000 (11:51 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Thu, 29 Sep 2011 11:51:59 +0000 (11:51 +0000)
PR target/50566
* config.gcc (extra_objs): Add avr-log.o for $target in:
avr-*-rtems*, avr-*-*.
* config/avr/t-avr (avr-log.o): New rule to compile...
* config/avr/avr-log.c: ...this new file.
* config/avr/avr.opt (mlog=): New option.
* config/avr/avr-protos.h (avr_edump, avr_fdump): New macros.
(avr_log_set_caller_e, avr_log_set_caller_f): New prototypes.
(avr_log_set_avr_log): New prototype.
(avr_log_t): New typedef.
(avr_log): New declaration.
* config/avr/avr.c (avr_option_override): Call avr_log_set_avr_log.

From-SVN: r179344

gcc/ChangeLog
gcc/config.gcc
gcc/config/avr/avr-log.c [new file with mode: 0644]
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c
gcc/config/avr/avr.opt
gcc/config/avr/t-avr

index 9cadb7106751c5fd6be13d46c7eda304ba5c7440..5cf8ceaad107b78d90017bd2b8da3efa6c67f689 100644 (file)
@@ -1,3 +1,18 @@
+2011-09-29  Georg-Johann Lay  <avr@gjlay.de>
+
+       PR target/50566
+       * config.gcc (extra_objs): Add avr-log.o for $target in:
+       avr-*-rtems*, avr-*-*.
+       * config/avr/t-avr (avr-log.o): New rule to compile...
+       * config/avr/avr-log.c: ...this new file.
+       * config/avr/avr.opt (mlog=): New option.
+       * config/avr/avr-protos.h (avr_edump, avr_fdump): New macros.
+       (avr_log_set_caller_e, avr_log_set_caller_f): New prototypes.
+       (avr_log_set_avr_log): New prototype.
+       (avr_log_t): New typedef.
+       (avr_log): New declaration.
+       * config/avr/avr.c (avr_option_override): Call avr_log_set_avr_log.
+
 2011-09-29  Artjoms Sinkarovs <artyom.shinkaroff@gmail.com>
 
        * expr.c (do_store_flag): Expand vector comparison by
index cf11364fd95a9ce054079addd59c1aa63966a8a3..24564025aef5b762862aa79b54d3232486d5694b 100644 (file)
@@ -939,14 +939,14 @@ avr-*-rtems*)
        libgcc_tm_file="$libgcc_tm_file avr/avr-lib.h"
        tmake_file="avr/t-avr t-rtems avr/t-rtems"
        extra_gcc_objs="driver-avr.o avr-devices.o"
-       extra_objs="avr-devices.o"
+       extra_objs="avr-devices.o avr-log.o"
        ;;
 avr-*-*)
        tm_file="elfos.h avr/elf.h avr/avr.h dbxelf.h newlib-stdint.h"
        libgcc_tm_file="$libgcc_tm_file avr/avr-lib.h"
        use_gcc_stdint=wrap
        extra_gcc_objs="driver-avr.o avr-devices.o"
-       extra_objs="avr-devices.o"
+       extra_objs="avr-devices.o avr-log.o"
        ;;
 bfin*-elf*)
        tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h bfin/elf.h"
diff --git a/gcc/config/avr/avr-log.c b/gcc/config/avr/avr-log.c
new file mode 100644 (file)
index 0000000..87cbd23
--- /dev/null
@@ -0,0 +1,319 @@
+/* Subroutines for log output for Atmel AVR back end.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+   Contributed by Georg-Johann Lay (avr@gjlay.de)
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+   
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "tree.h"
+#include "output.h"
+#include "input.h"
+#include "function.h"
+#include "tm_p.h"
+#include "tree-pass.h"
+
+/* This file supplies some functions for AVR back-end developers
+   with a printf-like interface.  The functions are called through
+   macros avr_edump or avr_fdump from avr-protos.h:
+
+      avr_edump (const char * fmt, ...);
+
+      avr_fdump (FILE * stream, const char * fmt, ...);
+
+   avr_edump (fmt, ...) is a shortcut for avr_fdump (stderr, fmt, ...)
+
+  == known %-codes ==
+  
+  r: rtx
+  t: tree
+  T: tree (brief)
+  C: enum rtx_code
+  m: enum machine_mode
+  R: enum reg_class
+  L: insn list
+  H: location_t
+
+  == no arguments ==
+  
+  A: call abort()
+  f: current_function_name()
+  F: caller (via __FUNCTION__)
+  P: Pass name and number
+  ?: Print caller, current function and pass info
+
+  == same as printf ==
+  
+  %: %
+  c: char
+  s: string
+  d: int (decimal)
+  x: int (hex)
+*/
+
+/* Set according to -mlog= option.  */
+avr_log_t avr_log;
+
+/* The caller as of __FUNCTION__ */
+static const char *avr_log_caller = "?";
+
+/* The worker function implementing the %-codes */
+static void avr_log_vadump (FILE*, const char*, va_list);
+
+/* As we have no variadic macros, avr_edump maps to a call to
+   avr_log_set_caller_e which saves __FUNCTION__ to avr_log_caller and
+   returns a function pointer to avr_log_fdump_e.  avr_fdump_e
+   gets the printf-like arguments and calls avr_log_vadump, the
+   worker function. avr_fdump works the same way.  */
+
+/* Provide avr_log_fdump_e/f so that avr_log_set_caller_e/_f can return
+   their address.  */
+
+static int
+avr_log_fdump_e (const char *fmt, ...)
+{
+  va_list ap;
+        
+  va_start (ap, fmt);
+  avr_log_vadump (stderr, fmt, ap);
+  va_end (ap);
+    
+  return 1;
+}
+
+static int
+avr_log_fdump_f (FILE *stream, const char *fmt, ...)
+{
+  va_list ap;
+        
+  va_start (ap, fmt);
+  if (stream)
+    avr_log_vadump (stream, fmt, ap);
+  va_end (ap);
+    
+  return 1;
+}
+
+/* Macros avr_edump/avr_fdump map to calls of the following two functions,
+   respectively.  You don't need to call them directly.  */
+
+int (*
+avr_log_set_caller_e (const char *caller)
+     )(const char*, ...)
+{
+  avr_log_caller = caller;
+  
+  return avr_log_fdump_e;
+}
+
+int (*
+avr_log_set_caller_f (const char *caller)
+     )(FILE*, const char*, ...)
+{
+  avr_log_caller = caller;
+
+  return avr_log_fdump_f;
+}
+
+/* Worker function implementing the %-codes and forwarning to
+   respective print/dump function.  */
+
+static void
+avr_log_vadump (FILE *file, const char *fmt, va_list ap)
+{
+  char bs[3] = {'\\', '?', '\0'};
+
+  while (*fmt)
+    {
+      switch (*fmt++)
+        {
+        default:
+          fputc (*(fmt-1), file);
+          break;
+          
+        case '\\':
+          bs[1] = *fmt++;
+          fputs (bs, file);
+          break;
+          
+        case '%':
+          switch (*fmt++)
+            {
+            case '%':
+              fputc ('%', file);
+              break;
+              
+            case 't':
+              {
+                tree t = va_arg (ap, tree);
+                if (NULL_TREE == t)
+                  fprintf (file, "<NULL-TREE>");
+                else
+                  {
+                    if (stderr == file)
+                      debug_tree (t);
+                    else
+                      {
+                        print_node (file, "", t, 0);
+                        putc ('\n', file);
+                      }
+                  }
+                break;
+              }
+              
+            case 'T':
+              print_node_brief (file, "", va_arg (ap, tree), 3);
+              break;
+              
+            case 'd':
+              fprintf (file, "%d", va_arg (ap, int));
+              break;
+              
+            case 'x':
+              fprintf (file, "%x", va_arg (ap, int));
+              break;
+                        
+            case 'c':
+              fputc (va_arg (ap, int), file);
+              break;
+                        
+            case 'r':
+              print_inline_rtx (file, va_arg (ap, rtx), 0);
+              break;
+                        
+            case 'L':
+              {
+                rtx insn = va_arg (ap, rtx);
+
+                while (insn)
+                  {
+                    print_inline_rtx (file, insn, 0);
+                    fprintf (file, "\n");
+                    insn = NEXT_INSN (insn);
+                  }
+                break;
+              }
+                        
+            case 'f':
+              if (cfun && cfun->decl)
+                fputs (current_function_name(), file);
+              break;
+                        
+            case 's':
+              {
+                const char *str = va_arg (ap, char*);
+                fputs (str ? str : "(null)", file);
+              }
+              break;
+                        
+            case 'm':
+              fputs (GET_MODE_NAME (va_arg (ap, enum machine_mode)), file);
+              break;
+              
+            case 'C':
+              fputs (rtx_name[va_arg (ap, enum rtx_code)], file);
+              break;
+              
+            case 'R':
+              fputs (reg_class_names[va_arg (ap, enum reg_class)], file);
+              break;
+              
+            case 'F':
+              fputs (avr_log_caller, file);
+              break;
+              
+            case 'H':
+              {
+                location_t loc = va_arg (ap, location_t);
+                
+                if (BUILTINS_LOCATION == loc)
+                  fprintf (file, "<BUILTIN-LOCATION");
+                else if (UNKNOWN_LOCATION == loc)
+                  fprintf (file, "<UNKNOWN-LOCATION>");
+                else
+                  fprintf (file, "%s:%d",
+                           LOCATION_FILE (loc), LOCATION_LINE (loc));
+                
+                break;
+              }
+              
+            case '!':
+              if (!current_pass)
+                return;
+              /* FALLTHRU */
+              
+            case '?':
+              avr_log_fdump_f (file, "%F[%f:%P]");
+              break;
+                        
+            case 'P':
+              if (current_pass)
+                fprintf (file, "%s(%d)", 
+                         current_pass->name,
+                         current_pass->static_pass_number);
+              else
+                fprintf (file, "pass=?");
+                        
+              break;
+                        
+            case 'A':
+              fflush (file);
+              abort();
+              
+            default:
+              fputc (*(fmt-1), file);
+            }
+          break; /* % */
+        }
+    }
+    
+  fflush (file);
+}
+
+
+/* Called from avr.c:avr_option_override().
+   Parse argument of -mlog= and set respective fields in avr_log.  */
+
+void
+avr_log_set_avr_log (void)
+{
+  if (avr_log_details)
+    {
+      /* Adding , at beginning and end of string makes searching easier.  */
+      
+      char *str = (char*) alloca (3 + strlen (avr_log_details));
+      
+      str[0] = ',';
+      strcat (stpcpy (str+1, avr_log_details), ",");
+      
+#define SET_DUMP_DETAIL(S)                                              \
+      avr_log.S = (TARGET_ALL_DEBUG                                     \
+                   || NULL != strstr (str, "," #S ",")                  \
+                   || NULL != strstr (str, ",all,"))
+
+      SET_DUMP_DETAIL (rtx_costs);
+      SET_DUMP_DETAIL (legitimate_address_p);
+      SET_DUMP_DETAIL (legitimize_address);
+      SET_DUMP_DETAIL (legitimize_reload_address);
+      SET_DUMP_DETAIL (constraints);
+
+#undef SET_DUMP_DETAIL
+    }
+}
index ed88ef70a291ea0a25a317c8ff85018c84b042e7..e34666c66780a56792d8d8c800a3f07333f78886 100644 (file)
@@ -111,3 +111,24 @@ extern rtx avr_incoming_return_addr_rtx (void);
 #ifdef REAL_VALUE_TYPE
 extern void asm_output_float (FILE *file, REAL_VALUE_TYPE n);
 #endif
+
+/* From avr-log.c */
+
+#define avr_edump (avr_log_set_caller_e (__FUNCTION__))
+#define avr_fdump (avr_log_set_caller_f (__FUNCTION__))
+
+extern int (*avr_log_set_caller_e (const char*))(const char*, ...);
+extern int (*avr_log_set_caller_f (const char*))(FILE*, const char*, ...);
+
+extern void avr_log_set_avr_log (void);
+
+typedef struct
+{
+  unsigned rtx_costs :1;
+  unsigned legitimate_address_p :1;
+  unsigned legitimize_address :1;
+  unsigned legitimize_reload_address :1;
+  unsigned constraints :1;
+} avr_log_t;
+
+extern avr_log_t avr_log;
index 5ffa7fc2a17f3bf38b12b70c967dca9501e48d47..f3abf6c22b072f3e0f7ebcbebd9e489a85d88fe2 100644 (file)
@@ -359,6 +359,8 @@ avr_option_override (void)
   zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
 
   init_machine_status = avr_init_machine_status;
+
+  avr_log_set_avr_log();
 }
 
 /* Function to set up the backend function structure.  */
index 59d6393c506c8d43850053ad9073c3170a793bd3..1128dd3bf0293acc7922ad472d9013ec2fa4cbca 100644 (file)
@@ -29,6 +29,9 @@ Target RejectNegative Joined Var(avr_mcu_index) Init(0) Enum(avr_mcu)
 mdeb
 Target Report Undocumented Mask(ALL_DEBUG)
 
+mlog=
+Target RejectNegative Joined Undocumented Var(avr_log_details)
+
 mint8
 Target Report Mask(INT8)
 Use an 8-bit 'int' type
index 85f374527b369bfed4d94d544b581e69866911ba..30e8d96447e56175aff762bbe9239feaf45abfdc 100644 (file)
@@ -30,6 +30,10 @@ avr-c.o: $(srcdir)/config/avr/avr-c.c \
   $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_COMMON_H)
        $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
 
+avr-log.o: $(srcdir)/config/avr/avr-log.c \
+  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(INPUT_H)
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
 $(srcdir)/config/avr/avr-tables.opt: $(srcdir)/config/avr/genopt.sh \
   $(srcdir)/config/avr/avr-mcus.def
        $(SHELL) $(srcdir)/config/avr/genopt.sh $(srcdir)/config/avr > \