WIP checkpoint: more matching changes, starting to work on patterns

This is a WIP checkpoint; not all tests pass yet.

More matching changes, and hopefully something much closer to what
really is desired now. The number of required patterns is now much
smaller.

However, a lot of *changes* are needed to the patterns.

Since some patterns are repeated all over the place, clean up the
x86/addflags.pl script and make it able to generate macro-based
common patterns; first use being the patterns for the "basic 8"
arithmetic patterns.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2024-08-11 21:28:57 -07:00
parent f13bad288b
commit c9457d42a6
23 changed files with 884 additions and 966 deletions

View file

@ -54,7 +54,7 @@
enum match_result {
/*
* Matching errors. These should be sorted so that more specific
* errors come later in the sequence.
* errors (higher priority) come later in the sequence.
*/
MERR_INVALOP,
MERR_OPSIZEMISSING,
@ -76,11 +76,23 @@ enum match_result {
MERR_REGSETSIZE,
MERR_REGSET,
MERR_WRONGIMM,
/*
* Matching success; the conditional ones first
* Matching successes in decreasing order of fuzziness;
* the fuzziness factor amounts to the factors (normally
* operands) fuzzed.
*/
MOK_JUMP, /* Matching OK but needs jmp_match() */
MOK_GOOD /* Matching unconditionally OK */
MOK_FIRST, /* First successful anything */
MOK_FUZZY8,
MOK_FUZZY7, /* Matching unconditionally OK */
MOK_FUZZY6,
MOK_FUZZY5,
MOK_FUZZY4,
MOK_FUZZY3,
MOK_FUZZY2,
MOK_FUZZY1,
MOK_GOOD
};
#define GEN_SIB(scale, index, base) \
@ -119,11 +131,25 @@ enum prefix_err {
static int prefix_byte(enum prefixes pfx, const int bits);
/*
* Convert operand/address/mode size to a BITS opflag constant.
* This is not valid for 80+ bits!
*/
static inline opflags_t mode_to_op(unsigned int bits)
{
nasm_static_assert((BITS8 >> SIZE_SHIFT) == 1);
nasm_static_assert(BITS16 == (BITS8 << 1));
nasm_static_assert(BITS32 == (BITS8 << 2));
nasm_static_assert(BITS64 == (BITS8 << 3));
return (opflags_t)bits << (SIZE_SHIFT - 3);
}
/*
* Return any of REX_[BXR]1 corresponding to non-GPR registers by
* masking them with the REX_[BXR]V flags.
*/
static inline uint32_t rex_highvec(uint32_t rexflags)
static inline const_func uint32_t rex_highvec(uint32_t rexflags)
{
return rexflags & (rexflags >> 4) & REX_BXR1;
}
@ -137,6 +163,15 @@ static inline struct operand *get_operand(insn *ins, unsigned int n)
return &ins->oprs[n];
}
static inline const struct operand *
get_operand_const(const insn *ins, unsigned int n)
{
if (n >= (unsigned int)ins->operands)
return NULL;
else
return &ins->oprs[n];
}
static inline bool absolute_op(const struct operand *o)
{
return o && o->segment == NO_SEG && o->wrt == NO_SEG &&
@ -183,14 +218,17 @@ static const char *size_name(int size)
static void warn_overflow(int size, const char *prefix, const char *suffix)
{
const char *pfxsp, *sufsp;
pfxsp = sufsp = " ";
if (!prefix)
prefix = "";
prefix = ++pfxsp;
if (!suffix)
suffix = "";
suffix = ++sufsp;
nasm_warn(ERR_PASS2 | WARN_NUMBER_OVERFLOW,
"%s%s%s exceeds bounds",
prefix, size_name(size), suffix);
"%s%s%s%s%s exceeds bounds",
prefix, pfxsp, size_name(size), sufsp, suffix);
}
static void warn_overflow_const(int64_t data, int size)
@ -199,16 +237,20 @@ static void warn_overflow_const(int64_t data, int size)
warn_overflow(size, NULL, NULL);
}
static void warn_overflow_out(int64_t data, int size, enum out_flags flags)
static void warn_overflow_out(int64_t data, int size,
enum out_flags flags, const char *what)
{
bool err;
const char *prefix;
if (flags & OUT_NOWARN)
return;
if (flags & OUT_SIGNED) {
prefix = "signed ";
prefix = "signed";
err = overflow_signed(data, size);
} else if (flags & OUT_UNSIGNED) {
prefix = "unsigned ";
prefix = "unsigned";
err = overflow_unsigned(data, size);
} else {
prefix = NULL;
@ -216,7 +258,7 @@ static void warn_overflow_out(int64_t data, int size, enum out_flags flags)
}
if (err)
warn_overflow(size, prefix, NULL);
warn_overflow(size, prefix, what);
}
/*
@ -296,7 +338,7 @@ static void out(struct out_data *data)
/* Support address space wrapping for low-bit modes */
data->flags &= ~OUT_SIGNMASK;
}
warn_overflow_out(addrval, asize, data->flags);
warn_overflow_out(addrval, asize, data->flags, data->what);
xdata.q = cpu_to_le64(addrval);
data->data = xdata.b;
data->type = OUT_RAWDATA;
@ -484,6 +526,9 @@ static void out(struct out_data *data)
data->insoffs += zeropad;
data->size += zeropad; /* Restore original size value */
}
/* FOr the next time... */
data->what = NULL;
}
static inline void out_rawdata(struct out_data *data, const void *rawdata,
@ -590,60 +635,81 @@ static void out_reladdr(struct out_data *data, const struct operand *opx,
out(data);
}
static bool jmp_match(insn * ins, const struct itemplate *temp)
/* This is a real hack. The jcc8 or jmp8 byte code must come first. */
static enum match_result jmp_match(const struct itemplate *temp, const insn *ins)
{
int64_t isize;
const uint8_t *code = temp->code;
uint8_t c = code[0];
bool is_byte;
const struct operand * const op0 = get_operand(ins, 0);
const struct operand * const op0 = get_operand_const(ins, 0);
int64_t delta;
if (op0->type & STRICT)
return false;
return MERR_INVALOP;
switch (c) {
case 0370:
if (ins->opt & OPTIM_NO_Jcc_RELAX)
return false;
break;
case 0371:
if (ins->opt & OPTIM_NO_JMP_RELAX)
return false;
break;
default:
return false;
if (unlikely(ins->opt & (OPTIM_NO_Jcc_RELAX|OPTIM_NO_JMP_RELAX))) {
const uint8_t c = temp->code[0];
switch (c) {
case 0370:
if (ins->opt & OPTIM_NO_Jcc_RELAX)
return MERR_INVALOP;
break;
case 0371:
if (ins->opt & OPTIM_NO_JMP_RELAX)
return MERR_INVALOP;
break;
default:
return MERR_INVALOP;
}
}
isize = calcsize(ins, temp);
if (op0->opflags & OPFLAG_UNKNOWN)
if (op0->opflags & OPFLAG_UNKNOWN) {
/* Be optimistic in pass 1 */
return true;
if (op0->segment != ins->loc.segment)
return false;
isize = op0->offset - ins->loc.offset - isize; /* isize is delta */
is_byte = (isize >= -128 && isize <= 127); /* is it byte size? */
if (is_byte && c == 0371 && ins->prefixes[PPS_REP] == P_BND) {
/* jmp short (opcode eb) cannot be used with bnd prefix. */
ins->prefixes[PPS_REP] = P_none;
/*!
*!prefix-bnd [on] invalid \c{BND} prefix
*!=bnd
*! warns about ineffective use of the \c{BND} prefix when the
*! \c{JMP} instruction is converted to the \c{SHORT} form.
*! This should be extremely rare since the short \c{JMP} only
*! is applicable to jumps inside the same module, but if
*! it is legitimate, it may be necessary to use
*! \c{bnd jmp dword}.
*/
nasm_warn(WARN_PREFIX_BND|ERR_PASS2 ,
"jmp short does not init bnd regs - bnd prefix dropped");
return MOK_GOOD;
}
return is_byte;
if (op0->segment != ins->loc.segment) {
/* Cross-segment jump */
return MERR_INVALOP;
}
/*
* An instruction can only range between 1 and 15 bytes.
* If that is guaranteed true or false, there is no reason
* to go through the process of calculating the exact instruction
* size.
*/
delta = op0->offset - ins->loc.offset;
if (delta < -128 + 1 || delta > 127 + 15) {
/* This cannot be a byte-sized jump */
return MERR_INVALOP;
} else if (delta >= -128 + 15 && delta <= 127 + 1) {
/* It is guaranteed to be safe, no need to go through test */
} else {
/*
* Need to do this the hard way.
*
* However, calcsize() can modify the instruction structure,
* but after a mismatch we have to revert to the original
* state, so make a copy here and hold error messages.
*/
int64_t isize;
insn tmpins;
errhold hold;
tmpins = *ins;
tmpins.dummy = true;
hold = nasm_error_hold_push();
isize = calcsize(&tmpins, temp);
if (nasm_error_hold_pop(hold, false) >= ERR_NONFATAL)
return MERR_INVALOP;
if (isize < 0)
return MERR_INVALOP;
delta -= isize;
if ((int8_t)delta != delta)
return MERR_INVALOP;
}
return MOK_GOOD;
}
static inline int64_t merge_resb(insn *ins, int64_t isize)
@ -881,7 +947,7 @@ int64_t assemble(insn *instruction)
m = find_match(&temp, instruction);
if (m == MOK_GOOD) {
if (m >= MOK_GOOD) {
/* Matches! */
if (unlikely(itemp_has(temp, IF_OBSOLETE))) {
errflags warning;
@ -1110,7 +1176,6 @@ static void debug_set_type(insn *instruction)
dfmt->debug_typevalue(typeinfo);
}
/* Proecess an EQU directive */
static void define_equ(insn * instruction)
{
@ -1226,7 +1291,7 @@ int64_t insn_size(insn *instruction)
add_asp(instruction);
m = find_match(&temp, instruction);
if (m != MOK_GOOD)
if (m < MOK_GOOD)
return -1; /* No match */
isize = calcsize(instruction, temp);
@ -1570,6 +1635,8 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
if (bits != 64 || (pfx && pfx != P_A64))
return -1;
else
ins->prefixes[PPS_ASIZE] = P_A64;
break;
}
@ -1724,14 +1791,17 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
*! any time for any number of reasons.
*/
/* The bytecode ends in 0, so opx points to operand 0 */
if (!absolute_op(opx))
if (!absolute_op(opx)) {
nasm_nonfatal("attempt to reserve non-constant"
" quantity of BSS space");
else if (opx->opflags & OPFLAG_FORWARD)
nasm_warn(WARN_FORWARD, "forward reference in RESx "
"can have unpredictable results");
else
length += opx->offset * resb_bytes(ins->opcode);
" quantity of memory");
return -1;
} else if (opx->opflags & OPFLAG_FORWARD) {
nasm_warn(WARN_FORWARD, "forward reference in %s "
"can have unpredictable results",
nasm_insn_names[ins->opcode]);
}
length += opx->offset * resb_bytes(ins->opcode);
break;
case 0341:
@ -1785,7 +1855,26 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
break;
case 0370:
break;
case 0371:
if (ins->prefixes[PPS_REP] == P_BND) {
/* jmp short (opcode eb) cannot be used with bnd prefix. */
ins->prefixes[PPS_REP] = P_none;
/*!
*!prefix-bnd [on] invalid \c{BND} prefix
*!=bnd
*! warns about ineffective use of the \c{BND} prefix when the
*! \c{JMP} instruction is converted to the \c{SHORT} form.
*! This should be extremely rare since the short \c{JMP} only
*! is applicable to jumps inside the same module, but if
*! it is legitimate, it may be necessary to use
*! \c{bnd jmp dword}.
*/
if (!ins->dummy)
nasm_warn(WARN_PREFIX_BND|ERR_PASS2 ,
"jmp short does not init bnd regs - bnd prefix dropped");
}
break;
case 0373:
@ -2417,11 +2506,6 @@ static void gencode(struct out_data *data, insn *ins)
break;
case4(0254):
if (absolute_op(opx) &&
(int32_t)opx->offset != (int64_t)opx->offset) {
nasm_warn(ERR_PASS2|WARN_NUMBER_OVERFLOW,
"signed dword immediate exceeds bounds");
}
out_imm(data, opx, 4, OUT_SIGNED);
break;
@ -2649,7 +2733,7 @@ static void gencode(struct out_data *data, insn *ins)
out_imm(data, opy, ins->ea.bytes,
(asize > ins->ea.bytes)
? OUT_SIGNED : OUT_WRAP);
? OUT_SIGNED|OUT_NOWARN : OUT_WRAP|OUT_NOWARN);
overflow = overflow_general(opy->offset, asize) ||
sext(opy->offset, ins->addr_size) !=
@ -2658,7 +2742,7 @@ static void gencode(struct out_data *data, insn *ins)
}
if (overflow)
warn_overflow(ins->ea.bytes, NULL, " displacement");
warn_overflow(ins->ea.bytes, NULL, "displacement");
}
break;
@ -2755,10 +2839,9 @@ static enum match_result find_match(const struct itemplate **tempp,
{
const int bits = instruction->bits;
const struct itemplate *temp;
const struct itemplate *best = NULL;
enum match_result m, merr;
opflags_t xsizeflags[MAX_OPERANDS];
bool opsizemissing = false;
int i;
int this_good;
int rex = instruction->prefixes[PPS_REX];
/* Impossible encoding request? */
@ -2767,81 +2850,28 @@ static enum match_result find_match(const struct itemplate **tempp,
return MERR_ENCMISMATCH;
}
for (i = 0; i < instruction->operands; i++)
xsizeflags[i] = instruction->oprs[i].xsize;
merr = MERR_INVALOP;
best = NULL;
this_good = 0;
for (temp = nasm_instructions[instruction->opcode];
temp->opcode != I_none; temp++) {
m = matches(temp, instruction);
if (m == MOK_JUMP) {
if (jmp_match(instruction, temp))
m = MOK_GOOD;
else
m = MERR_INVALOP;
} else if (m == MERR_OPSIZEMISSING && !itemp_has(temp, IF_SX)) {
/*
* Missing operand size and a candidate for fuzzy matching...
*/
for (i = 0; i < temp->operands; i++) {
if (instruction->oprs[i].bcast)
xsizeflags[i] |= temp->deco[i] & BRSIZE_MASK;
else
xsizeflags[i] |= temp->opd[i] & SIZE_MASK;
}
opsizemissing = true;
}
if (m > merr)
if (m > merr) {
best = temp;
merr = m;
if (merr == MOK_GOOD)
goto done;
}
/* No match, but see if we can get a fuzzy operand size match... */
if (!opsizemissing)
goto done;
for (i = 0; i < instruction->operands; i++) {
struct operand *op = &instruction->oprs[i];
/*
* We ignore extrinsic operand sizes on registers, so we should
* never try to fuzzy-match on them. This also resolves the case
* when we have e.g. "xmmrm128" in two different positions.
*/
if (is_class(REGISTER, op->type))
continue;
/* This tests if xsizeflags[i] has more than one bit set */
if ((xsizeflags[i] & (xsizeflags[i]-1)))
goto done; /* No luck */
if (op->bcast) {
op->decoflags |= xsizeflags[i];
op->type |= brsize_to_size(xsizeflags[i]);
} else {
op->type |= xsizeflags[i]; /* Set the size */
this_good = 1;
if (merr == MOK_GOOD)
goto done; /* Not fuzzy at all */
} else if (m == merr) {
this_good++;
}
}
/* Try matching again... */
for (temp = nasm_instructions[instruction->opcode];
temp->opcode != I_none; temp++) {
m = matches(temp, instruction);
if (m == MOK_JUMP) {
if (jmp_match(instruction, temp))
m = MOK_GOOD;
else
m = MERR_INVALOP;
}
if (m > merr)
merr = m;
if (merr == MOK_GOOD)
goto done;
}
if (merr >= MOK_FIRST)
merr = MOK_GOOD; /* Fuzzy match but valid */
done:
*tempp = temp;
*tempp = best;
return merr;
}
@ -2864,20 +2894,23 @@ static uint8_t get_broadcast_num(opflags_t opflags, opflags_t brsize)
}
static enum match_result matches(const struct itemplate * const itemp,
const insn *instruction)
const insn * const ins)
{
const int bits = instruction->bits;
bool opsizemissing = false;
const int bits = ins->bits;
int i;
const int oprs = instruction->operands;
const int oprs = ins->operands;
unsigned int arflag;
unsigned int armask, smmask;
bool if_anysize, if_sx;
opflags_t arsize, smsize;
opflags_t size[MAX_OPERANDS];
opflags_t isize[MAX_OPERANDS]; /* Adjusted instruction operand sizes */
opflags_t tsize[MAX_OPERANDS]; /* Adjusted template operand sizes */
opflags_t itype[MAX_OPERANDS]; /* Adjusted instruction flags */
/*
* Check the opcode
*/
if (itemp->opcode != instruction->opcode)
if (itemp->opcode != ins->opcode)
return MERR_INVALOP;
/*
@ -2889,7 +2922,7 @@ static enum match_result matches(const struct itemplate * const itemp,
/*
* Is it legal?
*/
if (unlikely(instruction->opt & OPTIM_STRICT_INSTR)) {
if (unlikely(ins->opt & OPTIM_STRICT_INSTR)) {
if (itemp_has(itemp, IF_OPT))
return MERR_INVALOP;
}
@ -2897,7 +2930,7 @@ static enum match_result matches(const struct itemplate * const itemp,
/*
* {rex/vexn/evex} available?
*/
switch (instruction->prefixes[PPS_REX]) {
switch (ins->prefixes[PPS_REX]) {
case P_EVEX:
if (!itemp_has(itemp, IF_EVEX))
return MERR_ENCMISMATCH;
@ -2940,133 +2973,35 @@ static enum match_result matches(const struct itemplate * const itemp,
}
/*
* First, cursory operand filtering
* First, cursory operand filtering and initialize
* itype[] and isize[]
*/
for (i = 0; i < oprs; i++) {
const struct operand * const op = &instruction->oprs[i];
if (op->type & ~itemp->opd[i] & (COLON | TO))
const struct operand * const op = &ins->oprs[i];
const opflags_t ttype = itemp->opd[i];
isize[i] = op->type & SIZE_MASK;
itype[i] = op->type - isize[i];
if (op->type & ~ttype & (COLON | TO))
return MERR_INVALOP;
if (op->iflag && !itemp_has(itemp, op->iflag))
return MERR_WRONGIMM;
}
/*
* Process size flags
*/
switch (itemp_smask(itemp)) {
case IF_GENBIT(IF_SB):
arsize = BITS8;
break;
case IF_GENBIT(IF_SW):
arsize = BITS16;
break;
case IF_GENBIT(IF_SD):
arsize = BITS32;
break;
case IF_GENBIT(IF_SQ):
arsize = BITS64;
break;
case IF_GENBIT(IF_SO):
arsize = BITS128;
break;
case IF_GENBIT(IF_SY):
arsize = BITS256;
break;
case IF_GENBIT(IF_SZ):
arsize = BITS512;
break;
case IF_GENBIT(IF_ANYSIZE):
arsize = SIZE_MASK;
break;
case IF_GENBIT(IF_SIZE):
switch (bits) {
case 16:
arsize = BITS16;
break;
case 32:
arsize = BITS32;
break;
case 64:
arsize = BITS64;
break;
default:
arsize = 0;
break;
}
break;
default:
arsize = 0;
break;
}
/* Flags for which the AR and SM flags apply */
armask = arsize ? itemp_arx(itemp) : 0;
smmask = itemp_smx(itemp);
/* Look for any sized operands among the size-match ones */
smsize = 0;
for (i = 0; i < oprs; i++) {
if (smmask & (1 << i)) {
opflags_t osz = instruction->oprs[i].type & SIZE_MASK;
if (osz) {
if (smsize && smsize != osz) {
/* Operands need to match, and they don't */
return MERR_OPSIZEMISMATCH;
}
smsize = osz;
}
}
}
if (!smsize)
smmask = 0;
/* Give unsized operands a size */
for (i = 0; i < oprs; i++) {
if (smmask & (1 << i))
size[i] = smsize;
else if (armask & (1 << i))
size[i] = arsize;
else
size[i] = 0;
}
/*
* Check that the operand flags all match up,
* it's a bit tricky so lets be verbose:
*
* 1) Find out the size of operand. If instruction
* doesn't have one specified -- we're trying to
* guess it either from template (IF_S* flag) or
* from code bits.
*
* 2) If template operand do not match the instruction OR
* template has an operand size specified AND this size differ
* from which instruction has (perhaps we got it from code bits)
* we are:
* a) Check that only size of instruction and operand is differ
* other characteristics do match
* b) Perhaps it's a register specified in instruction so
* for such a case we just mark that operand as "size
* missing" and this will turn on fuzzy operand size
* logic facility (handled by a caller)
* Compare various operand flags that don't depend on sizes,
* and compute the "true" template operand sizes.
*/
for (i = 0; i < oprs; i++) {
opflags_t type = instruction->oprs[i].type;
decoflags_t deco = instruction->oprs[i].decoflags;
decoflags_t ideco = itemp->deco[i];
bool is_broadcast = deco & BRDCAST_MASK;
uint8_t brcast_num = 0;
opflags_t template_opsize, insn_opsize;
const opflags_t ttype = itemp->opd[i];
const decoflags_t deco = ins->oprs[i].decoflags;
const decoflags_t ideco = itemp->deco[i];
const bool is_broadcast = deco & BRDCAST_MASK;
if (!(type & SIZE_MASK))
type |= size[i];
insn_opsize = type & SIZE_MASK;
if (!is_broadcast) {
template_opsize = itemp->opd[i] & SIZE_MASK;
tsize[i] = ttype & SIZE_MASK;
} else {
decoflags_t deco_brsize = ideco & BRSIZE_MASK;
const decoflags_t ideco_brsize = ideco & BRSIZE_MASK;
if (~ideco & BRDCAST_MASK)
return MERR_BRNOTHERE;
@ -3075,46 +3010,179 @@ static enum match_result matches(const struct itemplate * const itemp,
* when broadcasting, the element size depends on
* the instruction type. decorator flag should match.
*/
if (deco_brsize) {
template_opsize = brsize_to_size(deco_brsize);
/* calculate the proper number : {1to<brcast_num>} */
brcast_num = get_broadcast_num(itemp->opd[i], template_opsize);
} else {
template_opsize = 0;
}
if (ideco_brsize)
tsize[i] = brsize_to_size(ideco_brsize);
else
tsize[i] = 0; /* Is this even possible? */
}
/* Check to see if we need to coerce an explicitly sized immediate */
if (unlikely(itype[i] & ttype & IMMEDIATE)) {
/*
* If this is an *explicitly* sized immediate,
* allow it to match an extending pattern.
*/
switch (isize[i]) {
case BITS8:
if (ttype & BYTEEXTMASK) {
isize[i] = tsize[i];
itype[i] |= BYTEEXTMASK;
}
break;
case BITS32:
if (ttype & DWORDEXTMASK)
isize[i] = tsize[i];
break;
default:
break;
}
/* MOST instructions which take an sdword64 are the only form;
* set the SDWORD flag to be strict about sdword64 matching
* (use when a true imm64 pattern exists.)
*/
if (!itemp_has(itemp, IF_SDWORD))
itype[i] |= SDWORD;
}
if (ttype & ~itype[i] & ~(SIZE_MASK|REGSET_MASK))
return MERR_INVALOP;
if (~ideco & deco & OPMASK_MASK)
return MERR_MASKNOTHERE;
if (~ideco & deco & (Z_MASK|STATICRND_MASK|SAE_MASK))
return MERR_DECONOTHERE;
if (itemp->opd[i] & ~type & ~(SIZE_MASK|REGSET_MASK))
return MERR_INVALOP;
if (~itemp->opd[i] & type & REGSET_MASK)
return (itemp->opd[i] & REGSET_MASK)
if (~ttype & itype[i] & REGSET_MASK)
return (ttype & REGSET_MASK)
? MERR_REGSETSIZE : MERR_REGSET;
}
if (template_opsize) {
if (template_opsize != insn_opsize) {
if (insn_opsize) {
return MERR_INVALOP;
} else if (!is_class(REGISTER, type)) {
/*
* Note: we don't honor extrinsic operand sizes for registers,
* so "missing operand size" for a register should be
* considered a wildcard match rather than an error.
*/
opsizemissing = true;
} else if (is_class(REG_HIGH, type) &&
instruction->prefixes[PPS_REX]) {
return MERR_ENCMISMATCH;
/*
* Process the operand sizes.
*/
arflag = itemp_smask(itemp);
nasm_static_assert(SIZE_SHIFT >= IF_SB);
nasm_static_assert((BITS8 >> SIZE_SHIFT) == 1);
arsize = (arflag & (IFM_SB|IFM_SW|IFM_SD|IFM_SQ|
IFM_ST|IFM_SO|IFM_SY|IFM_SZ))
<< (SIZE_SHIFT - IF_SB);
if (arflag & IFM_SIZE)
arsize = mode_to_op(bits);
if_anysize = itemp_has(itemp, IF_ANYSIZE);
if_sx = itemp_has(itemp, IF_SX);
/* Flags for which the AR and SM flags apply */
armask = itemp_arx(itemp);
smmask = itemp_smx(itemp);
/* Apply ARx sizes and handle size coersion */
for (i = 0; i < oprs; i++) {
const unsigned int bit = 1U << i;
if (!isize[i] && is_class(REGISTER, itype[i]))
isize[i] = tsize[i];
if (armask & bit) {
if (!isize[i] && !if_sx)
isize[i] = arsize;
}
}
/* Look the common subset for the size-matched operands */
smsize = SIZE_MASK;
if (smmask) {
unsigned int nosizemask = 0;
for (i = 0; i < oprs; i++) {
const unsigned int bit = 1U << i;
if (isize[i]) {
if (smmask & bit)
smsize &= isize[i];
} else if (!is_class(REGISTER, itype[i])) {
nosizemask |= bit;
}
}
if (!smsize) {
/* No valid common set */
return MERR_OPSIZEMISMATCH;
} else if (!(smmask & ~nosizemask)) {
/*
* No sized or register operand in the whole set...
*/
return MERR_OPSIZEMISSING;
}
}
/*
* Check that the operand sizes actually match,
* and look for other kinds of mismatches, e.g.
* REG_HIGH when REX is specified.
*/
for (i = 0; i < oprs; i++) {
const opflags_t type = itype[i];
const decoflags_t deco = ins->oprs[i].decoflags;
const decoflags_t ideco = itemp->deco[i];
const bool is_broadcast = deco & BRDCAST_MASK;
const bool has_ar = (armask >> i) & 1;
const bool has_sm = (smmask >> i) & 1;
/*
* Operand sizes are considered matching at this stage
* if any one of these is true:
*
* 1. The template size is undefined.
* XXX: apply ARx|Sx flags here?
* 2. The operand size matches the template size.
* 3. There is an ARx|ANYSIZE flag in the template.
* 4. The operand size is unspecified and the
* template does not carry an ARx|SX flag.
*/
if (tsize[i]) {
if (isize[i] != tsize[i]) {
if (has_ar) {
if (if_anysize)
goto isize_ok;
if (unlikely(if_sx) && !is_class(REGISTER, itype[i]))
return MERR_OPSIZEMISMATCH;
}
} else if (is_broadcast &&
(brcast_num !=
(2U << ((deco & BRNUM_MASK) >> BRNUM_SHIFT)))) {
if (isize[i])
return MERR_OPSIZEMISMATCH;
}
isize_ok:
if (has_sm)
smsize &= tsize[i];
} else {
/*
* SX with an unsized operand means only an unsized operand
* is OK.
*/
if (unlikely(if_sx) && has_ar)
if (isize[i])
return MERR_OPSIZEMISMATCH;
}
if (is_class(REG_HIGH, type) && ins->prefixes[PPS_REX]) {
/* High registers cannot be combined with any REX type */
return MERR_INVALOP;
}
if (is_broadcast) {
/* calculate the proper number : {1to<brcast_num>} */
const decoflags_t ideco_brsize = ideco & BRSIZE_MASK;
unsigned int brcast_num = 0;
if (ideco_brsize)
brcast_num = get_broadcast_num(itemp->opd[i], tsize[i]);
if (brcast_num != (2U << ((deco & BRNUM_MASK) >> BRNUM_SHIFT))) {
/*
* broadcasting opsize matches but the number of repeated memory
* element does not match.
@ -3124,18 +3192,17 @@ static enum match_result matches(const struct itemplate * const itemp,
return MERR_BRNUMMISMATCH;
}
}
}
if (opsizemissing)
return MERR_OPSIZEMISSING;
}
/*
* Check operand sizes
* Make sure that our size match set, if any, did not get exhausted,
* and contains exactly one valid combination still...
*/
for (i = 0; i < oprs; i++) {
if (!(itemp->opd[i] & SIZE_MASK) &&
(instruction->oprs[i].type & SIZE_MASK & ~size[i]))
if (smmask) {
if (!smsize)
return MERR_OPSIZEMISMATCH;
else if (!is_power2(smsize))
return MERR_OPSIZEMISSING;
}
/*
@ -3154,48 +3221,48 @@ static enum match_result matches(const struct itemplate * const itemp,
* If we have a HLE prefix, look for the NOHLE flag
*/
if (itemp_has(itemp, IF_NOHLE) &&
(has_prefix(instruction, PPS_REP, P_XACQUIRE) ||
has_prefix(instruction, PPS_REP, P_XRELEASE)))
(has_prefix(ins, PPS_REP, P_XACQUIRE) ||
has_prefix(ins, PPS_REP, P_XRELEASE)))
return MERR_BADHLE;
/*
* {nf} or {zu} prefixes used? Must be permitted.
*/
if (has_prefix(instruction, PPS_NF, P_NF)) {
if (has_prefix(ins, PPS_NF, P_NF)) {
if (!itemp_has(itemp, IF_NF) &&
(itemp_has(itemp, IF_FL) ||
(instruction->opt & OPTIM_STRICT_INSTR)))
(ins->opt & OPTIM_STRICT_INSTR)))
return MERR_BADNF;
} else if (itemp_has(itemp, IF_NF_R)) {
return MERR_REQNF;
}
if (has_prefix(instruction, PPS_ZU, P_ZU)) {
if (has_prefix(ins, PPS_ZU, P_ZU)) {
if (!itemp_has(itemp, IF_ZU))
return MERR_BADZU;
else if (!(instruction->oprs[0].type & REGISTER))
else if (!(ins->oprs[0].type & REGISTER))
return MERR_MEMZU;
}
/*
* Check if special handling needed for Jumps
*/
if ((itemp->code[0] & ~1) == 0370)
return MOK_JUMP;
/*
* Check if BND prefix is allowed.
* Other 0xF2 (REPNE/REPNZ) prefix is prohibited.
*/
if (!itemp_has(itemp, IF_BND) &&
(has_prefix(instruction, PPS_REP, P_BND) ||
has_prefix(instruction, PPS_REP, P_NOBND)))
(has_prefix(ins, PPS_REP, P_BND) ||
has_prefix(ins, PPS_REP, P_NOBND)))
return MERR_BADBND;
else if (itemp_has(itemp, IF_BND) &&
(has_prefix(instruction, PPS_REP, P_REPNE) ||
has_prefix(instruction, PPS_REP, P_REPNZ)))
(has_prefix(ins, PPS_REP, P_REPNE) ||
has_prefix(ins, PPS_REP, P_REPNZ)))
return MERR_BADREPNE;
/*
* Check if special handling needed for relaxable jump
*/
if (itemp_has(itemp, IF_JMP_RELAX))
return jmp_match(itemp, ins);
return MOK_GOOD;
}

View file

@ -53,4 +53,31 @@ void process_insn(insn *instruction);
bool process_directives(char *);
void process_pragma(char *);
/* Is this a compile-time absolute constant? */
static inline bool op_compile_abs(const struct operand * const op)
{
if (op->opflags & OPFLAG_UNKNOWN)
return true; /* Be optimistic in pass 1 */
if (op->opflags & OPFLAG_RELATIVE)
return false;
if (op->wrt != NO_SEG)
return false;
return op->segment == NO_SEG;
}
/* Is this a compile-time relative constant? */
static inline bool op_compile_rel(const insn * const ins,
const struct operand * const op)
{
if (op->opflags & OPFLAG_UNKNOWN)
return true; /* Be optimistic in pass 1 */
if (!(op->opflags & OPFLAG_RELATIVE))
return false;
if (op->wrt != NO_SEG) /* Is this correct?! */
return false;
return op->segment == ins->loc.segment;
}
#endif

View file

@ -1565,10 +1565,9 @@ static void forward_refs(insn *instruction)
int i;
struct forwrefinfo *fwinf;
instruction->forw_ref = false;
/* Don't bother for -O1 */
if (instruction->opt & OPTIM_DISABLE_FWREF)
return; /* For -O0 don't bother */
return;
if (!forwref)
return;
@ -1576,7 +1575,6 @@ static void forward_refs(insn *instruction)
if (forwref->lineno != globallineno)
return;
instruction->forw_ref = true;
do {
instruction->oprs[forwref->operand].opflags |= OPFLAG_FORWARD;
forwref = saa_rstruct(forwrefs);
@ -1999,13 +1997,17 @@ struct nasm_errhold *nasm_error_hold_push(void)
return eh;
}
void nasm_error_hold_pop(struct nasm_errhold *eh, bool issue)
/* Pop an error hold. Returns the highest severity issued or dropped. */
errflags nasm_error_hold_pop(struct nasm_errhold *eh, bool issue)
{
struct nasm_errtext *et, *etmp;
errflags worst = 0;
/* Allow calling with a null argument saying no hold in the first place */
/*
* Allow calling with a null argument saying no hold in the first place.
*/
if (!eh)
return;
return worst;
/* This *must* be the current top of the errhold stack */
nasm_assert(eh == errhold_stack);
@ -2018,18 +2020,25 @@ void nasm_error_hold_pop(struct nasm_errhold *eh, bool issue)
eh->up->tail = eh->tail;
} else {
/* Issue errors */
list_for_each_safe(et, etmp, eh->head)
list_for_each_safe(et, etmp, eh->head) {
if (et->true_type > worst)
worst = et->true_type;
nasm_issue_error(et);
}
}
} else {
/* Free the list, drop errors */
list_for_each_safe(et, etmp, eh->head)
list_for_each_safe(et, etmp, eh->head) {
if (et->true_type > worst)
worst = et->true_type;
nasm_free_error(et);
}
}
}
errhold_stack = eh->up;
nasm_free(eh);
return worst;
}
/**

View file

@ -659,28 +659,51 @@ static bool add_prefix(insn *result)
}
/* Set value-specific immediate flags. */
static opflags_t imm_flags(int64_t n, opflags_t flags, enum optimization opt)
static inline opflags_t set_imm_flags(struct operand *op, enum optimization opt)
{
if (n == 1)
flags |= UNITY;
const bool strict = (op->type & STRICT) || (opt & OPTIM_STRICT_OPER);
const int64_t n = op->offset;
/* Allow FOURBITS matching for negative values, so things like ~0 work */
if (n >= -16 && n <= 15)
flags |= FOURBITS;
if (!(op->type & IMMEDIATE))
return op->type;
if ((flags & STRICT) || (opt & OPTIM_STRICT_OPER))
return flags;
if (op->opflags & OPFLAG_UNKNOWN) {
/* Be optimistic in pass 1 */
if (!strict || !(op->type & SIZE_MASK))
op->type |= UNITY|FOURBITS;
if (!strict)
op->type |= SBYTEDWORD|SBYTEWORD|UDWORD|SDWORD;
return op->type;
}
if (!(op->opflags & OPFLAG_SIMPLE))
return op->type;
if (!strict || !(op->type & SIZE_MASK)) {
if (n == 1)
op->type |= UNITY;
/*
* Allow FOURBITS matching for negative values, so things
* like ~0 work
*/
if (n >= -16 && n <= 15)
op->type |= FOURBITS;
}
if (strict)
return op->type;
if ((int32_t)n == (int8_t)n)
flags |= SBYTEDWORD;
op->type |= SBYTEDWORD;
if ((int16_t)n == (int8_t)n)
flags |= SBYTEWORD;
op->type |= SBYTEWORD;
if ((uint64_t)n == (uint32_t)n)
flags |= UDWORD;
op->type |= UDWORD;
if ((int64_t)n == (int32_t)n)
flags |= SDWORD;
op->type |= SDWORD;
return flags;
return op->type;
}
insn *parse_line(char *buffer, insn *result, const int bits)
@ -788,9 +811,11 @@ restart_parse:
*/
result->opcode = I_RESB;
result->operands = 1;
result->oprs[0].type = imm_flags(0, IMM_NORMAL, 0);
result->oprs[0].type = IMM_NORMAL;
result->oprs[0].opflags = OPFLAG_SIMPLE;
result->oprs[0].offset = 0;
result->oprs[0].segment = result->oprs[0].wrt = NO_SEG;
set_imm_flags(&result->oprs[0], result->opt);
}
} else if (!first) {
nasm_nonfatal("instruction expected");
@ -914,13 +939,13 @@ restart_parse:
* without requiring a post-comma.
*/
if (i == TOKEN_BRCCONST) {
op->type |= imm_flags(tokval.t_integer, IMMEDIATE, result->opt);
op->opflags = 0;
op->type = IMMEDIATE; /* But not IMM_NORMAL! */
op->opflags = OPFLAG_SIMPLE;
op->offset = tokval.t_integer;
op->segment = NO_SEG;
op->wrt = NO_SEG;
op->iflag = tokval.t_inttwo;
set_imm_flags(op, result->opt);
i = stdscan(NULL, &tokval);
if (i != ',')
stdscan_pushback(&tokval);
@ -1048,9 +1073,6 @@ restart_parse:
value = evaluate(stdscan, NULL, &tokval,
&op->opflags, critical, &hints);
i = tokval.t_type;
if (op->opflags & OPFLAG_FORWARD) {
result->forw_ref = true;
}
if (!value) /* Error in evaluator */
goto fail;
@ -1215,12 +1237,7 @@ restart_parse:
op->segment = NO_SEG; /* don't care again */
op->wrt = NO_SEG; /* still don't care */
if(!(op->type & STRICT) &&
!(result->opt & OPTIM_STRICT_OPER)) {
/* Be optimistic */
op->type |=
UNITY | SBYTEWORD | SBYTEDWORD | UDWORD | SDWORD;
}
set_imm_flags(op, result->opt);
} else if (is_reloc(value)) { /* it's immediate */
uint64_t n = reloc_value(value);
@ -1228,10 +1245,12 @@ restart_parse:
op->offset = n;
op->segment = reloc_seg(value);
op->wrt = reloc_wrt(value);
op->opflags |= is_self_relative(value) ? OPFLAG_RELATIVE : 0;
if (is_self_relative(value))
op->opflags |= OPFLAG_RELATIVE;
if (is_simple(value))
op->type = imm_flags(n, op->type, result->opt);
op->opflags |= OPFLAG_SIMPLE;
set_imm_flags(op, result->opt);
} else if (value->type == EXPR_RDSAE) {
/*
* it's not an operand but a rounding or SAE decorator.

View file

@ -135,12 +135,17 @@ void reset_warnings(void);
* If "issue" is true the errors are committed (or promoted to the next
* higher stack level), if false then they are discarded.
*
* Return the highest severity level issued or discarded; note that if
* promoted, the severity level will be reported at the time the
* messages are issued, when the top level stack is popped. Fix this if
* this ever becomes a problem, but it would come at a cost.
*
* Errors stronger than ERR_NONFATAL cannot be held.
*/
struct nasm_errhold;
typedef struct nasm_errhold *errhold;
errhold nasm_error_hold_push(void);
void nasm_error_hold_pop(errhold hold, bool issue);
errflags nasm_error_hold_pop(errhold hold, bool issue);
/* Should be included from within error.h only */
#include "warnings.h"

View file

@ -71,7 +71,8 @@ static inline int iflag_cmp(const iflag_t *a, const iflag_t *b)
IF_GEN_HELPER(xor, ^)
/* Some helpers which are to work with predefined masks */
#define IF_SMASK (IFM_SB|IFM_SW|IFM_SD|IFM_SQ|IFM_SO|IFM_SY|IFM_SZ|IFM_SIZE|IFM_ANYSIZE)
#define IF_SMASK (IFM_SB|IFM_SW|IFM_SD|IFM_SQ|IFM_ST|IFM_SO|\
IFM_SY|IFM_SZ|IFM_SIZE|IFM_ANYSIZE|IFM_SX)
#define IF_ARMASK (IFM_AR0|IFM_AR1|IFM_AR2|IFM_AR3|IFM_AR4)
#define IF_SMMASK (IFM_SM0|IFM_SM1|IFM_SM2|IFM_SM3|IFM_SM4)

View file

@ -123,7 +123,8 @@ enum out_flags {
OUT_WRAP = 0, /* Undefined signedness (wraps) */
OUT_SIGNED = 1, /* Value is signed */
OUT_UNSIGNED = 2, /* Value is unsigned */
OUT_SIGNMASK = 3 /* Mask for signedness bits */
OUT_SIGNMASK = 3, /* Mask for signedness bits */
OUT_NOWARN = 4 /* Don't warn on overflow (already done?) */
};
/*
@ -156,6 +157,7 @@ struct out_data {
int32_t twrt; /* Relocation with respect to */
int64_t relbase; /* Relative base for OUT_RELADDR */
struct src_location where; /* Source file and line */
const char *what; /* Additional description, e.g. "immediate" */
};
/*
@ -691,6 +693,7 @@ typedef struct operand { /* operand to an instruction */
(always a forward reference also) */
#define OPFLAG_RELATIVE 8 /* operand is self-relative, e.g. [foo - $]
where foo is not in the current segment */
#define OPFLAG_SIMPLE 16 /* operand is a simple expression */
enum extop_type { /* extended operand types */
EOT_NOTHING = 0,
@ -842,8 +845,8 @@ typedef struct insn { /* an instruction itself */
extop *eops; /* extended operands */
int eops_float; /* true if DD and floating */
int32_t times; /* repeat count (TIMES prefix) */
bool forw_ref; /* is there a forward reference? */
bool rex_done; /* REX prefix emitted? */
bool dummy; /* not a real instruction, no errors */
uint8_t bits; /* Execution mode (16, 32, 64) */
uint8_t op_size; /* operand size */
uint8_t addr_size; /* address size */

View file

@ -39,7 +39,7 @@
#define NASM_OPFLAGS_H
#include "compiler.h"
#include "tables.h" /* for opflags_t and nasm_reg_flags[] */
#include "tables.h"
#include "regs.h"
/*
@ -73,7 +73,7 @@
*
* Bits: 4 - 6
*/
#define MODIFIER_SHIFT (4)
#define MODIFIER_SHIFT (OPTYPE_SHIFT + OPTYPE_BITS)
#define MODIFIER_BITS (3)
#define MODIFIER_MASK OP_GENMASK(MODIFIER_BITS, MODIFIER_SHIFT)
#define GEN_MODIFIER(bit) OP_GENBIT(bit, MODIFIER_SHIFT)
@ -83,7 +83,7 @@
*
* Bits: 7 - 17
*/
#define REG_CLASS_SHIFT (7)
#define REG_CLASS_SHIFT (MODIFIER_SHIFT + MODIFIER_BITS)
#define REG_CLASS_BITS (11)
#define REG_CLASS_MASK OP_GENMASK(REG_CLASS_BITS, REG_CLASS_SHIFT)
#define GEN_REG_CLASS(bit) OP_GENBIT(bit, REG_CLASS_SHIFT)
@ -93,7 +93,7 @@
*
* Bits: 18 - 25
*/
#define SUBCLASS_SHIFT (18)
#define SUBCLASS_SHIFT (REG_CLASS_SHIFT + REG_CLASS_BITS)
#define SUBCLASS_BITS (8)
#define SUBCLASS_MASK OP_GENMASK(SUBCLASS_BITS, SUBCLASS_SHIFT)
#define GEN_SUBCLASS(bit) OP_GENBIT(bit, SUBCLASS_SHIFT)
@ -104,7 +104,7 @@
*
* Bits: 26 - 32
*/
#define SPECIAL_SHIFT (26)
#define SPECIAL_SHIFT (SUBCLASS_SHIFT + SUBCLASS_BITS)
#define SPECIAL_BITS (7)
#define SPECIAL_MASK OP_GENMASK(SPECIAL_BITS, SPECIAL_SHIFT)
#define GEN_SPECIAL(bit) OP_GENBIT(bit, SPECIAL_SHIFT)
@ -114,7 +114,7 @@
*
* Bits: 33 - 44
*/
#define SIZE_SHIFT (33)
#define SIZE_SHIFT (SPECIAL_SHIFT + SPECIAL_BITS)
#define SIZE_BITS (12)
#define SIZE_MASK OP_GENMASK(SIZE_BITS, SIZE_SHIFT)
#define GEN_SIZE(bit) OP_GENBIT(bit, SIZE_SHIFT)
@ -124,26 +124,32 @@
*
* Bits: 45 - 49
*/
#define REGSET_SHIFT (45)
#define REGSET_SHIFT (SIZE_SHIFT + SIZE_BITS)
#define REGSET_BITS (5)
#define REGSET_MASK OP_GENMASK(REGSET_BITS, REGSET_SHIFT)
#define GEN_REGSET(bit) OP_GENBIT(bit, REGSET_SHIFT)
/*
* Remaining bits
*/
#define OPFLAGS_USED_BITS (REGSET_SHIFT + REGSET_BITS)
#define OPFLAGS_UNUSED_BITS (64-OPFLAGS_USED_BITS)
/*
* Bits distribution (counted from 0)
*
* 6 5 4 3 2 1
* 3210987654321098765432109876543210987654321098765432109876543210
* |
* | dword bound
*
* ............................................................1111 optypes
* .........................................................111.... modifiers
* ..............................................11111111111....... register classes
* ......................................11111111.................. subclasses
* |
* |dword boundary
* |
* ...............................|............................1111 optypes
* ...............................|.........................111.... modifiers
* ...............................|..............11111111111....... register classes
* ...............................|......11111111.................. subclasses
* ...............................1111111.......................... specials
* ...................111111111111................................. sizes
* ..............11111............................................. regset count
* ...................111111111111|................................ sizes
* ..............11111............|............................... regset count
*/
#define REGISTER GEN_OPTYPE(0) /* register number in 'basereg' */
@ -184,6 +190,28 @@
#define REG_CLASS_VECTOR (REG_CLASS_RM_XMM|REG_CLASS_RM_YMM|\
REG_CLASS_RM_ZMM|REG_CLASS_RM_TMM)
/*
* The bitfield and the union are handy for
* debugging, but are not portable in general.
*/
#if defined(__GNUC__) && defined(WORDS_LITTLEENDIAN)
struct opflag_bits {
unsigned int type : OPTYPE_BITS;
unsigned int mod : MODIFIER_BITS;
unsigned int regclass : REG_CLASS_BITS;
unsigned int subclass : SUBCLASS_BITS;
unsigned int special : SPECIAL_BITS;
unsigned int size : SIZE_BITS;
unsigned int regset : REGSET_BITS;
unsigned int pad : OPFLAGS_UNUSED_BITS;
} __attribute__((__packed__));
union opflags {
opflags_t v;
struct opflag_bits f;
};
#endif
/* Helper function to test for a value matching a class */
static inline bool is_class(opflags_t class, opflags_t op)
{
@ -346,6 +374,9 @@ static inline bool is_reg_class(opflags_t class, int reg)
#define UDWORD (GEN_SUBCLASS(5) | IMMEDIATE) /* operand is in the range 0..0xFFFFFFFF */
#define FOURBITS (GEN_SUBCLASS(6) | IMMEDIATE) /* operand is in the range 0-15 */
#define BYTEEXTMASK (GEN_SUBCLASS(2) | GEN_SUBCLASS(3))
#define DWORDEXTMASK (GEN_SUBCLASS(4) | GEN_SUBCLASS(5))
/* Register set sizes */
#define RS2 GEN_REGSET(0)
#define RS4 GEN_REGSET(1)

View file

@ -1,15 +1,21 @@
;Testname=test; Arguments=-fbin -oandbyte.bin; Files=stdout stderr andbyte.bin
;Testname=otest; Arguments=-Ox -fbin -oandbyte.bin; Files=stdout stderr andbyte.bin
bits 16
add sp, byte -0x10
add sp, -0x10
add sp, word -0x10
adc sp, byte -0x10
adc sp, -0x10
adc sp, word -0x10
and sp, byte -0x10
and sp, -0x10
and sp, word -0x10
sbb sp, byte -0x10
sbb sp, -0x10
sbb sp, word -0x10
sub sp, byte -0x10
sub sp, -0x10
sub sp, word -0x10

View file

@ -1,16 +1,10 @@
./travis/test/imm64.asm:24: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:24: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:25: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:26: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:27: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:27: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:28: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:28: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:52: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:52: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:53: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:54: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:55: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:55: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:56: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:56: warning: signed dword exceeds bounds [-w+number-overflow]

View file

@ -1,16 +1,10 @@
./travis/test/imm64.asm:24: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:24: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:25: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:26: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:27: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:27: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:28: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:28: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:52: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:52: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:53: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:54: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:55: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:55: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:56: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:56: warning: signed dword exceeds bounds [-w+number-overflow]

Binary file not shown.

View file

@ -1,16 +1,10 @@
./travis/test/imm64.asm:24: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:24: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:25: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:26: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:27: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:27: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:28: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:28: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:52: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:52: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:53: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:54: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:55: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:55: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:56: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imm64.asm:56: warning: signed dword exceeds bounds [-w+number-overflow]

Binary file not shown.

View file

@ -4,7 +4,5 @@
./travis/test/immwarn.asm:32: warning: word exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:37: warning: signed byte exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:49: warning: signed byte exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:75: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:75: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:79: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:89: warning: signed byte exceeds bounds [-w+number-overflow]

View file

@ -4,8 +4,6 @@
./travis/test/immwarn.asm:32: warning: word exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:37: warning: signed byte exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:49: warning: signed byte exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:75: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:75: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:79: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:79: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/immwarn.asm:89: warning: signed byte exceeds bounds [-w+number-overflow]

View file

@ -38,18 +38,12 @@
./travis/test/imul.asm:42: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: dword exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:43: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:45: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:45: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed byte exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:46: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:47: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:47: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:48: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:48: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: word exceeds bounds [-w+number-overflow]
@ -60,8 +54,6 @@
./travis/test/imul.asm:53: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed byte exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:54: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed dword immediate exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:56: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed dword exceeds bounds [-w+number-overflow]
./travis/test/imul.asm:56: ... from macro `test' defined here
./travis/test/imul.asm:113: warning: signed byte exceeds bounds [-w+number-overflow]

View file

@ -1,5 +1,9 @@
#!/usr/bin/perl
#
# Preprocess the instruction pattern file.
#
# Generate some common repeated patterns here.
#
# Tag instructions which set the flags, and tag instructions
# which already do upper-zeroing.
#
@ -9,6 +13,82 @@
use integer;
use strict;
# Common patterns for the basic 8 arithmetric functions
sub mac_arith {
my @l;
my $cnt = 0;
foreach my $op (@_) {
my $o0 = sprintf("%02x", ($cnt << 3)+0);
my $o1 = sprintf("%02x", ($cnt << 3)+1);
my $o2 = sprintf("%02x", ($cnt << 3)+2);
my $o3 = sprintf("%02x", ($cnt << 3)+3);
my $o4 = sprintf("%02x", ($cnt << 3)+4);
my $o5 = sprintf("%02x", ($cnt << 3)+5);
my($hle,$lock,$zu) = ($op ne 'CMP') ? ('hle','LOCK','ZU') : ('','','');
push(@l, <<EOL);
$op rm8,reg8 [mr: $hle $o0 /r] 8086,SM,$lock
$op rm16,reg16 [mr: $hle o16 $o1 /r] 8086,SM,$lock
$op rm32,reg32 [mr: $hle o32 $o1 /r] 386,SM,$lock,$zu
$op rm64,reg64 [mr: $hle o64 $o1 /r] X86_64,LONG,SM,$lock,$zu
$op reg8,rm8 [rm: $o2 /r] 8086,SM
$op reg16,rm16 [rm: o16 $o3 /r] 8086,SM
$op reg32,rm32 [rm: o32 $o3 /r] 386,SM,$zu
$op reg64,rm64 [rm: o64 $o3 /r] X86_64,LONG,SM,$zu
$op reg_al,imm8 [-i: $o4 ib] 8086,SM
$op rm8,imm8 [mi: $hle 80 /$cnt ib] 8086,SM,$lock
$op rm16,sbyteword16 [mi: $hle o16 83 /$cnt ib,s] 8086,SM,$lock
$op reg_ax,imm16 [-i: o16 $o5 iw] 8086,SM
$op rm16,imm16 [mi: $hle o16 81 /$cnt iw] 8086,SM,$lock
$op rm32,sbytedword32 [mi: $hle o32 83 /$cnt ib,s] 386,SM,$lock,$zu
$op reg_eax,imm32 [-i: o32 $o5 id] 386,SM,$zu
$op rm32,imm32 [mi: $hle o32 81 /$cnt id] 386,SM,$lock,$zu
$op rm64,sbytedword64 [mi: $hle o64 83 /$cnt ib,s] X86_64,LONG,SM,$lock,$zu
$op reg_rax,sdword64 [-i: o64 $o5 id,s] X86_64,LONG,SM,$zu
$op rm64,sdword64 [mi: $hle o64 81 /$cnt id,s] X86_64,LONG,SM,$lock,$zu
$op reg8?,reg8,rm8 [vrm: evex.ndx.nf.l0.m4.o8 $o2 /r ] APX,SM
$op reg16?,reg16,rm16 [vrm: evex.ndx.nf.l0.m4.o16 $o3 /r ] APX,SM
$op reg32?,reg32,rm32 [vrm: evex.ndx.nf.l0.m4.o32 $o3 /r ] APX,SM
$op reg64?,reg64,rm64 [vrm: evex.ndx.nf.l0.m4.o64 $o3 /r ] APX,SM
$op reg8?,rm8,reg8 [vmr: evex.ndx.nf.l0.m4.o8 $o0 /r ] APX,SM
$op reg16?,rm16,reg16 [vmr: evex.ndx.nf.l0.m4.o16 $o1 /r ] APX,SM
$op reg32?,rm32,reg32 [vmr: evex.ndx.nf.l0.m4.o32 $o1 /r ] APX,SM,$zu
$op reg64?,rm64,reg64 [vmr: evex.ndx.nf.l0.m4.o64 $o1 /r ] APX,SM,$zu
$op reg8?,rm8,imm8 [vmi: evex.ndx.nf.l0.m4.o8 80 /$cnt ib ] APX,SM
$op reg16?,rm16,sbyteword16 [vmi: evex.ndx.nf.l0.m4.o16 83 /$cnt ib,s ] APX,SM,ND
$op reg16?,rm16,imm16 [vmi: evex.ndx.nf.l0.m4.o16 81 /$cnt iw ] APX,SM
$op reg32?,rm32,sbytedword32 [vmi: evex.ndx.nf.l0.m4.o32 83 /$cnt ib,s ] APX,SM,ND
$op reg32?,rm32,imm32 [vmi: evex.ndx.nf.l0.m4.o32 81 /$cnt id ] APX,SM
$op reg64?,rm64,sbytedword32 [vmi: evex.ndx.nf.l0.m4.o64 83 /$cnt ib,s ] APX,SM,ND
$op reg64?,rm64,sdword64 [vmi: evex.ndx.nf.l0.m4.o64 81 /$cnt id,s ] APX,SM
EOL
$cnt++;
}
return @l;
}
my %macros = ( 'arith' => *mac_arith );
my($infile, $outfile) = @ARGV;
my $line = 0;
sub process_macro(@) {
my $macro = shift(@_);
my $mfunc = $macros{$macro};
if (!defined($mfunc)) {
die "$0:$infile:$line: no macro named \$$macro\n";
}
return map { split(/\n/, $_) } $mfunc->(@_);
}
## XXX: fix special case: XCHG
## XXX: check: CMPSS, CMPSD
## XXX: check VEX encoded instructions that do not write
# Instructions which (possibly) change the flags
my $flaggy = '^(aa[adms]|ad[dc]|ad[co]x|aes\w*kl|and|andn|arpl|bextr|bl[sc]ic?|bl[sc]msk|bl[sc]r|\
bs[rf]|bt|bt[crs]|bzhi|clac|clc|cld|cli|clrssbsy|cmc|cmp|cmpxchg.*|da[as]|dec|div|\
@ -21,28 +101,12 @@ umwait|ver[rw]|vtestp[ps]|xadd|xor|xtest|getsec|rsm|sbb|cmps[bwdq]|hint_.*)$';
my $nozero = '^(jmp|call|bt|test|cmp|ud[012].*|ptwrite|tpause|u?monitor.*|u?mwait.*|incssp.*|\
enqcmds?|senduipi|hint_.*|jmpe|nop|inv.*|push2?p?|vmwrite|clzero|clflush|clwb|lkgs)$';
my($infile, $outfile) = @ARGV;
open(my $in, '<', $infile) or die "$0:$infile: $!\n";
open(my $out, '>', $outfile) or die "$0:$outfile: $!\n";
while (defined(my $l = <$in>)) {
chomp $l;
if ($l =~ /^\s*\;/ ||
$l !~ /^(\s*)(\S+)(\s+)(\S+)(\s+)(\S+|\[.*\])(\s+)(\S+)\s*$/) {
print $out $l, "\n";
next;
}
# Opcode = $f[1]
# Operands = $f[3]
# Encoding = $f[5]
# Flags = $f[7]
my @f = ($1, $2, $3, $4, $5, $6, $7, $8);
sub adjust_instruction_flags(@) {
my($opcode, $operands, $encoding, $flags) = @_;
# Flag-changing instructions
if ($f[7] !~ /\b(FL|NF)\b/ && $f[1] =~ /$flaggy/io) {
$f[7] .= ',FL';
if ($flags !~ /\b(FL|NF)\b/ && $opcode =~ /$flaggy/io) {
$flags .= ',FL';
}
## XXX: fix special case: XCHG
@ -51,15 +115,64 @@ while (defined(my $l = <$in>)) {
# Zero-upper. This can also be used to select the AVX forms
# to clear the upper part of a vector register.
if ($f[7] !~ /\bZU\b/ &&
(($f[5] =~ /\bE?VEXb/ && $f[3] =~ /^(xyz)mm(reg|rm)/) ||
$f[3] =~ /^((reg|rm)(32|64)|reg_[re]([abcd]x|[sb]p|[sd]i))\b/) &&
$f[1] !~ /$nozero/io) {
$f[7] .= ',ZU';
if ($flags !~ /\bZU\b/ &&
(($encoding =~ /\bE?VEXb/ && $operands =~ /^(xyz)mm(reg|rm)/) ||
$operands =~ /^((reg|rm)(32|64)|reg_[re]([abcd]x|[sb]p|[sd]i))\b/) &&
$opcode !~ /$nozero/io) {
$flags .= ',ZU';
}
return ($opcode, $operands, $encoding, $flags);
}
sub adjust_instruction(@) {
my @i = @_;
@i = adjust_instruction_flags(@i);
return @i;
}
sub process_insn($$) {
my($out, $l) = @_;
if ($l !~ /^(\s*)([^\s\;]+)(\s+)([^\s\;]+)(\s+)([^\s\;]+|\[[^\;]*\])(\s+)([^\s\;]+)(\s*(\;.*)?)$/) {
print $out $l, "\n";
return;
}
# Opcode = $f[1]
# Operands = $f[3]
# Encoding = $f[5]
# Flags = $f[7]
my @f = ($1, $2, $3, $4, $5, $6, $7, $8);
# Modify the instruction flags
($f[1], $f[3], $f[5], $f[7]) = adjust_instruction($f[1], $f[3], $f[5], $f[7]);
# Clean up stray commas in flags
$f[7] =~ s/^\+//;
$f[7] =~ s/\+$//;
$f[7] =~ s/\,\,+/,/g;
print $out @f, "\n";
}
open(my $in, '<', $infile) or die "$0:$infile: $!\n";
open(my $out, '>', $outfile) or die "$0:$outfile: $!\n";
while (defined(my $l = <$in>)) {
chomp $l;
if ($l =~ /^\$\s*([^\s\;][^\;]*?)\s*(\;.*)?$/) {
foreach my $ins (process_macro(split(/\s+/, $1))) {
process_insn($out, $ins);
}
} else {
process_insn($out, $l);
}
}
close($in);
close($out);

View file

@ -97,7 +97,7 @@ VEX/XOP prefixes are followed by the sequence:
t = 0 for VEX (C4/C5), t = 1 for XOP (8F).
\271 hlexr instruction takes XRELEASE (F3) with or without lock
\271 hlex instruction takes XRELEASE (F3) with or without lock
\272 hlenl instruction takes XACQUIRE/XRELEASE with or without lock
\273 hle instruction takes XACQUIRE/XRELEASE with lock only
\274..\277 ib,s a byte immediate operand, from operand 0..3, sign-extended

View file

@ -3,7 +3,7 @@
#
# dword bound, index 0 - specific flags
#
if_align('IGEN');
if_align('IGEN', $NOBREAK);
# The following MUST be in word 0
if_("SM0", "Size match operand 0");
@ -16,18 +16,24 @@ if_("AR1", "SB, SW, SD applies to operand 1");
if_("AR2", "SB, SW, SD applies to operand 2");
if_("AR3", "SB, SW, SD applies to operand 3");
if_("AR4", "SB, SW, SD applies to operand 4");
# These must match the order of the BITSx flags in opflags.h
if_("SB", "Unsized operands can't be non-byte");
if_("SW", "Unsized operands can't be non-word");
if_("SD", "Unsized operands can't be non-dword");
if_("SQ", "Unsized operands can't be non-qword");
if_("ST", "Unsized operands can't be non-tword");
if_("SO", "Unsized operands can't be non-oword");
if_("SY", "Unsized operands can't be non-yword");
if_("SZ", "Unsized operands can't be non-zword");
# End BITSx order match requirement
if_("SIZE", "Unsized operands must match the bitsize");
if_("SX", "Unsized operands not allowed");
if_("ANYSIZE", "Ignore operand size even if explicit");
# End word 0 requirement
if_("SX", "Unsized operands not allowed");
if_("SX_W", "At least one sized SMx operand required");
if_("SDWORD", "Strict sdword64 matching");
if_break_ok();
if_("JMP_RELAX", "Relaxable jump instruction");
if_("OPT", "Optimizing assembly only");
if_("LATEVEX", "Only if EVEX instructions are disabled");
if_("NOAPX", "Instruction does not support APX registers");

View file

@ -1,7 +1,7 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2018 The NASM Authors - All Rights Reserved
## Copyright 1996-2024 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
@ -77,19 +77,32 @@ my %flag_byname;
my @flag_bynum;
my @flag_fields;
my $iflag_words;
my $no_word_break = 0;
my $current_group;
our $NOBREAK = 0;
sub if_($$) {
my($name, $def) = @_;
my $num = $n_iflags++;
my $v = [$num, $name, $def];
if (!($n_iflags & 31) && $no_word_break) {
die "iflags: group $current_group has disallowed dword break\n";
}
$flag_byname{$name} = $v;
$flag_bynum[$num] = $v;
return 1;
}
sub if_align($) {
my($name) = @_;
sub if_break_ok(;$) {
my($ok) = @_;
$no_word_break = defined($ok) && !$ok;
}
sub if_align($;$) {
my($name, $break_ok) = @_;
if_break_ok($break_ok);
if ($#flag_fields >= 0) {
$flag_fields[$#flag_fields]->[2] = $n_iflags-1;
@ -97,6 +110,7 @@ sub if_align($) {
$n_iflags = ($n_iflags + 31) & ~31;
if (defined($name)) {
$current_group = $name;
push(@flag_fields, [$name, $n_iflags, undef]);
}
@ -131,6 +145,8 @@ sub split_flags($) {
foreach my $flag (split(',', $flagstr)) {
# Somewhat nicer syntax for required flags (NF! -> NF_R)
$flag =~ s/\!$/_R/;
# Ditto for weak flags (SX- -> SX_W)
$flag =~ s/\-$/_W/;
if ($flag =~ /^(.*)(([0-9]+[+-])+[0-9]+)$/) {
my $pref = $1;

View file

@ -71,129 +71,14 @@ EQU imm ignore ignore
EQU imm:imm ignore ignore
;# Conventional instructions
$arith ADD OR ADC SBB AND SUB XOR CMP
AAA void [ 37] 8086,NOLONG
AAD void [ d5 0a] 8086,NOLONG
AAD imm [i: d5 ib,u] 8086,SB,NOLONG
AAM void [ d4 0a] 8086,NOLONG
AAM imm [i: d4 ib,u] 8086,SB,NOLONG
AAS void [ 3f] 8086,NOLONG
ADC mem,reg8 [mr: hle 10 /r] 8086,SM,LOCK
ADC reg8,reg8 [mr: 10 /r] 8086
ADC mem,reg16 [mr: hle o16 11 /r] 8086,SM,LOCK
ADC reg16,reg16 [mr: o16 11 /r] 8086
ADC mem,reg32 [mr: hle o32 11 /r] 386,SM,LOCK
ADC reg32,reg32 [mr: o32 11 /r] 386
ADC mem,reg64 [mr: hle o64 11 /r] X86_64,LONG,SM,LOCK
ADC reg64,reg64 [mr: o64 11 /r] X86_64,LONG
ADC reg8,mem [rm: 12 /r] 8086,SM
ADC reg8,reg8 [rm: 12 /r] 8086
ADC reg16,mem [rm: o16 13 /r] 8086,SM
ADC reg16,reg16 [rm: o16 13 /r] 8086
ADC reg32,mem [rm: o32 13 /r] 386,SM
ADC reg32,reg32 [rm: o32 13 /r] 386
ADC reg64,mem [rm: o64 13 /r] X86_64,LONG,SM
ADC reg64,reg64 [rm: o64 13 /r] X86_64,LONG
ADC rm16,imm8 [mi: hle o16 83 /2 ib,s] 8086,LOCK
ADC rm32,imm8 [mi: hle o32 83 /2 ib,s] 386,LOCK
ADC rm64,imm8 [mi: hle o64 83 /2 ib,s] X86_64,LONG,LOCK
ADC reg_al,imm [-i: 14 ib] 8086,SM
ADC reg_ax,sbyteword [mi: o16 83 /2 ib,s] 8086,SM,ND
ADC reg_ax,imm [-i: o16 15 iw] 8086,SM
ADC reg_eax,sbytedword [mi: o32 83 /2 ib,s] 386,SM,ND
ADC reg_eax,imm [-i: o32 15 id] 386,SM
ADC reg_rax,sbytedword [mi: o64 83 /2 ib,s] X86_64,LONG,SM,ND
ADC reg_rax,imm [-i: o64 15 id,s] X86_64,LONG,SM
ADC rm8,imm [mi: hle 80 /2 ib] 8086,SM,LOCK
ADC rm16,sbyteword [mi: hle o16 83 /2 ib,s] 8086,SM,LOCK,ND
ADC rm16,imm [mi: hle o16 81 /2 iw] 8086,SM,LOCK
ADC rm32,sbytedword [mi: hle o32 83 /2 ib,s] 386,SM,LOCK,ND
ADC rm32,imm [mi: hle o32 81 /2 id] 386,SM,LOCK
ADC rm64,sbytedword [mi: hle o64 83 /2 ib,s] X86_64,LONG,SM,LOCK,ND
ADC rm64,imm [mi: hle o64 81 /2 id,s] X86_64,LONG,SM,LOCK
ADC mem,imm8 [mi: hle 80 /2 ib] 8086,SM,LOCK,ND
ADC mem,sbyteword16 [mi: hle o16 83 /2 ib,s] 8086,SM,LOCK,ND
ADC mem,imm16 [mi: hle o16 81 /2 iw] 8086,SM,LOCK
ADC mem,sbytedword32 [mi: hle o32 83 /2 ib,s] 386,SM,LOCK,ND
ADC mem,imm32 [mi: hle o32 81 /2 id] 386,SM,LOCK
ADC rm8,imm [mi: hle 82 /2 ib] 8086,SM,LOCK,ND,NOLONG
ADD mem,reg8 [mr: hle 00 /r] 8086,SM,LOCK
ADD reg8,reg8 [mr: 00 /r] 8086
ADD mem,reg16 [mr: hle o16 01 /r] 8086,SM,LOCK
ADD reg16,reg16 [mr: o16 01 /r] 8086
ADD mem,reg32 [mr: hle o32 01 /r] 386,SM,LOCK
ADD reg32,reg32 [mr: o32 01 /r] 386
ADD mem,reg64 [mr: hle o64 01 /r] X86_64,LONG,SM,LOCK
ADD reg64,reg64 [mr: o64 01 /r] X86_64,LONG
ADD reg8,mem [rm: 02 /r] 8086,SM
ADD reg8,reg8 [rm: 02 /r] 8086
ADD reg16,mem [rm: o16 03 /r] 8086,SM
ADD reg16,reg16 [rm: o16 03 /r] 8086
ADD reg32,mem [rm: o32 03 /r] 386,SM
ADD reg32,reg32 [rm: o32 03 /r] 386
ADD reg64,mem [rm: o64 03 /r] X86_64,LONG,SM
ADD reg64,reg64 [rm: o64 03 /r] X86_64,LONG
ADD rm16,imm8 [mi: hle o16 83 /0 ib,s] 8086,LOCK
ADD rm32,imm8 [mi: hle o32 83 /0 ib,s] 386,LOCK
ADD rm64,imm8 [mi: hle o64 83 /0 ib,s] X86_64,LONG,LOCK
ADD reg_al,imm [-i: 04 ib] 8086,SM
ADD reg_ax,sbyteword [mi: o16 83 /0 ib,s] 8086,SM,ND
ADD reg_ax,imm [-i: o16 05 iw] 8086,SM
ADD reg_eax,sbytedword [mi: o32 83 /0 ib,s] 386,SM,ND
ADD reg_eax,imm [-i: o32 05 id] 386,SM
ADD reg_rax,sbytedword [mi: o64 83 /0 ib,s] X86_64,LONG,SM,ND
ADD reg_rax,imm [-i: o64 05 id,s] X86_64,LONG,SM
ADD rm8,imm [mi: hle 80 /0 ib] 8086,SM,LOCK
ADD rm16,sbyteword [mi: hle o16 83 /0 ib,s] 8086,SM,LOCK,ND
ADD rm16,imm [mi: hle o16 81 /0 iw] 8086,SM,LOCK
ADD rm32,sbytedword [mi: hle o32 83 /0 ib,s] 386,SM,LOCK,ND
ADD rm32,imm [mi: hle o32 81 /0 id] 386,SM,LOCK
ADD rm64,sbytedword [mi: hle o64 83 /0 ib,s] X86_64,LONG,SM,LOCK,ND
ADD rm64,imm [mi: hle o64 81 /0 id,s] X86_64,LONG,SM,LOCK
ADD mem,imm8 [mi: hle 80 /0 ib] 8086,SM,LOCK
ADD mem,sbyteword16 [mi: hle o16 83 /0 ib,s] 8086,SM,LOCK,ND
ADD mem,imm16 [mi: hle o16 81 /0 iw] 8086,SM,LOCK
ADD mem,sbytedword32 [mi: hle o32 83 /0 ib,s] 386,SM,LOCK,ND
ADD mem,imm32 [mi: hle o32 81 /0 id] 386,SM,LOCK
ADD rm8,imm [mi: hle 82 /0 ib] 8086,SM,LOCK,ND,NOLONG
AND mem,reg8 [mr: hle 20 /r] 8086,SM,LOCK
AND reg8,reg8 [mr: 20 /r] 8086
AND mem,reg16 [mr: hle o16 21 /r] 8086,SM,LOCK
AND reg16,reg16 [mr: o16 21 /r] 8086
AND mem,reg32 [mr: hle o32 21 /r] 386,SM,LOCK
AND reg32,reg32 [mr: o32 21 /r] 386
AND mem,reg64 [mr: hle o64 21 /r] X86_64,LONG,SM,LOCK
AND reg64,reg64 [mr: o64 21 /r] X86_64,LONG
AND reg8,mem [rm: 22 /r] 8086,SM
AND reg8,reg8 [rm: 22 /r] 8086
AND reg16,mem [rm: o16 23 /r] 8086,SM
AND reg16,reg16 [rm: o16 23 /r] 8086
AND reg32,mem [rm: o32 23 /r] 386,SM
AND reg32,reg32 [rm: o32 23 /r] 386
AND reg64,mem [rm: o64 23 /r] X86_64,LONG,SM
AND reg64,reg64 [rm: o64 23 /r] X86_64,LONG
AND rm16,imm8 [mi: hle o16 83 /4 ib,s] 8086,LOCK
AND rm32,imm8 [mi: hle o32 83 /4 ib,s] 386,LOCK
AND rm64,imm8 [mi: hle o64 83 /4 ib,s] X86_64,LONG,LOCK
AND reg_al,imm [-i: 24 ib] 8086,SM
AND reg_ax,sbyteword [mi: o16 83 /4 ib,s] 8086,SM,ND
AND reg_ax,imm [-i: o16 25 iw] 8086,SM
AND reg_eax,sbytedword [mi: o32 83 /4 ib,s] 386,SM,ND
AND reg_eax,imm [-i: o32 25 id] 386,SM
AND reg_rax,sbytedword [mi: o64 83 /4 ib,s] X86_64,LONG,SM,ND
AND reg_rax,imm [-i: o64 25 id,s] X86_64,LONG,SM
AND rm8,imm [mi: hle 80 /4 ib] 8086,SM,LOCK
AND rm16,sbyteword [mi: hle o16 83 /4 ib,s] 8086,SM,LOCK,ND
AND rm16,imm [mi: hle o16 81 /4 iw] 8086,SM,LOCK
AND rm32,sbytedword [mi: hle o32 83 /4 ib,s] 386,SM,LOCK,ND
AND rm32,imm [mi: hle o32 81 /4 id] 386,SM,LOCK
AND rm64,sbytedword [mi: hle o64 83 /4 ib,s] X86_64,LONG,SM,LOCK,ND
AND rm64,imm [mi: hle o64 81 /4 id,s] X86_64,LONG,SM,LOCK
AND mem,imm8 [mi: hle 80 /4 ib] 8086,SM,LOCK
AND mem,sbyteword16 [mi: hle o16 83 /4 ib,s] 8086,SM,LOCK,ND
AND mem,imm16 [mi: hle o16 81 /4 iw] 8086,SM,LOCK
AND mem,sbytedword32 [mi: hle o32 83 /4 ib,s] 386,SM,LOCK,ND
AND mem,imm32 [mi: hle o32 81 /4 id] 386,SM,LOCK
AND rm8,imm [mi: hle 82 /4 ib] 8086,SM,LOCK,ND,NOLONG
ARPL mem,reg16 [mr: 63 /r] 286,PROT,SM,NOLONG
ARPL reg16,reg16 [mr: 63 /r] 286,PROT,NOLONG
BB0_RESET void [ 0f 3a] PENT,CYRIX,NOLONG,OBSOLETE,ND
@ -250,33 +135,33 @@ BTS reg64,reg64 [mr: o64 0f ab /r] X86_64,LONG
BTS rm16,imm8 [mi: hle o16 0f ba /5 ib,u] 386,LOCK
BTS rm32,imm8 [mi: hle o32 0f ba /5 ib,u] 386,LOCK
BTS rm64,imm8 [mi: hle o64 0f ba /5 ib,u] X86_64,LONG,LOCK
CALL imm [i: odf e8 rel] 8086,BND,NOAPX
CALL imm|near [i: odf e8 rel] 8086,ND,BND,NOAPX
CALL imm|far [i: odf 9a iwd seg] 8086,ND,NOLONG
CALL imm [i: odf e8 rel] 8086,BND,NOAPX,SIZE
CALL imm|near [i: odf e8 rel] 8086,ND,BND,NOAPX,SIZE
CALL imm|far [i: odf 9a iwd seg] 8086,ND,NOLONG,SIZE
CALL imm:imm [ji: odf 9a iwd iw] 8086,NOLONG,SIZE,AR1
; Call/jmp near imm/reg/mem is always 64-bit in long mode.
CALL imm16 [i: o16 e8 rel] 8086,NOLONG,BND
CALL imm16|near [i: o16 e8 rel] 8086,ND,NOLONG,BND
CALL imm16|far [i: o16 9a iwd seg] 8086,ND,NOLONG
CALL imm32 [i: o32 e8 rel] 386,NOLONG,BND
CALL imm32|near [i: o32 e8 rel] 386,ND,NOLONG,BND
CALL imm32|far [i: o32 9a iwd seg] 386,ND,NOLONG
CALL imm64 [i: o64nw e8 rel] X86_64,LONG,BND,NOAPX
CALL imm16 [i: o16 e8 rel] 8086,NOLONG,BND,SX
CALL imm16|near [i: o16 e8 rel] 8086,ND,NOLONG,BND,SX,ND
CALL imm16|far [i: o16 9a iwd seg] 8086,ND,NOLONG,SX,ND
CALL imm32 [i: o32 e8 rel] 386,NOLONG,BND,SX,ND
CALL imm32|near [i: o32 e8 rel] 386,ND,NOLONG,BND,SX,ND
CALL imm32|far [i: o32 9a iwd seg] 386,ND,NOLONG,SX,ND
CALL imm64 [i: o64nw e8 rel] X86_64,LONG,BND,NOAPX,SX,ND
CALL imm64|near [i: o64nw e8 rel] X86_64,LONG,ND,BND,NOAPX
CALL imm:imm [ji: odf 9a iwd iw] 8086,NOLONG
CALL imm16:imm [ji: o16 9a iw iw] 8086,NOLONG
CALL imm:imm16 [ji: o16 9a iw iw] 8086,NOLONG
CALL imm32:imm [ji: o32 9a id iw] 386,NOLONG
CALL imm:imm32 [ji: o32 9a id iw] 386,NOLONG
CALL mem|far [m: odf ff /3] 8086,NOLONG
CALL mem|far [m: o64 ff /3] X86_64,LONG
CALL mem16|far [m: o16 ff /3] 8086
CALL mem32|far [m: o32 ff /3] 386
CALL mem64|far [m: o64 ff /3] X86_64,LONG
CALL mem|near [m: odf ff /2] 8086,ND,BND
CALL rm16|near [m: o16 ff /2] 8086,NOLONG,ND,BND
CALL rm32|near [m: o32 ff /2] 386,NOLONG,ND,BND
CALL rm64|near [m: o64nw ff /2] X86_64,LONG,ND,BND
CALL mem [m: odf ff /2] 8086,BND
CALL imm16:imm [ji: o16 9a iw iw] 8086,NOLONG,SX,AR0,ND
CALL imm:imm16 [ji: o16 9a iw iw] 8086,NOLONG,SX,AR1
CALL imm32:imm [ji: o32 9a id iw] 386,NOLONG,SX,AR0,ND
CALL imm:imm32 [ji: o32 9a id iw] 386,NOLONG,SX,AR1
CALL mem|far [m: odf ff /3] 8086,NOLONG,SX
CALL mem|far [m: o64 ff /3] X86_64,LONG,SX
CALL mem16|far [m: o16 ff /3] 8086,SX
CALL mem32|far [m: o32 ff /3] 386,SX
CALL mem64|far [m: o64 ff /3] X86_64,SX,LONG
CALL mem|near [m: odf ff /2] 8086,ND,BND,SX
CALL rm16|near [m: o16 ff /2] 8086,NOLONG,ND,BND,SX
CALL rm32|near [m: o32 ff /2] 386,NOLONG,ND,BND,SX
CALL rm64|near [m: o64nw ff /2] X86_64,LONG,ND,BND,SX
CALL mem [m: odf ff /2] 8086,BND,SIZE
CALL rm16 [m: o16 ff /2] 8086,NOLONG,BND
CALL rm32 [m: o32 ff /2] 386,NOLONG,BND
CALL rm64 [m: o64nw ff /2] X86_64,LONG,BND
@ -289,45 +174,7 @@ CLD void [ fc] 8086
CLI void [ fa] 8086
CLTS void [ 0f 06] 286,PRIV
CMC void [ f5] 8086
CMP mem,reg8 [mr: 38 /r] 8086,SM
CMP reg8,reg8 [mr: 38 /r] 8086
CMP mem,reg16 [mr: o16 39 /r] 8086,SM
CMP reg16,reg16 [mr: o16 39 /r] 8086
CMP mem,reg32 [mr: o32 39 /r] 386,SM
CMP reg32,reg32 [mr: o32 39 /r] 386
CMP mem,reg64 [mr: o64 39 /r] X86_64,LONG,SM
CMP reg64,reg64 [mr: o64 39 /r] X86_64,LONG
CMP reg8,mem [rm: 3a /r] 8086,SM
CMP reg8,reg8 [rm: 3a /r] 8086
CMP reg16,mem [rm: o16 3b /r] 8086,SM
CMP reg16,reg16 [rm: o16 3b /r] 8086
CMP reg32,mem [rm: o32 3b /r] 386,SM
CMP reg32,reg32 [rm: o32 3b /r] 386
CMP reg64,mem [rm: o64 3b /r] X86_64,LONG,SM
CMP reg64,reg64 [rm: o64 3b /r] X86_64,LONG
CMP rm16,imm8 [mi: o16 83 /7 ib,s] 8086
CMP rm32,imm8 [mi: o32 83 /7 ib,s] 386
CMP rm64,imm8 [mi: o64 83 /7 ib,s] X86_64,LONG
CMP reg_al,imm [-i: 3c ib] 8086,SM
CMP reg_ax,sbyteword [mi: o16 83 /7 ib,s] 8086,SM,ND
CMP reg_ax,imm [-i: o16 3d iw] 8086,SM
CMP reg_eax,sbytedword [mi: o32 83 /7 ib,s] 386,SM,ND
CMP reg_eax,imm [-i: o32 3d id] 386,SM
CMP reg_rax,sbytedword [mi: o64 83 /7 ib,s] X86_64,LONG,SM,ND
CMP reg_rax,imm [-i: o64 3d id,s] X86_64,LONG,SM
CMP rm8,imm [mi: 80 /7 ib] 8086,SM
CMP rm16,sbyteword [mi: o16 83 /7 ib,s] 8086,SM,ND
CMP rm16,imm [mi: o16 81 /7 iw] 8086,SM
CMP rm32,sbytedword [mi: o32 83 /7 ib,s] 386,SM,ND
CMP rm32,imm [mi: o32 81 /7 id] 386,SM
CMP rm64,sbytedword [mi: o64 83 /7 ib,s] X86_64,LONG,SM,ND
CMP rm64,imm [mi: o64 81 /7 id,s] X86_64,LONG,SM
CMP mem,imm8 [mi: 80 /7 ib] 8086,SM
CMP mem,sbyteword16 [mi: o16 83 /7 ib,s] 8086,SM,ND
CMP mem,imm16 [mi: o16 81 /7 iw] 8086,SM
CMP mem,sbytedword32 [mi: o32 83 /7 ib,s] 386,SM,ND
CMP mem,imm32 [mi: o32 81 /7 id] 386,SM
CMP rm8,imm [mi: 82 /7 ib] 8086,SM,ND,NOLONG
CMPSB void [ repe a6] 8086,NOAPX
CMPSD void [ repe o32 a7] 386,NOAPX
CMPSQ void [ repe o64 a7] X86_64,LONG,NOAPX
@ -601,48 +448,15 @@ IMUL rm8 [m: f6 /5] 8086
IMUL rm16 [m: o16 f7 /5] 8086
IMUL rm32 [m: o32 f7 /5] 386
IMUL rm64 [m: o64 f7 /5] X86_64,LONG
IMUL reg16,mem [rm: o16 0f af /r] 386,SM
IMUL reg16,reg16 [rm: o16 0f af /r] 386
IMUL reg32,mem [rm: o32 0f af /r] 386,SM
IMUL reg32,reg32 [rm: o32 0f af /r] 386
IMUL reg64,mem [rm: o64 0f af /r] X86_64,LONG,SM
IMUL reg64,reg64 [rm: o64 0f af /r] X86_64,LONG
IMUL reg16,mem,imm8 [rmi: o16 6b /r ib,s] 186,SM0-1
IMUL reg16,mem,sbyteword [rmi: o16 6b /r ib,s] 186,SM,ND
IMUL reg16,mem,imm16 [rmi: o16 69 /r iw] 186,SM
IMUL reg16,mem,imm [rmi: o16 69 /r iw] 186,SM,ND
IMUL reg16,reg16,imm8 [rmi: o16 6b /r ib,s] 186
IMUL reg16,reg16,sbyteword [rmi: o16 6b /r ib,s] 186,SM,ND
IMUL reg16,reg16,imm16 [rmi: o16 69 /r iw] 186
IMUL reg16,reg16,imm [rmi: o16 69 /r iw] 186,SM,ND
IMUL reg32,mem,imm8 [rmi: o32 6b /r ib,s] 386,SM0-1
IMUL reg32,mem,sbytedword [rmi: o32 6b /r ib,s] 386,SM,ND
IMUL reg32,mem,imm32 [rmi: o32 69 /r id] 386,SM
IMUL reg32,mem,imm [rmi: o32 69 /r id] 386,SM,ND
IMUL reg32,reg32,imm8 [rmi: o32 6b /r ib,s] 386
IMUL reg32,reg32,sbytedword [rmi: o32 6b /r ib,s] 386,SM,ND
IMUL reg32,reg32,imm32 [rmi: o32 69 /r id] 386
IMUL reg32,reg32,imm [rmi: o32 69 /r id] 386,SM,ND
IMUL reg64,mem,imm8 [rmi: o64 6b /r ib,s] X86_64,LONG,SM0-1
IMUL reg64,mem,sbytedword [rmi: o64 6b /r ib,s] X86_64,LONG,SM,ND
IMUL reg64,mem,imm32 [rmi: o64 69 /r id] X86_64,LONG,SM0-1
IMUL reg64,mem,imm [rmi: o64 69 /r id,s] X86_64,LONG,SM,ND
IMUL reg64,reg64,imm8 [rmi: o64 6b /r ib,s] X86_64,LONG
IMUL reg64,reg64,sbytedword [rmi: o64 6b /r ib,s] X86_64,LONG,SM,ND
IMUL reg64,reg64,imm32 [rmi: o64 69 /r id] X86_64,LONG
IMUL reg64,reg64,imm [rmi: o64 69 /r id,s] X86_64,LONG,SM,ND
IMUL reg16,imm8 [r+mi: o16 6b /r ib,s] 186
IMUL reg16,sbyteword [r+mi: o16 6b /r ib,s] 186,SM,ND
IMUL reg16,imm16 [r+mi: o16 69 /r iw] 186
IMUL reg16,imm [r+mi: o16 69 /r iw] 186,SM,ND
IMUL reg32,imm8 [r+mi: o32 6b /r ib,s] 386
IMUL reg32,sbytedword [r+mi: o32 6b /r ib,s] 386,SM,ND
IMUL reg32,imm32 [r+mi: o32 69 /r id] 386
IMUL reg32,imm [r+mi: o32 69 /r id] 386,SM,ND
IMUL reg64,imm8 [r+mi: o64 6b /r ib,s] X86_64,LONG
IMUL reg64,sbytedword [r+mi: o64 6b /r ib,s] X86_64,LONG,SM,ND
IMUL reg64,imm32 [r+mi: o64 69 /r id,s] X86_64,LONG
IMUL reg64,imm [r+mi: o64 69 /r id,s] X86_64,LONG,SM,ND
IMUL reg16,rm16 [rm: o16 0f af /r] 386,SM
IMUL reg32,rm32 [rm: o32 0f af /r] 386,SM
IMUL reg64,rm64 [rm: o64 0f af /r] X86_64,LONG,SM
IMUL reg16,rm16*,sbyteword16 [rmi: o16 6b /r ib,s] 186,SM
IMUL reg16,rm16*,imm16 [rmi: o16 69 /r iw] 186,SM
IMUL reg32,rm32*,sbytedword32 [rmi: o32 6b /r ib,s] 386,SM
IMUL reg32,rm32*,imm32 [rmi: o32 69 /r id] 386,SM
IMUL reg64,rm64*,sbytedword64 [rmi: o64 6b /r ib,s] X86_64,LONG,SM
IMUL reg64,rm64*,sdword64 [rmi: o64 69 /r id,s] X86_64,LONG,SM
IN reg_al,imm [-i: e4 ib,u] 8086,SB,NOAPX
IN reg_ax,imm [-i: o16 e5 ib,u] 8086,SB,NOAPX
IN reg_eax,imm [-i: o32 e5 ib,u] 386,SB,NOAPX
@ -679,34 +493,36 @@ IRETW void [ o16 cf] 8086
JCXZ imm [i: a16 e3 rel8] 8086,NOLONG
JECXZ imm [i: a32 nw e3 rel8] 386,NOAPX
JRCXZ imm [i: a64 nw e3 rel8] X86_64,LONG,NOAPX
JMP imm|short [i: nw eb rel8] 8086,NOAPX
JMP imm [i: jmp8 nw eb rel8] 8086,ND,NOAPX
JMP imm [i: nw odf e9 rel] 8086,BND,NOAPX
JMP imm|near [i: nw odf e9 rel] 8086,ND,BND,NOAPX
JMP imm|far [i: odf ea iwd seg] 8086,ND,NOLONG
; Call/jmp near imm/reg/mem is always 64-bit in long mode.
JMP imm16 [i: o16 e9 rel] 8086,NOLONG,BND
JMP imm16|near [i: o16 e9 rel] 8086,ND,NOLONG,BND
JMP imm16|far [i: o16 ea iwd seg] 8086,ND,NOLONG
JMP imm32 [i: o32 e9 rel] 386,NOLONG,BND
JMP imm32|near [i: o32 e9 rel] 386,ND,NOLONG,BND
JMP imm32|far [i: o32 ea iwd seg] 386,ND,NOLONG
JMP imm64 [i: o64nw e9 rel] X86_64,LONG,BND,NOAPX
JMP imm64|near [i: o64nw e9 rel] X86_64,LONG,ND,BND,NOAPX
JMP imm|short [i: nw eb rel8] 8086,NOAPX,SX
JMP imm8 [i: nw eb rel8] 8086,NOAPX,SX
JMP imm8|short [i: nw eb rel8] 8086,NOAPX,SX
JMP imm [i: jmp8 nw eb rel8] 8086,SX,ND,NOAPX
JMP imm [i: nw odf e9 rel] 8086,SX,BND,NOAPX
JMP imm|near [i: nw odf e9 rel] 8086,SX,ND,BND,NOAPX
JMP imm|far [i: odf ea iwd seg] 8086,SX,ND,NOLONG
JMP imm16 [i: o16 e9 rel] 8086,SX,NOLONG,BND
JMP imm16|near [i: o16 e9 rel] 8086,SX,ND,NOLONG,BND
JMP imm16|far [i: o16 ea iwd seg] 8086,SX,ND,NOLONG
JMP imm32 [i: o32 e9 rel] 386,SX,NOLONG,BND
JMP imm32|near [i: o32 e9 rel] 386,SX,ND,NOLONG,BND
JMP imm32|far [i: o32 ea iwd seg] 386,SX,ND,NOLONG
JMP imm64 [i: o64nw e9 rel] X86_64,SX,LONG,BND,NOAPX
JMP imm64|near [i: o64nw e9 rel] X86_64,SX,LONG,ND,BND,NOAPX
JMP imm:imm [ji: odf ea iwd iw] 8086,NOLONG
JMP imm16:imm [ji: o16 ea iw iw] 8086,NOLONG
JMP imm:imm16 [ji: o16 ea iw iw] 8086,NOLONG
JMP imm32:imm [ji: o32 ea id iw] 386,NOLONG
JMP imm:imm32 [ji: o32 ea id iw] 386,NOLONG
JMP mem|far [m: odf ff /5] 8086,NOLONG
JMP mem|far [m: o64 ff /5] X86_64,LONG
JMP mem16|far [m: o16 ff /5] 8086
JMP mem32|far [m: o32 ff /5] 386
JMP mem64|far [m: o64 ff /5] X86_64,LONG
JMP mem|near [m: odf ff /4] 8086,ND,BND
JMP rm16|near [m: o16 ff /4] 8086,NOLONG,ND,BND
JMP rm32|near [m: o32 ff /4] 386,NOLONG,ND,BND
JMP rm64|near [m: o64nw ff /4] X86_64,LONG,ND,BND
JMP imm16:imm [ji: o16 ea iw iw] 8086,SX,AR0,NOLONG
JMP imm:imm16 [ji: o16 ea iw iw] 8086,SX,AR1,NOLONG
JMP imm32:imm [ji: o32 ea id iw] 386,SX,AR0,NOLONG
JMP imm:imm32 [ji: o32 ea id iw] 386,SX,AR1,NOLONG
JMP mem|far [m: odf ff /5] 8086,SX,NOLONG
JMP mem|far [m: o64 ff /5] X86_64,SX,LONG
JMP mem16|far [m: o16 ff /5] 8086,SX
JMP mem32|far [m: o32 ff /5] 386,SX
JMP mem64|far [m: o64 ff /5] X86_64,LONG,SX
JMP mem|near [m: odf ff /4] 8086,ND,BND,SX
JMP rm16|near [m: o16 ff /4] 8086,NOLONG,ND,SX,BND
JMP rm32|near [m: o32 ff /4] 386,NOLONG,ND,SX,BND
JMP rm64|near [m: o64nw ff /4] X86_64,LONG,ND,SX,BND
JMP mem [m: odf ff /4] 8086,BND
JMP rm16 [m: o16 ff /4] 8086,NOLONG,BND
JMP rm32 [m: o32 ff /4] 386,NOLONG,BND
@ -742,12 +558,12 @@ LAR reg64,reg32 [rm: o64 0f 02 /r] X86_64,LONG,PROT
LAR reg64,reg64 [rm: o64 0f 02 /r] X86_64,LONG,PROT
LDS reg16,mem [rm: o16 c5 /r] 8086,NOLONG
LDS reg32,mem [rm: o32 c5 /r] 386,NOLONG
LEA reg16,mem [rm: o16 8d /r] 8086,ANYSIZE
LEA reg32,mem [rm: o32 8d /r] 386,ANYSIZE
LEA reg64,mem [rm: o64 8d /r] X86_64,LONG,ANYSIZE
LEA reg16,imm [rm: o16 8d /r] 8086,ND,ANYSIZE
LEA reg32,imm [rm: o32 8d /r] 386,ND,ANYSIZE
LEA reg64,imm [rm: o64 8d /r] X86_64,LONG,ND,ANYSIZE
LEA reg16,mem [rm: o16 8d /r] 8086,ANYSIZE,AR1
LEA reg32,mem [rm: o32 8d /r] 386,ANYSIZE,AR1
LEA reg64,mem [rm: o64 8d /r] X86_64,LONG,ANYSIZE,AR1
LEA reg16,imm [rm: o16 8d /r] 8086,ND,ANYSIZE,AR1
LEA reg32,imm [rm: o32 8d /r] 386,ND,ANYSIZE,AR1
LEA reg64,imm [rm: o64 8d /r] X86_64,LONG,ND,ANYSIZE,AR1
LEAVE void [ c9] 186
LES reg16,mem [rm: o16 c4 /r] 8086,NOLONG
LES reg32,mem [rm: o32 c4 /r] 386,NOLONG
@ -780,18 +596,18 @@ LOOPE imm [i: adf nw e1 rel8] 8086,NOAPX
LOOPE imm,reg_cx [i-: a16 e1 rel8] 8086,NOLONG
LOOPE imm,reg_ecx [i-: a32 nw e1 rel8] 386,NOAPX
LOOPE imm,reg_rcx [i-: a64 nw e1 rel8] X86_64,LONG,NOAPX
LOOPZ imm [i: adf nw e1 rel8] 8086,NOAPX,ND
LOOPZ imm,reg_cx [i-: a16 e1 rel8] 8086,NOLONG,ND
LOOPZ imm,reg_ecx [i-: a32 nw e1 rel8] 386,NOAPX,ND
LOOPZ imm,reg_rcx [i-: a64 nw e1 rel8] X86_64,LONG,NOAPX,ND
LOOPNE imm [i: adf nw e0 rel8] 8086,NOAPX
LOOPNE imm,reg_cx [i-: a16 e0 rel8] 8086,NOLONG
LOOPNE imm,reg_ecx [i-: a32 nw e0 rel8] 386,NOAPX
LOOPNE imm,reg_rcx [i-: a64 nw e0 rel8] X86_64,LONG,NOAPX
LOOPNZ imm [i: adf nw e0 rel8] 8086,NOAPX
LOOPNZ imm,reg_cx [i-: a16 e0 rel8] 8086,NOLONG
LOOPNZ imm,reg_ecx [i-: a32 nw e0 rel8] 386,NOAPX
LOOPNZ imm,reg_rcx [i-: a64 nw e0 rel8] X86_64,LONG,NOAPX
LOOPZ imm [i: adf nw e1 rel8] 8086,NOAPX
LOOPZ imm,reg_cx [i-: a16 e1 rel8] 8086,NOLONG
LOOPZ imm,reg_ecx [i-: a32 nw e1 rel8] 386,NOAPX
LOOPZ imm,reg_rcx [i-: a64 nw e1 rel8] X86_64,LONG,NOAPX
LOOPNZ imm [i: adf nw e0 rel8] 8086,NOAPX,ND
LOOPNZ imm,reg_cx [i-: a16 e0 rel8] 8086,NOLONG,ND
LOOPNZ imm,reg_ecx [i-: a32 nw e0 rel8] 386,NOAPX,ND
LOOPNZ imm,reg_rcx [i-: a64 nw e0 rel8] X86_64,LONG,NOAPX,ND
LSL reg16,mem [rm: o16 0f 03 /r] 286,PROT,SW
LSL reg16,reg16 [rm: o16 0f 03 /r] 286,PROT
LSL reg16,reg32 [rm: o16 0f 03 /r] 386,PROT
@ -848,36 +664,29 @@ MOV reg_dreg,reg32 [rm: 0f 23 /r] 386,PRIV,NOLONG
MOV reg_dreg,reg64 [rm: o64nw 0f 23 /r] X86_64,LONG,PRIV
MOV reg32,reg_treg [mr: 0f 24 /r] 386,NOLONG,ND
MOV reg_treg,reg32 [rm: 0f 26 /r] 386,NOLONG,ND
MOV mem,reg8 [mr: hlexr 88 /r] 8086,SM
MOV mem8,reg8 [mr: hlexr 88 /r] 8086,SM
MOV reg8,reg8 [mr: 88 /r] 8086
MOV mem,reg16 [mr: hlexr o16 89 /r] 8086,SM
MOV mem16,reg16 [mr: hlexr o16 89 /r] 8086,SM
MOV reg16,reg16 [mr: o16 89 /r] 8086
MOV mem,reg32 [mr: hlexr o32 89 /r] 386,SM
MOV mem32,reg32 [mr: hlexr o32 89 /r] 386,SM
MOV reg32,reg32 [mr: o32 89 /r] 386
MOV mem,reg64 [mr: hlexr o64 89 /r] X86_64,LONG,SM
MOV mem64,reg64 [mr: hlexr o64 89 /r] X86_64,LONG,SM
MOV reg64,reg64 [mr: o64 89 /r] X86_64,LONG
MOV reg8,mem [rm: 8a /r] 8086,SM
MOV reg8,mem8 [rm: 8a /r] 8086,SM
MOV reg8,reg8 [rm: 8a /r] 8086
MOV reg16,mem [rm: o16 8b /r] 8086,SM
MOV reg16,reg16 [rm: o16 8b /r] 8086
MOV reg32,mem [rm: o32 8b /r] 386,SM
MOV reg32,reg32 [rm: o32 8b /r] 386
MOV reg64,mem [rm: o64 8b /r] X86_64,LONG,SM
MOV reg64,reg64 [rm: o64 8b /r] X86_64,LONG
MOV reg8,imm [ri: b0+r ib] 8086,SM
MOV reg16,imm [ri: o16 b8+r iw] 8086,SM
MOV reg32,imm [ri: o32 b8+r id] 386,SM
MOV reg64,udword [ri: o64nw b8+r id] X86_64,LONG,SM,OPT,ND
MOV reg64,sdword [mi: o64 c7 /0 id,s] X86_64,LONG,SM,OPT,ND
MOV reg64,imm [ri: o64 b8+r iq] X86_64,LONG,SM
MOV rm8,imm [mi: hlexr c6 /0 ib] 8086,SM
MOV rm16,imm [mi: hlexr o16 c7 /0 iw] 8086,SM
MOV rm32,imm [mi: hlexr o32 c7 /0 id] 386,SM
MOV rm64,imm [mi: hlexr o64 c7 /0 id,s] X86_64,LONG,SM
MOV rm64,imm32 [mi: hlexr o64 c7 /0 id,s] X86_64,LONG
MOV mem,imm8 [mi: hlexr c6 /0 ib] 8086,SM
MOV mem,imm16 [mi: hlexr o16 c7 /0 iw] 8086,SM
MOV mem,imm32 [mi: hlexr o32 c7 /0 id] 386,SM
MOV reg16,rm16 [rm: o16 8b /r] 8086,SM
MOV reg32,rm32 [rm: o32 8b /r] 386,SM
MOV reg64,rm64 [rm: o64 8b /r] X86_64,LONG,SM
MOV reg8,imm8 [ri: b0+r ib] 8086,SM
MOV reg16,imm16 [ri: o16 b8+r iw] 8086,SM
MOV reg32,imm32 [ri: o32 b8+r id] 386,SM
MOV reg64,udword64 [ri: o64nw b8+r id] X86_64,LONG,SM,OPT,ND
MOV reg64,sdword64 [mi: o64 c7 /0 id,s] X86_64,LONG,SM,OPT,SDWORD,ND
MOV reg64,imm64 [ri: o64 b8+r iq] X86_64,LONG,SM
MOV rm8,imm8 [mi: hlexr c6 /0 ib] 8086,SM
MOV rm16,imm16 [mi: hlexr o16 c7 /0 iw] 8086,SM
MOV rm32,imm32 [mi: hlexr o32 c7 /0 id] 386,SM
MOV rm64,sdword64 [mi: hlexr o64 c7 /0 id,s] X86_64,LONG,SM
MOVD mmxreg,rm32 [rm: np 0f 6e /r] PENT,MMX,SD
MOVD rm32,mmxreg [mr: np 0f 7e /r] PENT,MMX,SD
MOVD mmxreg,rm64 [rm: np o64 0f 6e /r] X86_64,LONG,MMX,SX,ND
@ -1097,17 +906,13 @@ PUSH reg_ss [-: 16] 8086,NOLONG
PUSH reg_ds [-: 1e] 8086,NOLONG
PUSH reg_fs [-: 0f a0] 386
PUSH reg_gs [-: 0f a8] 386
PUSH imm8 [i: nw 6a ib,s] 186
PUSH sbyteword16 [i: o16 6a ib,s] 186,AR0,SIZE,ND
PUSH imm16 [i: o16 68 iw] 186,AR0,SIZE
PUSH sbytedword32 [i: o32 6a ib,s] 386,NOLONG,AR0,SIZE,ND
PUSH imm32 [i: o32 68 id] 386,NOLONG,AR0,SIZE
PUSH sbytedword32 [i: o32 6a ib,s] 386,NOLONG,SD,ND
PUSH imm32 [i: o32 68 id] 386,NOLONG,SD
PUSH sbytedword64 [i: o64nw 6a ib,s] X86_64,LONG,AR0,SIZE,ND
PUSH imm64 [i: o64nw 68 id,s] X86_64,LONG,AR0,SIZE
PUSH sbytedword32 [i: o64nw 6a ib,s] X86_64,LONG,AR0,SIZE,ND
PUSH imm32 [i: o64nw 68 id,s] X86_64,LONG,AR0,SIZE
PUSH imm8 [i: 6a ib,s] 186,NOLONG,SX,ND
PUSH sbyteword16 [i: o16 6a ib,s] 186,NOLONG,SIZE
PUSH imm16 [i: o16 68 iw] 186,NOLONG,SIZE
PUSH sbytedword32 [i: o32 6a ib,s] 386,NOLONG,SIZE
PUSH imm32 [i: o32 68 id] 386,NOLONG,SIZE
PUSH sbytedword64 [i: o64nw 6a ib,s] X86_64,LONG,SIZE
PUSH sdword64 [i: o64nw 68 id,s] X86_64,LONG,SIZE
PUSHA void [ odf 60] 186,NOLONG
PUSHAD void [ o32 60] 386,NOLONG
PUSHAW void [ o16 60] 186,NOLONG
@ -1225,45 +1030,6 @@ SAR rm32,imm8 [mi: o32 c1 /7 ib,u] 386
SAR rm64,unity [m-: o64 d1 /7] X86_64,LONG
SAR rm64,reg_cl [m-: o64 d3 /7] X86_64,LONG
SAR rm64,imm8 [mi: o64 c1 /7 ib,u] X86_64,LONG
SBB mem,reg8 [mr: hle 18 /r] 8086,SM,LOCK
SBB reg8,reg8 [mr: 18 /r] 8086
SBB mem,reg16 [mr: hle o16 19 /r] 8086,SM,LOCK
SBB reg16,reg16 [mr: o16 19 /r] 8086
SBB mem,reg32 [mr: hle o32 19 /r] 386,SM,LOCK
SBB reg32,reg32 [mr: o32 19 /r] 386
SBB mem,reg64 [mr: hle o64 19 /r] X86_64,LONG,SM,LOCK
SBB reg64,reg64 [mr: o64 19 /r] X86_64,LONG
SBB reg8,mem [rm: 1a /r] 8086,SM
SBB reg8,reg8 [rm: 1a /r] 8086
SBB reg16,mem [rm: o16 1b /r] 8086,SM
SBB reg16,reg16 [rm: o16 1b /r] 8086
SBB reg32,mem [rm: o32 1b /r] 386,SM
SBB reg32,reg32 [rm: o32 1b /r] 386
SBB reg64,mem [rm: o64 1b /r] X86_64,LONG,SM
SBB reg64,reg64 [rm: o64 1b /r] X86_64,LONG
SBB rm16,imm8 [mi: hle o16 83 /3 ib,s] 8086,LOCK
SBB rm32,imm8 [mi: hle o32 83 /3 ib,s] 386,LOCK
SBB rm64,imm8 [mi: hle o64 83 /3 ib,s] X86_64,LONG,LOCK
SBB reg_al,imm [-i: 1c ib] 8086,SM
SBB reg_ax,sbyteword [mi: o16 83 /3 ib,s] 8086,SM,ND
SBB reg_ax,imm [-i: o16 1d iw] 8086,SM
SBB reg_eax,sbytedword [mi: o32 83 /3 ib,s] 386,SM,ND
SBB reg_eax,imm [-i: o32 1d id] 386,SM
SBB reg_rax,sbytedword [mi: o64 83 /3 ib,s] X86_64,LONG,SM,ND
SBB reg_rax,imm [-i: o64 1d id,s] X86_64,LONG,SM
SBB rm8,imm [mi: hle 80 /3 ib] 8086,SM,LOCK
SBB rm16,sbyteword [mi: hle o16 83 /3 ib,s] 8086,SM,LOCK,ND
SBB rm16,imm [mi: hle o16 81 /3 iw] 8086,SM,LOCK
SBB rm32,sbytedword [mi: hle o32 83 /3 ib,s] 386,SM,LOCK,ND
SBB rm32,imm [mi: hle o32 81 /3 id] 386,SM,LOCK
SBB rm64,sbytedword [mi: hle o64 83 /3 ib,s] X86_64,LONG,SM,LOCK,ND
SBB rm64,imm [mi: hle o64 81 /3 id,s] X86_64,LONG,SM,LOCK
SBB mem,imm8 [mi: hle 80 /3 ib] 8086,SM,LOCK
SBB mem,sbyteword16 [mi: hle o16 83 /3 ib,s] 8086,SM,LOCK,ND
SBB mem,imm16 [mi: hle o16 81 /3 iw] 8086,SM,LOCK
SBB mem,sbytedword32 [mi: hle o32 83 /3 ib,s] 386,SM,LOCK,ND
SBB mem,imm32 [mi: hle o32 81 /3 id] 386,SM,LOCK
SBB rm8,imm [mi: hle 82 /3 ib] 8086,SM,LOCK,ND,NOLONG
SCASB void [ repe ae] 8086,NOAPX
SCASD void [ repe o32 af] 386,NOAPX
SCASQ void [ repe o64 af] X86_64,LONG,NOAPX
@ -1347,45 +1113,6 @@ STR mem16 [m: 0f 00 /1] 286,PROT
STR reg16 [m: o16 0f 00 /1] 286,PROT
STR reg32 [m: o32 0f 00 /1] 386,PROT
STR reg64 [m: o64 0f 00 /1] X86_64,LONG
SUB mem,reg8 [mr: hle 28 /r] 8086,SM,LOCK
SUB reg8,reg8 [mr: 28 /r] 8086
SUB mem,reg16 [mr: hle o16 29 /r] 8086,SM,LOCK
SUB reg16,reg16 [mr: o16 29 /r] 8086
SUB mem,reg32 [mr: hle o32 29 /r] 386,SM,LOCK
SUB reg32,reg32 [mr: o32 29 /r] 386
SUB mem,reg64 [mr: hle o64 29 /r] X86_64,LONG,SM,LOCK
SUB reg64,reg64 [mr: o64 29 /r] X86_64,LONG
SUB reg8,mem [rm: 2a /r] 8086,SM
SUB reg8,reg8 [rm: 2a /r] 8086
SUB reg16,mem [rm: o16 2b /r] 8086,SM
SUB reg16,reg16 [rm: o16 2b /r] 8086
SUB reg32,mem [rm: o32 2b /r] 386,SM
SUB reg32,reg32 [rm: o32 2b /r] 386
SUB reg64,mem [rm: o64 2b /r] X86_64,LONG,SM
SUB reg64,reg64 [rm: o64 2b /r] X86_64,LONG
SUB rm16,imm8 [mi: hle o16 83 /5 ib,s] 8086,LOCK
SUB rm32,imm8 [mi: hle o32 83 /5 ib,s] 386,LOCK
SUB rm64,imm8 [mi: hle o64 83 /5 ib,s] X86_64,LONG,LOCK
SUB reg_al,imm [-i: 2c ib] 8086,SM
SUB reg_ax,sbyteword [mi: o16 83 /5 ib,s] 8086,SM,ND
SUB reg_ax,imm [-i: o16 2d iw] 8086,SM
SUB reg_eax,sbytedword [mi: o32 83 /5 ib,s] 386,SM,ND
SUB reg_eax,imm [-i: o32 2d id] 386,SM
SUB reg_rax,sbytedword [mi: o64 83 /5 ib,s] X86_64,LONG,SM,ND
SUB reg_rax,imm [-i: o64 2d id,s] X86_64,LONG,SM
SUB rm8,imm [mi: hle 80 /5 ib] 8086,SM,LOCK
SUB rm16,sbyteword [mi: hle o16 83 /5 ib,s] 8086,SM,LOCK,ND
SUB rm16,imm [mi: hle o16 81 /5 iw] 8086,SM,LOCK
SUB rm32,sbytedword [mi: hle o32 83 /5 ib,s] 386,SM,LOCK,ND
SUB rm32,imm [mi: hle o32 81 /5 id] 386,SM,LOCK
SUB rm64,sbytedword [mi: hle o64 83 /5 ib,s] X86_64,LONG,SM,LOCK,ND
SUB rm64,imm [mi: hle o64 81 /5 id,s] X86_64,LONG,SM,LOCK
SUB mem,imm8 [mi: hle 80 /5 ib] 8086,SM,LOCK
SUB mem,sbyteword16 [mi: hle o16 83 /5 ib,s] 8086,SM,LOCK,ND
SUB mem,imm16 [mi: hle o16 81 /5 iw] 8086,SM,LOCK
SUB mem,sbytedword32 [mi: hle o32 83 /5 ib,s] 386,SM,LOCK,ND
SUB mem,imm32 [mi: hle o32 81 /5 id] 386,SM,LOCK
SUB rm8,imm [mi: hle 82 /5 ib] 8086,SM,LOCK,ND,NOLONG
SVDC mem80,reg_sreg [mr: 0f 78 /r] 486,CYRIX,SMM
SVLDT mem80 [m: 0f 7a /0] 486,CYRIX,SMM,ND
SVTS mem80 [m: 0f 7c /0] 486,CYRIX,SMM
@ -1488,60 +1215,21 @@ XCHG reg32,mem [rm: hlenl o32 87 /r] 386,SM,LOCK1
XCHG reg64,mem [rm: hlenl o64 87 /r] X86_64,LONG,SM,LOCK1
XLATB void [ d7] 8086
XLAT void [ d7] 8086
XOR mem,reg8 [mr: hle 30 /r] 8086,SM,LOCK
XOR reg8,reg8 [mr: 30 /r] 8086
XOR mem,reg16 [mr: hle o16 31 /r] 8086,SM,LOCK
XOR reg16,reg16 [mr: o16 31 /r] 8086
XOR mem,reg32 [mr: hle o32 31 /r] 386,SM,LOCK
XOR reg32,reg32 [mr: o32 31 /r] 386
XOR mem,reg64 [mr: hle o64 31 /r] X86_64,LONG,SM,LOCK
XOR reg64,reg64 [mr: o64 31 /r] X86_64,LONG
XOR reg8,mem [rm: 32 /r] 8086,SM
XOR reg8,reg8 [rm: 32 /r] 8086
XOR reg16,mem [rm: o16 33 /r] 8086,SM
XOR reg16,reg16 [rm: o16 33 /r] 8086
XOR reg32,mem [rm: o32 33 /r] 386,SM
XOR reg32,reg32 [rm: o32 33 /r] 386
XOR reg64,mem [rm: o64 33 /r] X86_64,LONG,SM
XOR reg64,reg64 [rm: o64 33 /r] X86_64,LONG
XOR rm16,imm8 [mi: hle o16 83 /6 ib,s] 8086,LOCK
XOR rm32,imm8 [mi: hle o32 83 /6 ib,s] 386,LOCK
XOR rm64,imm8 [mi: hle o64 83 /6 ib,s] X86_64,LONG,LOCK
XOR reg_al,imm [-i: 34 ib] 8086,SM
XOR reg_ax,sbyteword [mi: o16 83 /6 ib,s] 8086,SM,ND
XOR reg_ax,imm [-i: o16 35 iw] 8086,SM
XOR reg_eax,sbytedword [mi: o32 83 /6 ib,s] 386,SM,ND
XOR reg_eax,imm [-i: o32 35 id] 386,SM
XOR reg_rax,sbytedword [mi: o64 83 /6 ib,s] X86_64,LONG,SM,ND
XOR reg_rax,imm [-i: o64 35 id,s] X86_64,LONG,SM
XOR rm8,imm [mi: hle 80 /6 ib] 8086,SM,LOCK
XOR rm16,sbyteword [mi: hle o16 83 /6 ib,s] 8086,SM,LOCK,ND
XOR rm16,imm [mi: hle o16 81 /6 iw] 8086,SM,LOCK
XOR rm32,sbytedword [mi: hle o32 83 /6 ib,s] 386,SM,LOCK,ND
XOR rm32,imm [mi: hle o32 81 /6 id] 386,SM,LOCK
XOR rm64,sbytedword [mi: hle o64 83 /6 ib,s] X86_64,LONG,SM,LOCK,ND
XOR rm64,imm [mi: hle o64 81 /6 id,s] X86_64,LONG,SM,LOCK
XOR mem,imm8 [mi: hle 80 /6 ib] 8086,SM,LOCK
XOR mem,sbyteword16 [mi: hle o16 83 /6 ib,s] 8086,SM,LOCK,ND
XOR mem,imm16 [mi: hle o16 81 /6 iw] 8086,SM,LOCK
XOR mem,sbytedword32 [mi: hle o32 83 /6 ib,s] 386,SM,LOCK,ND
XOR mem,imm32 [mi: hle o32 81 /6 id] 386,SM,LOCK
XOR rm8,imm [mi: hle 82 /6 ib] 8086,SM,LOCK,ND,NOLONG
CMOVcc reg16,mem [rm: o16 0f 40+c /r] P6,SM
CMOVcc reg16,reg16 [rm: o16 0f 40+c /r] P6
CMOVcc reg32,mem [rm: o32 0f 40+c /r] P6,SM
CMOVcc reg32,reg32 [rm: o32 0f 40+c /r] P6
CMOVcc reg64,mem [rm: o64 0f 40+c /r] X86_64,LONG,SM
CMOVcc reg64,reg64 [rm: o64 0f 40+c /r] X86_64,LONG
Jcc imm|near [i: odf 0f 80+c rel] 386,BND,NOAPX
Jcc imm16|near [i: o16 0f 80+c rel] 386,NOLONG,BND
Jcc imm32|near [i: o32 0f 80+c rel] 386,NOLONG,BND
Jcc imm64|near [i: o64nw 0f 80+c rel] X86_64,LONG,BND,NOAPX
Jcc imm|short [i: nw 70+c rel8] 8086,ND,BND,NOAPX
Jcc imm [i: jcc8 nw 70+c rel8] 8086,ND,BND,NOAPX
Jcc imm|near [i: odf 0f 80+c rel] 386,BND,SX,NOAPX
Jcc imm16|near [i: o16 0f 80+c rel] 386,NOLONG,SX,BND
Jcc imm32|near [i: o32 0f 80+c rel] 386,NOLONG,SX,BND
Jcc imm64|near [i: o64nw 0f 80+c rel] X86_64,LONG,SX,BND,NOAPX
Jcc imm|short [i: nw 70+c rel8] 8086,ND,BND,SX,NOAPX
Jcc imm8 [i: nw 70+c rel8] 8086,ND,BND,SX,NOAPX
Jcc imm [i: jcc8 nw 70+c rel8] 8086,BND,NOAPX
Jcc imm [i: nw 0f 80+c rel] 386,ND,BND,NOAPX
Jcc imm [i: nw 71+c jlen e9 rel] 8086,ND,BND,NOAPX
Jcc imm [i: nw 70+c rel8] 8086,BND,NOAPX
Jcc imm [i: nw 71+c jlen e9 rel] 8086,ND,NOAPX
SETcc rm8 [m: 0f 90+c /0] 386,SB
@ -1573,16 +1261,13 @@ CMPSS xmmreg,xmmrm32,imm8 [rmi: f3 0f c2 /r ib,u] KATMAI,SSE
COMISS xmmreg,xmmrm32 [rm: np 0f 2f /r] KATMAI,SSE
CVTPI2PS xmmreg,mmxrm64 [rm: np 0f 2a /r] KATMAI,SSE,MMX
CVTPS2PI mmxreg,xmmrm64 [rm: np 0f 2d /r] KATMAI,SSE,MMX
CVTSI2SS xmmreg,mem [rm: f3 0f 2a /r] KATMAI,SSE,SD,AR1,ND
CVTSI2SS xmmreg,rm32 [rm: f3 0f 2a /r] KATMAI,SSE,SD,AR1
CVTSI2SS xmmreg,rm64 [rm: o64 f3 0f 2a /r] X86_64,LONG,SSE,SQ,AR1
CVTSS2SI reg32,xmmreg [rm: f3 0f 2d /r] KATMAI,SSE,SD,AR1
CVTSS2SI reg32,mem [rm: f3 0f 2d /r] KATMAI,SSE,SD,AR1
CVTSS2SI reg64,xmmreg [rm: o64 f3 0f 2d /r] X86_64,LONG,SSE,SD,AR1
CVTSS2SI reg64,mem [rm: o64 f3 0f 2d /r] X86_64,LONG,SSE,SD,AR1
CVTTPS2PI mmxreg,xmmrm [rm: np 0f 2c /r] KATMAI,SSE,MMX,SQ
CVTTSS2SI reg32,xmmrm [rm: f3 0f 2c /r] KATMAI,SSE,SD,AR1
CVTTSS2SI reg64,xmmrm [rm: o64 f3 0f 2c /r] X86_64,LONG,SSE,SD,AR1
CVTSI2SS xmmreg,rm32 [rm: f3 0f 2a /r] KATMAI,SSE
CVTSI2SS xmmreg,rm64 [rm: o64 f3 0f 2a /r] X86_64,LONG,SSE,SX,AR1
CVTSS2SI reg32,xmmrm32 [rm: f3 0f 2d /r] KATMAI,SSE
CVTSS2SI reg64,xmmrm32 [rm: o64 f3 0f 2d /r] X86_64,LONG,SSE
CVTTPS2PI mmxreg,xmmrm64 [rm: np 0f 2c /r] KATMAI,SSE,MMX
CVTTSS2SI reg32,xmmrm32 [rm: f3 0f 2c /r] KATMAI,SSE
CVTTSS2SI reg64,xmmrm32 [rm: o64 f3 0f 2c /r] X86_64,LONG,SSE
DIVPS xmmreg,xmmrm128 [rm: np 0f 5e /r] KATMAI,SSE
DIVSS xmmreg,xmmrm32 [rm: f3 0f 5e /r] KATMAI,SSE
LDMXCSR mem32 [m: np 0f ae /2] KATMAI,SSE
@ -1832,22 +1517,17 @@ CVTPD2PS xmmreg,xmmrm [rm: 66 0f 5a /r] WILLAMETTE,SSE2,SO
CVTPI2PD xmmreg,mmxrm [rm: 66 0f 2a /r] WILLAMETTE,SSE2,SQ
CVTPS2DQ xmmreg,xmmrm [rm: 66 0f 5b /r] WILLAMETTE,SSE2,SO
CVTPS2PD xmmreg,xmmrm [rm: np 0f 5a /r] WILLAMETTE,SSE2,SQ
CVTSD2SI reg32,xmmreg [rm: norexw f2 0f 2d /r] WILLAMETTE,SSE2,SQ,AR1
CVTSD2SI reg32,mem [rm: norexw f2 0f 2d /r] WILLAMETTE,SSE2,SQ,AR1
CVTSD2SI reg64,xmmreg [rm: o64 f2 0f 2d /r] X86_64,LONG,SSE2,SQ,AR1
CVTSD2SI reg64,mem [rm: o64 f2 0f 2d /r] X86_64,LONG,SSE2,SQ,AR1
CVTSD2SS xmmreg,xmmrm [rm: f2 0f 5a /r] WILLAMETTE,SSE2,SQ
CVTSI2SD xmmreg,mem [rm: f2 0f 2a /r] WILLAMETTE,SSE2,SD,AR1,ND
CVTSI2SD xmmreg,rm32 [rm: norexw f2 0f 2a /r] WILLAMETTE,SSE2,SD,AR1
CVTSI2SD xmmreg,rm64 [rm: o64 f2 0f 2a /r] X86_64,LONG,SSE2,SQ,AR1
CVTSD2SI reg32,xmmrm64 [rm: norexw f2 0f 2d /r] WILLAMETTE,SSE2
CVTSD2SI reg64,xmmrm64 [rm: o64 f2 0f 2d /r] X86_64,LONG,SSE2
CVTSD2SS xmmreg,xmmrm64 [rm: f2 0f 5a /r] WILLAMETTE,SSE2,SQ
CVTSI2SD xmmreg,rm32 [rm: norexw f2 0f 2a /r] WILLAMETTE,SSE2
CVTSI2SD xmmreg,rm64 [rm: o64 f2 0f 2a /r] X86_64,LONG,SSE2,SX,AR1
CVTSS2SD xmmreg,xmmrm [rm: f3 0f 5a /r] WILLAMETTE,SSE2,SD
CVTTPD2PI mmxreg,xmmrm [rm: 66 0f 2c /r] WILLAMETTE,SSE2,SO
CVTTPD2DQ xmmreg,xmmrm [rm: 66 0f e6 /r] WILLAMETTE,SSE2,SO
CVTTPS2DQ xmmreg,xmmrm [rm: f3 0f 5b /r] WILLAMETTE,SSE2,SO
CVTTSD2SI reg32,xmmreg [rm: norexw f2 0f 2c /r] WILLAMETTE,SSE2,SQ,AR1
CVTTSD2SI reg32,mem [rm: norexw f2 0f 2c /r] WILLAMETTE,SSE2,SQ,AR1
CVTTSD2SI reg64,xmmreg [rm: o64 f2 0f 2c /r] X86_64,LONG,SSE2,SQ,AR1
CVTTSD2SI reg64,mem [rm: o64 f2 0f 2c /r] X86_64,LONG,SSE2,SQ,AR1
CVTTSD2SI reg32,xmmrm64 [rm: norexw f2 0f 2c /r] WILLAMETTE,SSE2
CVTTSD2SI reg64,xmmrm64 [rm: o64 f2 0f 2c /r] X86_64,LONG,SSE2
DIVPD xmmreg,xmmrm [rm: 66 0f 5e /r] WILLAMETTE,SSE2,SO
DIVSD xmmreg,xmmrm [rm: f2 0f 5e /r] WILLAMETTE,SSE2,SQ
MAXPD xmmreg,xmmrm [rm: 66 0f 5f /r] WILLAMETTE,SSE2,SO
@ -3636,37 +3316,37 @@ VBCSTNEBF16PS xmmreg,mem16 [rm: vex.128.f3.0f38.w0 b1 /r] AVXNECONVERT,FUTURE
VBCSTNEBF16PS ymmreg,mem16 [rm: vex.256.f3.0f38.w0 b1 /r] AVXNECONVERT,FUTURE,LATEVEX,SW
VBCSTNESH2PS xmmreg,mem16 [rm: vex.128.66.0f38.w0 b1 /r] AVXNECONVERT,FUTURE,LATEVEX,SW
VBCSTNESH2PS ymmreg,mem16 [rm: vex.256.66.0f38.w0 b1 /r] AVXNECONVERT,FUTURE,LATEVEX,SW
VCVTNEEBF162PS xmmreg,mem128 [rm: vex.128.f3.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SX
VCVTNEEBF162PS xmmreg,mem128 [rm: vex.128.f3.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SO
VCVTNEEBF162PS ymmreg,mem256 [rm: vex.256.f3.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SY
VCVTNEEPH2PS xmmreg,mem128 [rm: vex.128.66.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SX
VCVTNEEPH2PS xmmreg,mem128 [rm: vex.128.66.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SO
VCVTNEEPH2PS ymmreg,mem256 [rm: vex.256.66.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SY
VCVTNEOBF162PS xmmreg,mem128 [rm: vex.128.f2.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SX
VCVTNEOBF162PS xmmreg,mem128 [rm: vex.128.f2.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SO
VCVTNEOBF162PS ymmreg,mem256 [rm: vex.256.f2.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SY
VCVTNEOPH2PS xmmreg,mem128 [rm: vex.128.np.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SX
VCVTNEOPH2PS xmmreg,mem128 [rm: vex.128.np.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SO
VCVTNEOPH2PS ymmreg,mem256 [rm: vex.256.np.0f38.w0 b0 /r] AVXNECONVERT,FUTURE,LATEVEX,SY
VCVTNEPS2BF16 xmmreg,xmmrm128 [rm: vex.128.f3.0f38.w0 72 /r] AVXNECONVERT,FUTURE,LATEVEX,SX
VCVTNEPS2BF16 xmmreg,xmmrm128 [rm: vex.128.f3.0f38.w0 72 /r] AVXNECONVERT,FUTURE,LATEVEX,SO
VCVTNEPS2BF16 ymmreg,ymmrm256 [rm: vex.256.f3.0f38.w0 72 /r] AVXNECONVERT,FUTURE,LATEVEX,SY
;# AVX Vector Neural Network Instructions
; Must precede AVX-512 versions
VPDPBSSD xmmreg,xmmreg,xmmrm128 [rvm: vex.128.f2.0f38.w0 50 /r] AVXVNNIINT8,FUTURE,LATEVEX,SX
VPDPBSSD xmmreg,xmmreg,xmmrm128 [rvm: vex.128.f2.0f38.w0 50 /r] AVXVNNIINT8,FUTURE,LATEVEX,SO
VPDPBSSD ymmreg,ymmreg,ymmrm256 [rvm: vex.256.f2.0f38.w0 50 /r] AVXVNNIINT8,FUTURE,LATEVEX,SY
VPDPBSSDS xmmreg,xmmreg,xmmrm128 [rvm: vex.128.f2.0f38.w0 51 /r] AVXVNNIINT8,FUTURE,LATEVEX,SX
VPDPBSSDS xmmreg,xmmreg,xmmrm128 [rvm: vex.128.f2.0f38.w0 51 /r] AVXVNNIINT8,FUTURE,LATEVEX,SO
VPDPBSSDS ymmreg,ymmreg,ymmrm256 [rvm: vex.256.f2.0f38.w0 51 /r] AVXVNNIINT8,FUTURE,LATEVEX,SY
VPDPBSUD xmmreg,xmmreg,xmmrm128 [rvm: vex.128.f3.0f38.w0 50 /r] AVXVNNIINT8,FUTURE,LATEVEX,SX
VPDPBSUD xmmreg,xmmreg,xmmrm128 [rvm: vex.128.f3.0f38.w0 50 /r] AVXVNNIINT8,FUTURE,LATEVEX,SO
VPDPBSUD ymmreg,ymmreg,ymmrm256 [rvm: vex.256.f3.0f38.w0 50 /r] AVXVNNIINT8,FUTURE,LATEVEX,SY
VPDPBSUDS xmmreg,xmmreg,xmmrm128 [rvm: vex.128.f3.0f38.w0 51 /r] AVXVNNIINT8,FUTURE,LATEVEX,SX
VPDPBSUDS xmmreg,xmmreg,xmmrm128 [rvm: vex.128.f3.0f38.w0 51 /r] AVXVNNIINT8,FUTURE,LATEVEX,SO
VPDPBSUDS ymmreg,ymmreg,ymmrm256 [rvm: vex.256.f3.0f38.w0 51 /r] AVXVNNIINT8,FUTURE,LATEVEX,SY
VPDPBUUD xmmreg,xmmreg,xmmrm128 [rvm: vex.128.np.0f38.w0 50 /r] AVXVNNIINT8,FUTURE,LATEVEX,SX
VPDPBUUD xmmreg,xmmreg,xmmrm128 [rvm: vex.128.np.0f38.w0 50 /r] AVXVNNIINT8,FUTURE,LATEVEX,SO
VPDPBUUD ymmreg,ymmreg,ymmrm256 [rvm: vex.256.np.0f38.w0 50 /r] AVXVNNIINT8,FUTURE,LATEVEX,SY
VPDPBUUDS xmmreg,xmmreg,xmmrm128 [rvm: vex.128.np.0f38.w0 51 /r] AVXVNNIINT8,FUTURE,LATEVEX,SX
VPDPBUUDS xmmreg,xmmreg,xmmrm128 [rvm: vex.128.np.0f38.w0 51 /r] AVXVNNIINT8,FUTURE,LATEVEX,SO
VPDPBUUDS ymmreg,ymmreg,ymmrm256 [rvm: vex.256.np.0f38.w0 51 /r] AVXVNNIINT8,FUTURE,LATEVEX,SY
;# AVX Integer Fused Multiply-Add
; Must precede AVX-512 versions
VPMADD52HUQ xmmreg,xmmreg,xmmrm128 [rvm: vex.128.66.0f38.w1 b5 /r] AVXIFMA,FUTURE,LATEVEX,SX
VPMADD52HUQ xmmreg,xmmreg,xmmrm128 [rvm: vex.128.66.0f38.w1 b5 /r] AVXIFMA,FUTURE,LATEVEX,SO
VPMADD52HUQ ymmreg,ymmreg,ymmrm256 [rvm: vex.256.66.0f38.w1 b5 /r] AVXIFMA,FUTURE,LATEVEX,SY
VPMADD52LUQ xmmreg,xmmreg,xmmrm128 [rvm: vex.128.66.0f38.w1 b4 /r] AVXIFMA,FUTURE,LATEVEX,SX
VPMADD52LUQ xmmreg,xmmreg,xmmrm128 [rvm: vex.128.66.0f38.w1 b4 /r] AVXIFMA,FUTURE,LATEVEX,SO
VPMADD52LUQ ymmreg,ymmreg,ymmrm256 [rvm: vex.256.66.0f38.w1 b4 /r] AVXIFMA,FUTURE,LATEVEX,SY
;# AVX-512 mask register instructions
@ -6127,10 +5807,10 @@ TDPBSSD tmmreg,tmmreg,tmmreg [rmv: vex.128.f2.0f38.w0 5e /r] AMXINT8,FUTURE,L
TDPBSUD tmmreg,tmmreg,tmmreg [rmv: vex.128.f3.0f38.w0 5e /r] AMXINT8,FUTURE,LONG
TDPBUSD tmmreg,tmmreg,tmmreg [rmv: vex.128.66.0f38.w0 5e /r] AMXINT8,FUTURE,LONG
TDPBUUD tmmreg,tmmreg,tmmreg [rmv: vex.128.np.0f38.w0 5e /r] AMXINT8,FUTURE,LONG
TILELOADD tmmreg,mem [rm: vex.128.f2.0f38.w0 4b /r] AMXTILE,MIB,SIB,FUTURE,SX,LONG
TILELOADDT1 tmmreg,mem [rm: vex.128.66.0f38.w0 4b /r] AMXTILE,MIB,SIB,FUTURE,SX,LONG
TILELOADD tmmreg,mem [rm: vex.128.f2.0f38.w0 4b /r] AMXTILE,MIB,SIB,ANYSIZE,AR1,FUTURE,LONG
TILELOADDT1 tmmreg,mem [rm: vex.128.66.0f38.w0 4b /r] AMXTILE,MIB,SIB,ANYSIZE,AR1,FUTURE,LONG
TILERELEASE void [ vex.128.np.0f38.w0 49 c0] AMXTILE,FUTURE,LONG
TILESTORED mem,tmmreg [mr: vex.128.f3.0f38.w0 4b /r] AMXTILE,MIB,SIB,FUTURE,SX,LONG
TILESTORED mem,tmmreg [mr: vex.128.f3.0f38.w0 4b /r] AMXTILE,MIB,SIB,ANYSIZE,AR0,FUTURE,LONG
TILEZERO tmmreg [r: vex.128.f2.0f38.w0 49 /3r0] AMXTILE,FUTURE,LONG
;# Intel AVX512-FP16 instructions
@ -6463,59 +6143,15 @@ POPP reg64:reg64 [mv: o64nw evex.nd1.l0.np.m4.w1 8f /0 ] APX,ND
PUSHP reg64 [r: o64nw rex.w rex2 50+r ] APX
POPP reg64 [r: o64nw rex.w rex2 58+r ] APX
ADC reg8?,reg8,rm8 [vrm: evex.ndx.l0.m4.o8 12 /r ] APX
ADC reg16?,reg16,rm16 [vrm: evex.ndx.l0.m4.o16 13 /r ] APX
ADC reg32?,reg32,rm32 [vrm: evex.ndx.l0.m4.o32 13 /r ] APX,ZU
ADC reg64?,reg64,rm64 [vrm: evex.ndx.l0.m4.o64 13 /r ] APX,ZU
ADC reg8?,rm8,reg8 [vmr: evex.ndx.l0.m4.o8 10 /r ] APX
ADC reg16?,rm16,reg16 [vmr: evex.ndx.l0.m4.o16 11 /r ] APX
ADC reg32?,rm32,reg32 [vmr: evex.ndx.l0.m4.o32 11 /r ] APX,ZU
ADC reg64?,rm64,reg64 [vmr: evex.ndx.l0.m4.o64 11 /r ] APX,ZU
ADC reg8?,rm8,imm8 [vmi: evex.ndx.l0.m4.o8 80 /2 ib ] APX,SM
ADC reg16?,rm16,imm8 [vmi: evex.ndx.l0.m4.o16 83 /2 ib,s ] APX
ADC reg16?,rm16,sbyteword16 [vmi: evex.ndx.l0.m4.o16 83 /2 ib,s ] APX,SM,ND
ADC reg16?,rm16,imm16 [vmi: evex.ndx.l0.m4.o16 81 /2 iw ] APX,SM
ADC reg32?,rm32,imm8 [vmi: evex.ndx.l0.m4.o32 83 /2 ib,s ] APX
ADC reg32?,rm32,sbytedword32 [vmi: evex.ndx.l0.m4.o32 83 /2 ib,s ] APX,SM,ND
ADC reg32?,rm32,imm32 [vmi: evex.ndx.l0.m4.o32 81 /2 id ] APX,SM
ADC reg64?,rm64,imm8 [vmi: evex.ndx.l0.m4.o64 83 /2 ib,s ] APX
ADC reg64?,rm64,sbytedword32 [vmi: evex.ndx.l0.m4.o64 83 /2 ib,s ] APX,SM,ND
ADC reg64?,rm64,imm32 [vmi: evex.ndx.l0.m4.o64 81 /2 id,s ] APX
ADCX reg32?,reg32,rm32 [vrm: evex.ndx.l0.66.m4.w0 66 /r ] APX,ZU
ADCX reg64?,reg64,rm64 [vrm: evex.ndx.l0.66.m4.w1 66 /r ] APX,ZU
ADD reg8?,reg8,rm8 [vrm: evex.ndx.nf.l0.m4.o8 02 /r ] APX
ADD reg16?,reg16,rm16 [vrm: evex.ndx.nf.l0.m4.o16 03 /r ] APX
ADD reg32?,reg32,rm32 [vrm: evex.ndx.nf.l0.m4.o32 03 /r ] APX,ZU
ADD reg64?,reg64,rm64 [vrm: evex.ndx.nf.l0.m4.o64 03 /r ] APX,ZU
ADD reg8?,rm8,reg8 [vmr: evex.ndx.nf.l0.m4.o8 00 /r ] APX
ADD reg16?,rm16,reg16 [vmr: evex.ndx.nf.l0.m4.o16 01 /r ] APX
ADD reg32?,rm32,reg32 [vmr: evex.ndx.nf.l0.m4.o32 01 /r ] APX,ZU
ADD reg64?,rm64,reg64 [vmr: evex.ndx.nf.l0.m4.o64 01 /r ] APX,ZU
ADD reg8?,rm8,imm [vmi: evex.ndx.nf.l0.m4.o8 80 /0 ib ] APX,SB,AR2
ADD reg16?,rm16,imm8 [vmi: evex.ndx.nf.l0.m4.o16 83 /0 ib,s ] APX,SM0-1
ADD reg16?,rm16,sbyteword [vmi: evex.ndx.nf.l0.m4.o16 83 /0 ib,s ] APX,SM0-1,ND
ADD reg16?,rm16,imm [vmi: evex.ndx.nf.l0.m4.o16 81 /0 iw ] APX,SM0-1,SW,AR2
ADD reg32?,rm32,imm8 [vmi: evex.ndx.nf.l0.m4.o32 83 /0 ib,s ] APX,SM0-1
ADD reg32?,rm32,sbytedword [vmi: evex.ndx.nf.l0.m4.o32 83 /0 ib,s ] APX,SM0-1,ND
ADD reg32?,rm32,imm [vmi: evex.ndx.nf.l0.m4.o32 81 /0 id ] APX,SM0-1,SD,AR2
ADD reg64?,rm64,imm8 [vmi: evex.ndx.nf.l0.m4.o64 83 /0 ib,s ] APX,SM0-1
ADD reg64?,rm64,sbytedword [vmi: evex.ndx.nf.l0.m4.o64 83 /0 ib,s ] APX,SM0-1,ND
ADD reg64?,rm64,imm [vmi: evex.ndx.nf.l0.m4.o64 81 /0 id,s ] APX,SM0-1,SD,AR2
ADOX reg32?,reg32,rm32 [vrm: evex.ndx.l0.f3.m4.w0 66 /r ] APX,ZU
ADOX reg64?,reg64,rm64 [vrm: evex.ndx.l0.f3.m4.w1 66 /r ] APX,ZU
AND reg8?,reg8,rm8 [vrm: evex.ndx.nf.l0.np.m4.wig 22 /r ] APX
AND reg16?,reg16,rm16 [vrm: evex.ndx.nf.l0.66.m4.w0 23 /r ] APX
AND reg32?,reg32,rm32 [vrm: evex.ndx.nf.l0.np.m4.w0 23 /r ] APX,ZU
AND reg64?,reg64,rm64 [vrm: evex.ndx.nf.l0.np.m4.w1 23 /r ] APX,ZU
AND reg8?,rm8,reg8 [vmr: evex.ndx.nf.l0.np.m4.wig 20 /r ] APX
AND reg16?,rm16,reg16 [vmr: evex.ndx.nf.l0.66.m4.w0 21 /r ] APX
AND reg32?,rm32,reg32 [vmr: evex.ndx.nf.l0.np.m4.w0 21 /r ] APX,ZU
AND reg64?,rm64,reg64 [vmr: evex.ndx.nf.l0.np.m4.w1 21 /r ] APX,ZU
JMP imm|abs [i: a64 np rex2 a1 iq ] APX
JMP imm64|abs [i: a64 np rex2 a1 iq ] APX,SQ
JMP imm64|abs [i: a64 np rex2 a1 iq ] APX,ND
JMPABS imm [i: a64 np rex2 a1 iq ] APX,ND
JMPABS imm64 [i: a64 np rex2 a1 iq ] APX,SQ,ND
JMPABS imm64 [i: a64 np rex2 a1 iq ] APX,ND
;# Systematic names for the hinting nop instructions
; These should be last in the file

View file

@ -602,10 +602,13 @@ sub set_implied_flags($;$) {
clean_flags($flags);
# If no ARx flags, make all operands ARx
# If no ARx flags, make all operands ARx if a size
# flag is present
if (!opr_flags($flags, 'AR', $oprs)) {
for (my $i = 0; $i < $oprs; $i++) {
$flags->{"AR$i"}++;
if (defined(size_flag($flags))) {
for (my $i = 0; $i < $oprs; $i++) {
$flags->{"AR$i"}++;
}
}
}
@ -630,11 +633,14 @@ sub set_implied_flags($;$) {
$flags->{'NF'}++ if ($flags->{'NF_R'} || $flags->{'NF_E'});
}
# Return the value of any assume-size flag if one exists
# Return the value of any assume-size flag if one exists;
# SX, ANYSIZE or SIZE return 0 as they are size flags but
# don't have a known value at compile time.
sub size_flag($) {
my($flags) = @_;
my %sflags = ( 'SB' => 8, 'SW' => 16, 'SD' => 32, 'SQ' => 64,
'SO' => 128, 'SY' => 256, 'SZ' => 512 );
'ST' => 80, 'SO' => 128, 'SY' => 256, 'SZ' => 512,
'SX' => 0, 'SIZE' => 0, 'ANYSIZE' => 0 );
my($flags) = @_;
foreach my $fl (keys(%sflags)) {
if ($flags->{$fl}) {
@ -669,9 +675,6 @@ sub format_insn($$$$) {
my $nd = !!$flags{'ND'};
delete $flags{'ND'};
$flagsindex = insns_flag_index(\%flags);
die "$fname:$line: error in flags $flags\n" unless (defined($flagsindex));
# format the operands
$operands =~ s/[\*\?]//g;
$operands =~ s/:/|colon,/g;
@ -732,9 +735,6 @@ sub format_insn($$$$) {
my $nops = scalar(@ops);
# Tidy up the flags now then the operand count is known
set_implied_flags(\%flags, $nops);
while (scalar(@ops) < $MAX_OPERANDS) {
push(@ops, '0');
push(@opsize, 0);
@ -749,6 +749,9 @@ sub format_insn($$$$) {
}
$decorators =~ tr/a-z/A-Z/;
# Tidy up the flags now then the operand count is known
set_implied_flags(\%flags, $nops);
# Look for SM flags clearly inconsistent with operand bitsizes
my $ssize = 0;
for (my $i = 0; $i < $nopr; $i++) {
@ -768,7 +771,7 @@ sub format_insn($$$$) {
# This doesn't apply to registers that pre-define specific sizes;
# this should really be derived from include/opflags.h...
my $fsize = size_flag(\%flags);
if (defined($fsize)) {
if ($fsize) {
for (my $i = 0; $i < $nops; $i++) {
next unless ($arx & (1 << $i));
if ($opsize[$i] && $ops[$i] !~ /(\breg_|reg\b)/ &&
@ -778,6 +781,10 @@ sub format_insn($$$$) {
}
}
# Generate the final index into the flags table
$flagsindex = insns_flag_index(\%flags);
die "$fname:$line: error in flags $flags\n" unless (defined($flagsindex));
return ("{I_$opcode, $nops, {$operands}, $decorators, \@\@CODES-$codes\@\@, $flagsindex},", $nd);
}
@ -1055,7 +1062,7 @@ sub byte_code_compile($$) {
'nw' => 0327, # Conditional o64nw
'a16' => 0310,
'a32' => 0311,
'adf' => 0312, # Address size is default
'adf' => 0312, # Address size is default (disassembly)
'a64' => 0313,
'!osp' => 0364,
'!asp' => 0365,
@ -1080,8 +1087,6 @@ sub byte_code_compile($$) {
'rex.w' => 0347,
'resb' => 0340,
'np' => 0360, # No prefix
'jcc8' => 0370, # Match only if Jcc possible with single byte
'jmp8' => 0371, # Match only if JMP possible with single byte
'jlen' => 0373, # Length of jump
'hlexr' => 0271,
'hlenl' => 0272,
@ -1475,6 +1480,10 @@ sub byte_code_compile($$) {
push(@codes, 05) if ($oppos{'r'} & 4);
push(@codes, 010 + ($oppos{'r'} & 3), hex $1);
$prefix_ok = 0;
} elsif ($op =~ /^(jcc|jmp)8$/) {
# A relaxable jump instruction
push(@codes, $op eq 'jcc8' ? 0370 : 0371);
$flags->{'JMP_RELAX'}++;
} elsif ($op =~ /^\\([0-7]+|x[0-9a-f]{2})$/) {
# Escape to enter literal bytecodes
push(@codes, oct $1);