aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2010-02-25 17:59:52 +0000
committerH.J. Lu <hjl.tools@gmail.com>2010-02-25 17:59:52 +0000
commit891edac42bbcac3e084c0cbfe846c73ddfc4d7c6 (patch)
treea93681a8c32e3af71028a5ef946a8724ba3dfb2a /gas/config
parenteb73e134997d622048918a758b3644b618585411 (diff)
downloadfsf-binutils-gdb-891edac42bbcac3e084c0cbfe846c73ddfc4d7c6.zip
fsf-binutils-gdb-891edac42bbcac3e084c0cbfe846c73ddfc4d7c6.tar.gz
fsf-binutils-gdb-891edac42bbcac3e084c0cbfe846c73ddfc4d7c6.tar.bz2
Improve x86 assembler error message.
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.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-i386.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 9e804c6..7b71bbc 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -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;
}