#!/usr/bin/perl use strict; sub plaintext { print $_[0]; } sub ins { my $bits = $_[0]; my $bline; #bit value line my $vline; my $nline; #print bit value line my $pvline; my @bitlist; my $tabular; my $count = 0; my @fields; my $i; my $x; my @fieldnames; my @flagnames = ('SF', 'CF', 'OF', 'ZF'); my $section = "\\subsubsection"; if($_[9]) { $section = "\\item "; } @fields = split(/\|/, $_[3]); foreach my $field (@fields) { #remove heading and trailing spaces $field =~ s/^\s+//; $field =~ s/\s+$//; $count += $field; #$tabular .= $field." \\\\"; } if($count != $bits) { return "Num of Fields not equal to Bits!"; } $count = 0; @fieldnames = split(/\|/, $_[4]); if(scalar(@fields) != scalar(@fieldnames)) { return "Num of Fields != Num of Names"; } $pvline = 0; foreach my $fieldn (@fieldnames) { #remove heading and trailing spaces $fieldn =~ s/^\s+//; $fieldn =~ s/\s+$//; if($fieldn =~ m/^[^\(.]*\(\s*([0-1]+)\s*\).*$/) { if(length($1) == $fields[$count]) { push(@bitlist,'S'.$1); $fieldn =~ s/\s?\(\s*[0-1]+\s*\)//; $pvline = 1; } else { $x = 'LX'; push(@bitlist,$x); } } else { $x = 'LX'; push(@bitlist,$x); } #$tabular .= $fieldn.": ". $bits." \\\\"; $count++; } #$tabular .= "\\textbf{names:} @fieldnames \n"; #$tabular .= "\\textbf{bitlist:} $bitlist \n"; $count = $bits-1; $tabular = $section."{\\texttt{".$_[1]."} -- ".$_[2]."}\n"; $tabular .= "\\begin{center} \n \\resizebox{\\textwidth}{!}{\n"; $tabular .= "\\begin{tabular}{|l|"; for($i = $bits-1; $i >= 0; $i--) { #build table $tabular .= "c|"; #build bitcount $bline .= $i; if($i != 0) { $bline .= " & "; } else { $bline .= "\\\\ \\hline \n"; } #build nameline and bitvalue #because of multicolumn we need to limit execution if($i == $count) { $nline .= "\\multicolumn{@fields[0]}{>{\\columncolor{names}}c|}{@fieldnames[0]}"; if(substr(@bitlist[0],0,1) eq "L") { $vline .= "\\multicolumn{@fields[0]}{>{\\columncolor{bitval}}c|}{".substr(@bitlist[0],1)."}"; } else { for(my $j = 1; $j <= @fields[0]; $j++) { $vline .= substr(@bitlist[0],$j,1); if($j != @fields[0]) { $vline .= " & "; } } } #update count $count -= @fields[0]; if($count < 0) { $nline .= "\\\\ \\hline \n"; $vline .= "\\\\ \\hline \n"; } else { $nline .= " & "; $vline .= " & "; } shift(@bitlist); shift(@fieldnames); shift(@fields); } } $tabular .= "} \\hline \n"; $tabular .= "\\multicolumn{".($bits+1)."}{|>{\\columncolor{title}}c|}{\\textbf{".$_[1]."} (".$_[2].")} \\\\ \\hline \n"; $tabular .= "\\rowcolor{bit} \\cellcolor{title} &". $bline; if($pvline == 1) { $tabular .= "\\rowcolor{bitval} \\cellcolor{title}Values &". $vline; } $tabular .= "\\cellcolor{title}Field &". $nline; $tabular .= "\\end{tabular}\n}\n \\end{center}\n"; if($_[5]) { $tabular .= "\\paragraph{Description:}~\\\\ \n ".$_[5]. "\n"; } if($_[6]) { $count = 0; my @flags = split(/\|/, $_[6]); if(scalar(@flags) == scalar(@flagnames)) { $tabular .= "\\paragraph{Flags:} \n"; foreach my $flag (@flags) { #remove heading and trailing spaces $flag =~ s/^\s+//; $flag =~ s/\s+$//; if(length($flag) > 0 ) { $tabular .= "\\subparagraph{".$flagnames[$count].":} ".$flag." \n"; } $count++; } } } if($_[7]) { $tabular .= "\\paragraph{Example:}~\\\\ \n \\begin{lstlisting} \n ".$_[7]. " \\end{lstlisting}\n"; } print $tabular; if($_[8]) { print "\\paragraph{Aliases to this Instruction:} \n"; my @aliases = split(/\|/, $_[8]); print "\\begin{list}{\\labelitemi}{\\leftmargin=0em \\itemindent=1em}"; foreach my $alias (@aliases) { my $long; my $sub; my @params; my $namelist = $_[4]; @params = split(/-/, $alias); $sub = @params[0]; $long = @params[1]; shift(@params); shift(@params); foreach my $vals (@params) { my $field; my $val; ($field, $val) = split(/\//, $vals); my @fieldnames = split(/\|/, $namelist); $fieldnames[$field] = $fieldnames[$field]."(".$val.")"; $namelist = join("|",@fieldnames); } ins($_[0], $sub, $long,$_[3], $namelist, '', '', '', '',1); } print "\\end{list}"; } } if($#ARGV != 0) { die "Usage: gentex.pl "; } my $output = $ARGV[0]; my $input = $ARGV[0]; $output =~ s/\.[^.]*$//; $output .= ".tex"; open STDOUT, '>', $output or die "Can't redirect STDOUT: $!"; do $input;