diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-05-21 11:05:39 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-05-21 11:05:39 -0700 |
commit | 2fb033af18c55d5e4412507b9a1bd513e8a6f2ff (patch) | |
tree | a96835d700178ff1ec1814dacd8bd1b46861c36a /insns.pl | |
parent | eb9e0938403b63e6478d6d874285a39e9984dbda (diff) | |
download | nasm-2fb033af18c55d5e4412507b9a1bd513e8a6f2ff.tar.gz nasm-2fb033af18c55d5e4412507b9a1bd513e8a6f2ff.tar.bz2 nasm-2fb033af18c55d5e4412507b9a1bd513e8a6f2ff.zip |
Disassembler: select table based on VEX prefixes
We can use the new VEX prefixes to select into a large table of new
opcode spaces. Since the table is (currently) sparse, add logic so we
don't end up producing tons of empty tables for no good reason.
This is also necessary since VEX is likely to reuse opcode bytes that
would appear as prefixes at some point, which would cause conflicts
with the regular tables.
Diffstat (limited to 'insns.pl')
-rw-r--r-- | insns.pl | 46 |
1 files changed, 42 insertions, 4 deletions
@@ -14,6 +14,15 @@ # This should match MAX_OPERANDS from nasm.h $MAX_OPERANDS = 5; +# Add VEX prefixes +@vexlist = (); +for ($m = 0; $m < 32; $m++) { + for ($lp = 0; $lp < 8; $lp++) { + push(@vexlist, sprintf("VEX%02X%01X", $m, $lp)); + } +} +@disasm_prefixes = (@vexlist, @disasm_prefixes); + print STDERR "Reading insns.dat...\n"; @args = (); @@ -182,8 +191,20 @@ if ( !defined($output) || $output eq 'd' ) { print D "};\n"; } + @prefix_list = (); foreach $h (@disasm_prefixes, '') { - $is_prefix{$h} = 1; + for ($c = 0; $c < 256; $c++) { + $nn = sprintf("%s%02X", $h, $c); + if ($is_prefix{$nn} || defined($dinstables{$nn})) { + # At least one entry in this prefix table + push(@prefix_list, $h); + $is_prefix{$h} = 1; + last; + } + } + } + + foreach $h (@prefix_list) { print D "\n"; print D "static " unless ($h eq ''); print D "const struct disasm_index "; @@ -202,8 +223,23 @@ if ( !defined($output) || $output eq 'd' ) { printf D " { NULL, 0 },\n"; } } - print D "};\n"; + print D "};\n"; + } + + print D "\nconst struct disasm_index * const itable_VEX[32][8] = {\n"; + for ($m = 0; $m < 32; $m++) { + print D "\t{\n"; + for ($lp = 0; $lp < 8; $lp++) { + $vp = sprintf("VEX%02X%01X", $m, $lp); + if ($is_prefix{$vp}) { + printf D "\t\titable_%s,\n", $vp; + } else { + print D "\t\tNULL,\n"; + } + } + print D "\t},\n"; } + print D "};\n"; close D; } @@ -464,8 +500,10 @@ sub startseq($) { } elsif ($c0 == 0 || $c0 == 0340) { return $prefix; } elsif (($c0 & ~3) == 0260 || $c0 == 0270) { - shift(@codes); # Skip VEX control bytes - shift(@codes); + my $m,$wlp,$vxp; + $m = shift(@codes); + $wlp = shift(@codes); + $prefix .= sprintf('VEX%02X%01X', $m, $wlp & 7); } elsif ($c0 >= 0172 && $c0 <= 174) { shift(@codes); # Skip is4 control byte } else { |