Hello 

The following patch adds a new pragma, "pragma address" for RL78.
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=rl78-sim

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

Index: ChangeLog
===================================================================
--- ChangeLog   (revision 255643)
+++ ChangeLog   (working copy)
@@ -1,3 +1,19 @@
+2017-12-14  Sebastian Perta  <sebastian.pe...@renesas.com>
+
+       * config/rl78/rl78.c (rl78_get_pragma_address): New function
+       * config/rl78/rl78.c (rl78_note_pragma_address): New function 
+       * config/rl78/rl78.c (rl78_output_aligned_common): use .set instead 
+       of .comm for pragma address variables
+       * config/rl78/rl78.c (rl78_insert_attributes): make pragma address 
+       variables volatile
+       * config/rl78/rl78-c.c (rl78_pragma_address): New function
+       * config/rl78/rl78-c.c (rl78_register_pragmas): registered the new 
+       pragma address
+       * config/rl78/rl78-protos.h: New declaration
rl78_note_pragma_address
+       * doc/entend.texi: Added documenation for RL78 pragmas
+       * testsuite/gcc.target/rl78/test_pragma_address.c: New file
+       
+       
 2017-12-14  Andreas Schwab  <sch...@linux-m68k.org>
 
        PR bootstrap/83396
Index: config/rl78/rl78-c.c
===================================================================
--- config/rl78/rl78-c.c        (revision 255643)
+++ config/rl78/rl78-c.c        (working copy)
@@ -23,7 +23,42 @@
 #include "coretypes.h"
 #include "tm.h"
 #include "c-family/c-common.h"
+#include "c-family/c-pragma.h"
+#include "rl78-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
+rl78_pragma_address (cpp_reader * reader ATTRIBUTE_UNUSED)
+{
+  /* on off */
+  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);
+             rl78_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");
+}
+
 /* Implements REGISTER_TARGET_PRAGMAS.  */
 void
 rl78_register_pragmas (void)
@@ -30,4 +65,7 @@
 {
   c_register_addr_space ("__near", ADDR_SPACE_NEAR);
   c_register_addr_space ("__far", ADDR_SPACE_FAR);
+  
+  c_register_pragma (NULL, "ADDRESS", rl78_pragma_address);
+  c_register_pragma (NULL, "address", rl78_pragma_address);
 }
Index: config/rl78/rl78-protos.h
===================================================================
--- config/rl78/rl78-protos.h   (revision 255643)
+++ config/rl78/rl78-protos.h   (working copy)
@@ -52,6 +52,7 @@
 int            rl78_sfr_p (rtx x);
 void           rl78_output_aligned_common (FILE *, tree, const char *,
                                            int, int, int);
+void           rl78_note_pragma_address (const char *varname, unsigned
address);
 
 int            rl78_one_far_p (rtx *operands, int num_operands);
 
Index: config/rl78/rl78.c
===================================================================
--- config/rl78/rl78.c  (revision 255643)
+++ config/rl78/rl78.c  (working copy)
@@ -4565,6 +4565,30 @@
   fputs (str2, file);
 }
 
+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
+rl78_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
 rl78_output_aligned_common (FILE *stream,
                            tree decl ATTRIBUTE_UNUSED,
@@ -4571,6 +4595,7 @@
                            const char *name,
                            int size, int align, int global)
 {
+  unsigned int address;
   /* We intentionally don't use rl78_section_tag() here.  */
   if (name[0] == '@' && name[2] == '.')
     {
@@ -4609,14 +4634,34 @@
       assemble_name (stream, name);
       fprintf (stream, "\n");
     }
-  fprintf (stream, "\t.comm\t");
-  assemble_name (stream, name);
-  fprintf (stream, ",%u,%u\n", size, align / BITS_PER_UNIT);
+  if (rl78_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);
+       }
 }
 
 #undef  TARGET_INSERT_ATTRIBUTES
 #define TARGET_INSERT_ATTRIBUTES rl78_insert_attributes
 
+void
+rl78_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;
+}
+
 static void
 rl78_insert_attributes (tree decl, tree *attributes ATTRIBUTE_UNUSED)
 {
@@ -4632,6 +4677,16 @@
 
       TREE_TYPE (decl) = build_type_attribute_qual_variant (type, attr, q);
     }
+  /* See if we need to make #pragma address variables volatile.  */
+  if (TREE_CODE (decl) == VAR_DECL)
+    {
+      unsigned addr;
+         const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
+      if (rl78_get_pragma_address  (name, &addr))
+      {
+         TREE_THIS_VOLATILE (decl) = true;
+      }
+    }
 }
 
 #undef  TARGET_ASM_INTEGER
Index: doc/extend.texi
===================================================================
--- doc/extend.texi     (revision 255643)
+++ doc/extend.texi     (working copy)
@@ -21843,6 +21843,7 @@
 * ARM Pragmas::
 * M32C Pragmas::
 * MeP Pragmas::
+* RL78 Pragmas::
 * RS/6000 and PowerPC Pragmas::
 * S/390 Pragmas::
 * Darwin Pragmas::
@@ -21994,6 +21995,29 @@
 
 @end table
 
+@node RL78 Pragmas
+@subsection RL78 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 to __far variables and variables which have 
+initalizers.   Example:
+
+@smallexample
+#pragma ADDRESS port3 0x8000
+char port3;
+@end smallexample
+
+@end table
+
 @node RS/6000 and PowerPC Pragmas
 @subsection RS/6000 and PowerPC Pragmas
 
Index: testsuite/gcc.target/rl78/test_pragma_address.c
===================================================================
--- testsuite/gcc.target/rl78/test_pragma_address.c     (nonexistent)
+++ testsuite/gcc.target/rl78/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);
+}

Reply via email to