This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: Support .quad for x32
- From: "Jan Beulich" <JBeulich at novell dot com>
- To: "H.J. Lu" <hjl dot tools at gmail dot com>
- Cc: <binutils at sourceware dot org>
- Date: Tue, 29 Mar 2011 09:35:47 +0100
- Subject: Re: PATCH: Support .quad for x32
- References: <20110328225109.GA30267@intel.com>
>>> On 29.03.11 at 00:51, "H.J. Lu" <hongjiu.lu@intel.com> wrote:
> Hi,
>
> For this testcase:
>
> ---
> union U
> {
> int *m;
> double d;
> };
>
> extern int xxxx;
>
> int
> foo (union U u)
> {
> union U v = { &xxxx};
> return u.d == v.d;
> }
> ---
>
> We can generate
>
> foo:
> .LFB0:
> .cfi_startproc
> movq %rdi, -8(%rsp)
> movsd .LC0(%rip), %xmm1
> movsd -8(%rsp), %xmm0
> movl $1, %eax
> ucomisd %xmm1, %xmm0
> jp .L3
> jne .L3
> rep
> ret
> .p2align 4,,10
> .p2align 3
> .L3:
> xorl %eax, %eax
> .p2align 4,,9
> ret
> .cfi_endproc
> .LFE0:
> .size foo, .-foo
> .section .rodata.cst8,"aM",@progbits,8
> .align 8
> .LC0:
> .quad xxxx
Looks more like a compiler bug than something that needs fixing in
binutils. If programming in assembly, using .quad may be intended
to generate wider than 32-bit relocs (e.g. when xxxx is a
constant in another translation unit). Yes, with the bogus tying
of the 32-bit ABI to the ELF object bit size (thus causing only
32-bit relocation forms to be used) that's sort of difficult to
achieve, but not impossible (global constant with less than 32 bits
plus addend with less than 32 bits).
Additionally, I think the change isn't correct either:
> I checked in this patch to allow .quad for x32.
>
>
> H.J.
> --
> diff --git a/gas/ChangeLog b/gas/ChangeLog
> index e759809..6ccff48 100644
> --- a/gas/ChangeLog
> +++ b/gas/ChangeLog
> @@ -1,3 +1,8 @@
> +2011-03-28 H.J. Lu <hongjiu.lu@intel.com>
> +
> + * config/tc-i386.c (handle_quad): New.
> + (md_pseudo_table): Add "quad".
> +
> 2011-03-26 John Marino <binutils@marino.st>
>
> * configure.tgt: Fix support for *-*-dragonfly*.
> diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
> index e7f9c9a..624c78a 100644
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -182,6 +182,7 @@ static void s_bss (int);
> #endif
> #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
> static void handle_large_common (int small ATTRIBUTE_UNUSED);
> +static void handle_quad (int);
> #endif
>
> static const char *default_arch = DEFAULT_ARCH;
> @@ -813,6 +814,7 @@ const pseudo_typeS md_pseudo_table[] =
> {"sse_check", set_sse_check, 0},
> #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
> {"largecomm", handle_large_common, 0},
> + {"quad", handle_quad, 8},
> #else
> {"file", (void (*) (int)) dwarf2_directive_file, 0},
> {"loc", dwarf2_directive_loc, 0},
> @@ -9149,4 +9151,50 @@ handle_large_common (int small ATTRIBUTE_UNUSED)
> bss_section = saved_bss_section;
> }
> }
> +
> +static void
> +handle_quad (int nbytes)
> +{
> + expressionS exp;
> +
> + if (x86_elf_abi != X86_64_X32_ABI)
> + {
> + cons (nbytes);
> + return;
> + }
> +
> + if (is_it_end_of_statement ())
> + {
> + demand_empty_rest_of_line ();
> + return;
> + }
> +
> + do
> + {
> + if (*input_line_pointer == '"')
> + {
> + as_bad (_("unexpected `\"' in expression"));
> + ignore_rest_of_line ();
> + return;
> + }
> + x86_cons (&exp, nbytes);
> + /* Output 4 bytes if not constant. */
> + if (exp.X_op != O_constant)
> + nbytes = 4;
> + emit_expr (&exp, (unsigned int) nbytes);
> + }
> + while (*input_line_pointer++ == ',');
So here you iterate over all the operands, ...
> +
> + input_line_pointer--; /* Put terminator back into stream. */
> +
> + demand_empty_rest_of_line ();
> +
> + /* Zero-extends to 8 bytes if not constant. */
> + if (nbytes == 4)
> + {
> + memset (&exp, '\0', sizeof (exp));
> + exp.X_op = O_constant;
> + emit_expr (&exp, nbytes);
> + }
... but then you zero-extend only the last one?
Jan
> +}
> #endif /* OBJ_ELF || OBJ_MAYBE_ELF */
> diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
> index 7975fb8..4f69afa 100644
> --- a/gas/testsuite/ChangeLog
> +++ b/gas/testsuite/ChangeLog
> @@ -1,3 +1,11 @@
> +2011-03-28 H.J. Lu <hongjiu.lu@intel.com>
> +
> + * gas/i386/ilp32/inval.s: Remove .quad.
> + * gas/i386/ilp32/inval.l: Updated.
> +
> + * gas/i386/ilp32/quad.d: New.
> + * gas/i386/ilp32/quad.s: Likewise.
> +
> 2011-03-24 Mike Frysinger <vapier@gentoo.org>
>
> * gas/bfin/expected_errors.s: Add invalid vector add/sub insn tests.
> diff --git a/gas/testsuite/gas/i386/ilp32/inval.l
> b/gas/testsuite/gas/i386/ilp32/inval.l
> index 70f9754..d037bae 100644
> --- a/gas/testsuite/gas/i386/ilp32/inval.l
> +++ b/gas/testsuite/gas/i386/ilp32/inval.l
> @@ -3,7 +3,6 @@
> .*:4: Error: .*
> .*:5: Error: .*
> .*:6: Error: .*
> -.*:10: Error: .*
> GAS LISTING .*
>
>
> @@ -19,11 +18,6 @@ GAS LISTING .*
> [ ]*5[ ]+00000000
> [ ]*5[ ]+0000
> [ ]*6[ ]+\?\?\?\? 48A10000 movabsq foo,%rax
> +\*\*\*\* Error:cannot represent relocation type BFD_RELOC_[ ]*64[ ]+in x32
> mode
> [ ]*6[ ]+00000000
> [ ]*6[ ]+0000
> -[ ]*7[ ]+
> -[ ]*8[ ]+\.data
> -[ ]*9[ ]+xxx:
> -[ ]*10[ ]+\?\?\?\? 00000000 \.quad foo
> -\*\*\*\* Error:cannot represent relocation type BFD_RELOC_[ ]*64[ ]+in x32
> mode
> -[ ]*10[ ]+00000000
> diff --git a/gas/testsuite/gas/i386/ilp32/inval.s
> b/gas/testsuite/gas/i386/ilp32/inval.s
> index 416c1f8..f117ca0 100644
> --- a/gas/testsuite/gas/i386/ilp32/inval.s
> +++ b/gas/testsuite/gas/i386/ilp32/inval.s
> @@ -4,7 +4,3 @@
> movabs foo,%rax
> movabsq xxx,%rax
> movabsq foo,%rax
> -
> - .data
> -xxx:
> - .quad foo
> diff --git a/gas/testsuite/gas/i386/ilp32/quad.d
> b/gas/testsuite/gas/i386/ilp32/quad.d
> new file mode 100644
> index 0000000..d3e6ff8
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/ilp32/quad.d
> @@ -0,0 +1,14 @@
> +#objdump: -sr
> +#name: xquad
> +
> +.*: +file format .*
> +
> +RELOCATION RECORDS FOR \[.data\]:
> +OFFSET +TYPE +VALUE
> +0+ R_X86_64_32 +foo
> +0+10 R_X86_64_32 +bar
> +
> +
> +Contents of section .data:
> + 0000 00000000 00000000 efcdab90 78674512 ............xgE.
> + 0010 00000000 00000000 ffffffff ffffffff ................
> diff --git a/gas/testsuite/gas/i386/ilp32/quad.s
> b/gas/testsuite/gas/i386/ilp32/quad.s
> new file mode 100644
> index 0000000..e96653a
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/ilp32/quad.s
> @@ -0,0 +1,5 @@
> + .data
> + .quad foo
> + .quad 0x1245677890abcdef
> + .quad bar
> + .quad -1