All MPX instructions in 64-bit mode ignore REX.W, which means we neither need to encode this bit nor should disassemble with 32-bit register operands. No MPX instructions would ever take a 16-bit register operand. gas/ 2013-10-08 Jan Beulich * tc-i386.c (process_suffix): Warn about 32-bit register operands to MPX instructions in 64-bit mode. opcodes/ 2013-10-08 Jan Beulich * i386-dis.c (intel_operand_size): Move v_bnd_mode alongside the default case. (OP_E_register): Move v_bnd_mode alongside m_mode. * i386-opc.h (REGNAM_RAX): New. * i386-opc.tbl (bndcl, bndcu, bndcn): Drop Reg16. Add NoRex64. * i386-tbl.h: Re-generate. --- 2013-10-07/gas/config/tc-i386.c +++ 2013-10-07/gas/config/tc-i386.c @@ -5073,8 +5078,24 @@ process_suffix (void) { /* We take i.suffix from the last register operand specified, Destination register type is more significant than source - register type. crc32 in SSE4.2 prefers source register - type. */ + register type. */ + + /* MPX instructions need no suffix, but may need a warning. */ + if (i.tm.cpu_flags.bitfield.cpumpx) + { +#if REGISTER_WARNINGS + if (flag_code == CODE_64BIT && !quiet_warnings + && i.tm.operand_types[0].bitfield.reg64 + && i.types[0].bitfield.reg32) + as_warn (_("using `%s%s' instead of `%s%s' for `%s'"), + register_prefix, + (i.op[0].regs + REGNAM_RAX - REGNAM_EAX)->reg_name, + register_prefix, i.op[0].regs->reg_name, i.tm.name); +#endif + return 1; + } + + /* crc32 in SSE4.2 prefers source register type. */ if (i.tm.base_opcode == 0xf20f38f1) { if (i.types[0].bitfield.reg16) --- 2013-10-07/opcodes/i386-dis.c +++ 2013-10-07/opcodes/i386-dis.c @@ -13800,7 +13801,6 @@ intel_operand_size (int bytemode, int si } /* FALLTHRU */ case v_mode: - case v_bnd_mode: case v_swap_mode: case dq_mode: USED_REX (REX_W); @@ -14082,6 +14082,7 @@ intel_operand_size (int bytemode, int si abort (); oappend ("WORD PTR "); break; + case v_bnd_mode: default: break; } @@ -14121,6 +14122,7 @@ OP_E_register (int bytemode, int sizefla names = names64; break; case m_mode: + case v_bnd_mode: names = address_mode == mode_64bit ? names64 : names32; break; case bnd_mode: @@ -14135,7 +14137,6 @@ OP_E_register (int bytemode, int sizefla bytemode = v_mode; /* FALLTHRU */ case v_mode: - case v_bnd_mode: case v_swap_mode: case dq_mode: case dqb_mode: --- 2013-10-07/opcodes/i386-opc.h +++ 2013-10-07/opcodes/i386-opc.h @@ -835,6 +835,7 @@ reg_entry; #define REGNAM_AL 1 #define REGNAM_AX 25 #define REGNAM_EAX 41 +#define REGNAM_RAX 57 extern const reg_entry i386_regtab[]; extern const unsigned int i386_regtab_size; --- 2013-10-07/opcodes/i386-opc.tbl +++ 2013-10-07/opcodes/i386-opc.tbl @@ -3064,9 +3064,9 @@ bnd, 0, 0xf2, None, 1, CpuMPX, No_bSuf|N bndmk, 2, 0xf30f1b, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Anysize|BaseIndex|Disp8|Disp16|Disp32|Disp32S, RegBND } bndmov, 2, 0x660f1a, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoAVX, { Xmmword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S|RegBND, RegBND } bndmov, 2, 0x660f1b, None, 2, CpuMPX, S|Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegBND, Xmmword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S|RegBND } -bndcl, 2, 0xf30f1a, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Reg32|Reg64|Anysize|BaseIndex|Disp8|Disp16|Disp32|Disp32S, RegBND } -bndcu, 2, 0xf20f1a, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Reg32|Reg64|Anysize|BaseIndex|Disp8|Disp16|Disp32|Disp32S, RegBND } -bndcn, 2, 0xf20f1b, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Reg32|Reg64|Anysize|BaseIndex|Disp8|Disp16|Disp32|Disp32S, RegBND } +bndcl, 2, 0xf30f1a, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64, { Reg32|Reg64|Anysize|BaseIndex|Disp8|Disp16|Disp32|Disp32S, RegBND } +bndcu, 2, 0xf20f1a, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64, { Reg32|Reg64|Anysize|BaseIndex|Disp8|Disp16|Disp32|Disp32S, RegBND } +bndcn, 2, 0xf20f1b, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64, { Reg32|Reg64|Anysize|BaseIndex|Disp8|Disp16|Disp32|Disp32S, RegBND } bndstx, 2, 0x0f1b, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegBND, Anysize|BaseIndex|Disp8|Disp16|Disp32|Disp32S } bndldx, 2, 0x0f1a, None, 2, CpuMPX, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Anysize|BaseIndex|Disp8|Disp16|Disp32|Disp32S, RegBND } --- 2013-10-07/opcodes/i386-tbl.h +++ 2013-10-07/opcodes/i386-tbl.h @@ -53915,10 +53915,10 @@ const insn_template i386_optab[] = 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0 }, - { { { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + { { { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, @@ -53930,10 +53930,10 @@ const insn_template i386_optab[] = 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0 }, - { { { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + { { { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, @@ -53945,10 +53945,10 @@ const insn_template i386_optab[] = 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0 }, - { { { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + { { { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0,