[PATCH 3/5] x86-64: defer 32-bit signed displacement check

H.J. Lu hjl.tools@gmail.com
Thu Apr 22 11:54:49 GMT 2021


On Thu, Apr 22, 2021 at 1:39 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> In preparation for extending the conditions here defer this check until
> operands have been parsed, as certain further attributes will need to
> be known for determining applicability of this check to be correct to
> LEA.
>
> gas/
> 2021-04-XX  Jan Beulich  <jbeulich@suse.com>
>
>         * config/tc-i386.c (i386_finalize_displacement): Move Disp32S
>         check ...
>         (md_assemble): ... here.
>
> ---
> Even with it moved later, the check still seems misplaced (too early,
> and hence not covering all cases) and overly ad-hoc (there shouldn't be
> anything CODE_64BIT specific here). But with the way optimize_disp() and
> other logic works, moving it even later doesn't look to be easily
> possible.
>
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -4740,6 +4740,34 @@ md_assemble (char *line)
>    if (i.imm_operands)
>      optimize_imm ();
>
> +  if (i.disp_operands && flag_code == CODE_64BIT && !i.prefix[ADDR_PREFIX])
> +    {
> +      for (j = 0; j < i.operands; ++j)
> +       {
> +         const expressionS *exp = i.op[j].disps;
> +
> +         if (!operand_type_check (i.types[j], disp))
> +           continue;
> +
> +         if (exp->X_op != O_constant)
> +           continue;
> +
> +         /* Since displacement is signed extended to 64bit, don't allow
> +            disp32 and turn off disp32s if they are out of range.  */
> +         i.types[j].bitfield.disp32 = 0;
> +         if (fits_in_signed_long (exp->X_add_number))
> +           continue;
> +
> +         i.types[j].bitfield.disp32s = 0;
> +         if (i.types[j].bitfield.baseindex)
> +           {
> +             as_bad (_("0x%" BFD_VMA_FMT "x out of range of signed 32bit displacement"),
> +                     exp->X_add_number);
> +             return;
> +           }
> +       }
> +    }
> +
>    /* Don't optimize displacement for movabs since it only takes 64bit
>       displacement.  */
>    if (i.disp_operands
> @@ -10912,25 +10940,6 @@ i386_finalize_displacement (segT exp_seg
>        ret = 0;
>      }
>
> -  else if (flag_code == CODE_64BIT
> -          && !i.prefix[ADDR_PREFIX]
> -          && exp->X_op == O_constant)
> -    {
> -      /* Since displacement is signed extended to 64bit, don't allow
> -        disp32 and turn off disp32s if they are out of range.  */
> -      i.types[this_operand].bitfield.disp32 = 0;
> -      if (!fits_in_signed_long (exp->X_add_number))
> -       {
> -         i.types[this_operand].bitfield.disp32s = 0;
> -         if (i.types[this_operand].bitfield.baseindex)
> -           {
> -             as_bad (_("0x%" BFD_VMA_FMT "x out of range of signed 32bit displacement"),
> -                     exp->X_add_number);
> -             ret = 0;
> -           }
> -       }
> -    }
> -
>  #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
>    else if (exp->X_op != O_constant
>            && OUTPUT_FLAVOR == bfd_target_aout_flavour
>

OK.

Thanks.

-- 
H.J.


More information about the Binutils mailing list