Improve x86 assembler error message.
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 25 Feb 2010 17:59:52 +0000 (17:59 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 25 Feb 2010 17:59:52 +0000 (17:59 +0000)
2010-02-25  H.J. Lu  <hongjiu.lu@intel.com>

* config/tc-i386.c (_i386_insn): Add err_msg.
(operand_size_match): Set err_msg on failure.
(operand_type_match): Likewise.
(operand_type_register_match): Likewise.
(VEX_check_operands): Likewise.
(match_template): Likewise.  Use i.err_msg with as_bad.

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

index 6dca72bc5259cad7deaaafc2be17a31a1fc800c5..fe4775fa390806578896d38911ebd5f759fae809 100644 (file)
@@ -1,3 +1,12 @@
+2010-02-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/tc-i386.c (_i386_insn): Add err_msg.
+       (operand_size_match): Set err_msg on failure.
+       (operand_type_match): Likewise.
+       (operand_type_register_match): Likewise.
+       (VEX_check_operands): Likewise.
+       (match_template): Likewise.  Use i.err_msg with as_bad.
+
 2010-02-25  Wu Zhangjin <wuzhangjin@gmail.com>
 
        * config/tc-mips.c (mips_fix_loongson2f, mips_fix_loongson2f_nop,
index 9e804c6cd6fbee1f627114cf41dc2a70310eded8..7b71bbc81340fd994fa626c352e8fe3f884a90b4 100644 (file)
@@ -260,6 +260,9 @@ struct _i386_insn
 
     /* Swap operand in encoding.  */
     unsigned int swap_operand;
+
+    /* Error message.  */
+    const char *err_msg;
   };
 
 typedef struct _i386_insn i386_insn;
@@ -1557,9 +1560,14 @@ operand_size_match (const insn_template *t)
        }
     }
 
-  if (match
-      || (!t->opcode_modifier.d && !t->opcode_modifier.floatd))
+  if (match)
     return match;
+  else if (!t->opcode_modifier.d && !t->opcode_modifier.floatd)
+    {
+mismatch:
+      i.err_msg = _("operand size mismatch");
+      return 0;
+    }
 
   /* Check reverse.  */
   gas_assert (i.operands == 2);
@@ -1569,17 +1577,11 @@ operand_size_match (const insn_template *t)
     {
       if (t->operand_types[j].bitfield.acc
          && !match_reg_size (t, j ? 0 : 1))
-       {
-         match = 0;
-         break;
-       }
+       goto mismatch;
 
       if (i.types[j].bitfield.mem
          && !match_mem_size (t, j ? 0 : 1))
-       {
-         match = 0;
-         break;
-       }
+       goto mismatch;
     }
 
   return match;
@@ -1602,10 +1604,15 @@ operand_type_match (i386_operand_type overlap,
   temp.bitfield.xmmword = 0;
   temp.bitfield.ymmword = 0;
   if (operand_type_all_zero (&temp))
-    return 0;
+    goto mismatch;
 
-  return (given.bitfield.baseindex == overlap.bitfield.baseindex
-         && given.bitfield.jumpabsolute == overlap.bitfield.jumpabsolute);
+  if (given.bitfield.baseindex == overlap.bitfield.baseindex
+      && given.bitfield.jumpabsolute == overlap.bitfield.jumpabsolute)
+    return 1;
+
+mismatch:
+  i.err_msg = _("operand type mismatch");
+  return 0;
 }
 
 /* If given types g0 and g1 are registers they must be of the same type
@@ -1648,10 +1655,15 @@ operand_type_register_match (i386_operand_type m0,
       t1.bitfield.reg64 = 1;
     }
 
-  return (!(t0.bitfield.reg8 & t1.bitfield.reg8)
-         && !(t0.bitfield.reg16 & t1.bitfield.reg16)
-         && !(t0.bitfield.reg32 & t1.bitfield.reg32)
-         && !(t0.bitfield.reg64 & t1.bitfield.reg64));
+  if (!(t0.bitfield.reg8 & t1.bitfield.reg8)
+      && !(t0.bitfield.reg16 & t1.bitfield.reg16)
+      && !(t0.bitfield.reg32 & t1.bitfield.reg32)
+      && !(t0.bitfield.reg64 & t1.bitfield.reg64))
+    return 1;
+
+  i.err_msg = _("register type mismatch");
+
+  return 0;
 }
 
 static INLINE unsigned int
@@ -3745,7 +3757,10 @@ VEX_check_operands (const insn_template *t)
     {
       if (i.op[0].imms->X_op != O_constant
          || !fits_in_imm4 (i.op[0].imms->X_add_number))
-       return 1;
+       {
+         i.err_msg = _("Imm4 isn't the first operand");
+         return 1;
+       }
 
       /* Turn off Imm8 so that update_imm won't complain.  */
       i.types[0] = vec_imm4;
@@ -3795,29 +3810,35 @@ match_template (void)
       addr_prefix_disp = -1;
 
       /* Must have right number of operands.  */
+      i.err_msg = _("number of operands mismatch");
       if (i.operands != t->operands)
        continue;
 
       /* Check processor support.  */
+      i.err_msg = _("instruction not supported");
       found_cpu_match = (cpu_flags_match (t)
                         == CPU_FLAGS_PERFECT_MATCH);
       if (!found_cpu_match)
        continue;
 
       /* Check old gcc support. */
+      i.err_msg = _("only supported with old gcc");
       if (!old_gcc && t->opcode_modifier.oldgcc)
        continue;
 
       /* Check AT&T mnemonic.   */
+      i.err_msg = _("not supported with Intel mnemonic");
       if (intel_mnemonic && t->opcode_modifier.attmnemonic)
        continue;
 
-      /* Check AT&T syntax Intel syntax.   */
+      /* Check AT&T/Intel syntax.   */
+      i.err_msg = _("unsupported syntax");
       if ((intel_syntax && t->opcode_modifier.attsyntax)
          || (!intel_syntax && t->opcode_modifier.intelsyntax))
        continue;
 
       /* Check the suffix, except for some instructions in intel mode.  */
+      i.err_msg = _("invalid instruction suffix");
       if ((!intel_syntax || !t->opcode_modifier.ignoresize)
          && ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf)
              || (t->opcode_modifier.no_wsuf && suffix_check.no_wsuf)
@@ -4069,12 +4090,8 @@ check_reverse:
   if (t == current_templates->end)
     {
       /* We found no match.  */
-      if (intel_syntax)
-       as_bad (_("ambiguous operand size or operands invalid for `%s'"),
-               current_templates->start->name);
-      else
-       as_bad (_("suffix or operands invalid for `%s'"),
-               current_templates->start->name);
+      as_bad (_("%s for `%s'"), i.err_msg,
+             current_templates->start->name);
       return NULL;
     }