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); +}