From e56c2dc5b7223f231d4d080690cb32a301ba8766 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin (Intel)" Date: Thu, 30 Jul 2020 15:13:13 -0700 Subject: [PATCH] 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) --- 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(-) create mode 100644 test/immsize.asm create mode 100644 test/insertps.asm create mode 100644 test/movhpd.asm create mode 100644 test/ssesize.asm diff --git a/test/immsize.asm b/test/immsize.asm new file mode 100644 index 000000000..742e3ae0e --- /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 000000000..d66240d87 --- /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 000000000..af1e5740c --- /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 000000000..a812cdee9 --- /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 bc0916a3d..e24c24794 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 b13569b56..aed8c6796 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/(? 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]);