#endif
#endif
-#ifndef REGISTER_WARNINGS
-#define REGISTER_WARNINGS 1
-#endif
-
#ifndef INFER_ADDR_PREFIX
#define INFER_ADDR_PREFIX 1
#endif
unsigned int prefixes;
unsigned char prefix[MAX_PREFIXES];
+ /* Register is in low 3 bits of opcode. */
+ bfd_boolean short_form;
+
/* The operand to a branch insn indicates an absolute branch. */
bfd_boolean jumpabsolute;
0 if att syntax. */
static int intel_syntax = 0;
-/* 1 for Intel64 ISA,
- 0 if AMD64 ISA. */
-static int intel64;
+static enum x86_64_isa
+{
+ amd64 = 1, /* AMD64 ISA. */
+ intel64 /* Intel64 ISA. */
+} isa64;
/* 1 for intel mnemonic,
0 if att mnemonic. */
/* If given types g0 and g1 are registers they must be of the same type
unless the expected operand type register overlap is null.
- Memory operand size of certain SIMD instructions is also being checked
- here. */
+ Some Intel syntax memory operand size checking also happens here. */
static INLINE int
operand_type_register_match (i386_operand_type g0,
&& g0.bitfield.class != RegSIMD
&& (!operand_type_check (g0, anymem)
|| g0.bitfield.unspecified
- || t0.bitfield.class != RegSIMD))
+ || (t0.bitfield.class != Reg
+ && t0.bitfield.class != RegSIMD)))
return 1;
if (g1.bitfield.class != Reg
&& g1.bitfield.class != RegSIMD
&& (!operand_type_check (g1, anymem)
|| g1.bitfield.unspecified
- || t1.bitfield.class != RegSIMD))
+ || (t1.bitfield.class != Reg
+ && t1.bitfield.class != RegSIMD)))
return 1;
if (g0.bitfield.byte == g1.bitfield.byte
i.tm.base_opcode = 0xb8;
i.tm.extension_opcode = None;
i.tm.opcode_modifier.w = 0;
- i.tm.opcode_modifier.shortform = 1;
i.tm.opcode_modifier.modrm = 0;
}
}
if (intel_mnemonic && t->opcode_modifier.attmnemonic)
continue;
- /* Check AT&T/Intel syntax and Intel64/AMD64 ISA. */
+ /* Check AT&T/Intel syntax. */
i.error = unsupported_syntax;
if ((intel_syntax && t->opcode_modifier.attsyntax)
- || (!intel_syntax && t->opcode_modifier.intelsyntax)
- || (intel64 && t->opcode_modifier.amd64)
- || (!intel64 && t->opcode_modifier.intel64))
+ || (!intel_syntax && t->opcode_modifier.intelsyntax))
continue;
+ /* Check Intel64/AMD64 ISA. */
+ switch (isa64)
+ {
+ default:
+ /* Default: Don't accept Intel64. */
+ if (t->opcode_modifier.isa64 == INTEL64)
+ continue;
+ break;
+ case amd64:
+ /* -mamd64: Don't accept Intel64 and Intel64 only. */
+ if (t->opcode_modifier.isa64 >= INTEL64)
+ continue;
+ break;
+ case intel64:
+ /* -mintel64: Don't accept AMD64. */
+ if (t->opcode_modifier.isa64 == AMD64 && flag_code == CODE_64BIT)
+ continue;
+ break;
+ }
+
/* Check the suffix. */
i.error = invalid_instruction_suffix;
if ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf)
}
}
+ if (!i.tm.opcode_modifier.modrm && i.reg_operands && i.tm.operands < 3)
+ i.short_form = (i.tm.operand_types[0].bitfield.class == Reg)
+ != (i.tm.operand_types[1].bitfield.class == Reg);
+
/* Change the opcode based on the operand size given by i.suffix. */
switch (i.suffix)
{
/* It's not a byte, select word/dword operation. */
if (i.tm.opcode_modifier.w)
{
- if (i.tm.opcode_modifier.shortform)
+ if (i.short_form)
i.tm.base_opcode |= 8;
else
i.tm.base_opcode |= 1;
&& i.tm.operand_types[op].bitfield.word)
continue;
- /* crc32 doesn't generate this warning. */
- if (i.tm.base_opcode == 0xf20f38f0)
+ /* crc32 only wants its source operand checked here. */
+ if (i.tm.base_opcode == 0xf20f38f0 && op)
continue;
- if ((i.types[op].bitfield.word
- || i.types[op].bitfield.dword
- || i.types[op].bitfield.qword)
- && i.op[op].regs->reg_num < 4
- /* Prohibit these changes in 64bit mode, since the lowering
- would be more complicated. */
- && flag_code != CODE_64BIT)
- {
-#if REGISTER_WARNINGS
- if (!quiet_warnings)
- as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"),
- register_prefix,
- (i.op[op].regs + (i.types[op].bitfield.word
- ? REGNAM_AL - REGNAM_AX
- : REGNAM_AL - REGNAM_EAX))->reg_name,
- register_prefix,
- i.op[op].regs->reg_name,
- i.suffix);
-#endif
- continue;
- }
/* Any other register is bad. */
if (i.types[op].bitfield.class == Reg
|| i.types[op].bitfield.class == RegMMX
i.suffix);
return 0;
}
- /* Warn if the e or r prefix on a general reg is present. */
- else if ((!quiet_warnings || flag_code == CODE_64BIT)
- && (i.types[op].bitfield.dword
+ /* Error if the e or r prefix on a general reg is present. */
+ else if ((i.types[op].bitfield.dword
|| i.types[op].bitfield.qword)
&& (i.tm.operand_types[op].bitfield.class == Reg
|| i.tm.operand_types[op].bitfield.instance == Accum)
&& i.tm.operand_types[op].bitfield.word)
{
- /* Prohibit these changes in the 64bit mode, since the
- lowering is more complicated. */
- if (flag_code == CODE_64BIT)
- {
- as_bad (_("incorrect register `%s%s' used with `%c' suffix"),
- register_prefix, i.op[op].regs->reg_name,
- i.suffix);
- return 0;
- }
-#if REGISTER_WARNINGS
- as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"),
- register_prefix,
- (i.op[op].regs + REGNAM_AX - REGNAM_EAX)->reg_name,
- register_prefix, i.op[op].regs->reg_name, i.suffix);
-#endif
+ as_bad (_("incorrect register `%s%s' used with `%c' suffix"),
+ register_prefix, i.op[op].regs->reg_name,
+ i.suffix);
+ return 0;
}
return 1;
}
on one of their operands, the default segment is ds. */
default_seg = &ds;
}
- else if (i.tm.opcode_modifier.shortform)
+ else if (i.short_form)
{
/* The register or float register operand is in operand
0 or 1. */
if (t->opcode_modifier.jump
!= current_templates->start->opcode_modifier.jump)
break;
- if (t->opcode_modifier.intel64)
+ if ((t->opcode_modifier.isa64 >= INTEL64))
has_intel64 = TRUE;
}
if (t < current_templates->end)
break;
case OPTION_MAMD64:
- intel64 = 0;
+ isa64 = amd64;
break;
case OPTION_MINTEL64:
- intel64 = 1;
+ isa64 = intel64;
break;
case 'O':