This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RE: [PATCH] RX pragma address
- From: "Sebastian Perta" <sebastian dot perta at renesas dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 5 Jan 2018 11:03:16 -0000
- Subject: RE: [PATCH] RX pragma address
- Authentication-results: sourceware.org; auth=none
- References:
Sorry the spaces got removed from previous email.
-----Original Message-----
From: Sebastian Perta
Sent: 05 January 2018 10:59
To: 'gcc-patches@gcc.gnu.org' <gcc-patches@gcc.gnu.org>
Subject: [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 void rx_expand_epilogue (bool);
extern void rx_expand_prologue (void);
extern int rx_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_BITFIELD
rx_narrow_volatile_bitfield
@@ -3624,6 +3694,9 @@
#undef TARGET_MODES_TIEABLE_P
#define TARGET_MODES_TIEABLE_P rx_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);
+}