Commit c892d8f5 by Jakub Jelinek

i386: Fix up -fdollars-in-identifiers with identifiers starting with $ in -masm=att [PR91298]

In AT&T syntax leading $ is special, so if we have identifiers that start
with dollar, we usually fail to assemble it (or assemble incorrectly).
As mentioned in the PR, what works is wrapping the identifiers inside of
parens, like:
	movl	$($a), %eax
	leaq	($a)(,%rdi,4), %rax
	movl	($a)(%rip), %eax
	movl	($a)+16(%rip), %eax
	.globl	$a
	.type	$a, @object
	.size	$a, 72
$a:
	.string	"$a"
	.quad	($a)
(this is x86_64 -fno-pic -O2).  In some places ($a) is not accepted,
like as .globl operand, in .type, .size, so the patch overrides
ASM_OUTPUT_SYMBOL_REF rather than e.g. ASM_OUTPUT_LABELREF.
I didn't want to duplicate what assemble_name is doing (following
transparent aliases), so split assemble_name into two parts; just
mere looking at the first character of a name before calling assemble_name
wouldn't be good enough, a transparent alias could lead from a name
not starting with $ to one starting with it and vice versa.

2020-01-22  Jakub Jelinek  <jakub@redhat.com>

	PR target/91298
	* output.h (assemble_name_resolve): Declare.
	* varasm.c (assemble_name_resolve): New function.
	(assemble_name): Use it.
	* config/i386/i386.h (ASM_OUTPUT_SYMBOL_REF): Define.

	* gcc.target/i386/pr91298-1.c: New test.
	* gcc.target/i386/pr91298-2.c: New test.
parent 44a9d801
2020-01-22 Jakub Jelinek <jakub@redhat.com>
PR target/91298
* output.h (assemble_name_resolve): Declare.
* varasm.c (assemble_name_resolve): New function.
(assemble_name): Use it.
* config/i386/i386.h (ASM_OUTPUT_SYMBOL_REF): Define.
2020-01-22 Joseph Myers <joseph@codesourcery.com> 2020-01-22 Joseph Myers <joseph@codesourcery.com>
* doc/sourcebuild.texi (Texinfo Manuals, Front End): Refer to * doc/sourcebuild.texi (Texinfo Manuals, Front End): Refer to
......
...@@ -2258,6 +2258,31 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER]; ...@@ -2258,6 +2258,31 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
#define ASM_OUTPUT_FUNCTION_LABEL(FILE, NAME, DECL) \ #define ASM_OUTPUT_FUNCTION_LABEL(FILE, NAME, DECL) \
ix86_asm_output_function_label ((FILE), (NAME), (DECL)) ix86_asm_output_function_label ((FILE), (NAME), (DECL))
/* A C statement (sans semicolon) to output a reference to SYMBOL_REF SYM.
If not defined, assemble_name will be used to output the name of the
symbol. This macro may be used to modify the way a symbol is referenced
depending on information encoded by TARGET_ENCODE_SECTION_INFO. */
#ifndef ASM_OUTPUT_SYMBOL_REF
#define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) \
do { \
const char *name \
= assemble_name_resolve (XSTR (x, 0)); \
/* In -masm=att wrap identifiers that start with $ \
into parens. */ \
if (ASSEMBLER_DIALECT == ASM_ATT \
&& name[0] == '$' \
&& user_label_prefix[0] == '\0') \
{ \
fputc ('(', (FILE)); \
assemble_name_raw ((FILE), name); \
fputc (')', (FILE)); \
} \
else \
assemble_name_raw ((FILE), name); \
} while (0)
#endif
/* Under some conditions we need jump tables in the text section, /* Under some conditions we need jump tables in the text section,
because the assembler cannot handle label differences between because the assembler cannot handle label differences between
sections. This is the case for x86_64 on Mach-O for example. */ sections. This is the case for x86_64 on Mach-O for example. */
......
...@@ -237,6 +237,12 @@ extern void assemble_label (FILE *, const char *); ...@@ -237,6 +237,12 @@ extern void assemble_label (FILE *, const char *);
addition of an underscore). */ addition of an underscore). */
extern void assemble_name_raw (FILE *, const char *); extern void assemble_name_raw (FILE *, const char *);
/* Return NAME that should actually be emitted, looking through
transparent aliases. If NAME refers to an entity that is also
represented as a tree (like a function or variable), mark the entity
as referenced. */
extern const char *assemble_name_resolve (const char *);
/* Like assemble_name_raw, but should be used when NAME might refer to /* Like assemble_name_raw, but should be used when NAME might refer to
an entity that is also represented as a tree (like a function or an entity that is also represented as a tree (like a function or
variable). If NAME does refer to such an entity, that entity will variable). If NAME does refer to such an entity, that entity will
......
2020-01-22 Jakub Jelinek <jakub@redhat.com> 2020-01-22 Jakub Jelinek <jakub@redhat.com>
PR target/91298
* gcc.target/i386/pr91298-1.c: New test.
* gcc.target/i386/pr91298-2.c: New test.
* gfortran.dg/gomp/target-parallel1.f90: New test. * gfortran.dg/gomp/target-parallel1.f90: New test.
* gfortran.dg/goacc/pr93329.f90: Enable commented out target parallel * gfortran.dg/goacc/pr93329.f90: Enable commented out target parallel
test. test.
......
/* PR target/91298 */
/* { dg-do assemble } */
/* { dg-options "-O2 -g -fdollars-in-identifiers" } */
int $a[18];
int *foo (void) { return &$a[0]; }
int *bar (int x) { return &$a[x]; }
int baz (void) { return $a[0]; }
int qux (void) { return $a[4]; }
int $quux (void) { return 1; }
int corge (void) { return $quux (); }
int grault (void) { return $quux () + 1; }
typedef int (*fn) (void);
fn foobar (void) { return $quux; }
/* PR target/91298 */
/* { dg-do assemble { target fpic } } */
/* { dg-options "-O2 -g -fdollars-in-identifiers -fpic" } */
#include "pr91298-1.c"
...@@ -2589,20 +2589,16 @@ assemble_name_raw (FILE *file, const char *name) ...@@ -2589,20 +2589,16 @@ assemble_name_raw (FILE *file, const char *name)
ASM_OUTPUT_LABELREF (file, name); ASM_OUTPUT_LABELREF (file, name);
} }
/* Like assemble_name_raw, but should be used when NAME might refer to /* Return NAME that should actually be emitted, looking through
an entity that is also represented as a tree (like a function or transparent aliases. If NAME refers to an entity that is also
variable). If NAME does refer to such an entity, that entity will represented as a tree (like a function or variable), mark the entity
be marked as referenced. */ as referenced. */
const char *
void assemble_name_resolve (const char *name)
assemble_name (FILE *file, const char *name)
{ {
const char *real_name; const char *real_name = targetm.strip_name_encoding (name);
tree id; tree id = maybe_get_identifier (real_name);
real_name = targetm.strip_name_encoding (name);
id = maybe_get_identifier (real_name);
if (id) if (id)
{ {
tree id_orig = id; tree id_orig = id;
...@@ -2614,7 +2610,18 @@ assemble_name (FILE *file, const char *name) ...@@ -2614,7 +2610,18 @@ assemble_name (FILE *file, const char *name)
gcc_assert (! TREE_CHAIN (id)); gcc_assert (! TREE_CHAIN (id));
} }
assemble_name_raw (file, name); return name;
}
/* Like assemble_name_raw, but should be used when NAME might refer to
an entity that is also represented as a tree (like a function or
variable). If NAME does refer to such an entity, that entity will
be marked as referenced. */
void
assemble_name (FILE *file, const char *name)
{
assemble_name_raw (file, assemble_name_resolve (name));
} }
/* Allocate SIZE bytes writable static space with a gensym name /* Allocate SIZE bytes writable static space with a gensym name
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment