This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: V2: [PATCH] x32: Generate 0x67 prefix for VSIB address without base


>>> On 26.02.19 at 05:35, <hjl.tools@gmail.com> wrote:
> In x32, add ADDR_PREFIX_OPCODE prefix for VSIB address without base
> register so that vector index register will be zero-extended to 64 bits.
> 
> We can't have ADDR_PREFIX_OPCODE prefix with 32-bit address if there is
> segment override since address will be segment base + zero-extended to 64
> bits of (base + index * scale + disp).  But GCC:
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89502 

Neither above nor in the bug you explain what's wrong with the
segment override plus address size override in x32 mode. Since you
keep using the same wording with just slight alterations, it must be
something very obvious to you, but entirely un-obvious to me. Is
this related to the desire of using both negative and positive
offsets into TLS, where (obviously I would say) there's not going
to be any wrapping at the 4Gb boundary? If so, I'd say the TLS
usage model is broken, but it's not the assembler that should
prevent use of otherwise valid constructs. Whether full 64-bit
addresses (and hence full non-zero %fs/%gs bases with no
wrapping at the 4Gb boundary) is intended is the programmer's
choice, not something the assembler should enforce unconditionally.
Optionally emitting a warning is acceptable, but then this shouldn't
be tied to any other, more generically applicable warnings.

In any event, if this is to stay, then at least the code comment
needs to be quite a bit more clear - "we can't have" is not enough
without explicitly saying why that is.

> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -8141,6 +8141,36 @@ output_insn (void)
>  	  i.prefix[LOCK_PREFIX] = 0;
>  	}
>  
> +#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
> +      if (flag_code == CODE_64BIT && x86_elf_abi == X86_64_X32_ABI)
> +	{
> +	  /* In x32, add ADDR_PREFIX_OPCODE prefix for VSIB address
> +	     without base register so that vector index register will
> +	     be zero-extended to 64 bits.  */
> +	  if (!i.base_reg && i.tm.opcode_modifier.vecsib)
> +	    add_prefix (ADDR_PREFIX_OPCODE);

Just to re-state: There needs to be a way to override this behavior.
And this is already leaving aside that making this the default from
now on has a fair risk of breaking currently working code. (Note
that this is not to say that I can't see that the change will also
help currently broken code.)

> +	  /* In x32, we can't have ADDR_PREFIX_OPCODE prefix with
> +	     segment override since final address will be segment
> +	     base + zero-extended (base + index * scale + disp).  */
> +	  if (operand_check != check_none
> +	      && 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];
> +	      if (operand_check == check_error)
> +		as_bad (_("can't encode segment `%s%s' with 32-bit address"),
> +			register_prefix, seg->seg_name);
> +	      else
> +		as_warn (_("segment `%s%s' override with 32-bit address"),
> +			 register_prefix, seg->seg_name);
> +	    }
> +	}
> +#endif
> +
>        /* Since the VEX/EVEX prefix contains the implicit prefix, we
>  	 don't need the explicit prefix.  */
>        if (!i.tm.opcode_modifier.vex && !i.tm.opcode_modifier.evex)




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]