static void BadOp (void);
static void REP_Fixup (int, int);
static void BND_Fixup (int, int);
+static void NOTRACK_Fixup (int, int);
static void HLE_Fixup1 (int, int);
static void HLE_Fixup2 (int, int);
static void HLE_Fixup3 (int, int);
#define Evh3 { HLE_Fixup3, v_mode }
#define BND { BND_Fixup, 0 }
+#define NOTRACK { NOTRACK_Fixup, 0 }
#define cond_jump_flag { NULL, cond_jump_mode }
#define loop_jcxz_flag { NULL, loop_jcxz_mode }
static int last_addr_prefix;
static int last_rex_prefix;
static int last_seg_prefix;
+static int last_active_prefix;
static int fwait_prefix;
/* The active segment register prefix. */
static int active_seg_prefix;
{
{ "incQ", { Evh1 }, 0 },
{ "decQ", { Evh1 }, 0 },
- { "call{&|}", { indirEv, BND }, 0 },
+ { "call{&|}", { indirEv, NOTRACK, BND }, 0 },
{ MOD_TABLE (MOD_FF_REG_3) },
- { "jmp{&|}", { indirEv, BND }, 0 },
+ { "jmp{&|}", { indirEv, NOTRACK, BND }, 0 },
{ MOD_TABLE (MOD_FF_REG_5) },
{ "pushU", { stackEv }, 0 },
{ Bad_Opcode },
#define XACQUIRE_PREFIX (0xf2 | 0x200)
#define XRELEASE_PREFIX (0xf3 | 0x400)
#define BND_PREFIX (0xf2 | 0x400)
+#define NOTRACK_PREFIX (0x3e | 0x100)
static int
ckprefix (void)
last_addr_prefix = -1;
last_rex_prefix = -1;
last_seg_prefix = -1;
+ last_active_prefix = -1;
fwait_prefix = -1;
active_seg_prefix = 0;
for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
return 1;
}
if (*codep != FWAIT_OPCODE)
- all_prefixes[i++] = *codep;
+ {
+ last_active_prefix = i;
+ all_prefixes[i++] = *codep;
+ }
rex = newrex;
codep++;
length++;
return "xrelease";
case BND_PREFIX:
return "bnd";
+ case NOTRACK_PREFIX:
+ return "notrack";
default:
return NULL;
}
all_prefixes[last_repnz_prefix] = BND_PREFIX;
}
+/* For NOTRACK-prefixed instructions, 0x3E prefix should be displayed as
+ "notrack". */
+
+static void
+NOTRACK_Fixup (int bytemode ATTRIBUTE_UNUSED,
+ int sizeflag ATTRIBUTE_UNUSED)
+{
+ if (modrm.mod == 3
+ && active_seg_prefix == PREFIX_DS
+ && (address_mode != mode_64bit || last_data_prefix < 0))
+ {
+ /* NOTRACK prefix is only valid on register indirect branch
+ instructions and it must be the last prefix before REX
+ prefix and opcode. NB: DATA prefix is unsupported for
+ Intel64. */
+ if (last_active_prefix >= 0)
+ {
+ int notrack_prefix = last_active_prefix;
+ if (last_rex_prefix == last_active_prefix)
+ notrack_prefix--;
+ if (all_prefixes[notrack_prefix] != NOTRACK_PREFIX_OPCODE)
+ return;
+ }
+ active_seg_prefix = 0;
+ all_prefixes[last_seg_prefix] = NOTRACK_PREFIX;
+ }
+}
+
/* Similar to OP_E. But the 0xf2/0xf3 prefixes should be displayed as
"xacquire"/"xrelease" for memory operand if there is a LOCK prefix.
*/