[nasm:nasm-2.15.xx] insns.pl: audit for impossible Sx patterns; fix a few

nasm-bot for H. Peter Anvin (Intel) hpa at zytor.com
Thu Jul 30 15:18:07 PDT 2020


Commit-ID:  e56c2dc5b7223f231d4d080690cb32a301ba8766
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=e56c2dc5b7223f231d4d080690cb32a301ba8766
Author:     H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Thu, 30 Jul 2020 15:13:13 -0700
Committer:  H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Thu, 30 Jul 2020 15:16:11 -0700

insns.pl: audit for impossible Sx patterns; fix a few

Break the instruction processing if there are impossible combinations
of Sx flags and operand sizes. If the intent is to always require
explicit sizes, use the SX flag.

The INSERTPS instruction pattern was explicitly wrong, the rest of
these are nuisance fixes.

TODO: fix the disassembler to be able to exclude patterns where these
bits don't matter.

Signed-off-by: H. Peter Anvin (Intel) <hpa at zytor.com>


---
 test/immsize.asm  | 36 ++++++++++++++++++++++++++++++++++++
 test/insertps.asm | 10 ++++++++++
 test/movhpd.asm   | 15 +++++++++++++++
 test/ssesize.asm  | 14 ++++++++++++++
 x86/insns.dat     | 34 +++++++++++++++++-----------------
 x86/insns.pl      | 53 +++++++++++++++++++++++++++++++++++++++++++++++++----
 6 files changed, 141 insertions(+), 21 deletions(-)

diff --git a/test/immsize.asm b/test/immsize.asm
new file mode 100644
index 00000000..742e3ae0
--- /dev/null
+++ b/test/immsize.asm
@@ -0,0 +1,36 @@
+	bits 64
+
+%macro b 1
+	%1 ax,16
+	%1 eax,16
+	%1 rax,16
+	%1 word [rdi],16
+	%1 dword [rdi],16
+	%1 qword [rdi],16
+	%1 ax,byte 16
+	%1 eax,byte 16
+	%1 rax,byte 16
+	%1 word [rdi],byte 16
+	%1 dword [rdi],byte 16
+	%1 qword [rdi],byte 16
+%endmacro
+
+	b bt
+	b btc
+	b btr
+	b bts
+
+	imul ax,[rdi],16
+	imul ax,word [rdi],16
+	imul ax,[rdi],byte 16
+	imul ax,word [rdi],byte 16
+
+	imul eax,[rdi],16
+	imul eax,dword [rdi],16
+	imul eax,[rdi],byte 16
+	imul eax,dword [rdi],byte 16
+
+	imul rax,[rdi],16
+	imul rax,qword [rdi],16
+	imul rax,[rdi],byte 16
+	imul rax,qword [rdi],byte 16
diff --git a/test/insertps.asm b/test/insertps.asm
new file mode 100644
index 00000000..d66240d8
--- /dev/null
+++ b/test/insertps.asm
@@ -0,0 +1,10 @@
+	bits 64
+	insertps xmm0,xmm1,16
+	insertps xmm0,dword xmm1,16
+	insertps xmm0,xmm1,byte 16
+	insertps xmm0,dword xmm1,byte 16
+
+	insertps xmm0,[rax],16
+	insertps xmm0,dword [rax],16
+	insertps xmm0,[rax],byte 16
+	insertps xmm0,dword [rax],byte 16
diff --git a/test/movhpd.asm b/test/movhpd.asm
new file mode 100644
index 00000000..af1e5740
--- /dev/null
+++ b/test/movhpd.asm
@@ -0,0 +1,15 @@
+	bits 64
+	movhpd xmm0,[rdi+2]
+	movhpd xmm0,qword [rdi+2]
+
+	movhpd [rsi+3],xmm1
+	movhpd qword [rsi+3],xmm1
+
+	vmovhpd xmm2,xmm1,[rax+4]
+	vmovhpd xmm2,xmm1,qword [rax+4]
+
+	vmovhpd xmm3,[rax+4]
+	vmovhpd xmm3,qword [rax+4]
+
+	vmovhpd [rcx+5],xmm4
+	vmovhpd qword [rcx+5],xmm4
diff --git a/test/ssesize.asm b/test/ssesize.asm
new file mode 100644
index 00000000..a812cdee
--- /dev/null
+++ b/test/ssesize.asm
@@ -0,0 +1,14 @@
+_start:
+	movd ecx,xmm0
+	movd [foo],xmm0
+	movd dword [foo],xmm0
+
+	movdqa xmm1,xmm0
+	movdqa [foo],xmm0
+	movdqa oword [foo],xmm0
+
+	cmppd xmm2,xmm3,8
+	cmppd xmm2,xmm3,byte 8
+
+	section .bss
+foo:	reso 1
diff --git a/x86/insns.dat b/x86/insns.dat
index bc0916a3..e24c2479 100644
--- a/x86/insns.dat
+++ b/x86/insns.dat
@@ -218,36 +218,36 @@ BT		mem,reg32			[mr:	o32 0f a3 /r]				386,SM
 BT		reg32,reg32			[mr:	o32 0f a3 /r]				386
 BT		mem,reg64			[mr:	o64 0f a3 /r]				X86_64,LONG,SM
 BT		reg64,reg64			[mr:	o64 0f a3 /r]				X86_64,LONG
-BT		rm16,imm			[mi:	o16 0f ba /4 ib,u]			386,SB
-BT		rm32,imm			[mi:	o32 0f ba /4 ib,u]			386,SB
-BT		rm64,imm			[mi:	o64 0f ba /4 ib,u]			X86_64,LONG,SB
+BT		rm16,imm8			[mi:	o16 0f ba /4 ib,u]			386
+BT		rm32,imm8			[mi:	o32 0f ba /4 ib,u]			386
+BT		rm64,imm8			[mi:	o64 0f ba /4 ib,u]			X86_64,LONG
 BTC		mem,reg16			[mr:	hle o16 0f bb /r]			386,SM,LOCK
 BTC		reg16,reg16			[mr:	o16 0f bb /r]				386
 BTC		mem,reg32			[mr:	hle o32 0f bb /r]			386,SM,LOCK
 BTC		reg32,reg32			[mr:	o32 0f bb /r]				386
 BTC		mem,reg64			[mr:	hle o64 0f bb /r]			X86_64,LONG,SM,LOCK
 BTC		reg64,reg64			[mr:	o64 0f bb /r]				X86_64,LONG
-BTC		rm16,imm			[mi:	hle o16 0f ba /7 ib,u]			386,SB,LOCK
-BTC		rm32,imm			[mi:	hle o32 0f ba /7 ib,u]			386,SB,LOCK
-BTC		rm64,imm			[mi:	hle o64 0f ba /7 ib,u]			X86_64,LONG,SB,LOCK
+BTC		rm16,imm8			[mi:	hle o16 0f ba /7 ib,u]			386,LOCK
+BTC		rm32,imm8			[mi:	hle o32 0f ba /7 ib,u]			386,LOCK
+BTC		rm64,imm8			[mi:	hle o64 0f ba /7 ib,u]			X86_64,LONG,LOCK
 BTR		mem,reg16			[mr:	hle o16 0f b3 /r]			386,SM,LOCK
 BTR		reg16,reg16			[mr:	o16 0f b3 /r]				386
 BTR		mem,reg32			[mr:	hle o32 0f b3 /r]			386,SM,LOCK
 BTR		reg32,reg32			[mr:	o32 0f b3 /r]				386
 BTR		mem,reg64			[mr:	hle o64 0f b3 /r]			X86_64,LONG,SM,LOCK
 BTR		reg64,reg64			[mr:	o64 0f b3 /r]				X86_64,LONG
-BTR		rm16,imm			[mi:	hle o16 0f ba /6 ib,u]			386,SB,LOCK
-BTR		rm32,imm			[mi:	hle o32 0f ba /6 ib,u]			386,SB,LOCK
-BTR		rm64,imm			[mi:	hle o64 0f ba /6 ib,u]			X86_64,LONG,SB,LOCK
+BTR		rm16,imm8			[mi:	hle o16 0f ba /6 ib,u]			386,LOCK
+BTR		rm32,imm8			[mi:	hle o32 0f ba /6 ib,u]			386,LOCK
+BTR		rm64,imm8			[mi:	hle o64 0f ba /6 ib,u]			X86_64,LONG,LOCK
 BTS		mem,reg16			[mr:	hle o16 0f ab /r]			386,SM,LOCK
 BTS		reg16,reg16			[mr:	o16 0f ab /r]				386
 BTS		mem,reg32			[mr:	hle o32 0f ab /r]			386,SM,LOCK
 BTS		reg32,reg32			[mr:	o32 0f ab /r]				386
 BTS		mem,reg64			[mr:	hle o64 0f ab /r]			X86_64,LONG,SM,LOCK
 BTS		reg64,reg64			[mr:	o64 0f ab /r]				X86_64,LONG
-BTS		rm16,imm			[mi:	hle o16 0f ba /5 ib,u]			386,SB,LOCK
-BTS		rm32,imm			[mi:	hle o32 0f ba /5 ib,u]			386,SB,LOCK
-BTS		rm64,imm			[mi:	hle o64 0f ba /5 ib,u]			X86_64,LONG,SB,LOCK
+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
 CALL		imm|near			[i:	odf e8 rel]				8086,ND,BND
 CALL		imm|far				[i:	odf 9a iwd seg]				8086,ND,NOLONG
@@ -607,7 +607,7 @@ 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,SM
+IMUL		reg16,mem,imm8			[rmi:	o16 6b /r ib,s]				186,SM2
 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
@@ -615,7 +615,7 @@ 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,SM
+IMUL		reg32,mem,imm8			[rmi:	o32 6b /r ib,s]				386,SM2
 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
@@ -623,9 +623,9 @@ 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,SM
+IMUL		reg64,mem,imm8			[rmi:	o64 6b /r ib,s]				X86_64,LONG,SM2
 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,SM
+IMUL		reg64,mem,imm32			[rmi:	o64 69 /r id]				X86_64,LONG,SM2
 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
@@ -1959,7 +1959,7 @@ DPPD		xmmreg,xmmrm128,imm8		[rmi:	66 0f 3a 41 /r ib,u]			SSE41
 DPPS		xmmreg,xmmrm128,imm8		[rmi:	66 0f 3a 40 /r ib,u]			SSE41
 EXTRACTPS	rm32,xmmreg,imm8		[mri:	66 0f 3a 17 /r ib,u]			SSE41
 EXTRACTPS	reg64,xmmreg,imm8		[mri:	o64 66 0f 3a 17 /r ib,u]		SSE41,X86_64,LONG
-INSERTPS	xmmreg,xmmrm32,imm8		[rmi:	66 0f 3a 21 /r ib,u]			SSE41,SD
+INSERTPS	xmmreg,xmmrm32,imm8		[rmi:	66 0f 3a 21 /r ib,u]			SSE41
 MOVNTDQA	xmmreg,mem128			[rm:	66 0f 38 2a /r]				SSE41
 MPSADBW		xmmreg,xmmrm128,imm8		[rmi:	66 0f 3a 42 /r ib,u]			SSE41
 PACKUSDW	xmmreg,xmmrm128			[rm:	66 0f 38 2b /r]				SSE41
diff --git a/x86/insns.pl b/x86/insns.pl
index b13569b5..aed8c679 100755
--- a/x86/insns.pl
+++ b/x86/insns.pl
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 ## --------------------------------------------------------------------------
 ##
-##   Copyright 1996-2017 The NASM Authors - All Rights Reserved
+##   Copyright 1996-2020 The NASM Authors - All Rights Reserved
 ##   See the file AUTHORS included with the NASM distribution for
 ##   the specific copyright holders.
 ##
@@ -444,7 +444,7 @@ sub format_insn($$$$$) {
     my $nd = 0;
     my ($num, $flagsindex);
     my @bytecode;
-    my ($op, @ops, $opp, @opx, @oppx, @decos, @opevex);
+    my ($op, @ops, @opsize, $opp, @opx, @oppx, @decos, @opevex);
 
     return (undef, undef) if $operands eq "ignore";
 
@@ -452,9 +452,11 @@ sub format_insn($$$$$) {
     $operands =~ s/\*//g;
     $operands =~ s/:/|colon,/g;
     @ops = ();
+    @opsize = ();
     @decos = ();
     if ($operands ne 'void') {
         foreach $op (split(/,/, $operands)) {
+	    my $opsz = 0;
             @opx = ();
             @opevex = ();
             foreach $opp (split(/\|/, $op)) {
@@ -465,6 +467,7 @@ sub format_insn($$$$$) {
 
                 if ($opp =~ s/(?<!\d)(8|16|32|64|80|128|256|512)$//) {
                     push(@oppx, "bits$1");
+		    $opsz = $1 + 0;
                 }
                 $opp =~ s/^mem$/memory/;
                 $opp =~ s/^memory_offs$/mem_offs/;
@@ -481,6 +484,7 @@ sub format_insn($$$$$) {
             }
             $op = join('|', @opx);
             push(@ops, $op);
+	    push(@opsize, $opsz);
             push(@decos, (@opevex ? join('|', @opevex) : '0'));
         }
     }
@@ -488,6 +492,7 @@ sub format_insn($$$$$) {
     $num = scalar(@ops);
     while (scalar(@ops) < $MAX_OPERANDS) {
         push(@ops, '0');
+	push(@opsize, 0);
         push(@decos, '0');
     }
     $operands = join(',', @ops);
@@ -499,11 +504,14 @@ sub format_insn($$$$$) {
     }
     $decorators =~ tr/a-z/A-Z/;
 
+    # Remember if we have an ARx flag
+    my $arx = undef;
+
     # expand and uniqify the flags
     my %flags;
     foreach my $flag (split(',', $flags)) {
 	next if ($flag eq '');
-	
+
 	if ($flag eq 'ND') {
 	    $nd = 1;
 	} else {
@@ -514,6 +522,10 @@ sub format_insn($$$$$) {
 	    # These flags imply OBSOLETE
 	    $flags{'OBSOLETE'}++;
 	}
+
+	if ($flag =~ /^AR([0-9]+)$/) {
+	    $arx = $1+0;
+	}
     }
 
     if ($codes =~ /evex\./) {
@@ -522,8 +534,41 @@ sub format_insn($$$$$) {
 	$flags{'VEX'}++;
     }
 
+    # Look for SM flags clearly inconsistent with operand bitsizes
+    if ($flags{'SM'} || $flags{'SM2'}) {
+	my $ssize = 0;
+	my $e = $flags{'SM2'} ? 2 : $MAX_OPERANDS;
+	for (my $i = 0; $i < $e; $i++) {
+	    next if (!$opsize[$i]);
+	    if (!$ssize) {
+		$ssize = $opsize[$i];
+	    } elsif ($opsize[$i] != $ssize) {
+		die "$fname:$line: inconsistent SM flag for argument $i\n";
+	    }
+	}
+    }
+
+    # Look for Sx flags that can never match operand bitsizes. If the
+    # intent is to never match (require explicit sizes), use the SX flag.
+    # This doesn't apply to registers that pre-define specific sizes;
+    # this should really be derived from include/opflags.h...
+    my %sflags = ( 'SB' => 8, 'SW' => 16, 'SD' => 32, 'SQ' => 64,
+		   'SO' => 128, 'SY' => 256, 'SZ' => 512 );
+    my $s = defined($arx) ? $arx : 0;
+    my $e = defined($arx) ? $arx : $MAX_OPERANDS - 1;
+
+    foreach my $sf (keys(%sflags)) {
+	next if (!$flags{$sf});
+	for (my $i = $s; $i <= $e; $i++) {
+	    if ($opsize[$i] && $ops[$i] !~ /\breg_(gpr|[cdts]reg)\b/) {
+		die "$fname:$line: inconsistent $sf flag for argument $i ($ops[$i])\n"
+		    if ($opsize[$i] != $sflags{$sf});
+	    }
+	}
+    }
+
     $flagsindex = insns_flag_index(keys %flags);
-    die "$fname:$line: error in flags $flags" unless (defined($flagsindex));
+    die "$fname:$line: error in flags $flags\n" unless (defined($flagsindex));
 
     @bytecode = (decodify($codes, $relax), 0);
     push(@bytecode_list, [@bytecode]);


More information about the Nasm-commits mailing list