Ping for trunk https://gcc.gnu.org/pipermail/gcc-patches/2024-December/672050.html
Notice that the patch is bootstrapped and reg-tested and I may commit-after-approval, so no further work from admins is needed. The avr part has already been approved 2024-12-20. The default action is an obvious no-op: Do nothing and return false. This patch adds a new target hook that allows the backend to asm output a full variable definition in its own way. This hook is needed because varasm.cc imposes a very restrictive layout for all variable definitions which will be basically ELF style (on ELF targets as least). To date, there is no way for a backend to output a variable definition in a different way. For example, int var; would print: .global var .type var, @object .size var, ... var: .byte ... Though the avr backend would use it to define a symbol (which is the semantics of the "io", "io_low" and "address" attributes) like: .global var var = 1234 no matter if -f[no-]common -f[no-]data-sections etc. The current implementation in the avr backend is a broken hack, and this patch puts the feature on solid grounds. The hook name is TARGET_ASM_VARIABLE but since avr BE is just defining a symbol, Hans-Peter Nilsson proposed TARGET_ASM_SYMBOL. I am fine with any naming as approved by the reviewers, like TARGET_ASM_VARIABLE TARGET_ASM_SYMBOL TARGET_ASM_OBJECT Johann -- Add new target hook TARGET_ASM_VARIABLE. This patch adds a new target hook that allows the backend to asm output a variable definition in its own way. This hook is needed because varasm.cc imposes a very restrictive layout for all variable definitions which will be basically ELF style (on ELF targets as least). To date, there is no way for a backend to output a variable definition in a different way. This hook is required by the avr backend when it outputs definitions for variables defined with the "io", "io_low" or "address" attribute that don't follow ELF style. These attributes are basically symbol definitions of the form .global var_io var_io = 32 with some additional assertions. gcc/ * target.def (TARGET_ASM_OUT) <variable>: Add new DEFHOOK. * targhooks.cc (default_asm_out_variable): New function. * targhooks.h (default_asm_out_variable): New prototype. * doc/tm.texi.in (TARGET_ASM_VARIABLE): Place hook documentation. * doc/tm.texi: Rebuild. * varasm.cc (assemble_variable): Call targetm.asm_out.variable in order to allow the backend to output a variable definition in its own style.
Add new target hook TARGET_ASM_VARIABLE. This patch adds a new target hook that allows the backend to asm output a variable definition in its own way. This hook is needed because varasm.cc imposes a very restrictive layout for all variable definitions which will be basically ELF style (on ELF targets as least). To date, there is no way for a backend to output a variable definition in a different way. This hook is required by the avr backend when it outputs definitions for variables defined with the "io", "io_low" or "address" attribute that don't follow ELF style. These attributes are basically symbol definitions of the form .global var_io var_io = 32 with some additional assertions. gcc/ * target.def (TARGET_ASM_OUT) <variable>: Add new DEFHOOK. * targhooks.cc (default_asm_out_variable): New function. * targhooks.h (default_asm_out_variable): New prototype. * doc/tm.texi.in (TARGET_ASM_VARIABLE): Place hook documentation. * doc/tm.texi: Rebuild. * varasm.cc (assemble_variable): Call targetm.asm_out.variable in order to allow the backend to output a variable definition in its own style. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index d7170f45206..3fc698367b9 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -8522,6 +8522,25 @@ The default implementation of this hook will use the when the relevant string is @code{NULL}. @end deftypefn +@deftypefn {Target Hook} bool TARGET_ASM_VARIABLE (FILE *@var{stream}, tree @var{decl}, const char *@var{name}) +This hook outputs the assembly code for a @var{decl} that satisfies +@code{VAR_P} for an object with assembler name @var{name}. +@code{DECL_RTL (@var{decl})} is of the form @code{(mem (symbol_ref))}. +Returns @code{true} when the output has been performed and +@code{false}, otherwise. + +It is unlikely that you'll ever need to implement this hook. +The middle-and knows how to output object definitions in terms of hook +macros and functions like @code{GLOBAL_ASM_OP}, +@code{TARGET_ASM_INTEGER}, etc. + +When the output is performed by means of this hook, then the complete object +definition has to be emit, including directives like @code{.global}, +@code{.size}, @code{.type}, @code{.section}, the object label and the +object content. The default implementation of the hook does nothing +and returns @code{false}. +@end deftypefn + @deftypefn {Target Hook} void TARGET_ASM_DECL_END (void) Define this hook if the target assembler requires a special marker to terminate an initialized variable declaration. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index f6657f9df1d..2bfeb6ca310 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -5256,6 +5256,8 @@ It must not be modified by command-line option processing. @hook TARGET_ASM_INTEGER +@hook TARGET_ASM_VARIABLE + @hook TARGET_ASM_DECL_END @hook TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA diff --git a/gcc/target.def b/gcc/target.def index 8cf29c57eae..7e45c64e1f6 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -93,6 +93,27 @@ when the relevant string is @code{NULL}.", bool, (rtx x, unsigned int size, int aligned_p), default_assemble_integer) +DEFHOOK +(variable, + "This hook outputs the assembly code for a @var{decl} that satisfies\n\ +@code{VAR_P} for an object with assembler name @var{name}.\n\ +@code{DECL_RTL (@var{decl})} is of the form @code{(mem (symbol_ref))}.\n\ +Returns @code{true} when the output has been performed and\n\ +@code{false}, otherwise.\n\ +\n\ +It is unlikely that you'll ever need to implement this hook.\n\ +The middle-and knows how to output object definitions in terms of hook\n\ +macros and functions like @code{GLOBAL_ASM_OP},\n\ +@code{TARGET_ASM_INTEGER}, etc.\n\ +\n\ +When the output is performed by means of this hook, then the complete object\n\ +definition has to be emit, including directives like @code{.global},\n\ +@code{.size}, @code{.type}, @code{.section}, the object label and the\n\ +object content. The default implementation of the hook does nothing\n\ +and returns @code{false}.", + bool, (FILE *stream, tree decl, const char *name), + default_asm_out_variable) + /* Assembly strings required after the .cfi_startproc label. */ DEFHOOK (post_cfi_startproc, diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc index 8ea8d778003..c0833b4573d 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -1463,6 +1463,14 @@ default_asm_out_destructor (rtx symbol ATTRIBUTE_UNUSED, sorry ("global destructors not supported on this target"); } +/* The default implementation of TARGET_ASM_VARIABLE doesn't handle decl. */ + +bool +default_asm_out_variable (FILE *, tree, const char *) +{ + return false; +} + /* By default, do no modification. */ tree default_mangle_decl_assembler_name (tree decl ATTRIBUTE_UNUSED, tree id) diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 7cf22038100..b6e6c1ae267 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -187,6 +187,7 @@ extern int default_reloc_rw_mask (void); extern bool default_generate_pic_addr_diff_vec (void); extern void default_asm_out_constructor (rtx, int); extern void default_asm_out_destructor (rtx, int); +extern bool default_asm_out_variable (FILE *, tree, const char *); extern tree default_mangle_decl_assembler_name (tree, tree); extern tree default_emutls_var_fields (tree, tree *); extern tree default_emutls_var_init (tree, tree, tree); diff --git a/gcc/varasm.cc b/gcc/varasm.cc index 0068ec2ce4d..8967a7185d7 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -2560,6 +2560,15 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, if (TREE_PUBLIC (decl) && DECL_NAME (decl)) notice_global_symbol (decl); + if (! dont_output_data) + { + /* Allow the target to output a variable definition in its own way + entirely. This is only needed in some rare cases. */ + + if (targetm.asm_out.variable (asm_out_file, decl, name)) + return; + } + /* Compute the alignment of this data. */ align_variable (decl, dont_output_data);