diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-05-20 11:23:18 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-05-20 11:23:18 -0700 |
commit | 70a13f5a3701faa71bd2b28390dff622d71c62a6 (patch) | |
tree | 4f31e4fc6c2b886cbddba31b9d62e44a87238197 /insns.pl | |
parent | d82dd4f1a38e20b0262f184f492fcb87308ec464 (diff) | |
download | nasm-70a13f5a3701faa71bd2b28390dff622d71c62a6.tar.gz nasm-70a13f5a3701faa71bd2b28390dff622d71c62a6.tar.bz2 nasm-70a13f5a3701faa71bd2b28390dff622d71c62a6.zip |
insns.pl: support operands that serve double duty
Sometimes assembly syntax wants to permit a single operand to serve
multiple functions; allow this.
The disassembler could really use to be smarter about those.
Diffstat (limited to 'insns.pl')
-rw-r--r-- | insns.pl | 15 |
1 files changed, 13 insertions, 2 deletions
@@ -491,6 +491,9 @@ sub startseq($) { # i = immediate # s = register field of is4/imz2 field # +# For an operand that should be filled into more than one field, +# enter it as e.g. "r+v". +# sub byte_code_compile($) { my($str) = @_; my $opr; @@ -509,8 +512,14 @@ sub byte_code_compile($) { $opc = "\L$str"; } + my $op = 0; for ($i = 0; $i < length($opr); $i++) { - $oppos{substr($opr,$i,1)} = $i; + my $c = substr($opr,$i,1); + if ($c eq '+') { + $op--; + } else { + $oppos{$c} = $op++; + } } $prefix_ok = 1; @@ -597,7 +606,9 @@ sub byte_code_compile($) { } elsif ($oq =~ /^m([0-9]+)$/) { $m = $1+0; } elsif ($oq eq 'nds' || $oq eq 'ndd') { - return undef if (!defined($oppos{'v'})); + if (!defined($oppos{'v'})) { + die "$0: $line: vex.$oq without 'v' operand\n"; + } } else { die "$0: $line: undefined VEX subcode: $oq\n"; } |