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.
The avr part that uses TARGET_ASM_VARIABLE is patch part 2/2.
The patch passes bootstrap and tests with no new regressions.
Ok for trunk?
Johann
--
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..12c09c88e6c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -8522,6 +8522,24 @@ 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 neede 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.
+@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..e90b4bad134 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -93,6 +93,26 @@ 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 neede 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.",
+ 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..06c54eef6f7 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -2560,6 +2560,12 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
if (TREE_PUBLIC (decl) && DECL_NAME (decl))
notice_global_symbol (decl);
+ if (! dont_output_data)
+ {
+ if (targetm.asm_out.variable (asm_out_file, decl, name))
+ return;
+ }
+
/* Compute the alignment of this data. */
align_variable (decl, dont_output_data);