[nasm:nasm-2.15.xx] Fix inefficient encoding of MPX instructions

nasm-bot for H. Peter Anvin hpa at zytor.com
Thu Aug 13 17:24:04 PDT 2020


Commit-ID:  d988ce719c8003b85f0d32cd6d026156ef5be86f
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=d988ce719c8003b85f0d32cd6d026156ef5be86f
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Thu, 13 Aug 2020 17:16:00 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Thu, 13 Aug 2020 17:21:00 -0700

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 at zytor.com>


---
 asm/assemble.c  | 19 +++++++++++--------
 doc/changes.src |  3 +++
 include/nasm.h  | 15 ++++++++-------
 x86/iflags.ph   |  3 ++-
 x86/insns.dat   |  6 +++---
 5 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/asm/assemble.c b/asm/assemble.c
index c82fcb1d..4801ad87 100644
--- a/asm/assemble.c
+++ b/asm/assemble.c
@@ -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;
 
diff --git a/doc/changes.src b/doc/changes.src
index eb0031cc..6f6c5b7b 100644
--- a/doc/changes.src
+++ b/doc/changes.src
@@ -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
diff --git a/include/nasm.h b/include/nasm.h
index 950ac45b..cf8b808e 100644
--- a/include/nasm.h
+++ b/include/nasm.h
@@ -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' */
diff --git a/x86/iflags.ph b/x86/iflags.ph
index 7067d740..7a1e13f5 100644
--- a/x86/iflags.ph
+++ b/x86/iflags.ph
@@ -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");
diff --git a/x86/insns.dat b/x86/insns.dat
index 18b573a6..a65180a5 100644
--- a/x86/insns.dat
+++ b/x86/insns.dat
@@ -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


More information about the Nasm-commits mailing list