#!/usr/bin/perl
-#
+#
# insns.pl produce insnsa.c, insnsd.c, insnsi.h, insnsn.c from insns.dat
#
# The Netwide Assembler is copyright (C) 1996 Simon Tatham and
# Julian Hall. All rights reserved. The software is
-# redistributable under the licence given in the file "Licence"
+# redistributable under the license given in the file "LICENSE"
# distributed in the NASM archive.
# Opcode prefixes which need their own opcode tables
# LONGER PREFIXES FIRST!
-@disasm_prefixes = qw(0F0F 0F24 0F25 0F38 0F3A 0F7A 0F);
+@disasm_prefixes = qw(0F24 0F25 0F38 0F3A 0F7A 0FA6 0FA7 0F);
print STDERR "Reading insns.dat...\n";
}
if ($formatted && !$nd) {
push @big, $formatted;
- foreach $i (startseq($_[2])) {
+ my @sseq = startseq($_[2]);
+ foreach $i (@sseq) {
if (!defined($dinstables{$i})) {
$dinstables{$i} = [];
}
if ( !defined($output) || $output eq 'a' ) {
print STDERR "Writing insnsa.c...\n";
-
+
open A, ">insnsa.c";
-
+
print A "/* This file auto-generated from insns.dat by insns.pl" .
" - don't edit it */\n\n";
print A "#include \"nasm.h\"\n";
print A "#include \"insns.h\"\n";
print A "\n";
-
+
foreach $i (@opcodes, @opcodes_cc) {
print A "static const struct itemplate instrux_${i}[] = {\n";
$aname = "aa_$i";
print A " instrux_${i},\n";
}
print A "};\n";
-
+
close A;
}
if ( !defined($output) || $output eq 'd' ) {
print STDERR "Writing insnsd.c...\n";
-
+
open D, ">insnsd.c";
-
+
print D "/* This file auto-generated from insns.dat by insns.pl" .
" - don't edit it */\n\n";
print D "#include \"nasm.h\"\n";
print D "#include \"insns.h\"\n";
print D "\n";
-
+
print D "static const struct itemplate instrux[] = {\n";
$n = 0;
foreach $j (@big) {
printf D " { itable_%s, -1 },\n", $nn;
} elsif (defined($dinstables{$nn})) {
printf D " { itable_%s, %u },\n",
- $nn, scalar(@{$dinstables{$nn}});
+ $nn, scalar(@{$dinstables{$nn}});
} else {
printf D " { NULL, 0 },\n";
}
}
print D "};\n";
}
-
+
close D;
}
if ( !defined($output) || $output eq 'i' ) {
print STDERR "Writing insnsi.h...\n";
-
+
open I, ">insnsi.h";
-
+
print I "/* This file is auto-generated from insns.dat by insns.pl" .
" - don't edit it */\n\n";
print I "/* This file in included by nasm.h */\n\n";
-
+
print I "/* Instruction names */\n\n";
print I "#ifndef NASM_INSNSI_H\n";
print I "#define NASM_INSNSI_H 1\n\n";
print I "\n};\n\n";
print I "#define MAX_INSLEN ", $maxlen, "\n\n";
print I "#endif /* NASM_INSNSI_H */\n";
-
+
close I;
}
if ( !defined($output) || $output eq 'n' ) {
print STDERR "Writing insnsn.c...\n";
-
+
open N, ">insnsn.c";
-
+
print N "/* This file is auto-generated from insns.dat by insns.pl" .
" - don't edit it */\n\n";
print N "/* This file in included by names.c */\n\n";
-
+
print N "static const char * const insn_names[] = {";
$first = 1;
foreach $i (@opcodes) {
$ilower =~ tr/A-Z/a-z/; # Change to lower case (Perl 4 compatible)
print N "\n\t\"${ilower}\"";
}
-
+
print N "\n};\n\n";
print N "/* and the corresponding opcodes */\n";
print N "static const enum opcode ico[] = {";
$first = 0;
print N "\n\tI_$i";
}
-
+
print N "\n};\n";
-
+
close N;
}
my $num, $nd = 0;
return (undef, undef) if $operands eq "ignore";
-
+
# format the operands
$operands =~ s/:/|colon,/g;
$operands =~ s/mem(\d+)/mem|bits$1/g;
}
$operands = join(',', @ops);
$operands =~ tr/a-z/A-Z/;
-
+
# format the flags
$flags =~ s/,/|IF_/g;
$flags =~ s/(\|IF_ND|IF_ND\|)//, $nd = 1 if $flags =~ /IF_ND/;
$flags = "IF_" . $flags;
-
+
("{I_$opcode, $num, {$operands}, \"$codes\", $flags},", $nd);
}
-sub hexlist($$$) {
- my($prefix, $start, $n) = @_;
- my $i;
+sub addprefix ($@) {
+ my ($prefix, @list) = @_;
+ my $x;
my @l = ();
- for ($i = 0; $i < $n; $i++) {
- push(@l, sprintf("%s%02X", $prefix, $start+$i));
+ foreach $x (@list) {
+ push(@l, sprintf("%s%02X", $prefix, $x));
}
+
return @l;
}
}
foreach $pfx (@disasm_prefixes) {
- if ($fbs =~ /^$pfx(.*)$/) {
+ if (substr($fbs, 0, length($pfx)) eq $pfx) {
$prefix = $pfx;
- $fbs = $1;
+ $fbs = substr($fbs, length($pfx));
last;
}
}
if ($fbs ne '') {
return ($prefix.substr($fbs,0,2));
}
+
+ unshift(@codes, $c0);
} elsif ($c0 == 04) {
- return ("07", "17", "1F");
+ return addprefix($prefix, 0x07, 0x17, 0x1F);
} elsif ($c0 == 05) {
- return ("A1", "A9");
+ return addprefix($prefix, 0xA1, 0xA9);
} elsif ($c0 == 06) {
- return ("06", "0E", "16", "1E");
+ return addprefix($prefix, 0x06, 0x0E, 0x16, 0x1E);
} elsif ($c0 == 07) {
- return ("A0", "A8");
+ return addprefix($prefix, 0xA0, 0xA8);
} elsif ($c0 >= 010 && $c0 <= 013) {
- return hexlist($prefix, $c1, 8);
+ return addprefix($prefix, $c1..($c1+7));
+ } elsif (($c0 & ~013) == 0144) {
+ return addprefix($prefix, $c1, $c1|2);
} elsif ($c0 == 0330) {
- return hexlist($prefix, $c1, 16);
+ return addprefix($prefix, $c1..($c1+15));
} elsif ($c0 == 0 || $c0 == 0340) {
- return ();
+ return $prefix;
+ } else {
+ # We really need to be able to distinguish "forbidden"
+ # and "ignorable" codes here
}
}
- return ();
+ return $prefix;
}