4 # -A .../insn-aliases.inc
9 # to-insn-aliases -P .../insn-aliases.inc (for debugging, really)
12 # gpdasm -p18f458 program+entire0.hex \
13 # | ../iwjpictest/to-insn-aliases -A ../iwjpictest/insn-aliases.inc \
14 # -M program+program.map -H /usr/share/gputils/header/p18f458.inc \
17 # ../iwjpictest/to-insn-aliases -A ../iwjpictest/insn-aliases.inc \
18 # <nmra-stream.asm >nmra-stream.asm.new
26 # $mapping{$opcode}[$i]{FormalArgs}[$j] = formal arg letter
27 # $mapping{$opcode}[$i]{Macro} = macro `opcode'
28 # $mapping{$opcode}[$i]{ActualArgs}[$j] = '0','1', or formal arg letter or W
31 # $syms{$loc}{$addr}[$i]= $show
32 # $addrs{$loc}[$i]= $addr
38 return unless $ARGV[0] =~ m/^\-/;
41 s/^\-([APHM])// or die;
42 if (!length) { @ARGV or die; $_= shift @ARGV; }
44 if ($1 eq 'P') { $doprint= 1; readaliases($f); }
45 elsif ($1 eq 'A') { readaliases($f); }
46 elsif ($1 eq 'M') { readmap($f); }
47 elsif ($1 eq 'H') { readheader($f); }
49 die $! if $f->error();
56 my ($ss, $name,$addr);
57 $ss= $syms{' sfr'}= { };
60 next unless m/^\;\-+\s*register file/i ... /^\;.*\-/;
64 die unless m/^(\w+)\s+equ\s+h\'0?(f[0-9a-f]{2})\'\s*$/i;
65 ($name,$addr) = ($1,$2);
67 next if exists $ss->{$addr};
74 my ($name,$addr,$loc,$stor,$file);
75 my ($scope,$show, $k);
77 next unless m/^\s+Symbols\s+$/ .. !m/\S/;
78 next if m/^\s+Symbols\s+$/;
79 next if m/^\s+Name\s+Address\s+Location\s+Storage\s+File\s+$/;
80 next unless m/[^ \t\n-]/;
82 m/^\s*(\w+)\s+(0x\w+|0+)\s+(program|data)\s+(static|extern)\s+(\S+)\s*$/;
83 ($name,$addr,$loc,$stor,$file)=($1,$2,$3,$4,$5);
84 $scope= $stor eq 'extern' ? '' : "$file:";
85 $scope =~ s/\.asm\:$/:/;
88 push @{ $syms{$loc}{$addr} }, $show;
89 push @{ $addrs{$loc} }, $addr;
91 foreach $k (keys %addrs) {
92 $addrs{$k}= [ sort { $a <=> $b } @{ $addrs{$k} } ];
96 sub builtin_opcodes () {
98 foreach $o (qw(bra goto call rcall)) {
99 push @{ $mapping{$o} }, {
100 FormalArgs => [qw(n)], Macro => $o, ActualArgs => [qw(n)]
103 push @{ $mapping{'call'} }, {
104 FormalArgs => [qw(n)], Macro => 'call', ActualArgs => [qw(n 0)]
106 foreach $o (qw(return retfie)) {
107 push @{ $mapping{$o} }, {
108 FormalArgs => [], Macro => $o, ActualArgs => [qw(0)]
113 sub addr2print ($$$) {
114 my ($loc, $av, $default) = @_;
115 my ($i,$j, $al, $h,$ha);
116 $av =~ s/^0x// or return $default;
118 if ($loc eq 'data' && $av >= 0xf00) {
120 return $default unless exists $al->{$av};
124 return $default unless $al;
127 #print ">$loc|$default|av=$av|i=$i|j=$j\n";
131 #print ">$loc|$default|av=$av|i=$i|j=$j|h=$h|ha=$ha\n";
132 if ($av == $ha) { return $syms{$loc}{$ha}[0]; }
133 elsif ($av < $ha) { $j=$h; }
137 if ($i < 0) { return $default; }
139 return sprintf "%s+0x%x", $syms{$loc}{$ha}[0], $av - $ha;
142 sub readaliases ($) {
144 my ($inmacro, @formalargs, $newmapping);
145 my ($formarglets) = 'inkfgb';
148 s/\binsn_aliases_arg_([a-z])\b/$1/g;
150 } elsif (m/^(\w+)\s+macro(?:\s+([$formarglets,]+))?\s*$/o) {
151 die if defined $inmacro;
153 @formalargs= defined $2 ? split /\,/, $2 : ();
154 } elsif (m/^\s+endm\b/) {
155 die unless defined $inmacro;
157 } elsif (m/^\s+(?:list|nolist)\b/) {
158 } elsif (m/^\s+(\w+)(?:\s+([01W$formarglets,]+))?\s*$/o) {
159 die if $inmacro eq '';
161 FormalArgs => [ @formalargs ],
164 push @{ $mapping{$1} }, $newmapping;
165 $newmapping->{ActualArgs}= defined $2 ? [ split /\,/, $2 ] : [];
173 sub printaliases () {
175 foreach $o (keys %mapping) {
176 foreach $m (@{ $mapping{$o} }) {
177 printf("%7s %-20s -> %13s %-20s\n",
178 $o, join(',', @{ $m->{ActualArgs} }),
179 $m->{Macro}, join(',', @{ $m->{FormalArgs} }));
187 my ($org_opcode, @org_args) = @_;
188 my ($m,$i,$mismatch,$specified,$pattern,%arg,$fa,$aa);
189 #print "**$org_opcode\n";
190 MAPPING: foreach $m (@{ $mapping{$org_opcode} }) {
191 next unless @org_args == @{ $m->{ActualArgs} };
192 #print "**$m->{Macro}|\n";
193 for ($i=0, $mismatch=0; !$mismatch && $i<@org_args; $i++) {
194 $specified= $org_args[$i];
195 $pattern= $m->{ActualArgs}[$i];
196 if ($pattern eq 'W') {
197 $pattern= 'WREG|0xfe8|0xe8';
198 $pattern= "(?:$pattern)";
199 } elsif ($pattern =~ m/^[01]$/) {
200 $pattern= "(?:0x)?$pattern";
202 if ($pattern =~ m/^[a-z]$/) {
203 $arg{$&}= $specified;
204 } elsif ($specified !~ m/^\s*$pattern\s*$/) {
205 #print "**$m->{Macro}|$pattern|$specified<\n";
211 foreach $fa (@{ $m->{FormalArgs} }) {
212 next unless $fa =~ m/^[a-z]$/;
214 #print ">@r|$fa|$aa<\n";
216 if ($m->{Macro} =~ m/_[wf]*a/ &&
217 $aa =~ m/^0x([6-9a-f][0-9a-f])$/) {
218 $aa= addr2print('data', "0xf$1", $aa);
220 $aa= addr2print('data', $aa, $aa);
222 } elsif ($fa =~ m/n/) {
223 $aa= addr2print('program', $aa, $aa);
232 sub processfiles () {
233 my ($comment,$addrshow, $addr,$symshow,$symbols);
234 my ($lhs,$opcode,$midspc,$args,$rhs, @args, $lastopcode);
236 $lastopcode= $insertnewline= '';
239 $comment= s/\;.*// ? $& : '';
241 if (s/^(([0-9a-f]{6})\:)\s+//) {
244 foreach $symshow (@{ $syms{'program'}{$addr} }) {
245 $symbols .= "$1 $symshow\n";
250 if (m/^(\w*\s+)(\w+)(\s+)(.*?)(\s*)$/) {
251 ($lhs,$opcode,$midspc,$args,$rhs) = ($1,$2,$3,$4,$5);
252 $symbols= $insertnewline.$symbols;
254 @args= split /\,/, $args;
255 ($opcode, @args) = mapinsn($opcode, @args);
256 $args= sprintf "%-*s", length($args), join ',', @args;
257 $midspc =~ s/\t$/ / if length($opcode) >= 8;
258 $_= $lhs.$opcode.$midspc.$args.$rhs;
259 #print ">$opcode|$lastopcode<?\n";
260 if (($opcode =~ m/^(?:return|retfie)(?:_r)?$/ ||
261 $opcode =~ m/^(?:goto|bra)$/) && length($addrshow) &&
262 length($lastopcode) && $lastopcode !~ m/_if\w+$/) {
263 #print ">$opcode|$lastopcode<INL\n";
264 $insertnewline= "\n";
266 $lastopcode= $opcode;
267 } elsif (length($addrshow) && m/^\w+\s*$/) {
269 $lastopcode= $insertnewline= '';
271 print $symbols, $addrshow, $_, $comment, "\n";
277 if ($doprint) { printaliases(); exit(0); }