&& t->opcode_modifier.jump != JUMP_ABSOLUTE)
return match;
+ for (j = 0; j < i.imm_operands; j++)
+ /* Instruction templates with only sign-extended 8-bit immediate
+ operand also have a second template with full-operand-size
+ immediate operand under a different opcode. Don't match the
+ first template if sign-extended 8-bit immediate operand should
+ be excluded. */
+ if (pp.no_imm8s
+ && !t->operand_types[j].bitfield.imm8
+ && t->operand_types[j].bitfield.imm8s)
+ {
+ gas_assert (!t->opcode_modifier.d);
+ return 0;
+ }
+
/* Check memory and accumulator operand size. */
- for (j = 0; j < i.operands; j++)
+ for (; j < i.operands; j++)
{
- /* Instruction templates with only sign-extended 8-bit immediate
- operand also have a second template with full-operand-size
- immediate operand under a different opcode. Don't match the
- first template if sign-extended 8-bit immediate operand should
- be excluded. */
- if (pp.no_imm8s
- && !t->operand_types[j].bitfield.imm8
- && t->operand_types[j].bitfield.imm8s)
- {
- match = 0;
- break;
- }
-
if (i.types[j].bitfield.class == Reg
&& (t->operand_types[j].bitfield.class == Reg
|| (t->operand_types[j].bitfield.instance == Accum
/* Check reverse. */
gas_assert (i.operands >= 2);
- for (j = 0; j < i.operands; j++)
+ for (j = i.imm_operands; j < i.operands; j++)
{
unsigned int given = i.operands - j - 1;
swap_operands ();
/* The order of the immediates should be reversed for 2-immediates EXTRQ
- and INSERTQ instructions. Also UWRMSR wants its immediate to be in the
- "canonical" place (first), despite it appearing last (in AT&T syntax, or
- because of the swapping above) in the incoming set of operands. */
+ and INSERTQ instructions. Also OUT, UWRMSR, and WRMSRNS want their
+ immediate to be in the "canonical" place (first), despite it appearing
+ last (in AT&T syntax, or because of the swapping above) in the incoming
+ set of operands. */
if ((i.imm_operands == 2
&& (t->mnem_off == MN_extrq || t->mnem_off == MN_insertq))
- || ((t->mnem_off == MN_uwrmsr || t->mnem_off == MN_wrmsrns)
+ || ((t->mnem_off == MN_out || t->mnem_off == MN_uwrmsr
+ || t->mnem_off == MN_wrmsrns)
&& i.imm_operands && i.operands > i.imm_operands))
swap_2_operands (0, 1);
|| t->mnem_off == MN_rdmsr
|| t->mnem_off == MN_wrmsrns)
{
- for (j = 0; j < i.operands; j++)
- {
- if (operand_type_check(i.types[j], imm))
- i.types[j] = smallest_imm_type (i.op[j].imms->X_add_number);
- }
+ for (j = 0; j < i.imm_operands; j++)
+ i.types[j] = smallest_imm_type (i.op[j].imms->X_add_number);
}
else
optimize_imm ();
&& (!t->opcode_modifier.jump
|| i.jumpabsolute || i.types[0].bitfield.baseindex))
{
- for (op = 0; op < i.operands; ++op)
+ for (op = i.imm_operands; op < i.operands; ++op)
{
const expressionS *exp = i.op[op].disps;
unsigned int j;
type.bitfield.baseindex = 1;
- for (j = 0; j < i.operands; ++j)
+ for (j = i.imm_operands; j < i.operands; ++j)
{
if (j != op
&& !operand_type_register_match(i.types[j],
else if (t->opcode_modifier.broadcast && i.mem_operands)
{
/* Find memory operand. */
- for (op = 0; op < i.operands; op++)
+ for (op = i.imm_operands; op < i.operands; op++)
if (i.flags[op] & Operand_Mem)
break;
gas_assert (op < i.operands);
const i386_operand_type *type = NULL, *fallback = NULL;
i.memshift = 0;
- for (op = 0; op < i.operands; op++)
+ for (op = i.imm_operands; op < i.operands; op++)
if (i.flags[op] & Operand_Mem)
{
if (t->opcode_modifier.evex == EVEXLIG)
i.memshift = -1;
}
- for (op = 0; op < i.operands; op++)
+ for (op = i.imm_operands; op < i.operands; op++)
if (operand_type_check (i.types[op], disp)
&& i.op[op].disps->X_op == O_constant)
{
if (!t->opcode_modifier.noegpr)
return false;
- for (unsigned int op = 0; op < i.operands; op++)
+ for (unsigned int op = i.imm_operands; op < i.operands; op++)
{
if (i.types[op].bitfield.class != Reg)
continue;
static bool
check_Rex_required (void)
{
- for (unsigned int op = 0; op < i.operands; op++)
+ for (unsigned int op = i.imm_operands; op < i.operands; op++)
{
if (i.types[op].bitfield.class != Reg)
continue;
else
need = flag_code == CODE_64BIT ? need_qword : need_word;
- for (op = 0; op < i.operands; op++)
+ for (op = i.imm_operands; op < i.operands; op++)
{
if (i.types[op].bitfield.class != Reg)
continue;
unnecessary segment overrides. */
const reg_entry *default_seg = NULL;
- for (unsigned int j = 0; j < i.operands; j++)
+ for (unsigned int j = i.imm_operands; j < i.operands; j++)
if (i.types[j].bitfield.instance != InstanceNone)
i.reg_operands--;
in, 0xec, 0, W|No_sSuf|No_qSuf, { InOutPortReg, Acc|Byte|Word|Dword }
in, 0xe4, 0, W|No_sSuf|No_qSuf|IntelSuffix, { Imm8 }
in, 0xec, 0, W|No_sSuf|No_qSuf|IntelSuffix, { InOutPortReg }
-out, 0xe6, 0, W|No_sSuf|No_qSuf, { Acc|Byte|Word|Dword, Imm8 }
+// Immediates want to be first; md_assemble() takes care of swapping operands
+// accordingly.
+out, 0xe6, 0, W|No_sSuf|No_qSuf, { Imm8, Acc|Byte|Word|Dword }
out, 0xee, 0, W|No_sSuf|No_qSuf, { Acc|Byte|Word|Dword, InOutPortReg }
out, 0xe6, 0, W|No_sSuf|No_qSuf|IntelSuffix, { Imm8 }
out, 0xee, 0, W|No_sSuf|No_qSuf|IntelSuffix, { InOutPortReg }
0, 0 },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
- { { { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
+ { { { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } },
- { { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ { { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
{ MN_out, 0xee, 2, SPACE_BASE, None,
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,