x86-64: defer 32-bit signed displacement check
authorJan Beulich <jbeulich@suse.com>
Fri, 23 Apr 2021 07:17:33 +0000 (09:17 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 23 Apr 2021 07:17:33 +0000 (09:17 +0200)
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
gas/config/tc-i386.c

index 669fb6b37429b1880c1b207a69f986e86f77de5e..aeacaa6b0fb34e72f504b39147e9428dda7fa02c 100644 (file)
@@ -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.
index 5180320bcac4a7e72db74f51823350e16e29251b..8098f5045f941313746a5fd11bbdf16cb00451f0 100644 (file)
@@ -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