[binutils-gdb] x86-64: defer 32-bit signed displacement check

Jan Beulich jbeulich@sourceware.org
Fri Apr 23 07:19:08 GMT 2021


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cce08655c696b771538e325065166ae8fdb7ff46

commit cce08655c696b771538e325065166ae8fdb7ff46
Author: Jan Beulich <jbeulich@suse.com>
Date:   Fri Apr 23 09:17:33 2021 +0200

    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:
---
 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  <jbeulich@suse.com>
+
+	* config/tc-i386.c (i386_finalize_displacement): Move Disp32S
+	check ...
+	(md_assemble): ... here.
+
 2021-04-23  Jan Beulich  <jbeulich@suse.com>
 
 	* 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


More information about the Binutils-cvs mailing list