x86: re-arrange process_operands()
authorJan Beulich <jbeulich@suse.com>
Mon, 4 Nov 2019 14:48:38 +0000 (15:48 +0100)
committerJan Beulich <jbeulich@suse.com>
Mon, 4 Nov 2019 14:48:38 +0000 (15:48 +0100)
Alter the sequence of conditions evaluated, without affecting the
overall result. This is going to help subsequent changes (and as a nice
side effect also slightly reduces overall indentation depth).

While doing this take the liberty of simplifying the calculation of the
operand index of the register operand in ShortForm handling.

gas/ChangeLog
gas/config/tc-i386.c

index fc99adce7f3b5638a81c03b95bb7c48f5c6b57e5..185469fbfaa686996e79ac466f8e8629c448f7bc 100644 (file)
@@ -1,3 +1,8 @@
+2019-11-04  Jan Beulich  <jbeulich@suse.com>
+
+       * config/tc-i386.c (process_operands): Handle ShortForm insns
+       later, splitting out their segment register sub-form.
+
 2019-10-31  H.J. Lu  <hongjiu.lu@intel.com>
 
        * testsuite/gas/i386/general.s: Add .code16gcc fldenv tests.
index f26b17c9563d34f499f27fa4439c120cdd343ef0..5866bd618e81caa7a9895cee3f699f8f744e8f0a 100644 (file)
@@ -7004,63 +7004,7 @@ duplicate:
       i.reg_operands++;
     }
 
-  if (i.tm.opcode_modifier.shortform)
-    {
-      if (i.types[0].bitfield.sreg)
-       {
-         if (flag_code != CODE_64BIT
-             ? i.tm.base_opcode == POP_SEG_SHORT
-               && i.op[0].regs->reg_num == 1
-             : (i.tm.base_opcode | 1) == POP_SEG386_SHORT
-               && i.op[0].regs->reg_num < 4)
-           {
-             as_bad (_("you can't `%s %s%s'"),
-                     i.tm.name, register_prefix, i.op[0].regs->reg_name);
-             return 0;
-           }
-         if ( i.op[0].regs->reg_num > 3 && i.tm.opcode_length == 1 )
-           {
-             i.tm.base_opcode ^= POP_SEG_SHORT ^ POP_SEG386_SHORT;
-             i.tm.opcode_length = 2;
-           }
-         i.tm.base_opcode |= (i.op[0].regs->reg_num << 3);
-       }
-      else
-       {
-         /* The register or float register operand is in operand
-            0 or 1.  */
-         unsigned int op;
-
-         if ((i.types[0].bitfield.reg && i.types[0].bitfield.tbyte)
-             || operand_type_check (i.types[0], reg))
-           op = 0;
-         else
-           op = 1;
-         /* Register goes in low 3 bits of opcode.  */
-         i.tm.base_opcode |= i.op[op].regs->reg_num;
-         if ((i.op[op].regs->reg_flags & RegRex) != 0)
-           i.rex |= REX_B;
-         if (!quiet_warnings && i.tm.opcode_modifier.ugh)
-           {
-             /* Warn about some common errors, but press on regardless.
-                The first case can be generated by gcc (<= 2.8.1).  */
-             if (i.operands == 2)
-               {
-                 /* Reversed arguments on faddp, fsubp, etc.  */
-                 as_warn (_("translating to `%s %s%s,%s%s'"), i.tm.name,
-                          register_prefix, i.op[!intel_syntax].regs->reg_name,
-                          register_prefix, i.op[intel_syntax].regs->reg_name);
-               }
-             else
-               {
-                 /* Extraneous `l' suffix on fp insn.  */
-                 as_warn (_("translating to `%s %s%s'"), i.tm.name,
-                          register_prefix, i.op[0].regs->reg_name);
-               }
-           }
-       }
-    }
-  else if (i.tm.opcode_modifier.modrm)
+  if (i.tm.opcode_modifier.modrm)
     {
       /* The opcode is completed (modulo i.tm.extension_opcode which
         must be put into the modrm byte).  Now, we make the modrm and
@@ -7068,6 +7012,25 @@ duplicate:
 
       default_seg = build_modrm_byte ();
     }
+  else if (i.types[0].bitfield.sreg)
+    {
+      if (flag_code != CODE_64BIT
+         ? i.tm.base_opcode == POP_SEG_SHORT
+           && i.op[0].regs->reg_num == 1
+         : (i.tm.base_opcode | 1) == POP_SEG386_SHORT
+           && i.op[0].regs->reg_num < 4)
+       {
+         as_bad (_("you can't `%s %s%s'"),
+                 i.tm.name, register_prefix, i.op[0].regs->reg_name);
+         return 0;
+       }
+      if ( i.op[0].regs->reg_num > 3 && i.tm.opcode_length == 1 )
+       {
+         i.tm.base_opcode ^= POP_SEG_SHORT ^ POP_SEG386_SHORT;
+         i.tm.opcode_length = 2;
+       }
+      i.tm.base_opcode |= (i.op[0].regs->reg_num << 3);
+    }
   else if ((i.tm.base_opcode & ~0x3) == MOV_AX_DISP32)
     {
       default_seg = &ds;
@@ -7078,6 +7041,35 @@ duplicate:
         on one of their operands, the default segment is ds.  */
       default_seg = &ds;
     }
+  else if (i.tm.opcode_modifier.shortform)
+    {
+      /* The register or float register operand is in operand
+        0 or 1.  */
+      unsigned int op = !i.tm.operand_types[0].bitfield.reg;
+
+      /* Register goes in low 3 bits of opcode.  */
+      i.tm.base_opcode |= i.op[op].regs->reg_num;
+      if ((i.op[op].regs->reg_flags & RegRex) != 0)
+       i.rex |= REX_B;
+      if (!quiet_warnings && i.tm.opcode_modifier.ugh)
+       {
+         /* Warn about some common errors, but press on regardless.
+            The first case can be generated by gcc (<= 2.8.1).  */
+         if (i.operands == 2)
+           {
+             /* Reversed arguments on faddp, fsubp, etc.  */
+             as_warn (_("translating to `%s %s%s,%s%s'"), i.tm.name,
+                      register_prefix, i.op[!intel_syntax].regs->reg_name,
+                      register_prefix, i.op[intel_syntax].regs->reg_name);
+           }
+         else
+           {
+             /* Extraneous `l' suffix on fp insn.  */
+             as_warn (_("translating to `%s %s%s'"), i.tm.name,
+                      register_prefix, i.op[0].regs->reg_name);
+           }
+       }
+    }
 
   if (i.tm.base_opcode == 0x8d /* lea */
       && i.seg[0]