#define Edb { OP_E, db_mode }
#define Edw { OP_E, dw_mode }
#define Edqd { OP_E, dqd_mode }
+#define Edqa { OP_E, dqa_mode }
#define Eq { OP_E, q_mode }
#define indirEv { OP_indirE, indir_v_mode }
#define indirEp { OP_indirE, f_mode }
#define Mo { OP_M, o_mode }
#define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
#define Mq { OP_M, q_mode }
+#define Mv_bnd { OP_M, v_bndmk_mode }
#define Mx { OP_M, x_mode }
#define Mxmm { OP_M, xmm_mode }
#define Gb { OP_G, b_mode }
cond_jump_mode,
loop_jcxz_mode,
v_bnd_mode,
+ /* like v_bnd_mode in 32bit, no RIP-rel in 64bit mode. */
+ v_bndmk_mode,
/* operand size depends on REX prefixes. */
dq_mode,
/* registers like dq_mode, memory like w_mode. */
dw_mode,
/* registers like dq_mode, memory like d_mode. */
dqd_mode,
+ /* operand size depends on the W bit as well as address mode. */
+ dqa_mode,
/* normal vex mode */
vex_mode,
/* 128bit vex mode */
},
{
/* MOD_0F1A_PREFIX_0 */
- { "bndldx", { Gbnd, Ev_bnd }, 0 },
+ { "bndldx", { Gbnd, Mv_bnd }, 0 },
{ "nopQ", { Ev }, 0 },
},
{
/* MOD_0F1B_PREFIX_0 */
- { "bndstx", { Ev_bnd, Gbnd }, 0 },
+ { "bndstx", { Mv_bnd, Gbnd }, 0 },
{ "nopQ", { Ev }, 0 },
},
{
/* MOD_0F1B_PREFIX_1 */
- { "bndmk", { Gbnd, Ev_bnd }, 0 },
+ { "bndmk", { Gbnd, Mv_bnd }, 0 },
{ "nopQ", { Ev }, 0 },
},
{
},
{
/* MOD_0F38F9_PREFIX_0 */
- { "movdiri", { Em, Gm }, PREFIX_OPCODE },
+ { "movdiri", { Em, Gv }, PREFIX_OPCODE },
},
{
/* MOD_62_32BIT */
case q_swap_mode:
oappend ("QWORD PTR ");
break;
+ case dqa_mode:
case m_mode:
if (address_mode == mode_64bit)
oappend ("QWORD PTR ");
oappend ("WORD PTR ");
break;
case v_bnd_mode:
+ case v_bndmk_mode:
default:
break;
}
case dqb_mode:
case dqd_mode:
case dqw_mode:
+ case dqa_mode:
USED_REX (REX_W);
if (rex & REX_W)
names = names64;
names = (address_mode == mode_64bit
? names64 : names32);
if (!(prefixes & PREFIX_ADDR))
- {
- if (address_mode == mode_16bit)
- names = names16;
- }
+ names = (address_mode == mode_16bit
+ ? names16 : names);
else
{
/* Remove "addr16/addr32". */
case d_scalar_swap_mode:
shift = 2;
break;
- case w_scalar_mode:
+ case w_scalar_mode:
case xmm_mw_mode:
shift = 1;
break;
- case b_scalar_mode:
+ case b_scalar_mode:
case xmm_mb_mode:
shift = 0;
break;
+ case dqa_mode:
+ shift = address_mode == mode_64bit ? 3 : 2;
+ break;
default:
abort ();
}
int havebase;
int haveindex;
int needindex;
+ int needaddr32;
int base, rbase;
int vindex = 0;
int scale = 0;
int addr32flag = !((sizeflag & AFLAG)
|| bytemode == v_bnd_mode
+ || bytemode == v_bndmk_mode
|| bytemode == bnd_mode
|| bytemode == bnd_swap_mode);
const char **indexes64 = names64;
if (address_mode == mode_64bit && !havesib)
riprel = 1;
disp = get32s ();
+ if (riprel && bytemode == v_bndmk_mode)
+ {
+ oappend ("(bad)");
+ return;
+ }
}
break;
case 1:
break;
}
- /* In 32bit mode, we need index register to tell [offset] from
- [eiz*1 + offset]. */
- needindex = (havesib
- && !havebase
- && !haveindex
- && address_mode == mode_32bit);
+ needindex = 0;
+ needaddr32 = 0;
+ if (havesib
+ && !havebase
+ && !haveindex
+ && address_mode != mode_16bit)
+ {
+ if (address_mode == mode_64bit)
+ {
+ /* Display eiz instead of addr32. */
+ needindex = addr32flag;
+ needaddr32 = 1;
+ }
+ else
+ {
+ /* In 32-bit mode, we need index register to tell [offset]
+ from [eiz*1 + offset]. */
+ needindex = 1;
+ }
+ }
+
havedisp = (havebase
|| needindex
|| (havesib && (haveindex || scale != 0)));
}
}
- if ((havebase || haveindex || riprel)
+ if ((havebase || haveindex || needaddr32 || riprel)
&& (bytemode != v_bnd_mode)
+ && (bytemode != v_bndmk_mode)
&& (bytemode != bnd_mode)
&& (bytemode != bnd_swap_mode))
used_prefixes |= PREFIX_ADDR;