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.pe...@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 <rguent...@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); +}