RL78 pragma address

Message ID 000001d37586$97f63980$c7e2ac80$@renesas.com
State New
Headers show
Series
  • RL78 pragma address
Related show

Commit Message

Sebastian Perta Dec. 15, 2017, 9:25 a.m.
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

Patch

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 255643)
+++ ChangeLog	(working copy)
@@ -1,3 +1,19 @@ 
+2017-12-14  Sebastian Perta  <sebastian.perta@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  <schwab@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);
+}