[nasm:nasm-2.16.xx] XCHG: adjust lock prefix warning, add specific warning for LOCK XCHG
nasm-bot for H. Peter Anvin
hpa at zytor.com
Thu Oct 12 14:54:04 PDT 2023
Commit-ID: e993b75aa6dc59fbd083ddd7c2b97751fd7bacfc
Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=e993b75aa6dc59fbd083ddd7c2b97751fd7bacfc
Author: H. Peter Anvin <hpa at zytor.com>
AuthorDate: Thu, 12 Oct 2023 14:49:53 -0700
Committer: H. Peter Anvin <hpa at zytor.com>
CommitDate: Thu, 12 Oct 2023 14:53:40 -0700
XCHG: adjust lock prefix warning, add specific warning for LOCK XCHG
"LOCK XCHG reg,mem" would issue a warning for being unlockable, which
is incorrect. In this case the RM encoding is simply an alias for the
MR encoding. Add a "LOCK1" bit to deal with that.
However, XCHG is *always* locked, so create a new warning to
explicitly flag a user-specified LOCK XCHG; default off.
Consider optimizing that prefix away in the future, but for now, let's
stick to the user-requested code sequence.
Signed-off-by: H. Peter Anvin <hpa at zytor.com>
---
asm/assemble.c | 29 +++++++++++++++++++++--------
x86/iflags.ph | 1 +
x86/insns.dat | 20 ++++++++------------
3 files changed, 30 insertions(+), 20 deletions(-)
diff --git a/asm/assemble.c b/asm/assemble.c
index dbea82cc..008b483f 100644
--- a/asm/assemble.c
+++ b/asm/assemble.c
@@ -1843,14 +1843,27 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
}
}
- if (has_prefix(ins, PPS_LOCK, P_LOCK) && lockcheck &&
- (!itemp_has(temp,IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type))) {
- /*!
- *!prefix-lock [on] LOCK prefix on unlockable instructions
- *!=lock
- *! warns about \c{LOCK} prefixes on unlockable instructions.
- */
- nasm_warn(WARN_PREFIX_LOCK|ERR_PASS2 , "instruction is not lockable");
+ if (lockcheck && has_prefix(ins, PPS_LOCK, P_LOCK)) {
+ if ((!itemp_has(temp,IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type)) &&
+ (!itemp_has(temp,IF_LOCK1) || !is_class(MEMORY, ins->oprs[1].type))) {
+ /*!
+ *!prefix-lock-error [on] LOCK prefix on unlockable instruction
+ *!=lock
+ *! warns about \c{LOCK} prefixes on unlockable instructions.
+ */
+ nasm_warn(WARN_PREFIX_LOCK_ERROR|ERR_PASS2 , "instruction is not lockable");
+ } else if (temp->opcode == I_XCHG) {
+ /*!
+ *!prefix-lock-xchg [on] superfluous LOCK prefix on XCHG instruction
+ *! warns about a \c{LOCK} prefix added to an \c{XCHG} instruction.
+ *! The \c{XCHG} instruction is \e{always} locking, and so this
+ *! prefix is not necessary; however, NASM will generate it if
+ *! explicitly provided by the user, so this warning indicates that
+ *! suboptimal code is being generated.
+ */
+ nasm_warn(WARN_PREFIX_LOCK_XCHG|ERR_PASS2,
+ "superfluous LOCK prefix on XCHG instruction");
+ }
}
bad_hle_warn(ins, hleok);
diff --git a/x86/iflags.ph b/x86/iflags.ph
index ffeb8e5b..35a672f0 100644
--- a/x86/iflags.ph
+++ b/x86/iflags.ph
@@ -34,6 +34,7 @@ if_("PRIV", "Privileged instruction");
if_("SMM", "Only valid in SMM");
if_("PROT", "Protected mode only");
if_("LOCK", "Lockable if operand 0 is memory");
+if_("LOCK1", "Lockable if operand 1 is memory");
if_("NOLONG", "Not available in long mode");
if_("LONG", "Long mode");
if_("NOHLE", "HLE prefixes forbidden");
diff --git a/x86/insns.dat b/x86/insns.dat
index 17a3f107..ae4c4b6a 100644
--- a/x86/insns.dat
+++ b/x86/insns.dat
@@ -1455,22 +1455,18 @@ XCHG reg64,reg_rax [r-: o64 90+r] X86_64,LONG
; This must be NOLONG since opcode 90 is NOP, and in 64-bit mode
; "xchg eax,eax" is *not* a NOP.
XCHG reg_eax,reg_eax [--: o32 90] 386,NOLONG
-XCHG reg8,mem [rm: hlenl 86 /r] 8086,SM,LOCK
-XCHG reg8,reg8 [rm: 86 /r] 8086
-XCHG reg16,mem [rm: hlenl o16 87 /r] 8086,SM,LOCK
-XCHG reg16,reg16 [rm: o16 87 /r] 8086
-XCHG reg32,mem [rm: hlenl o32 87 /r] 386,SM,LOCK
-XCHG reg32,reg32 [rm: o32 87 /r] 386
-XCHG reg64,mem [rm: hlenl o64 87 /r] X86_64,LONG,SM,LOCK
-XCHG reg64,reg64 [rm: o64 87 /r] X86_64,LONG
-XCHG mem,reg8 [mr: hlenl 86 /r] 8086,SM,LOCK
XCHG reg8,reg8 [mr: 86 /r] 8086
-XCHG mem,reg16 [mr: hlenl o16 87 /r] 8086,SM,LOCK
XCHG reg16,reg16 [mr: o16 87 /r] 8086
-XCHG mem,reg32 [mr: hlenl o32 87 /r] 386,SM,LOCK
XCHG reg32,reg32 [mr: o32 87 /r] 386
-XCHG mem,reg64 [mr: hlenl o64 87 /r] X86_64,LONG,SM,LOCK
XCHG reg64,reg64 [mr: o64 87 /r] X86_64,LONG
+XCHG mem,reg8 [mr: hlenl 86 /r] 8086,SM,LOCK
+XCHG mem,reg16 [mr: hlenl o16 87 /r] 8086,SM,LOCK
+XCHG mem,reg32 [mr: hlenl o32 87 /r] 386,SM,LOCK
+XCHG mem,reg64 [mr: hlenl o64 87 /r] X86_64,LONG,SM,LOCK
+XCHG reg8,mem [rm: hlenl 86 /r] 8086,SM,LOCK1
+XCHG reg16,mem [rm: hlenl o16 87 /r] 8086,SM,LOCK1
+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
More information about the Nasm-commits
mailing list