xref: /netbsd-src/external/lgpl3/gmp/dist/mpn/alpha/ev6/slot.pl (revision ce54336801cf28877c3414aa2fcb251dddd543a2)
1#!/usr/bin/perl -w
2
3# Copyright 2000, 2001, 2003-2005, 2011 Free Software Foundation, Inc.
4#
5#  This file is part of the GNU MP Library.
6#
7#  The GNU MP Library is free software; you can redistribute it and/or modify
8#  it under the terms of either:
9#
10#    * the GNU Lesser General Public License as published by the Free
11#      Software Foundation; either version 3 of the License, or (at your
12#      option) any later version.
13#
14#  or
15#
16#    * the GNU General Public License as published by the Free Software
17#      Foundation; either version 2 of the License, or (at your option) any
18#      later version.
19#
20#  or both in parallel, as here.
21#
22#  The GNU MP Library is distributed in the hope that it will be useful, but
23#  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25#  for more details.
26#
27#  You should have received copies of the GNU General Public License and the
28#  GNU Lesser General Public License along with the GNU MP Library.  If not,
29#  see https://www.gnu.org/licenses/.
30
31
32# Usage: slot.pl [filename.o]...
33#
34# Run "objdump" to produce a disassembly of the given object file(s) and
35# annotate the output with "U" or "L" slotting which Alpha EV6 will use.
36#
37# When an instruction is E (ie. either U or L), an "eU" or "eL" is shown, as
38# a reminder that it wasn't a fixed requirement that gave the U or L, but
39# the octaword slotting rules.
40#
41# If an instruction is not recognised, that octaword does not get any U/L
42# shown, only lower-case "u", "l" or "e" for the instructions which are
43# known.  Add any unknown instructions to %optable below.
44
45
46use strict;
47
48# The U or L which various instructions demand, or E if either.
49#
50my %optable =
51  (
52   'addq'   => 'E',
53   'and'    => 'E',
54   'andnot' => 'E',
55   'beq'    => 'U',
56   'bge'    => 'U',
57   'bgt'    => 'U',
58   'bic'    => 'E',
59   'bis'    => 'E',
60   'blt'    => 'U',
61   'bne'    => 'U',
62   'br'     => 'L',
63   'clr'    => 'E',
64   'cmpule' => 'E',
65   'cmpult' => 'E',
66   'cmpeq'  => 'E',
67   'cmoveq' => 'E',
68   'cmovne' => 'E',
69   'ctpop'  => 'U',
70   'ctlz'   => 'U',
71   'cttz'   => 'U',
72   'extbl'  => 'U',
73   'extlh'  => 'U',
74   'extll'  => 'U',
75   'extqh'  => 'U',
76   'extql'  => 'U',
77   'extwh'  => 'U',
78   'extwl'  => 'U',
79   'jsr'    => 'L',
80   'lda'    => 'E',
81   'ldah'   => 'E',
82   'ldbu'   => 'L',
83   'ldl'    => 'L',
84   'ldq'    => 'L',
85   'ldt'    => 'L',
86   'ret'    => 'L',
87   'mov'    => 'E',
88   'mull'   => 'U',
89   'mulq'   => 'U',
90   'negq'   => 'E',
91   'nop'    => 'E',
92   'not'    => 'E',
93   's8addq' => 'E',
94   's8subq' => 'E',
95   # 'sextb'  => ?
96   # 'sextl'  => ?
97   'sll'    => 'U',
98   'srl'    => 'U',
99   'stq'    => 'L',
100   'subq'   => 'E',
101   'umulh'  => 'U',
102   'unop'   => 'E',
103   'xor'    => 'E',
104  );
105
106# Slottings used for a given pattern of U/L/E in an octaword.  This is as
107# per the "Ebox Slotting" section of the EV6 hardware reference manual.
108#
109my %slottable =
110  (
111   'EEEE' => 'ULUL',
112   'EEEL' => 'ULUL',
113   'EEEU' => 'ULLU',
114   'EELE' => 'ULLU',
115   'EELL' => 'UULL',
116   'EELU' => 'ULLU',
117   'EEUE' => 'ULUL',
118   'EEUL' => 'ULUL',
119   'EEUU' => 'LLUU',
120   'ELEE' => 'ULUL',
121   'ELEL' => 'ULUL',
122   'ELEU' => 'ULLU',
123   'ELLE' => 'ULLU',
124   'ELLL' => 'ULLL',
125   'ELLU' => 'ULLU',
126   'ELUE' => 'ULUL',
127   'ELUL' => 'ULUL',
128
129   'LLLL' => 'LLLL',
130   'LLLU' => 'LLLU',
131   'LLUE' => 'LLUU',
132   'LLUL' => 'LLUL',
133   'LLUU' => 'LLUU',
134   'LUEE' => 'LULU',
135   'LUEL' => 'LUUL',
136   'LUEU' => 'LULU',
137   'LULE' => 'LULU',
138   'LULL' => 'LULL',
139   'LULU' => 'LULU',
140   'LUUE' => 'LUUL',
141   'LUUL' => 'LUUL',
142   'LUUU' => 'LUUU',
143   'UEEE' => 'ULUL',
144   'UEEL' => 'ULUL',
145   'UEEU' => 'ULLU',
146
147   'ELUU' => 'LLUU',
148   'EUEE' => 'LULU',
149   'EUEL' => 'LUUL',
150   'EUEU' => 'LULU',
151   'EULE' => 'LULU',
152   'EULL' => 'UULL',
153   'EULU' => 'LULU',
154   'EUUE' => 'LUUL',
155   'EUUL' => 'LUUL',
156   'EUUU' => 'LUUU',
157   'LEEE' => 'LULU',
158   'LEEL' => 'LUUL',
159   'LEEU' => 'LULU',
160   'LELE' => 'LULU',
161   'LELL' => 'LULL',
162   'LELU' => 'LULU',
163   'LEUE' => 'LUUL',
164   'LEUL' => 'LUUL',
165   'LEUU' => 'LLUU',
166   'LLEE' => 'LLUU',
167   'LLEL' => 'LLUL',
168   'LLEU' => 'LLUU',
169   'LLLE' => 'LLLU',
170
171   'UELE' => 'ULLU',
172   'UELL' => 'UULL',
173   'UELU' => 'ULLU',
174   'UEUE' => 'ULUL',
175   'UEUL' => 'ULUL',
176   'UEUU' => 'ULUU',
177   'ULEE' => 'ULUL',
178   'ULEL' => 'ULUL',
179   'ULEU' => 'ULLU',
180   'ULLE' => 'ULLU',
181   'ULLL' => 'ULLL',
182   'ULLU' => 'ULLU',
183   'ULUE' => 'ULUL',
184   'ULUL' => 'ULUL',
185   'ULUU' => 'ULUU',
186   'UUEE' => 'UULL',
187   'UUEL' => 'UULL',
188   'UUEU' => 'UULU',
189   'UULE' => 'UULL',
190   'UULL' => 'UULL',
191   'UULU' => 'UULU',
192   'UUUE' => 'UUUL',
193   'UUUL' => 'UUUL',
194   'UUUU' => 'UUUU',
195  );
196
197# Check all combinations of U/L/E are present in %slottable.
198sub coverage {
199  foreach my $a ('U', 'L', 'E') {
200    foreach my $b ('U', 'L', 'E') {
201      foreach my $c ('U', 'L', 'E') {
202        foreach my $d ('U', 'L', 'E') {
203          my $x = $a . $b . $c . $d;
204          if (! defined $slottable{$x}) {
205            print "slottable missing: $x\n"
206          }
207        }
208      }
209    }
210  }
211}
212
213# Certain consistency checks for %slottable.
214sub check {
215  foreach my $x (keys %slottable) {
216    my $a = substr($x,0,1);
217    my $b = substr($x,1,1);
218    my $c = substr($x,2,1);
219    my $d = substr($x,3,1);
220    my $es = ($a eq 'E') + ($b eq 'E') + ($c eq 'E') + ($d eq 'E');
221    my $ls = ($a eq 'L') + ($b eq 'L') + ($c eq 'L') + ($d eq 'L');
222    my $us = ($a eq 'U') + ($b eq 'U') + ($c eq 'U') + ($d eq 'U');
223
224    my $got = $slottable{$x};
225    my $want = $x;
226
227    if ($es == 0) {
228
229    } elsif ($es == 1) {
230      # when only one E, it's mapped to whichever of U or L is otherwise
231      # used the least
232      if ($ls > $us) {
233        $want =~ s/E/U/;
234      } else {
235        $want =~ s/E/L/;
236      }
237    } elsif ($es == 2) {
238      # when two E's and two U, then the E's map to L; vice versa for two E
239      # and two L
240      if ($ls == 2) {
241        $want =~ s/E/U/g;
242      } elsif ($us == 2) {
243        $want =~ s/E/L/g;
244      } else {
245        next;
246      }
247    } elsif ($es == 3) {
248      next;
249
250    } else { # $es == 4
251      next;
252    }
253
254    if ($want ne $got) {
255      print "slottable $x want $want got $got\n";
256    }
257  }
258}
259
260sub disassemble {
261  my ($file) = @_;
262
263  open (IN, "objdump -Srfh $file |") || die "Cannot open pipe from objdump\n";
264
265  my (%pre, %post, %type);
266  while (<IN>) {
267    my $line = $_ . "";
268
269    if ($line =~ /(^[ \t]*[0-9a-f]*([0-9a-f]):[ \t]*[0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] )\t(([a-z0-9]+).*)/) {
270      my ($this_pre, $addr, $this_post, $opcode) = ($1, $2, $3, $4);
271
272      my $this_type = $optable{$opcode};
273      if (! defined ($this_type)) { $this_type = ' '; }
274
275      $pre{$addr} = $this_pre;
276      $post{$addr} = $this_post;
277      $type{$addr} = $this_type;
278
279      if ($addr eq 'c') {
280        my %slot = ('0'=>' ', '4'=>' ', '8'=>' ', 'c'=>' ');
281
282        my $str = $type{'c'} . $type{'8'} . $type{'4'} . $type{'0'};
283        $str = $slottable{$str};
284        if (defined $str) {
285          $slot{'c'} = substr($str,0,1);
286          $slot{'8'} = substr($str,1,1);
287          $slot{'4'} = substr($str,2,1);
288          $slot{'0'} = substr($str,3,1);
289        }
290
291        foreach my $i ('0', '4', '8', 'c') {
292          if ($slot{$i} eq $type{$i}) { $type{$i} = ' '; }
293          print $pre{$i}, ' ', lc($type{$i}),$slot{$i}, '  ', $post{$i}, "\n";
294        }
295
296        %pre = ();
297        %type = ();
298        %post = ();
299      }
300    }
301  }
302
303  close IN || die "Error from objdump (or objdump not available)\n";
304}
305
306coverage();
307check();
308
309my @files;
310if ($#ARGV >= 0) {
311  @files = @ARGV;
312} else {
313  die
314}
315
316foreach (@files)  {
317    disassemble($_);
318}
319