This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] RX pragma address


Hello,

The following patch adds a new pragma, "pragma address" for RX.
The patch updates extend.texi and add a test case to the regression as well.
For the test case I checked than test is getting picked up in gcc.log
unfortunately for the .texi part I don't know where to look/what to do to get the
documentation generated.

This is similar to the pragma address implemented for M32C.

Regression test is OK, tested with the following command:
make -k check-gcc RUNTESTFLAGS=--target_board=rx-sim

Please let me know if this is OK, Thank you!
Sebastian

Index: ChangeLog
===================================================================
--- ChangeLog(revision 256076)
+++ ChangeLog(working copy)
@@ -1,3 +1,21 @@
+2018-01-03  Sebastian Perta  <sebastian.perta@renesas.com>
+
+* config/rx/rx.c (rx_get_pragma_address): New function
+* config/rx/rx.c (rx_note_pragma_address): New function
+* config/rx/rx.c (rx_output_aligned_common): New function use .set instead
+of .comm for pragma address variables
+* config/rx/rx.c (rx_insert_attributes): New function which makes pragma address
+variables volatile
+* config/rx/rx-pragma.c: New file with 2 functions rx_pragma_address and
+rx_register_pragmas to implement and register the new pragma
+* config/rx/rx-protos.h: New declarations rl78_note_pragma_address,
+rx_register_pragmas, rx_output_aligned_common
+* config/rx/t-rx: added rx-pragma.o
+* config/rx/rx.h: defined ASM_OUTPUT_ALIGNED_DECL_COMMON and REGISTER_TARGET_PRAGMAS
+* doc/entend.texi: Added documenation for RX pragmas
+* testsuite/gcc.target/rx/test_pragma_address.c: New file
+* config.gcc: added "rx-pragma.o" to c_target_objs and cxx_target_objs
+
 2018-01-02  Richard Biener  <rguenther@suse.de>

 * ipa-inline.c (big_speedup_p): Fix expression.
Index: config.gcc
===================================================================
--- config.gcc(revision 256076)
+++ config.gcc(working copy)
@@ -2661,6 +2661,8 @@
 rx-*-elf*)
 tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
 tmake_file="${tmake_file} rx/t-rx"
+c_target_objs="rx-pragma.o"
+cxx_target_objs="rx-pragma.o"
 ;;
 s390-*-linux*)
 tm_file="s390/s390.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h s390/linux.h"
Index: config/rx/rx-pragma.c
===================================================================
--- config/rx/rx-pragma.c(nonexistent)
+++ config/rx/rx-pragma.c(working copy)
@@ -0,0 +1,67 @@
+/* Subroutines used for code generation on Renesas RX processors.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   Contributed by Sebastian Perta.
+
+   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 "tree.h"
+#include "c-family/c-common.h"
+#include "c-family/c-pragma.h"
+#include "rx-protos.h"
+
+/* Implements the "pragma ADDRESS" pragma.  This pragma takes a
+ *    variable name and an address, and arranges for that variable to be
+ *       "at" that address.  The variable is also made volatile.  */
+static void
+rx_pragma_address (cpp_reader * reader ATTRIBUTE_UNUSED)
+{
+  tree var, addr;
+  enum cpp_ttype type;
+  type = pragma_lex (&var);
+  if (type == CPP_NAME)
+    {
+      type = pragma_lex (&addr);
+      if (type == CPP_NUMBER)
+{
+  if (var != error_mark_node)
+{
+   unsigned uaddr = tree_to_uhwi (addr);
+   rx_note_pragma_address (IDENTIFIER_POINTER (var), uaddr);
+}
+
+  type = pragma_lex (&var);
+  if (type != CPP_EOF)
+{
+   error ("junk at end of #pragma ADDRESS");
+}
+  return;
+}
+    }
+  error ("malformed #pragma ADDRESS variable address");
+}
+
+void
+rx_register_pragmas (void)
+{
+  c_register_pragma (NULL, "ADDRESS", rx_pragma_address);
+  c_register_pragma (NULL, "address", rx_pragma_address);
+}
+
Index: config/rx/rx-protos.h
===================================================================
--- config/rx/rx-protos.h(revision 256076)
+++ config/rx/rx-protos.h(working copy)
@@ -25,7 +25,11 @@
 extern voidrx_expand_epilogue (bool);
 extern voidrx_expand_prologue (void);
 extern intrx_initial_elimination_offset (int, int);
+extern void rx_register_pragmas (void);

+extern void rx_note_pragma_address (const char *varname, unsigned address);
+extern void rx_output_aligned_common (FILE *stream, tree decl ATTRIBUTE_UNUSED, const char *name,int size, int align);
+
 bool is_interrupt_func (const_tree decl);
 bool is_fast_interrupt_func (const_tree decl);

Index: config/rx/rx.c
===================================================================
--- config/rx/rx.c(revision 256076)
+++ config/rx/rx.c(working copy)
@@ -3462,6 +3462,76 @@
   == (GET_MODE_CLASS (mode2) == MODE_FLOAT
       || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
 }
+
+struct GTY(()) pragma_entry {
+  const char *varname;
+  unsigned address;
+};
+typedef struct pragma_entry pragma_entry;
+
+/* Hash table of pragma info.  */
+static GTY(()) hash_map<nofree_string_hash, unsigned> *pragma_htab;
+
+static bool
+rx_get_pragma_address (const char *varname, unsigned *address)
+{
+  if (!pragma_htab)
+    return false;
+  unsigned int *slot = pragma_htab->get (varname);
+  if (slot)
+    {
+      *address = *slot;
+      return true;
+    }
+  return false;
+}
+
+void
+rx_note_pragma_address (const char *varname, unsigned address)
+{
+  if (!pragma_htab)
+    pragma_htab = hash_map<nofree_string_hash, unsigned>::create_ggc (31);
+
+  const char *name = ggc_strdup (varname);
+  unsigned int *slot = &pragma_htab->get_or_insert (name);
+  *slot = address;
+}
+
+void
+rx_output_aligned_common (FILE *stream, tree decl ATTRIBUTE_UNUSED,
+    const char *name,
+    int size, int align)
+{
+  unsigned int address;
+  if (rx_get_pragma_address (name, &address))
+{
+  fprintf (stream, "\t.set ");
+  assemble_name (stream, name);
+  fprintf (stream, ", 0x%08x\n", address);
+}
+  else
+{
+  fprintf (stream, "\t.comm\t");
+  assemble_name (stream, name);
+  fprintf (stream, ",%u,%u\n", size, align / BITS_PER_UNIT);
+}
+}
+
+static void
+rx_insert_attributes (tree node, tree * attr_ptr ATTRIBUTE_UNUSED)
+{
+  unsigned addr;
+  /* See if we need to make #pragma address variables volatile.  */
+  if ((TREE_CODE (node) == VAR_DECL) && DECL_NAME (node))
+    {
+      const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
+      if (rx_get_pragma_address  (name, &addr))
+{
+      TREE_THIS_VOLATILE (node) = true;
+}
+    }
+}
+


 #undef  TARGET_NARROW_VOLATILE_BITFIELD
 #define TARGET_NARROW_VOLATILE_BITFIELDrx_narrow_volatile_bitfield
@@ -3624,6 +3694,9 @@
 #undef  TARGET_MODES_TIEABLE_P
 #define TARGET_MODES_TIEABLE_Prx_modes_tieable_p

+#undef TARGET_INSERT_ATTRIBUTES
+#define TARGET_INSERT_ATTRIBUTES rx_insert_attributes
+
 struct gcc_target targetm = TARGET_INITIALIZER;

 #include "gt-rx.h"
Index: config/rx/rx.h
===================================================================
--- config/rx/rx.h(revision 256076)
+++ config/rx/rx.h(working copy)
@@ -646,3 +646,9 @@
       (LENGTH) = rx_adjust_insn_length ((INSN), (LENGTH));\
     }\
   while (0)
+
+#undef ASM_OUTPUT_ALIGNED_DECL_COMMON
+#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGNMENT) \
+rx_output_aligned_common (STREAM, DECL, NAME, SIZE, ALIGNMENT)
+
+#define REGISTER_TARGET_PRAGMAS() rx_register_pragmas()
Index: config/rx/t-rx
===================================================================
--- config/rx/t-rx(revision 256076)
+++ config/rx/t-rx(working copy)
@@ -18,6 +18,9 @@
 # License along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.

+rx-pragma.o: $(srcdir)/config/rx/rx-pragma.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_H)
+$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
 # Enable multilibs:

 MULTILIB_OPTIONS    = m64bit-doubles  mnofpu        mbig-endian-data  mpid
Index: doc/extend.texi
===================================================================
--- doc/extend.texi(revision 256076)
+++ doc/extend.texi(working copy)
@@ -21850,6 +21850,7 @@
 * M32C Pragmas::
 * MeP Pragmas::
 * RS/6000 and PowerPC Pragmas::
+* RX Pragmas::
 * S/390 Pragmas::
 * Darwin Pragmas::
 * Solaris Pragmas::
@@ -22021,6 +22022,28 @@
 declarations.
 @end table

+@node RX Pragmas
+@subsection RX Pragmas
+
+@table @code
+
+@item ADDRESS @var{name} @var{address}
+@cindex pragma, address
+For any declared symbols matching @var{name}, this does three things
+to that symbol: it forces the symbol to be located at the given
+address (a number), it forces the symbol to be volatile, and it
+changes the symbol's scope to be static. Note that this pragma does
+not work in C++ only C and that the common @code{1234H} numeric syntax
+is not supported (use @code{0x1234} instead). Please also not that
+this pragma does not work with variables which have initalizers. Example:
+
+@smallexample
+#pragma ADDRESS port3 0x8000
+char port3;
+@end smallexample
+
+@end table
+
 @c Describe h8300 pragmas here.
 @c Describe sh pragmas here.
 @c Describe v850 pragmas here.
Index: testsuite/gcc.target/rx/test_pragma_address.c
===================================================================
--- testsuite/gcc.target/rx/test_pragma_address.c(nonexistent)
+++ testsuite/gcc.target/rx/test_pragma_address.c(working copy)
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#pragma address x 0x8000
+int x;
+
+int main()
+{
+if((int)&x != 0x8000)
+{
+abort();
+}
+exit(0);
+}



Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered No. 04586709.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]