This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] x32: Generate 0x67 prefix for VSIB address without base
>>> On 25.02.19 at 16:55, <hjl.tools@gmail.com> wrote:
> On Mon, Feb 25, 2019 at 7:14 AM Jan Beulich <JBeulich@suse.com> wrote:
>>
>> >>> On 25.02.19 at 15:02, <hjl.tools@gmail.com> wrote:
>> > --- a/gas/config/tc-i386.c
>> > +++ b/gas/config/tc-i386.c
>> > @@ -8194,6 +8194,32 @@ output_insn (void)
>> > }
>> > else
>> > {
>> > +#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
>> > + if (x86_elf_abi == X86_64_X32_ABI
>> > + && i.tm.opcode_modifier.vecsib)
>> > + {
>> > + /* In x32, add ADDR_PREFIX_OPCODE prefix for VSIB address
>> > + without base register so that vector index register
>> > + won't be sign-extended to 64 bits. */
>> > + if (!i.base_reg)
>> > + add_prefix (ADDR_PREFIX_OPCODE);
>>
>> Leaving aside the question of how one would go about overriding
>> this behavior (after all iirc it's not forbidden to use full 64-bit
>> addresses / base registers in x32) I understand this part, but ...
>
> You can use a 64-bit base register to avoid 0x67 prefix,
I don't understand - this is about the no-base-register case. I was
referring to the 64-bit base register case merely for comparison
purposes. Don't forget that in the qword-index-element case you
now actively truncate index elements.
>> > + /* In x32, we can't have ADDR_PREFIX_OPCODE prefix for
>> > + VSIB if there is segment override since address will
>> > + be segment override + zero-extended to 64 bits of
>> > + (base + index * scale + disp). */
>>
>> ... I don't understand this: What is it that goes wrong here in
>> x32 mode? "base" is either zero or a full 64-bit value anyway, so
>
> "base" can be a 32-bit register:
>
> vgatherdps %ymm12,%fs:0xc(%eax,%ymm15,1),%ymm11
Oh, sorry, I mixed up base and segment base (because of the
mention of a segment override here).
>> I'm struggling in the first place what (uniform) zero-extension the
>> comment is talking about. But I also don't understand why, if this
>> was needed at all, it would affect VSIB addressing only.
>
> Segment override is applied AFTER "base + index * scale + disp".
> So memory address in
>
> movl %fs:(%eax), %eax
>
> is %fs + zero-extend (%eax), not zero-extend (%fs + %eax).
Sure.
> In x32, GCC avoids 32-bit base/index for TLS:
>[...]
I'm sorry, but this still doesn't make me see what's wrong with
segment overrides in x32 mode, and only with VSIB addressing.
>> > + if (i.prefix[ADDR_PREFIX] && i.prefix[SEG_PREFIX])
>> > + {
>> > + const seg_entry *seg;
>> > + if (i.seg[0])
>> > + seg = i.seg[0];
>> > + else
>> > + seg = i.seg[1];
>> > + as_bad (_("can't encode segment `%s' with 32-bit VSIB"),
>> > + seg->seg_name);
>>
>> Please don't emit the % prefix unconditionally, it should not be there
>> in no-prefix / Intel mode.
>
> What % prefix?
>
> [hjl@gnu-4 pr24263]$ cat y.s
> .text
> vgatherdps %ymm12,%fs:0xc(%eax,%ymm15,1),%ymm11
> vgatherdps %ymm12,%fs:0xc(,%ymm15,1),%ymm11
> [hjl@gnu-4 pr24263]$ ./as --x32 -o y.o y.s
> y.s: Assembler messages:
> y.s:2: Error: can't encode segment `fs' with 32-bit VSIB
> y.s:3: Error: can't encode segment `fs' with 32-bit VSIB
> [hjl@gnu-4 pr24263]$
Oops, sorry - I should have asked for a % prefix to be added outside
of no-prefix mode.
Jan