[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