From: Jan Beulich Date: Fri, 23 Apr 2021 07:17:33 +0000 (+0200) Subject: x86-64: defer 32-bit signed displacement check X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cce08655c696b771538e325065166ae8fdb7ff46;p=binutils-gdb.git x86-64: defer 32-bit signed displacement check 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 determinig applicability of this check to be correct to LEA. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 669fb6b3742..aeacaa6b0fb 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2021-04-23 Jan Beulich + + * config/tc-i386.c (i386_finalize_displacement): Move Disp32S + check ... + (md_assemble): ... here. + 2021-04-23 Jan Beulich * config/tc-i386.c (optimize_disp): Move down BFD64 section. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 5180320bcac..8098f5045f9 100644 --- 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 ATTRIBUTE_UNUSED, expressionS *exp, 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