From cce08655c696b771538e325065166ae8fdb7ff46 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 23 Apr 2021 09:17:33 +0200 Subject: [PATCH] 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. --- gas/ChangeLog | 6 ++++++ gas/config/tc-i386.c | 47 ++++++++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 19 deletions(-) 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 -- 2.30.2