From d9c93e06aece2d3c589e095aae28b0ec726851c9 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Mon, 26 Jan 2026 23:01:03 +0100 Subject: [PATCH 01/13] insns.dat: Fix issue #186 - scalar AVX512 instructions treated as vector operations Multiple AVX512 instructions were incorrectly encoded when it comes to the embedded rounding value - they were treated as 128 bit vector operations when in reality they are scalar operations. Correct the following instructions' EVEX encodings: VCVTSD2SI VCVTSD2USI VCVTSS2SI VCVTSS2USI VCVTTSD2SI VCVTTSD2USI VCVTTSS2SI VCVTTSS2USI VGETEXPSH VGETMANTSH Signed-off-by: Maciej Wieczor-Retman --- x86/insns.dat | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/x86/insns.dat b/x86/insns.dat index 8e4bfa097..695995d47 100644 --- a/x86/insns.dat +++ b/x86/insns.dat @@ -3568,20 +3568,20 @@ VCVTQQ2PD zmmreg|mask|z,zmmrm512|b64|er [rm:fv: evex.512.f3.0f.w1 e6 VCVTQQ2PS xmmreg|mask|z,xmmrm128|b64 [rm:fv: evex.128.0f.w1 5b /r ] AVX512VL,AVX512DQ VCVTQQ2PS xmmreg|mask|z,ymmrm256|b64 [rm:fv: evex.256.0f.w1 5b /r ] AVX512VL,AVX512DQ VCVTQQ2PS ymmreg|mask|z,zmmrm512|b64|er [rm:fv: evex.512.0f.w1 5b /r ] AVX512DQ -VCVTSD2SI reg32,xmmrm64|er [rm:t1f64: evex.128.f2.0f.w0 2d /r ] AVX512 -VCVTSD2SI reg64,xmmrm64|er [rm:t1f64: evex.128.f2.0f.w1 2d /r ] AVX512 +VCVTSD2SI reg32,xmmrm64|er [rm:t1f64: evex.lig.f2.0f.w0 2d /r ] AVX512 +VCVTSD2SI reg64,xmmrm64|er [rm:t1f64: evex.lig.f2.0f.w1 2d /r ] AVX512 VCVTSD2SS xmmreg|mask|z,xmmreg*,xmmrm64|er [rvm:t1s: evex.nds.lig.f2.0f.w1 5a /r ] AVX512 -VCVTSD2USI reg32,xmmrm64|er [rm:t1f64: evex.128.f2.0f.w0 79 /r ] AVX512 -VCVTSD2USI reg64,xmmrm64|er [rm:t1f64: evex.128.f2.0f.w1 79 /r ] AVX512 +VCVTSD2USI reg32,xmmrm64|er [rm:t1f64: evex.lig.f2.0f.w0 79 /r ] AVX512 +VCVTSD2USI reg64,xmmrm64|er [rm:t1f64: evex.lig.f2.0f.w1 79 /r ] AVX512 VCVTSI2SD xmmreg,xmmreg*,rm32 [rvm:t1s: evex.nds.lig.f2.0f.w0 2a /r ] AVX512 VCVTSI2SD xmmreg,xmmreg*,rm64|er [rvm:t1s: evex.nds.lig.f2.0f.w1 2a /r ] AVX512 VCVTSI2SS xmmreg,xmmreg*,rm32|er [rvm:t1s: evex.nds.lig.f3.0f.w0 2a /r ] AVX512 VCVTSI2SS xmmreg,xmmreg*,rm64|er [rvm:t1s: evex.nds.lig.f3.0f.w1 2a /r ] AVX512 VCVTSS2SD xmmreg|mask|z,xmmreg*,xmmrm32|sae [rvm:t1s: evex.nds.lig.f3.0f.w0 5a /r ] AVX512 -VCVTSS2SI reg32,xmmrm32|er [rm:t1f32: evex.128.f3.0f.w0 2d /r ] AVX512 -VCVTSS2SI reg64,xmmrm32|er [rm:t1f32: evex.128.f3.0f.w1 2d /r ] AVX512 -VCVTSS2USI reg32,xmmrm32|er [rm:t1f32: evex.128.f3.0f.w0 79 /r ] AVX512 -VCVTSS2USI reg64,xmmrm32|er [rm:t1f32: evex.128.f3.0f.w1 79 /r ] AVX512 +VCVTSS2SI reg32,xmmrm32|er [rm:t1f32: evex.lig.f3.0f.w0 2d /r ] AVX512 +VCVTSS2SI reg64,xmmrm32|er [rm:t1f32: evex.lig.f3.0f.w1 2d /r ] AVX512 +VCVTSS2USI reg32,xmmrm32|er [rm:t1f32: evex.lig.f3.0f.w0 79 /r ] AVX512 +VCVTSS2USI reg64,xmmrm32|er [rm:t1f32: evex.lig.f3.0f.w1 79 /r ] AVX512 VCVTTPD2DQ xmmreg|mask|z,xmmrm128|b64 [rm:fv: evex.128.66.0f.w1 e6 /r ] AVX512VL,AVX512 VCVTTPD2DQ xmmreg|mask|z,ymmrm256|b64 [rm:fv: evex.256.66.0f.w1 e6 /r ] AVX512VL,AVX512 VCVTTPD2DQ ymmreg|mask|z,zmmrm512|b64|sae [rm:fv: evex.512.66.0f.w1 e6 /r ] AVX512 @@ -3606,14 +3606,14 @@ VCVTTPS2UDQ zmmreg|mask|z,zmmrm512|b32|sae [rm:fv: evex.512.0f.w0 78 /r VCVTTPS2UQQ xmmreg|mask|z,xmmrm64|b32 [rm:hv: evex.128.66.0f.w0 78 /r ] AVX512VL,AVX512DQ VCVTTPS2UQQ ymmreg|mask|z,xmmrm128|b32 [rm:hv: evex.256.66.0f.w0 78 /r ] AVX512VL,AVX512DQ VCVTTPS2UQQ zmmreg|mask|z,ymmrm256|b32|sae [rm:hv: evex.512.66.0f.w0 78 /r ] AVX512DQ -VCVTTSD2SI reg32,xmmrm64|sae [rm:t1f64: evex.128.f2.0f.w0 2c /r ] AVX512 -VCVTTSD2SI reg64,xmmrm64|sae [rm:t1f64: evex.128.f2.0f.w1 2c /r ] AVX512 -VCVTTSD2USI reg32,xmmrm64|sae [rm:t1f64: evex.128.f2.0f.w0 78 /r ] AVX512 -VCVTTSD2USI reg64,xmmrm64|sae [rm:t1f64: evex.128.f2.0f.w1 78 /r ] AVX512 -VCVTTSS2SI reg32,xmmrm32|sae [rm:t1f32: evex.128.f3.0f.w0 2c /r ] AVX512 -VCVTTSS2SI reg64,xmmrm32|sae [rm:t1f32: evex.128.f3.0f.w1 2c /r ] AVX512 -VCVTTSS2USI reg32,xmmrm32|sae [rm:t1f32: evex.128.f3.0f.w0 78 /r ] AVX512 -VCVTTSS2USI reg64,xmmrm32|sae [rm:t1f32: evex.128.f3.0f.w1 78 /r ] AVX512 +VCVTTSD2SI reg32,xmmrm64|sae [rm:t1f64: evex.lig.f2.0f.w0 2c /r ] AVX512 +VCVTTSD2SI reg64,xmmrm64|sae [rm:t1f64: evex.lig.f2.0f.w1 2c /r ] AVX512 +VCVTTSD2USI reg32,xmmrm64|sae [rm:t1f64: evex.lig.f2.0f.w0 78 /r ] AVX512 +VCVTTSD2USI reg64,xmmrm64|sae [rm:t1f64: evex.lig.f2.0f.w1 78 /r ] AVX512 +VCVTTSS2SI reg32,xmmrm32|sae [rm:t1f32: evex.lig.f3.0f.w0 2c /r ] AVX512 +VCVTTSS2SI reg64,xmmrm32|sae [rm:t1f32: evex.lig.f3.0f.w1 2c /r ] AVX512 +VCVTTSS2USI reg32,xmmrm32|sae [rm:t1f32: evex.lig.f3.0f.w0 78 /r ] AVX512 +VCVTTSS2USI reg64,xmmrm32|sae [rm:t1f32: evex.lig.f3.0f.w1 78 /r ] AVX512 VCVTUDQ2PD xmmreg|mask|z,xmmrm64|b32 [rm:hv: evex.128.f3.0f.w0 7a /r ] AVX512VL,AVX512 VCVTUDQ2PD ymmreg|mask|z,xmmrm128|b32 [rm:hv: evex.256.f3.0f.w0 7a /r ] AVX512VL,AVX512 VCVTUDQ2PD zmmreg|mask|z,ymmrm256|b32|er [rm:hv: evex.512.f3.0f.w0 7a /r ] AVX512 @@ -5623,11 +5623,11 @@ VFPCLASSSH kreg|mask,xmmrm16,imm8 [rmi:t1s: evex.lig.np.0f3a.w0 67 /r ib] AVX5 VGETEXPPH xmmreg|mask|z,xmmrm128|b16 [rm:fv: evex.128.66.map6.w0 42 /r] AVX512FP16,AVX512VL VGETEXPPH ymmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.66.map6.w0 42 /r] AVX512FP16,AVX512VL VGETEXPPH zmmreg|mask|z,zmmrm512|b16|sae [rm:fv: evex.512.66.map6.w0 42 /r] AVX512FP16 -VGETEXPSH xmmreg|mask|z,xmmrm16|sae [rm:t1s: evex.128.66.map6.w0 43 /r] AVX512FP16 +VGETEXPSH xmmreg|mask|z,xmmrm16|sae [rm:t1s: evex.lig.66.map6.w0 43 /r] AVX512FP16 VGETMANTPH xmmreg|mask|z,xmmrm128|b16,imm8 [rmi:fv: evex.128.np.0f3a.w0 26 /r ib] AVX512FP16,AVX512VL VGETMANTPH ymmreg|mask|z,ymmrm256|b16,imm8 [rmi:fv: evex.256.np.0f3a.w0 26 /r ib] AVX512FP16,AVX512VL VGETMANTPH zmmreg|mask|z,zmmrm512|b16|sae,imm8 [rmi:fv: evex.512.np.0f3a.w0 26 /r ib] AVX512FP16 -VGETMANTSH xmmreg|mask|z,xmmrm16|sae,imm8 [rmi:t1s: evex.128.np.0f3a.w0 27 /r ib] AVX512FP16 +VGETMANTSH xmmreg|mask|z,xmmrm16|sae,imm8 [rmi:t1s: evex.lig.np.0f3a.w0 27 /r ib] AVX512FP16 VMAXPH xmmreg|mask|z,xmmreg*,xmmrm128|b16 [rvm:fv: evex.128.np.map5.w0 5f /r ] AVX512FP16,AVX512VL VMAXPH ymmreg|mask|z,ymmreg*,ymmrm256|b16 [rvm:fv: evex.256.np.map5.w0 5f /r ] AVX512FP16,AVX512VL VMAXPH zmmreg|mask|z,zmmreg*,zmmrm512|b16|sae [rvm:fv: evex.512.np.map5.w0 5f /r ] AVX512FP16 From 5c224e169ef74cb78f73901fb342ead57a533587 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Tue, 2 Dec 2025 10:49:31 +0100 Subject: [PATCH 02/13] insns.dat: Fix typos and incorrect operands Fix errors found through comparing XED and NASM instruction encodings. From APX the UWRMSR instruction had swapped operands. Most fixes related to AVX/AVX512 deal with operand sizes not matching the SDM nor the XED produced encodings. Some (like VGETEXPSH) had a wrong amont of operands. Others (like VP4DPWSSDS) had misspelled mnemonics. At last some AVX10.2 instructions had wrong operands sizes that didn't match the newest (june 2025) AVX10.2 documentation. Signed-off-by: Maciej Wieczor-Retman --- x86/insns.dat | 78 +++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/x86/insns.dat b/x86/insns.dat index 695995d47..00b6e52c1 100644 --- a/x86/insns.dat +++ b/x86/insns.dat @@ -458,9 +458,9 @@ WRMSRLIST void [ f3 0f 01 c6 ] PRIV,MSRLIST,LONG URDMSR reg64,reg64 [mr: f2 0f 38 f8 /r ] FUTURE,NOAPX URDMSR reg64,reg64 [mr: evex.nf0.nd0.l0.f2.m4.w0 f8 /r] APX,FUTURE URDMSR reg64,imm32 [mi: vex+.128.f2.m7.w0 f8 /0 id] FUTURE -UWRMSR reg64,reg64 [mr: f3 0f 38 f8 /r ] FUTURE,NOAPX -UWRMSR reg64,reg64 [mr: evex.nf0.nd0.l0.f3.m4.w0 f8 /r] APX,FUTURE -UWRMSR reg64,imm32 [mi: vex+.128.f3.m7.w0 f8 /0 id] FUTURE +UWRMSR reg64,reg64 [rm: f3 0f 38 f8 /r ] FUTURE,NOAPX +UWRMSR reg64,reg64 [rm: evex.nf0.nd0.l0.f3.m4.w0 f8 /r] APX,FUTURE +UWRMSR imm32,reg64 [im: vex+.128.f3.m7.w0 f8 /0 id] FUTURE $bwd UMOV rm#,reg# [mr: np o# 0f 10# /r] 386,UNDOC,SM,ND,NOLONG,OBSOLETE $bwd UMOV reg#,rm# [rm: np o# 0f 12# /r] 386,UNDOC,SM,ND,NOLONG,OBSOLETE @@ -1249,7 +1249,7 @@ CMPUNORDSD xmmreg,xmmrm [rm: f2 0f c2 /r 03] WILLAMETTE,SSE2,SQ ; CMPPD/CMPSD must come after the specific ops; that way the disassembler will find the ; specific ops first and only disassemble illegal ones as cmppd/cmpsd. CMPPD xmmreg,xmmrm128,imm8 [rmi: 66 0f c2 /r ib,u] WILLAMETTE,SSE2 -CMPSD xmmreg,xmmrm128,imm8 [rmi: f2 0f c2 /r ib,u] WILLAMETTE,SSE2 +CMPSD xmmreg,xmmrm64,imm8 [rmi: f2 0f c2 /r ib,u] WILLAMETTE,SSE2 COMISD xmmreg,xmmrm64 [rm: 66 0f 2f /r] WILLAMETTE,SSE2 CVTDQ2PD xmmreg,xmmrm [rm: f3 0f e6 /r] WILLAMETTE,SSE2,SQ CVTDQ2PS xmmreg,xmmrm [rm: np 0f 5b /r] WILLAMETTE,SSE2,SO @@ -1849,7 +1849,7 @@ VCMPNEQ_OSSS xmmreg,xmmreg*,xmmrm64 [rvm: vex.nds.lig.f3.0f c2 /r 1c] AVX,SAND VCMPGE_OQSS xmmreg,xmmreg*,xmmrm64 [rvm: vex.nds.lig.f3.0f c2 /r 1d] AVX,SANDYBRIDGE VCMPGT_OQSS xmmreg,xmmreg*,xmmrm64 [rvm: vex.nds.lig.f3.0f c2 /r 1e] AVX,SANDYBRIDGE VCMPTRUE_USSS xmmreg,xmmreg*,xmmrm64 [rvm: vex.nds.lig.f3.0f c2 /r 1f] AVX,SANDYBRIDGE -VCMPSS xmmreg,xmmreg*,xmmrm64,imm8 [rvmi: vex.nds.lig.f3.0f c2 /r ib] AVX,SANDYBRIDGE +VCMPSS xmmreg,xmmreg*,xmmrm32,imm8 [rvmi: vex.nds.lig.f3.0f c2 /r ib] AVX,SANDYBRIDGE VCOMISD xmmreg,xmmrm64 [rm: vex.lig.66.0f 2f /r] AVX,SANDYBRIDGE VCOMISS xmmreg,xmmrm32 [rm: vex.lig.0f 2f /r] AVX,SANDYBRIDGE VCVTDQ2PD xmmreg,xmmrm64 [rm: vex.128.f3.0f e6 /r] AVX,SANDYBRIDGE @@ -5308,12 +5308,12 @@ VPSHUFBITQMB kreg|mask,zmmreg,zmmrm512 [rvm:fvm: evex.nds.512.66.0f38.w0 8f /r ;# AVX512 4-iteration Multiply-Add V4FMADDPS zmmreg|mask|z,zmmreg|rs4,mem [rvm:m128:evex.dds.512.f2.0f38.w0 9a /r] AVX5124FMAPS,SO V4FNMADDPS zmmreg|mask|z,zmmreg|rs4,mem [rvm:m128:evex.dds.512.f2.0f38.w0 aa /r] AVX5124FMAPS,SO -V4FMADDSS zmmreg|mask|z,zmmreg|rs4,mem [rvm:m128:evex.dds.lig.f2.0f38.w0 9b /r] AVX5124FMAPS,SO -V4FNMADDSS zmmreg|mask|z,zmmreg|rs4,mem [rvm:m128:evex.dds.lig.f2.0f38.w0 ab /r] AVX5124FMAPS,SO +V4FMADDSS xmmreg|mask|z,xmmreg|rs4,mem [rvm:m128:evex.dds.lig.f2.0f38.w0 9b /r] AVX5124FMAPS,SO +V4FNMADDSS xmmreg|mask|z,xmmreg|rs4,mem [rvm:m128:evex.dds.lig.f2.0f38.w0 ab /r] AVX5124FMAPS,SO ;# AVX512 4-iteration Dot Product -V4DPWSSDS zmmreg|mask|z,zmmreg|rs4,mem [rvm:m128:evex.dds.512.f2.0f38.w0 53 /r] AVX5124VNNIW,SO -V4DPWSSD zmmreg|mask|z,zmmreg|rs4,mem [rvm:m128:evex.dds.512.f2.0f38.w0 52 /r] AVX5124VNNIW,SO +VP4DPWSSDS zmmreg|mask|z,zmmreg|rs4,mem [rvm:m128:evex.dds.512.f2.0f38.w0 53 /r] AVX5124VNNIW,SO +VP4DPWSSD zmmreg|mask|z,zmmreg|rs4,mem [rvm:m128:evex.dds.512.f2.0f38.w0 52 /r] AVX5124VNNIW,SO ;# Intel Software Guard Extensions (SGX) ENCLS void [ np 0f 01 cf] SGX @@ -5440,11 +5440,11 @@ VCMPPH kreg|mask,zmmreg*,zmmrm512|b16|sae,imm8 [rvmi:fv: evex.nds.512.np.0f3a.w VCMPSH kreg|mask,xmmreg*,xmmrm16|sae,imm8 [rvmi:t1s: evex.nds.lig.f3.0f3a.w0 C2 /r ib] AVX512FP16 VCOMISH xmmreg,xmmrm16|sae [rm:fv: evex.lig.np.map5.w0 2F /r] AVX512FP16 VCVTDQ2PH xmmreg|mask|z,xmmrm128|b32 [rm:fv: evex.128.np.map5.w0 5B /r] AVX512FP16,AVX512VL -VCVTDQ2PH ymmreg|mask|z,ymmrm256|b32 [rm:fv: evex.256.np.map5.w0 5B /r] AVX512FP16,AVX512VL -VCVTDQ2PH zmmreg|mask|z,zmmrm512|b32|er [rm:fv: evex.512.np.map5.w0 5B /r] AVX512FP16 +VCVTDQ2PH xmmreg|mask|z,ymmrm256|b32 [rm:fv: evex.256.np.map5.w0 5B /r] AVX512FP16,AVX512VL +VCVTDQ2PH ymmreg|mask|z,zmmrm512|b32|er [rm:fv: evex.512.np.map5.w0 5B /r] AVX512FP16 VCVTPD2PH xmmreg|mask|z,xmmrm128|b64 [rm:fv: evex.128.66.map5.w1 5A /r] AVX512FP16,AVX512VL -VCVTPD2PH ymmreg|mask|z,ymmrm256|b64 [rm:fv: evex.256.66.map5.w1 5A /r] AVX512FP16,AVX512VL -VCVTPD2PH zmmreg|mask|z,zmmrm512|b64|er [rm:fv: evex.512.66.map5.w1 5A /r] AVX512FP16 +VCVTPD2PH xmmreg|mask|z,ymmrm256|b64 [rm:fv: evex.256.66.map5.w1 5A /r] AVX512FP16,AVX512VL +VCVTPD2PH xmmreg|mask|z,zmmrm512|b64|er [rm:fv: evex.512.66.map5.w1 5A /r] AVX512FP16 VCVTPH2DQ xmmreg|mask|z,xmmrm64|b16 [rm:hv: evex.128.66.map5.w0 5B /r] AVX512FP16,AVX512VL VCVTPH2DQ ymmreg|mask|z,xmmrm128|b16 [rm:hv: evex.256.66.map5.w0 5B /r] AVX512FP16,AVX512VL VCVTPH2DQ zmmreg|mask|z,ymmrm256|b16|er [rm:hv: evex.512.66.map5.w0 5B /r] AVX512FP16 @@ -5460,9 +5460,9 @@ VCVTPH2PSX zmmreg|mask|z,ymmrm256|b16|sae [rm:hv: evex.512.66.map6.w0 13 /r] AVX VCVTPH2QQ xmmreg|mask|z,xmmrm32|b16 [rm:qvm:evex.128.66.map5.w0 7b /r] AVX512FP16,AVX512VL VCVTPH2QQ ymmreg|mask|z,xmmrm64|b16 [rm:qvm:evex.256.66.map5.w0 7b /r] AVX512FP16,AVX512VL VCVTPH2QQ zmmreg|mask|z,xmmrm128|b16|er [rm:qvm:evex.512.66.map5.w0 7b /r] AVX512FP16 -VCVTPH2UDQ xmmreg|mask|z,xmmrm32|b16 [rm:hv: evex.128.map5.w0 79 /r] AVX512FP16,AVX512VL -VCVTPH2UDQ ymmreg|mask|z,xmmrm64|b16 [rm:hv: evex.256.map5.w0 79 /r] AVX512FP16,AVX512VL -VCVTPH2UDQ zmmreg|mask|z,xmmrm128|b16|er [rm:hv: evex.512.map5.w0 79 /r] AVX512FP16 +VCVTPH2UDQ xmmreg|mask|z,xmmrm64|b16 [rm:hv: evex.128.map5.w0 79 /r] AVX512FP16,AVX512VL +VCVTPH2UDQ ymmreg|mask|z,xmmrm128|b16 [rm:hv: evex.256.map5.w0 79 /r] AVX512FP16,AVX512VL +VCVTPH2UDQ zmmreg|mask|z,ymmrm256|b16|er [rm:hv: evex.512.map5.w0 79 /r] AVX512FP16 VCVTPH2UQQ xmmreg|mask|z,xmmrm32|b16 [rm:qvm:evex.128.66.map5.w0 79 /r] AVX512FP16,AVX512VL VCVTPH2UQQ ymmreg|mask|z,xmmrm64|b16 [rm:qvm:evex.256.66.map5.w0 79 /r] AVX512FP16,AVX512VL VCVTPH2UQQ zmmreg|mask|z,xmmrm128|b16|er [rm:qvm:evex.512.66.map5.w0 79 /r] AVX512FP16 @@ -5482,8 +5482,8 @@ VCVTPS2PHX xmmreg|mask|z,xmmrm128|b32 [rm:fv: evex.128.66.map5.w0 1d /r] AVX512F VCVTPS2PHX xmmreg|mask|z,ymmrm256|b32 [rm:fv: evex.256.66.map5.w0 1d /r] AVX512FP16,AVX512VL VCVTPS2PHX ymmreg|mask|z,zmmrm512|b32|er [rm:fv: evex.512.66.map5.w0 1d /r] AVX512FP16 VCVTQQ2PH xmmreg|mask|z,xmmrm128|b64 [rm:fv: evex.128.np.map5.w1 5b /r] AVX512FP16,AVX512VL -VCVTQQ2PH ymmreg|mask|z,ymmrm256|b64 [rm:fv: evex.256.np.map5.w1 5b /r] AVX512FP16,AVX512VL -VCVTQQ2PH zmmreg|mask|z,zmmrm512|b64|er [rm:fv: evex.512.np.map5.w1 5b /r] AVX512FP16,AVX512VL +VCVTQQ2PH xmmreg|mask|z,ymmrm256|b64 [rm:fv: evex.256.np.map5.w1 5b /r] AVX512FP16,AVX512VL +VCVTQQ2PH xmmreg|mask|z,zmmrm512|b64|er [rm:fv: evex.512.np.map5.w1 5b /r] AVX512FP16,AVX512VL VCVTSD2SH xmmreg|mask|z,xmmreg*,xmmrm64|er [rvm:t1s: evex.nds.lig.f2.map5.w1 5a /r] AVX512FP16 VCVTSH2SD xmmreg,xmmreg*,xmmrm16|sae [rvm:t1s: evex.nds.lig.f3.map5.w0 5a /r] AVX512FP16 VCVTSH2SI reg32,xmmrm16|er [rm:t1s:evex.lig.f3.map5.w0 2d /r] AVX512FP16 @@ -5517,11 +5517,11 @@ VCVTTSH2SI reg64,xmmrm16|sae [rm:t1s:evex.lig.f3.map5.w1 2c /r] AVX512FP16 VCVTTSH2USI reg32,xmmrm16|sae [rm:t1s:evex.lig.f3.map5.w0 78 /r] AVX512FP16 VCVTTSH2USI reg64,xmmrm16|sae [rm:t1s:evex.lig.f3.map5.w1 78 /r] AVX512FP16 VCVTUDQ2PH xmmreg|mask|z,xmmrm128|b32 [rm:fv: evex.128.f2.map5.w0 7a /r] AVX512FP16,AVX512VL -VCVTUDQ2PH ymmreg|mask|z,ymmrm256|b32 [rm:fv: evex.256.f2.map5.w0 7a /r] AVX512FP16,AVX512VL -VCVTUDQ2PH zmmreg|mask|z,zmmrm512|b32 [rm:fv: evex.512.f2.map5.w0 7a /r] AVX512FP16 +VCVTUDQ2PH xmmreg|mask|z,ymmrm256|b32 [rm:fv: evex.256.f2.map5.w0 7a /r] AVX512FP16,AVX512VL +VCVTUDQ2PH ymmreg|mask|z,zmmrm512|b32 [rm:fv: evex.512.f2.map5.w0 7a /r] AVX512FP16 VCVTUQQ2PH xmmreg|mask|z,xmmrm128|b32 [rm:fv: evex.128.f2.map5.w1 7a /r] AVX512FP16,AVX512VL -VCVTUQQ2PH ymmreg|mask|z,ymmrm256|b32 [rm:fv: evex.256.f2.map5.w1 7a /r] AVX512FP16,AVX512VL -VCVTUQQ2PH zmmreg|mask|z,zmmrm512|b32 [rm:fv: evex.512.f2.map5.w1 7a /r] AVX512FP16 +VCVTUQQ2PH xmmreg|mask|z,ymmrm256|b32 [rm:fv: evex.256.f2.map5.w1 7a /r] AVX512FP16,AVX512VL +VCVTUQQ2PH xmmreg|mask|z,zmmrm512|b32 [rm:fv: evex.512.f2.map5.w1 7a /r] AVX512FP16 VCVTUSI2SH xmmreg,xmmreg|er,rm32|er [rvm:t1s: evex.nds.lig.f3.map5.w0 7b /r] AVX512FP16 VCVTUSI2SS xmmreg,xmmreg|er,rm64|er [rvm:t1s: evex.nds.lig.f3.map5.w1 7b /r] AVX512FP16 VCVTUW2PH xmmreg|mask|z,xmmrm128|b16 [rm:fv: evex.128.f2.map5.w0 7d /r] AVX512FP16,AVX512VL @@ -5623,11 +5623,11 @@ VFPCLASSSH kreg|mask,xmmrm16,imm8 [rmi:t1s: evex.lig.np.0f3a.w0 67 /r ib] AVX5 VGETEXPPH xmmreg|mask|z,xmmrm128|b16 [rm:fv: evex.128.66.map6.w0 42 /r] AVX512FP16,AVX512VL VGETEXPPH ymmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.66.map6.w0 42 /r] AVX512FP16,AVX512VL VGETEXPPH zmmreg|mask|z,zmmrm512|b16|sae [rm:fv: evex.512.66.map6.w0 42 /r] AVX512FP16 -VGETEXPSH xmmreg|mask|z,xmmrm16|sae [rm:t1s: evex.lig.66.map6.w0 43 /r] AVX512FP16 +VGETEXPSH xmmreg|mask|z,xmmreg,xmmrm16|sae [rvm:t1s: evex.lig.66.map6.w0 43 /r] AVX512FP16 VGETMANTPH xmmreg|mask|z,xmmrm128|b16,imm8 [rmi:fv: evex.128.np.0f3a.w0 26 /r ib] AVX512FP16,AVX512VL VGETMANTPH ymmreg|mask|z,ymmrm256|b16,imm8 [rmi:fv: evex.256.np.0f3a.w0 26 /r ib] AVX512FP16,AVX512VL VGETMANTPH zmmreg|mask|z,zmmrm512|b16|sae,imm8 [rmi:fv: evex.512.np.0f3a.w0 26 /r ib] AVX512FP16 -VGETMANTSH xmmreg|mask|z,xmmrm16|sae,imm8 [rmi:t1s: evex.lig.np.0f3a.w0 27 /r ib] AVX512FP16 +VGETMANTSH xmmreg|mask|z,xmmreg,xmmrm16|sae,imm8 [rvmi:t1s: evex.lig.np.0f3a.w0 27 /r ib] AVX512FP16 VMAXPH xmmreg|mask|z,xmmreg*,xmmrm128|b16 [rvm:fv: evex.128.np.map5.w0 5f /r ] AVX512FP16,AVX512VL VMAXPH ymmreg|mask|z,ymmreg*,ymmrm256|b16 [rvm:fv: evex.256.np.map5.w0 5f /r ] AVX512FP16,AVX512VL VMAXPH zmmreg|mask|z,zmmreg*,zmmrm512|b16|sae [rvm:fv: evex.512.np.map5.w0 5f /r ] AVX512FP16 @@ -5646,9 +5646,9 @@ VMULPH xmmreg|mask|z,xmmreg*,xmmrm128|b16 [rvm:fv: evex.nds.128.np.map5.w0 59 / VMULPH ymmreg|mask|z,ymmreg*,ymmrm256|b16 [rvm:fv: evex.nds.256.np.map5.w0 59 /r] AVX512FP16,AVX512VL VMULPH zmmreg|mask|z,zmmreg*,zmmrm512|b16 [rvm:fv: evex.nds.512.np.map5.w0 59 /r] AVX512FP16 VMULSH xmmreg|mask|z,xmmreg*,xmmrm16|er [rvm:t1s: evex.nds.lig.f3.map5.w0 59 /r] AVX512FP16 -VRCPPH xmmreg|mask|z,xmmreg*,xmmrm128|b16 [rvm:fv: evex.nds.128.66.map6.w0 4c /r] AVX512FP16,AVX512VL -VRCPPH ymmreg|mask|z,ymmreg*,ymmrm256|b16 [rvm:fv: evex.nds.256.66.map6.w0 4c /r] AVX512FP16,AVX512VL -VRCPPH zmmreg|mask|z,zmmreg*,zmmrm512|b16 [rvm:fv: evex.nds.512.66.map6.w0 4c /r] AVX512FP16 +VRCPPH xmmreg|mask|z,xmmrm128|b16 [rm:fv: evex.128.66.map6.w0 4c /r] AVX512FP16,AVX512VL +VRCPPH ymmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.66.map6.w0 4c /r] AVX512FP16,AVX512VL +VRCPPH zmmreg|mask|z,zmmrm512|b16 [rm:fv: evex.512.66.map6.w0 4c /r] AVX512FP16 VRCPSH xmmreg|mask|z,xmmreg*,xmmrm16|sae [rvm:t1s: evex.nds.lig.66.map6.w0 4d /r] AVX512FP16 VREDUCEPH xmmreg|mask|z,xmmrm128|b16,imm8 [rmi:fv: evex.128.np.0f3a.w0 56 /r ib] AVX512FP16,AVX512VL VREDUCEPH ymmreg|mask|z,ymmrm256|b16,imm8 [rmi:fv: evex.256.np.0f3a.w0 56 /r ib] AVX512FP16,AVX512VL @@ -5658,10 +5658,10 @@ VENDSCALEPH xmmreg|mask|z,xmmrm128|b16,imm8 [rmi:fv: evex.128.np.0f3a.w0 08 /r VENDSCALEPH ymmreg|mask|z,ymmrm256|b16,imm8 [rmi:fv: evex.256.np.0f3a.w0 08 /r ib] AVX512FP16,AVX512VL VENDSCALEPH zmmreg|mask|z,zmmrm512|b16|sae,imm8 [rmi:fv: evex.512.np.0f3a.w0 08 /r ib] AVX512FP16 VENDSCALESH xmmreg|mask|z,xmmreg*,xmmrm16|sae,imm8 [rvmi:t1s: evex.nds.lig.np.0f3a.w0 0a /r ib] AVX512FP16 -VRSQRTPH xmmreg|mask|z,xmmrm128|b16,imm8 [rmi:fv: evex.128.66.map6.w0 4e /r ib] AVX512FP16,AVX512VL -VRSQRTPH ymmreg|mask|z,ymmrm256|b16,imm8 [rmi:fv: evex.256.66.map6.w0 4e /r ib] AVX512FP16,AVX512VL -VRSQRTPH zmmreg|mask|z,zmmrm512|b16|sae,imm8 [rmi:fv: evex.512.66.map6.w0 4e /r ib] AVX512FP16 -VRSQRTSH xmmreg|mask|z,xmmreg*,xmmrm16|sae,imm8 [rvmi:t1s: evex.nds.lig.66.map6.w0 4f /r ib] AVX512FP16 +VRSQRTPH xmmreg|mask|z,xmmrm128|b16 [rm:fv: evex.128.66.map6.w0 4e /r] AVX512FP16,AVX512VL +VRSQRTPH ymmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.66.map6.w0 4e /r] AVX512FP16,AVX512VL +VRSQRTPH zmmreg|mask|z,zmmrm512|b16|sae [rm:fv: evex.512.66.map6.w0 4e /r] AVX512FP16 +VRSQRTSH xmmreg|mask|z,xmmreg*,xmmrm16|sae [rvm:t1s: evex.nds.lig.66.map6.w0 4f /r] AVX512FP16 VSCALEFPH xmmreg|mask|z,xmmreg*,xmmrm128|b16 [rvm:fv: evex.nds.128.66.map6.w0 2c /r] AVX512FP16,AVX512VL VSCALEFPH ymmreg|mask|z,ymmreg*,ymmrm256|b16 [rvm:fv: evex.nds.256.66.map6.w0 2c /r] AVX512FP16,AVX512VL VSCALEFPH zmmreg|mask|z,zmmreg*,zmmrm512|b16|er [rvm:fv: evex.nds.512.66.map6.w0 2c /r] AVX512FP16 @@ -5808,17 +5808,17 @@ VCVT2PH2HF8S xmmreg|mask|z,xmmreg,xmmrm128|b16 [rvm:fv: evex.128.f2.map5. VCVT2PH2HF8S ymmreg|mask|z,ymmreg,ymmrm256|b16 [rvm:fv: evex.256.f2.map5.w0 1b /r ] AVX10_2 VCVT2PH2HF8S zmmreg|mask|z,zmmreg,zmmrm512|b16 [rvm:fv: evex.512.f2.map5.w0 1b /r ] AVX10_2 VCVTPH2BF8 xmmreg|mask|z,xmmrm128|b16 [rm:fv: evex.128.f3.0f38.w0 74 /r ] AVX10_2 -VCVTPH2BF8 ymmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.f3.0f38.w0 74 /r ] AVX10_2 -VCVTPH2BF8 zmmreg|mask|z,zmmrm512|b16 [rm:fv: evex.512.f3.0f38.w0 74 /r ] AVX10_2 +VCVTPH2BF8 xmmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.f3.0f38.w0 74 /r ] AVX10_2 +VCVTPH2BF8 ymmreg|mask|z,zmmrm512|b16 [rm:fv: evex.512.f3.0f38.w0 74 /r ] AVX10_2 VCVTPH2BF8S xmmreg|mask|z,xmmrm128|b16 [rm:fv: evex.128.f3.map5.w0 74 /r ] AVX10_2 -VCVTPH2BF8S ymmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.f3.map5.w0 74 /r ] AVX10_2 -VCVTPH2BF8S zmmreg|mask|z,zmmrm512|b16 [rm:fv: evex.512.f3.map5.w0 74 /r ] AVX10_2 +VCVTPH2BF8S xmmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.f3.map5.w0 74 /r ] AVX10_2 +VCVTPH2BF8S ymmreg|mask|z,zmmrm512|b16 [rm:fv: evex.512.f3.map5.w0 74 /r ] AVX10_2 VCVTPH2HF8 xmmreg|mask|z,xmmrm128|b16 [rm:fv: evex.128.f3.map5.w0 18 /r ] AVX10_2 -VCVTPH2HF8 ymmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.f3.map5.w0 18 /r ] AVX10_2 -VCVTPH2HF8 zmmreg|mask|z,zmmrm512|b16 [rm:fv: evex.512.f3.map5.w0 18 /r ] AVX10_2 +VCVTPH2HF8 xmmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.f3.map5.w0 18 /r ] AVX10_2 +VCVTPH2HF8 ymmreg|mask|z,zmmrm512|b16 [rm:fv: evex.512.f3.map5.w0 18 /r ] AVX10_2 VCVTPH2HF8S xmmreg|mask|z,xmmrm128|b16 [rm:fv: evex.128.f3.map5.w0 1b /r ] AVX10_2 -VCVTPH2HF8S ymmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.f3.map5.w0 1b /r ] AVX10_2 -VCVTPH2HF8S zmmreg|mask|z,zmmrm512|b16 [rm:fv: evex.512.f3.map5.w0 1b /r ] AVX10_2 +VCVTPH2HF8S xmmreg|mask|z,ymmrm256|b16 [rm:fv: evex.256.f3.map5.w0 1b /r ] AVX10_2 +VCVTPH2HF8S ymmreg|mask|z,zmmrm512|b16 [rm:fv: evex.512.f3.map5.w0 1b /r ] AVX10_2 VCVT2PS2PHX xmmreg|mask|z,xmmreg,xmmrm128|b32 [rvm:fv: evex.128.66.0f38.w0 67 /r ] AVX10_2 VCVT2PS2PHX ymmreg|mask|z,ymmreg,ymmrm256|b32 [rvm:fv: evex.256.66.0f38.w0 67 /r ] AVX10_2 VCVT2PS2PHX zmmreg|mask|z,zmmreg,zmmrm512|b32 [rvm:fv: evex.512.66.0f38.w0 67 /r ] AVX10_2 From 3f188d7222f584f6538fa9e250f917fe5d8c4389 Mon Sep 17 00:00:00 2001 From: RMarx1456 Date: Tue, 20 Jan 2026 21:36:59 -0800 Subject: [PATCH 03/13] disasm.c: Fix issue #193 by swapping arguments of is_class Incorrect ordering led to specific encoding for implicit shift by one (M1 - UNITY from include/opflags.h & x86/insnsd.c) being skipped over in disasm.c:1519. The skip over the is_class UNITY check would lead to adding 0x0 to the end of the instruction and moving onwards having emitted the incorrect immediate operand. Fixes: 56567a0c4c07 ("disasm: fix the disassembler for many APX cases") --- disasm/disasm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disasm/disasm.c b/disasm/disasm.c index 4366301ea..3471685c2 100644 --- a/disasm/disasm.c +++ b/disasm/disasm.c @@ -1516,7 +1516,7 @@ int32_t disasm(const uint8_t *dp, int32_t data_size, slen += append_evex_reg_deco(output + slen, outbufsize - slen, deco, &prefix); } else if (t & IMMEDIATE) { - if (is_class(t, UNITY)) { + if (is_class(UNITY, t)) { output[slen++] = '1'; } else if (o->segment & SEG_DFV) { int fl; From 89682def9b518ae52092885a67a0612579b92679 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Tue, 27 Jan 2026 22:16:14 +0100 Subject: [PATCH 04/13] disp8: Fix issue #185 - EVEX compressed shift for MOVDDUP tuple type MOVDDUP tuple type uses a compression shift for the disp8 addressing scheme. The shift depends on the vector lenght and is defined as 8 for 128 bits, 32 for 256 bits and 64 for 512 bits. Current implementation doesn't work for the 128 bit vector case since the expression used evaluates to 16 instead of 8. Fix it with a special if check before the current expression is returned. Signed-off-by: Maciej Wieczor-Retman --- include/disp8.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/disp8.h b/include/disp8.h index 00fa31858..46797adc0 100644 --- a/include/disp8.h +++ b/include/disp8.h @@ -73,6 +73,12 @@ static inline unsigned int get_disp8_shift(const insn *ins) /* MOVDDUP */ case DUP: + /* + * 128-bit vector case doesn't follow the same formula as 256- and + * 512-bit vectors. + */ + if (!vectlen) + return 3; return vectlen + 4; default: From 0058d91bec4a70057a3bad51b0636f56637f1221 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Tue, 3 Feb 2026 20:46:10 +0100 Subject: [PATCH 05/13] travis: Fix tests after instruction corrections The UWRMSR was incorrectly encoded with operands swapped. Correct that mistake. Some AVX512 and AVX10.2 instructions had incorrect operands in the database. Correct the tests after fixing the database entries. Signed-off-by: Maciej Wieczor-Retman --- travis/test/apx.asm | 8 ++++---- travis/test/apx.bin.t | Bin 2197 -> 2197 bytes travis/test/avx10.2.asm | 16 ++++++++-------- travis/test/v4.asm | 10 +++++----- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/travis/test/apx.asm b/travis/test/apx.asm index f42dd6916..a36910e45 100644 --- a/travis/test/apx.asm +++ b/travis/test/apx.asm @@ -637,13 +637,13 @@ testcase {0x62, 0xDF, 0x7F, 0x08, 0xF8, 0xC2, 0xFF, 0xFF, 0xFF, 0xFF}, \ ; --- uwrmsr instruction --- ; legacy -testcase {0xF3, 0x0F, 0x38, 0xF8, 0xCA}, {uwrmsr rdx, rcx} +testcase {0xF3, 0x0F, 0x38, 0xF8, 0xD1}, {uwrmsr rdx, rcx} testcase {0xC4, 0xE7, 0x7A, 0xF8, 0xC2, 0xFF, 0xFF, 0xFF, 0xFF}, \ - {uwrmsr rdx, 0xFFFFFFFF} + {uwrmsr 0xFFFFFFFF, rdx} ; apx -testcase {0x62, 0xDC, 0x7E, 0x08, 0xF8, 0xCA}, {uwrmsr r26, rcx} +testcase {0x62, 0x64, 0x7E, 0x08, 0xF8, 0xD1}, {uwrmsr r26, rcx} testcase {0x62, 0xDF, 0x7E, 0x08, 0xF8, 0xC2, 0xFF, 0xFF, 0xFF, 0xFF}, \ - {uwrmsr r26, 0xFFFFFFFF} + {uwrmsr 0xFFFFFFFF, r26} ; --- wrmsrns instruction --- ; legacy diff --git a/travis/test/apx.bin.t b/travis/test/apx.bin.t index 0cc3afd9ff6308de356aa647cb4c157d5a7ec275..0dadd4bb498b07be76b6f1f7aee7664376c29bf6 100644 GIT binary patch delta 29 kcmbO#I8|^%CA+}IBhRaT9QqFgNhx(4KQ3BhRaT9QqFgNq6cvew^Ce$ Date: Mon, 2 Feb 2026 22:21:48 +0100 Subject: [PATCH 06/13] parser.c: Fix issue #182 - no warning when size is omitted with labels In cases such as "mov [es:bx], a_label" the operation defaults to a BYTE size which copies only part of the label value. Implement a check that warns the user of this issue when no size specifier is used. Signed-off-by: Maciej Wieczor-Retman --- asm/parser.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/asm/parser.c b/asm/parser.c index c0fba6007..1dd6dab99 100644 --- a/asm/parser.c +++ b/asm/parser.c @@ -1255,6 +1255,7 @@ restart_parse: if (!(eclass & ~(EC_RELOC | EC_UNKNOWN))) { /* It is an immediate */ + bool size_was_specified = false; op->offset = reloc_value(value); op->segment = reloc_seg(value); op->wrt = reloc_wrt(value); @@ -1268,6 +1269,27 @@ restart_parse: op->type |= IMM_NORMAL; set_imm_flags(op, result->opt); + /* + * Catch a missing size specifier when dealing with a label - + * which might result in non-intentional handling of only part + * of the label's address instead of the whole value. + */ + for(int j = 0 ; j <= opnum ; j++) + size_was_specified |= !!(result->oprs[j].xsize & SIZE_MASK); + + /* + * Raise a 'label operation missing size specifier' error when: + * 1. No size specifier was mentioned up to this point. + * 2. One of the operands is a memory reference. + * 3. The current operand is a label and not a simple immediate. + */ + if (!size_was_specified && (op->opflags & OPFLAG_FORWARD)) { + for(int j = 0 ; j <= opnum ; j++) { + if ((result->oprs[j].type & OPTYPE_MASK) == MEMORY) + nasm_fatal("size wasn't specified, some data may be omitted"); + } + } + /* * Special hack: if the previous operand was a colon * immediate operand with an explicit size, and this From 3910b58e96929f57bee18201f97e5a6baf6ef082 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Wed, 4 Feb 2026 17:18:44 +0100 Subject: [PATCH 07/13] parser.c: Fix issue #181 - redundancy needed to avoid NEAR optimized out To assemble a JMP in the NEAR form the STRICT keyword is needed. This change introduced recently reportedly breaks building boot sectors and is non-intuitive since other JMP versions don't behave this way. Disable optimizing the JMP size if the NEAR keyword is used. Signed-off-by: Maciej Wieczor-Retman --- asm/parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asm/parser.c b/asm/parser.c index 1dd6dab99..8f57e1946 100644 --- a/asm/parser.c +++ b/asm/parser.c @@ -1017,7 +1017,7 @@ restart_parse: break; case S_NEAR: /* This is not legacy behavior, even if it perhaps should be */ - /* result->opt |= OPTIM_NO_Jcc_RELAX | OPTIM_NO_JMP_RELAX; */ + result->opt |= OPTIM_NO_Jcc_RELAX | OPTIM_NO_JMP_RELAX; op->type |= NEAR; break; case S_SHORT: From 627ec8b865e201f8fee3af90c1320c950c73e4a8 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Fri, 6 Feb 2026 18:09:41 +0100 Subject: [PATCH 08/13] insns.dat: Fix issue #196 - CMP not being lockable Using LOCK on any CMP configuration of operands will result in #UD. Remove the possibility of adding the LOCK prefix to the CMP instruction. Signed-off-by: Maciej Wieczor-Retman --- x86/insns.dat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x86/insns.dat b/x86/insns.dat index 00b6e52c1..017eba2a9 100644 --- a/x86/insns.dat +++ b/x86/insns.dat @@ -69,7 +69,7 @@ $wdq LEA reg#,mem [rm: o# 8d /r] 8086 $wdq LEA reg#,imm# [rn: o# 8d /r] 8086,ND ;# The basic 8 arithmetic operations -$arith nf=nf ADD OR nf=,ADC nf=,SBB AND SUB XOR nf=,!evex,CMP +$arith nf=nf ADD OR nf=,ADC nf=,SBB AND SUB XOR nf=,lock=,!evex,CMP ;# Bitwise testing $bwdq TEST rm#,reg# [mr: o# 84# /r ] 8086,SM From 1ef93d643dba956a7c67f0e34b941a3142654076 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Fri, 6 Feb 2026 19:15:52 +0100 Subject: [PATCH 09/13] doc: Fix issue #191 - badly formatted link Fix bad link formatting that prevents building the documentation. Signed-off-by: Maciej Wieczor-Retman --- doc/changes.src | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/changes.src b/doc/changes.src index 79f9eb967..dca411549 100644 --- a/doc/changes.src +++ b/doc/changes.src @@ -30,9 +30,9 @@ It is the production version of NASM since 2025. \> That \c{JMPE} has apparently been wrong all these years is probably as good of a hint as any how much it has been actually used, but it \e{does} have the possibility of breaking virtual environments. In - that case, please file a bug report to \W{https://bugs.nasm.us/} - with details about the virtual environment, and we will figure out - a suitable solution. + that case, please file a bug report to + \W{https://bugs.nasm.us/}\c{https://bugs.nasm.us} with details about the + virtual environment, and we will figure out a suitable solution. \S{cl-3.01} Version 3.01 From 874422630991ed846f1098b16a1a50e3b0e2727e Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Fri, 6 Feb 2026 19:17:32 +0100 Subject: [PATCH 10/13] doc: Document jump size behavior Document the logic behind determining the jump sizes, amounts of bytes emitted related to size and length keywords. Change is related to issue #181. Also fix the JMPABS not being visible due to wrong tag used. Signed-off-by: Maciej Wieczor-Retman --- doc/syntax.src | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/doc/syntax.src b/doc/syntax.src index a1ee9193e..ae5ba0ec1 100644 --- a/doc/syntax.src +++ b/doc/syntax.src @@ -12,7 +12,7 @@ operation. Near jumps are jumps within a single segment. Probably the most common way to use them is through labels, as explained in \k{locallab}. \i\c{APX} added a near -jump instruction - \I\c{JMPABS}, that allows jumps to any \I{64-bit +jump instruction - \i\c{JMPABS}, that allows jumps to any \I{64-bit immediate}64-bit address specified with an immediate operand. The instruction works with absolute addresses and the syntax options are shown in \k{jmpabs}. @@ -88,6 +88,29 @@ NASM allows this instruction to be specified either as: The generated code is identical. The \c{ABS} is required regardless of the \c{DEFAULT} setting. +\S{opt_jumps} Optimizing jump lengths and sizes + +\i\c{JMP} lengths can be specified using keywords such as \i\c{SHORT} and +\i\c{NEAR}. The keyword used also has consequences in how many bytes will be +emitted in the final assembled instruction. It's worth to note the behavior of +\c{SHORT} and \c{NEAR} for example in 16 bit mode. If it's specifically required +to emit a 3 byte encoding of the jump instruction, then the \c{NEAR} version +shall always fulfill this requirement, even if the jump is made within a +\c{SHORT} distance (so up to a byte away). If the optimized version is expected +then it's best to not use a length specifier at all and let the assembler pick +the relevant version by itself. + +Using size specifiers with jumps (and therefore with labels which are just +immediates) will be optimized down to the shortest possible encoding since the +size specifier is relevant to the operation size and not to the jump length. + +\c 00000000 EB09 jmp label +\c 00000002 EB07 jmp SHORT label +\c 00000004 E90400 jmp NEAR label +\c 00000007 EB02 jmp BYTE label +\c 00000009 EB00 jmp WORD label +\c +\c label: \H{shortnddnds} Compact \i{NDS}/\i{NDD} Operands From 14f887fb4e44aae8bd36c19d8995a01036309fb7 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Fri, 20 Feb 2026 15:14:57 +0100 Subject: [PATCH 11/13] insns.dat: Fix issue #171 - valid prefixes not allowed Instructions like IRET, POPF and PUSHF used to not have a operand size specifier but after applying macros they received the 'osm' one - meaning must be the same as the BITS mode. Which is not true for these instructions, using the operand size prefix doesn't change their encoding and their default 64-bit encoding is the 32-bit version. Align these with other similar instructions like RET, RETF and use the 'od#' keyword which returns their previous behavior. Signed-off-by: Maciej Wieczor-Retman --- x86/insns.dat | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x86/insns.dat b/x86/insns.dat index 017eba2a9..28ad0952f 100644 --- a/x86/insns.dat +++ b/x86/insns.dat @@ -356,7 +356,7 @@ SYSENTER void [ 0f 34] P6,NOAPX SYSEXIT void [ 0f 35] P6,PRIV,NOAPX SYSRET void [ 0f 07] P6,PRIV,AMD -$zwdq IRET% void [ o# cf] 8086 +$zwdq IRET% void [ od# cf] 8086 ERETS void [ f2 0f 01 ca ] FRED,PRIV,LONG ERETU void [ f3 0f 01 ca ] FRED,PRIV,LONG @@ -378,8 +378,8 @@ LAHF void [ 9f] 8086 SAHF void [ 9e] 8086 SALC void [ d6] 8086,UNDOC,NOLONG -$zwdq PUSHF% void [ nw o# 9c] 8086 -$zwdq POPF% void [ nw o# 9d] 8086 +$zwdq PUSHF% void [ nw od# 9c] 8086 +$zwdq POPF% void [ nw od# 9d] 8086 ;# String instructions $bwdq CMPS% void [ repe o# a6#] 8086,NOAPX From 85cd46de67a14137a396ace077ed4daf6b08c928 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Mon, 23 Feb 2026 14:29:58 +0100 Subject: [PATCH 12/13] insns.dat: Fix issue #164 - broken dissasembly on JMP, JMPE and CALL After macroization it seems the 'JMP rm' form was replaced by 'JPM rm#|near' which caused the dissasembler to not emit anything. Signed-off-by: Maciej Wieczor-Retman --- x86/insns.dat | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x86/insns.dat b/x86/insns.dat index 28ad0952f..2afcc8fc2 100644 --- a/x86/insns.dat +++ b/x86/insns.dat @@ -271,6 +271,7 @@ $br JMP short [i: os eb rel8] 8086,NOAPX,ND $br JMP near [i: jmp8 os eb rel8] 8086,NOAPX,JMP_RELAX $br JMP near [i: os e9 rel] 8086,BND $wdq JMP rm#|near [m: nw o# ff /4] 8086,BND,OSIZE +$wdq JMP rm# [m: nw o# ff /4] 8086,BND,OSIZE $wd JMP imm#|far [i: o# ea iwd seg] 8086,OSIZE,ND,NOLONG ; These are hacks to support the legacy syntax "[d]word seg:offs" to mean "seg:[d]word offs" @@ -317,10 +318,12 @@ $br $wdq LOOPNZ near|short,cx# [i-: a# os e0 rel8] 8086,NOAPX ; $wdq JMPE imm#|near [i: norep o# 0f b8 i##] IA64,OSIZE $wdq JMPE rm#|near [m: norep o# 0f 00 /6] IA64,OSIZE +$wdq JMPE rm# [m: norep o# 0f 00 /6] IA64,OSIZE ;# Call and return $br CALL near [i: os e8 rel] 8086,BND,NOAPX $wdq CALL rm#|near [m: nw o# ff /2] 8086,BND,(wd:OSIZE,NOLONG) +$wdq CALL rm# [m: nw o# ff /2] 8086,BND,(wd:OSIZE,NOLONG) $wd CALL imm#|far [i: o# 9a iwd seg] 8086,ND,NOLONG,OSIZE ; These are hacks to support the legacy syntax "[d]word seg:offs" to mean "seg:[d]word offs" From ef587a2566ff9ab4e5e1e50a1b6fd9bf3caaed51 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Thu, 26 Feb 2026 07:53:04 +0100 Subject: [PATCH 13/13] docs: Fix issue #190 - no cp -u on MacOS prevents building Use cp without -u to generate the documentation as the -u option doesn't have to be present on other POSIX platforms and breaks builing the project on MacOS. Signed-off-by: Maciej Wieczor-Retman --- doc/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Makefile.in b/doc/Makefile.in index a6128d6e9..8fdfdeb69 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -91,7 +91,7 @@ htmltarget=html/nasm00.html html: $(HTMLAUX) $(MKDIR_P) html - for f in $(HTMLAUX); do $(CP_UF) "$(srcdir)/$$f" html/; done + for f in $(HTMLAUX); do $(CP_F) "$(srcdir)/$$f" html/; done $(MAKE) $(htmltarget) RDSRC = $(RUNPERL) $(srcdir)/rdsrc.pl -I$(srcdir) -M$(@F).dep