diff --git a/gcc/config/rs6000/aix51.h b/gcc/config/rs6000/aix51.h index 4a5a9ecfe10..981b94a6058 100644 --- a/gcc/config/rs6000/aix51.h +++ b/gcc/config/rs6000/aix51.h @@ -185,3 +185,8 @@ do { \ /* This target uses the aix64.opt file. */ #define TARGET_USES_AIX64_OPT 1 + +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_USE_JCR_SECTION 0 diff --git a/gcc/config/rs6000/aix52.h b/gcc/config/rs6000/aix52.h index f0744e1b428..b40e4670e00 100644 --- a/gcc/config/rs6000/aix52.h +++ b/gcc/config/rs6000/aix52.h @@ -196,3 +196,8 @@ extern long long int atoll(const char *); /* This target uses the aix64.opt file. */ #define TARGET_USES_AIX64_OPT 1 + +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_USE_JCR_SECTION 0 diff --git a/gcc/config/rs6000/aix53.h b/gcc/config/rs6000/aix53.h index f599508a6f5..09cd2bfce33 100644 --- a/gcc/config/rs6000/aix53.h +++ b/gcc/config/rs6000/aix53.h @@ -192,3 +192,8 @@ extern long long int atoll(const char *); /* This target uses the aix64.opt file. */ #define TARGET_USES_AIX64_OPT 1 + +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_USE_JCR_SECTION 0 diff --git a/gcc/config/rs6000/aix61.h b/gcc/config/rs6000/aix61.h index 9e01bca1eea..e62a775c745 100644 --- a/gcc/config/rs6000/aix61.h +++ b/gcc/config/rs6000/aix61.h @@ -194,4 +194,11 @@ extern long long int atoll(const char *); /* This target uses the aix64.opt file. */ #define TARGET_USES_AIX64_OPT 1 +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_USE_JCR_SECTION 0 + +/* Default to 128 bit long double. */ + #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128 diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 0c5b11122b1..2f1b04c4f38 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -181,6 +181,10 @@ extern void rs6000_cpu_cpp_builtins (struct cpp_reader *); char *output_call (rtx, rtx *, int, int); #endif +#ifdef NO_DOLLAR_IN_LABEL +const char * rs6000_xcoff_strip_dollar (const char *); +#endif + void rs6000_final_prescan_insn (rtx, rtx *operand, int num_operands); extern bool rs6000_hard_regno_mode_ok_p[][FIRST_PSEUDO_REGISTER]; diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 05f4e26ea53..612c7d45d67 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -18041,6 +18041,35 @@ toc_hash_eq (const void *h1, const void *h2) || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \ || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0) +#ifdef NO_DOLLAR_IN_LABEL +/* Return a GGC-allocated character string translating dollar signs in + input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */ + +const char * +rs6000_xcoff_strip_dollar (const char *name) +{ + char *strip, *p; + int len; + + p = strchr (name, '$'); + + if (p == 0 || p == name) + return name; + + len = strlen (name); + strip = (char *) alloca (len + 1); + strcpy (strip, name); + p = strchr (strip, '$'); + while (p) + { + *p = '_'; + p = strchr (p + 1, '$'); + } + + return ggc_alloc_string (strip, len); +} +#endif + void rs6000_output_symbol_ref (FILE *file, rtx x) { diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h index 3cf6e4b13ab..08e06b4a757 100644 --- a/gcc/config/rs6000/xcoff.h +++ b/gcc/config/rs6000/xcoff.h @@ -135,6 +135,7 @@ /* 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. + Dollar signs are converted to underscores. The csect for the function will have already been created when text_section was selected. We do have to go back to that csect, however. @@ -143,36 +144,54 @@ are placeholders which no longer have any use. */ #define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \ -{ if (TREE_PUBLIC (DECL)) \ +{ char *buffer = (char *) alloca (strlen (NAME) + 1); \ + char *p; \ + int dollar_inside = 0; \ + strcpy (buffer, NAME); \ + p = strchr (buffer, '$'); \ + while (p) { \ + *p = '_'; \ + dollar_inside++; \ + p = strchr (p + 1, '$'); \ + } \ + if (TREE_PUBLIC (DECL)) \ { \ if (!RS6000_WEAK || !DECL_WEAK (decl)) \ { \ + if (dollar_inside) { \ + fprintf(FILE, "\t.rename .%s,\".%s\"\n", buffer, NAME); \ + fprintf(FILE, "\t.rename %s,\"%s\"\n", buffer, NAME); \ + } \ fputs ("\t.globl .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ + RS6000_OUTPUT_BASENAME (FILE, buffer); \ putc ('\n', FILE); \ } \ } \ else \ { \ + if (dollar_inside) { \ + fprintf(FILE, "\t.rename .%s,\".%s\"\n", buffer, NAME); \ + fprintf(FILE, "\t.rename %s,\"%s\"\n", buffer, NAME); \ + } \ fputs ("\t.lglobl .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ + RS6000_OUTPUT_BASENAME (FILE, buffer); \ putc ('\n', FILE); \ } \ fputs ("\t.csect ", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ + RS6000_OUTPUT_BASENAME (FILE, buffer); \ fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ + RS6000_OUTPUT_BASENAME (FILE, buffer); \ fputs (":\n", FILE); \ fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ + RS6000_OUTPUT_BASENAME (FILE, buffer); \ fputs (", TOC[tc0], 0\n", FILE); \ in_section = NULL; \ switch_to_section (function_section (DECL)); \ putc ('.', FILE); \ - RS6000_OUTPUT_BASENAME (FILE, NAME); \ + RS6000_OUTPUT_BASENAME (FILE, buffer); \ fputs (":\n", FILE); \ if (write_symbols != NO_DEBUG) \ - xcoffout_declare_function (FILE, DECL, NAME); \ + xcoffout_declare_function (FILE, DECL, buffer); \ } /* Output a reference to SYM on FILE. */ @@ -180,11 +199,28 @@ #define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) \ rs6000_output_symbol_ref (FILE, SYM) -/* This says how to output an external. */ +/* This says how to output an external. + Dollar signs are converted to underscores. */ #undef ASM_OUTPUT_EXTERNAL #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \ +{ char *buffer = (char *) alloca (strlen (NAME) + 1); \ + char *p; \ + rtx _symref = XEXP (DECL_RTL (DECL), 0); \ + int dollar_inside = 0; \ + strcpy (buffer, NAME); \ + p = strchr (buffer, '$'); \ + while (p) { \ + *p = '_'; \ + dollar_inside++; \ + p = strchr (p + 1, '$'); \ + } \ + if (dollar_inside) { \ + fputs ("\t.extern .", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, buffer); \ + putc ('\n', FILE); \ + fprintf(FILE, "\t.rename .%s,\".%s\"\n", buffer, NAME); \ + } \ if ((TREE_CODE (DECL) == VAR_DECL \ || TREE_CODE (DECL) == FUNCTION_DECL) \ && (NAME)[strlen (NAME) - 1] != ']') \ @@ -196,6 +232,12 @@ } \ } +/* This is how to output a reference to a user-level label named NAME. + `assemble_name' uses this. */ + +#define ASM_OUTPUT_LABELREF(FILE,NAME) \ + asm_fprintf ((FILE), "%U%s", rs6000_xcoff_strip_dollar (NAME)); + /* This is how to output an internal label prefix. rs6000.c uses this when generating traceback tables. */ diff --git a/gcc/xcoffout.h b/gcc/xcoffout.h index be6d2a2e1d2..2143192c38f 100644 --- a/gcc/xcoffout.h +++ b/gcc/xcoffout.h @@ -84,7 +84,7 @@ along with GCC; see the file COPYING3. If not see fputs (_p+1, asm_out_file); \ else \ for (; *_p != '[' && *_p; _p++) \ - putc (*_p, asm_out_file); \ + putc (*_p != '$' ? *_p : '_', asm_out_file); \ } \ else \ output_addr_const (asm_out_file, ADDR); \