aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-07-09 17:56:40 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-07-09 15:56:40 +0000
commit9af4687354ee7ca7acc3ec7d5aac008858851612 (patch)
tree461621670e504047f2f52bb339066a519ad7ede8 /gcc/config/rs6000
parent7aee864645f2ec7c418030977b7d7ab00908371d (diff)
downloadgcc-9af4687354ee7ca7acc3ec7d5aac008858851612.zip
gcc-9af4687354ee7ca7acc3ec7d5aac008858851612.tar.gz
gcc-9af4687354ee7ca7acc3ec7d5aac008858851612.tar.bz2
rs6000-protos.h (rs6000_xcoff_declare_object_name): Declare.
* rs6000/rs6000-protos.h (rs6000_xcoff_declare_object_name): Declare. * rs6000/rs6000.c: Inline output of .set instruction. (declare_alias_data): New struct. (rs6000_declare_alias): New function. (rs6000_xcoff_declare_function_name): Use it. (rs6000_xcoff_declare_object_name): New function. * config/rs6000/xcoff.h: Define ASM_DECLARE_OBJECT_NAME. (ASM_OUTPUT_DEF): Turn to empty definition. From-SVN: r212394
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c108
-rw-r--r--gcc/config/rs6000/xcoff.h21
3 files changed, 120 insertions, 10 deletions
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 6a2a930..83581ac0 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -165,6 +165,7 @@ extern rtx rs6000_va_arg (tree, tree);
extern int function_ok_for_sibcall (tree);
extern int rs6000_reg_parm_stack_space (tree, bool);
extern void rs6000_xcoff_declare_function_name (FILE *, const char *, tree);
+extern void rs6000_xcoff_declare_object_name (FILE *, const char *, tree);
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
extern bool rs6000_elf_in_small_data_p (const_tree);
#ifdef ARGS_SIZE_RTX
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 1c8c992..3b692f0 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -29158,7 +29158,11 @@ rs6000_xcoff_asm_output_anchor (rtx symbol)
sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
SYMBOL_REF_BLOCK_OFFSET (symbol));
- ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
+ fprintf (asm_out_file, "%s", SET_ASM_OP);
+ RS6000_OUTPUT_BASENAME (asm_out_file, XSTR (symbol, 0));
+ fprintf (asm_out_file, ",");
+ RS6000_OUTPUT_BASENAME (asm_out_file, buffer);
+ fprintf (asm_out_file, "\n");
}
static void
@@ -29455,6 +29459,85 @@ rs6000_xcoff_file_end (void)
asm_out_file);
}
+struct declare_alias_data
+{
+ FILE *file;
+ bool function_descriptor;
+};
+
+/* Declare alias N. A helper function for for_node_and_aliases. */
+
+static bool
+rs6000_declare_alias (struct symtab_node *n, void *d)
+{
+ struct declare_alias_data *data = (struct declare_alias_data *)d;
+ /* Main symbol is output specially, because varasm machinery does part of
+ the job for us - we do not need to declare .globl/lglobs and such. */
+ if (!n->alias || n->weakref)
+ return false;
+
+ if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (n->decl)))
+ return false;
+
+ /* Prevent assemble_alias from trying to use .set pseudo operation
+ that does not behave as expected by the middle-end. */
+ TREE_ASM_WRITTEN (n->decl) = true;
+
+ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl));
+ char *buffer = (char *) alloca (strlen (name) + 2);
+ char *p;
+ int dollar_inside = 0;
+
+ strcpy (buffer, name);
+ p = strchr (buffer, '$');
+ while (p) {
+ *p = '_';
+ dollar_inside++;
+ p = strchr (p + 1, '$');
+ }
+ if (TREE_PUBLIC (n->decl))
+ {
+ if (!RS6000_WEAK || !DECL_WEAK (n->decl))
+ {
+ if (dollar_inside) {
+ if (data->function_descriptor)
+ fprintf(data->file, "\t.rename .%s,\".%s\"\n", buffer, name);
+ else
+ fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name);
+ }
+ if (data->function_descriptor)
+ fputs ("\t.globl .", data->file);
+ else
+ fputs ("\t.globl ", data->file);
+ RS6000_OUTPUT_BASENAME (data->file, buffer);
+ putc ('\n', data->file);
+ }
+ else if (DECL_WEAK (n->decl) && !data->function_descriptor)
+ ASM_WEAKEN_DECL (data->file, n->decl, name, NULL);
+ }
+ else
+ {
+ if (dollar_inside)
+ {
+ if (data->function_descriptor)
+ fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name);
+ else
+ fprintf(data->file, "\t.rename .%s,\".%s\"\n", buffer, name);
+ }
+ if (data->function_descriptor)
+ fputs ("\t.lglobl .", data->file);
+ else
+ fputs ("\t.lglobl ", data->file);
+ RS6000_OUTPUT_BASENAME (data->file, buffer);
+ putc ('\n', data->file);
+ }
+ if (data->function_descriptor)
+ fputs (".", data->file);
+ RS6000_OUTPUT_BASENAME (data->file, buffer);
+ fputs (":\n", data->file);
+ return false;
+}
+
/* This macro produces the initial definition of a function name.
On the RS/6000, we need to place an extra '.' in the function name and
output the function descriptor.
@@ -29464,7 +29547,10 @@ rs6000_xcoff_file_end (void)
text_section was selected. We do have to go back to that csect, however.
The third and fourth parameters to the .function pseudo-op (16 and 044)
- are placeholders which no longer have any use. */
+ are placeholders which no longer have any use.
+
+ Because AIX assembler's .set command has unexpected semantics, we output
+ all aliases as alternative labels in front of the definition. */
void
rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl)
@@ -29472,6 +29558,8 @@ rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl)
char *buffer = (char *) alloca (strlen (name) + 1);
char *p;
int dollar_inside = 0;
+ struct declare_alias_data data = {file, false};
+
strcpy (buffer, name);
p = strchr (buffer, '$');
while (p) {
@@ -29507,6 +29595,7 @@ rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl)
fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", file);
RS6000_OUTPUT_BASENAME (file, buffer);
fputs (":\n", file);
+ symtab_for_node_and_aliases (symtab_get_node (decl), rs6000_declare_alias, &data, true);
fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", file);
RS6000_OUTPUT_BASENAME (file, buffer);
fputs (", TOC[tc0], 0\n", file);
@@ -29515,11 +29604,26 @@ rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl)
putc ('.', file);
RS6000_OUTPUT_BASENAME (file, buffer);
fputs (":\n", file);
+ data.function_descriptor = true;
+ symtab_for_node_and_aliases (symtab_get_node (decl), rs6000_declare_alias, &data, true);
if (write_symbols != NO_DEBUG && !DECL_IGNORED_P (decl))
xcoffout_declare_function (file, decl, buffer);
return;
}
+/* This macro produces the initial definition of a object (variable) name.
+ Because AIX assembler's .set command has unexpected semantics, we output
+ all aliases as alternative labels in front of the definition. */
+
+void
+rs6000_xcoff_declare_object_name (FILE *file, const char *name, tree decl)
+{
+ struct declare_alias_data data = {file, false};
+ RS6000_OUTPUT_BASENAME (file, name);
+ fputs (":\n", file);
+ symtab_for_node_and_aliases (symtab_get_node (decl), rs6000_declare_alias, &data, true);
+}
+
#ifdef HAVE_AS_TLS
static void
rs6000_xcoff_encode_section_info (tree decl, rtx rtl, int first)
diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h
index 847edc9..4df90f6 100644
--- a/gcc/config/rs6000/xcoff.h
+++ b/gcc/config/rs6000/xcoff.h
@@ -139,6 +139,9 @@
#undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
rs6000_xcoff_declare_function_name ((FILE), (NAME), (DECL))
+#undef ASM_DECLARE_OBJECT_NAME
+#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
+ rs6000_xcoff_declare_object_name ((FILE), (NAME), (DECL))
/* Output a reference to SYM on FILE. */
@@ -280,14 +283,16 @@
/* This is how we tell the assembler that two symbols have the same value. */
#define SET_ASM_OP "\t.set "
-/* This is how we tell the assembler to equate two values. */
-#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
- do { fprintf ((FILE), "%s", SET_ASM_OP); \
- RS6000_OUTPUT_BASENAME (FILE, LABEL1); \
- fprintf (FILE, ","); \
- RS6000_OUTPUT_BASENAME (FILE, LABEL2); \
- fprintf (FILE, "\n"); \
- } while (0)
+/* This is how we tell the assembler to equate two values.
+ The semantic of AIX assembler's .set do not correspond to middle-end expectations.
+ We output aliases as alternative symbols in the front of the definition
+ via DECLARE_FUNCTION_NAME and DECLARE_OBJECT_NAME.
+ We still need to define this macro to let middle-end know that aliases are
+ supported.
+ */
+#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) do { } while (0)
+
+/* Used by rs6000_assemble_integer, among others. */
/* Used by rs6000_assemble_integer, among others. */
#define DOUBLE_INT_ASM_OP "\t.llong\t"