Fix inefficient encoding of MPX instructions

BNDMK, BNDLDX, and BNDSTX are split-SIB (MIB) instructions, but do
*not* require a SIB encoding. However, TILELOAD* and TILESTORE* *do*
require a SIB in all cases. Split the MIB flag into MIB (split
address) and SIB (SIB required) flags.

This fixes travis test mpx.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2020-08-13 17:16:00 -07:00
parent 7839766663
commit d988ce719c
5 changed files with 27 additions and 19 deletions

View file

@ -1226,7 +1226,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
enum ea_type eat;
uint8_t hleok = 0;
bool lockcheck = true;
enum reg_enum mib_index = R_none; /* For a separate index MIB reg form */
enum reg_enum mib_index = R_none; /* For a separate index reg form */
const char *errmsg;
ins->rex = 0; /* Ensure REX is reset */
@ -1262,7 +1262,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
break;
case4(014):
/* this is an index reg of MIB operand */
/* this is an index reg of a split SIB operand */
mib_index = opx->basereg;
break;
@ -1592,6 +1592,10 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
}
}
/* SIB encoding required */
if (itemp_has(temp, IF_SIB))
opy->eaflags |= EAF_SIB;
if (process_ea(opy, &ea_data, bits,
rfield, rflags, ins, &errmsg) != eat) {
nasm_nonfatal("%s", errmsg);
@ -2813,9 +2817,8 @@ static enum ea_type process_ea(operand *input, ea *output, int bits,
}
}
if (bits == 64 &&
!(IP_REL & ~input->type) && (eaflags & EAF_MIB)) {
*errmsg = "RIP-relative addressing is prohibited for MIB";
if (bits == 64 && !(IP_REL & ~input->type) && (eaflags & EAF_SIB)) {
*errmsg = "instruction requires SIB encoding, cannot be RIP-relative";
goto err;
}
@ -2824,7 +2827,7 @@ static enum ea_type process_ea(operand *input, ea *output, int bits,
input->disp_size != (addrbits != 16 ? 32 : 16)))
nasm_warn(WARN_OTHER, "displacement size ignored on absolute address");
if ((eaflags & EAF_MIB) || (bits == 64 && (~input->type & IP_REL))) {
if ((eaflags & EAF_SIB) || (bits == 64 && (~input->type & IP_REL))) {
output->sib_present = true;
output->sib = GEN_SIB(0, 4, 5);
output->bytes = 4;
@ -3002,7 +3005,7 @@ static enum ea_type process_ea(operand *input, ea *output, int bits,
bt = it, bx = ix, it = -1, ix = 0;
}
if (eaflags & EAF_MIB) {
/* only for mib operands */
/* MIB/split-SIB encoding */
if (it == -1 && (hb == b && ht == EAH_NOTBASE)) {
/*
* make a single reg index [reg*1].
@ -3043,7 +3046,7 @@ static enum ea_type process_ea(operand *input, ea *output, int bits,
output->rex |= rexflags(it, ix, REX_X);
output->rex |= rexflags(bt, bx, REX_B);
if (it == -1 && (bt & 7) != REG_NUM_ESP && !(eaflags & EAF_MIB)) {
if (it == -1 && (bt & 7) != REG_NUM_ESP && !(eaflags & EAF_SIB)) {
/* no SIB needed */
int mod, rm;

View file

@ -37,6 +37,9 @@ useful to debug NASM crashes. See \k{opt-L}.
\b Fix the \c{__float80e__} and \c{__float128h__} conversions, which
would return the wrong bytes of the result.
\b Fix inefficient encoding of the \c{BNDMK}, \c{BNDLDX}, and
\c{BNDSTX} instructions under certain circumstances.
\S{cl-2.15.03} Version 2.15.03
\b Add instructions from the Intel Instruction Set Extensions and

View file

@ -553,13 +553,14 @@ enum prefixes { /* instruction prefixes */
};
enum ea_flags { /* special EA flags */
EAF_BYTEOFFS = 1, /* force offset part to byte size */
EAF_WORDOFFS = 2, /* force offset part to [d]word size */
EAF_TIMESTWO = 4, /* really do EAX*2 not EAX+EAX */
EAF_REL = 8, /* IP-relative addressing */
EAF_ABS = 16, /* non-IP-relative addressing */
EAF_FSGS = 32, /* fs/gs segment override present */
EAF_MIB = 64 /* mib operand */
EAF_BYTEOFFS = 1, /* force offset part to byte size */
EAF_WORDOFFS = 2, /* force offset part to [d]word size */
EAF_TIMESTWO = 4, /* really do EAX*2 not EAX+EAX */
EAF_REL = 8, /* IP-relative addressing */
EAF_ABS = 16, /* non-IP-relative addressing */
EAF_FSGS = 32, /* fs/gs segment override present */
EAF_MIB = 64, /* mib operand */
EAF_SIB = 128 /* SIB encoding obligatory */
};
enum eval_hint { /* values for `hinttype' */

View file

@ -36,7 +36,8 @@ if_("LOCK", "Lockable if operand 0 is memory");
if_("NOLONG", "Not available in long mode");
if_("LONG", "Long mode");
if_("NOHLE", "HLE prefixes forbidden");
if_("MIB", "disassemble with split EA");
if_("MIB", "split base/index EA");
if_("SIB", "SIB encoding required");
if_("BND", "BND (0xF2) prefix available");
if_("UNDOC", "Undocumented");
if_("HLE", "HLE prefixed");

View file

@ -6049,10 +6049,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,FUTURE,SX,LONG
TILELOADDT1 tmmreg,mem [rm: vex.128.66.0f38.w0 4b /r] AMXTILE,MIB,FUTURE,SX,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
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,FUTURE,SX,LONG
TILESTORED mem,tmmreg [mr: vex.128.f3.0f38.w0 4b /r] AMXTILE,MIB,SIB,FUTURE,SX,LONG
TILEZERO tmmreg [r: vex.128.f2.0f38.w0 49 /3r0] AMXTILE,FUTURE,LONG
;# Systematic names for the hinting nop instructions