Home | History | Annotate | Line # | Download | only in ev6
      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 
     46 use strict;
     47 
     48 # The U or L which various instructions demand, or E if either.
     49 #
     50 my %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 #
    109 my %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.
    198 sub 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.
    214 sub 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 
    260 sub 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 
    306 coverage();
    307 check();
    308 
    309 my @files;
    310 if ($#ARGV >= 0) {
    311   @files = @ARGV;
    312 } else {
    313   die
    314 }
    315 
    316 foreach (@files)  {
    317     disassemble($_);
    318 }
    319