Blame mpn/alpha/ev6/slot.pl

Packit 5c3484
#!/usr/bin/perl -w
Packit 5c3484
Packit 5c3484
# Copyright 2000, 2001, 2003-2005, 2011 Free Software Foundation, Inc.
Packit 5c3484
#
Packit 5c3484
#  This file is part of the GNU MP Library.
Packit 5c3484
#
Packit 5c3484
#  The GNU MP Library is free software; you can redistribute it and/or modify
Packit 5c3484
#  it under the terms of either:
Packit 5c3484
#
Packit 5c3484
#    * the GNU Lesser General Public License as published by the Free
Packit 5c3484
#      Software Foundation; either version 3 of the License, or (at your
Packit 5c3484
#      option) any later version.
Packit 5c3484
#
Packit 5c3484
#  or
Packit 5c3484
#
Packit 5c3484
#    * the GNU General Public License as published by the Free Software
Packit 5c3484
#      Foundation; either version 2 of the License, or (at your option) any
Packit 5c3484
#      later version.
Packit 5c3484
#
Packit 5c3484
#  or both in parallel, as here.
Packit 5c3484
#
Packit 5c3484
#  The GNU MP Library is distributed in the hope that it will be useful, but
Packit 5c3484
#  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit 5c3484
#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit 5c3484
#  for more details.
Packit 5c3484
#
Packit 5c3484
#  You should have received copies of the GNU General Public License and the
Packit 5c3484
#  GNU Lesser General Public License along with the GNU MP Library.  If not,
Packit 5c3484
#  see https://www.gnu.org/licenses/.
Packit 5c3484
Packit 5c3484
Packit 5c3484
# Usage: slot.pl [filename.o]...
Packit 5c3484
#
Packit 5c3484
# Run "objdump" to produce a disassembly of the given object file(s) and
Packit 5c3484
# annotate the output with "U" or "L" slotting which Alpha EV6 will use.
Packit 5c3484
#
Packit 5c3484
# When an instruction is E (ie. either U or L), an "eU" or "eL" is shown, as
Packit 5c3484
# a reminder that it wasn't a fixed requirement that gave the U or L, but
Packit 5c3484
# the octaword slotting rules.
Packit 5c3484
#
Packit 5c3484
# If an instruction is not recognised, that octaword does not get any U/L
Packit 5c3484
# shown, only lower-case "u", "l" or "e" for the instructions which are
Packit 5c3484
# known.  Add any unknown instructions to %optable below.
Packit 5c3484
Packit 5c3484
Packit 5c3484
use strict;
Packit 5c3484
Packit 5c3484
# The U or L which various instructions demand, or E if either.
Packit 5c3484
#
Packit 5c3484
my %optable =
Packit 5c3484
  (
Packit 5c3484
   'addq'   => 'E',
Packit 5c3484
   'and'    => 'E',
Packit 5c3484
   'andnot' => 'E',
Packit 5c3484
   'beq'    => 'U',
Packit 5c3484
   'bge'    => 'U',
Packit 5c3484
   'bgt'    => 'U',
Packit 5c3484
   'bic'    => 'E',
Packit 5c3484
   'bis'    => 'E',
Packit 5c3484
   'blt'    => 'U',
Packit 5c3484
   'bne'    => 'U',
Packit 5c3484
   'br'     => 'L',
Packit 5c3484
   'clr'    => 'E',
Packit 5c3484
   'cmpule' => 'E',
Packit 5c3484
   'cmpult' => 'E',
Packit 5c3484
   'cmpeq'  => 'E',
Packit 5c3484
   'cmoveq' => 'E',
Packit 5c3484
   'cmovne' => 'E',
Packit 5c3484
   'ctpop'  => 'U',
Packit 5c3484
   'ctlz'   => 'U',
Packit 5c3484
   'cttz'   => 'U',
Packit 5c3484
   'extbl'  => 'U',
Packit 5c3484
   'extlh'  => 'U',
Packit 5c3484
   'extll'  => 'U',
Packit 5c3484
   'extqh'  => 'U',
Packit 5c3484
   'extql'  => 'U',
Packit 5c3484
   'extwh'  => 'U',
Packit 5c3484
   'extwl'  => 'U',
Packit 5c3484
   'jsr'    => 'L',
Packit 5c3484
   'lda'    => 'E',
Packit 5c3484
   'ldah'   => 'E',
Packit 5c3484
   'ldbu'   => 'L',
Packit 5c3484
   'ldl'    => 'L',
Packit 5c3484
   'ldq'    => 'L',
Packit 5c3484
   'ldt'    => 'L',
Packit 5c3484
   'ret'    => 'L',
Packit 5c3484
   'mov'    => 'E',
Packit 5c3484
   'mull'   => 'U',
Packit 5c3484
   'mulq'   => 'U',
Packit 5c3484
   'negq'   => 'E',
Packit 5c3484
   'nop'    => 'E',
Packit 5c3484
   'not'    => 'E',
Packit 5c3484
   's8addq' => 'E',
Packit 5c3484
   's8subq' => 'E',
Packit 5c3484
   # 'sextb'  => ?
Packit 5c3484
   # 'sextl'  => ?
Packit 5c3484
   'sll'    => 'U',
Packit 5c3484
   'srl'    => 'U',
Packit 5c3484
   'stq'    => 'L',
Packit 5c3484
   'subq'   => 'E',
Packit 5c3484
   'umulh'  => 'U',
Packit 5c3484
   'unop'   => 'E',
Packit 5c3484
   'xor'    => 'E',
Packit 5c3484
  );
Packit 5c3484
Packit 5c3484
# Slottings used for a given pattern of U/L/E in an octaword.  This is as
Packit 5c3484
# per the "Ebox Slotting" section of the EV6 hardware reference manual.
Packit 5c3484
#
Packit 5c3484
my %slottable =
Packit 5c3484
  (
Packit 5c3484
   'EEEE' => 'ULUL',
Packit 5c3484
   'EEEL' => 'ULUL',
Packit 5c3484
   'EEEU' => 'ULLU',
Packit 5c3484
   'EELE' => 'ULLU',
Packit 5c3484
   'EELL' => 'UULL',
Packit 5c3484
   'EELU' => 'ULLU',
Packit 5c3484
   'EEUE' => 'ULUL',
Packit 5c3484
   'EEUL' => 'ULUL',
Packit 5c3484
   'EEUU' => 'LLUU',
Packit 5c3484
   'ELEE' => 'ULUL',
Packit 5c3484
   'ELEL' => 'ULUL',
Packit 5c3484
   'ELEU' => 'ULLU',
Packit 5c3484
   'ELLE' => 'ULLU',
Packit 5c3484
   'ELLL' => 'ULLL',
Packit 5c3484
   'ELLU' => 'ULLU',
Packit 5c3484
   'ELUE' => 'ULUL',
Packit 5c3484
   'ELUL' => 'ULUL',
Packit 5c3484
Packit 5c3484
   'LLLL' => 'LLLL',
Packit 5c3484
   'LLLU' => 'LLLU',
Packit 5c3484
   'LLUE' => 'LLUU',
Packit 5c3484
   'LLUL' => 'LLUL',
Packit 5c3484
   'LLUU' => 'LLUU',
Packit 5c3484
   'LUEE' => 'LULU',
Packit 5c3484
   'LUEL' => 'LUUL',
Packit 5c3484
   'LUEU' => 'LULU',
Packit 5c3484
   'LULE' => 'LULU',
Packit 5c3484
   'LULL' => 'LULL',
Packit 5c3484
   'LULU' => 'LULU',
Packit 5c3484
   'LUUE' => 'LUUL',
Packit 5c3484
   'LUUL' => 'LUUL',
Packit 5c3484
   'LUUU' => 'LUUU',
Packit 5c3484
   'UEEE' => 'ULUL',
Packit 5c3484
   'UEEL' => 'ULUL',
Packit 5c3484
   'UEEU' => 'ULLU',
Packit 5c3484
Packit 5c3484
   'ELUU' => 'LLUU',
Packit 5c3484
   'EUEE' => 'LULU',
Packit 5c3484
   'EUEL' => 'LUUL',
Packit 5c3484
   'EUEU' => 'LULU',
Packit 5c3484
   'EULE' => 'LULU',
Packit 5c3484
   'EULL' => 'UULL',
Packit 5c3484
   'EULU' => 'LULU',
Packit 5c3484
   'EUUE' => 'LUUL',
Packit 5c3484
   'EUUL' => 'LUUL',
Packit 5c3484
   'EUUU' => 'LUUU',
Packit 5c3484
   'LEEE' => 'LULU',
Packit 5c3484
   'LEEL' => 'LUUL',
Packit 5c3484
   'LEEU' => 'LULU',
Packit 5c3484
   'LELE' => 'LULU',
Packit 5c3484
   'LELL' => 'LULL',
Packit 5c3484
   'LELU' => 'LULU',
Packit 5c3484
   'LEUE' => 'LUUL',
Packit 5c3484
   'LEUL' => 'LUUL',
Packit 5c3484
   'LEUU' => 'LLUU',
Packit 5c3484
   'LLEE' => 'LLUU',
Packit 5c3484
   'LLEL' => 'LLUL',
Packit 5c3484
   'LLEU' => 'LLUU',
Packit 5c3484
   'LLLE' => 'LLLU',
Packit 5c3484
Packit 5c3484
   'UELE' => 'ULLU',
Packit 5c3484
   'UELL' => 'UULL',
Packit 5c3484
   'UELU' => 'ULLU',
Packit 5c3484
   'UEUE' => 'ULUL',
Packit 5c3484
   'UEUL' => 'ULUL',
Packit 5c3484
   'UEUU' => 'ULUU',
Packit 5c3484
   'ULEE' => 'ULUL',
Packit 5c3484
   'ULEL' => 'ULUL',
Packit 5c3484
   'ULEU' => 'ULLU',
Packit 5c3484
   'ULLE' => 'ULLU',
Packit 5c3484
   'ULLL' => 'ULLL',
Packit 5c3484
   'ULLU' => 'ULLU',
Packit 5c3484
   'ULUE' => 'ULUL',
Packit 5c3484
   'ULUL' => 'ULUL',
Packit 5c3484
   'ULUU' => 'ULUU',
Packit 5c3484
   'UUEE' => 'UULL',
Packit 5c3484
   'UUEL' => 'UULL',
Packit 5c3484
   'UUEU' => 'UULU',
Packit 5c3484
   'UULE' => 'UULL',
Packit 5c3484
   'UULL' => 'UULL',
Packit 5c3484
   'UULU' => 'UULU',
Packit 5c3484
   'UUUE' => 'UUUL',
Packit 5c3484
   'UUUL' => 'UUUL',
Packit 5c3484
   'UUUU' => 'UUUU',
Packit 5c3484
  );
Packit 5c3484
Packit 5c3484
# Check all combinations of U/L/E are present in %slottable.
Packit 5c3484
sub coverage {
Packit 5c3484
  foreach my $a ('U', 'L', 'E') {
Packit 5c3484
    foreach my $b ('U', 'L', 'E') {
Packit 5c3484
      foreach my $c ('U', 'L', 'E') {
Packit 5c3484
        foreach my $d ('U', 'L', 'E') {
Packit 5c3484
          my $x = $a . $b . $c . $d;
Packit 5c3484
          if (! defined $slottable{$x}) {
Packit 5c3484
            print "slottable missing: $x\n"
Packit 5c3484
          }
Packit 5c3484
        }
Packit 5c3484
      }
Packit 5c3484
    }
Packit 5c3484
  }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
# Certain consistency checks for %slottable.
Packit 5c3484
sub check {
Packit 5c3484
  foreach my $x (keys %slottable) {
Packit 5c3484
    my $a = substr($x,0,1);
Packit 5c3484
    my $b = substr($x,1,1);
Packit 5c3484
    my $c = substr($x,2,1);
Packit 5c3484
    my $d = substr($x,3,1);
Packit 5c3484
    my $es = ($a eq 'E') + ($b eq 'E') + ($c eq 'E') + ($d eq 'E');
Packit 5c3484
    my $ls = ($a eq 'L') + ($b eq 'L') + ($c eq 'L') + ($d eq 'L');
Packit 5c3484
    my $us = ($a eq 'U') + ($b eq 'U') + ($c eq 'U') + ($d eq 'U');
Packit 5c3484
Packit 5c3484
    my $got = $slottable{$x};
Packit 5c3484
    my $want = $x;
Packit 5c3484
Packit 5c3484
    if ($es == 0) {
Packit 5c3484
Packit 5c3484
    } elsif ($es == 1) {
Packit 5c3484
      # when only one E, it's mapped to whichever of U or L is otherwise
Packit 5c3484
      # used the least
Packit 5c3484
      if ($ls > $us) {
Packit 5c3484
        $want =~ s/E/U/;
Packit 5c3484
      } else {
Packit 5c3484
        $want =~ s/E/L/;
Packit 5c3484
      }
Packit 5c3484
    } elsif ($es == 2) {
Packit 5c3484
      # when two E's and two U, then the E's map to L; vice versa for two E
Packit 5c3484
      # and two L
Packit 5c3484
      if ($ls == 2) {
Packit 5c3484
        $want =~ s/E/U/g;
Packit 5c3484
      } elsif ($us == 2) {
Packit 5c3484
        $want =~ s/E/L/g;
Packit 5c3484
      } else {
Packit 5c3484
        next;
Packit 5c3484
      }
Packit 5c3484
    } elsif ($es == 3) {
Packit 5c3484
      next;
Packit 5c3484
Packit 5c3484
    } else { # $es == 4
Packit 5c3484
      next;
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
    if ($want ne $got) {
Packit 5c3484
      print "slottable $x want $want got $got\n";
Packit 5c3484
    }
Packit 5c3484
  }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
sub disassemble {
Packit 5c3484
  my ($file) = @_;
Packit 5c3484
Packit 5c3484
  open (IN, "objdump -Srfh $file |") || die "Cannot open pipe from objdump\n";
Packit 5c3484
Packit 5c3484
  my (%pre, %post, %type);
Packit 5c3484
  while (<IN>) {
Packit 5c3484
    my $line = $_ . "";
Packit 5c3484
Packit 5c3484
    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]+).*)/) {
Packit 5c3484
      my ($this_pre, $addr, $this_post, $opcode) = ($1, $2, $3, $4);
Packit 5c3484
Packit 5c3484
      my $this_type = $optable{$opcode};
Packit 5c3484
      if (! defined ($this_type)) { $this_type = ' '; }
Packit 5c3484
Packit 5c3484
      $pre{$addr} = $this_pre;
Packit 5c3484
      $post{$addr} = $this_post;
Packit 5c3484
      $type{$addr} = $this_type;
Packit 5c3484
Packit 5c3484
      if ($addr eq 'c') {
Packit 5c3484
        my %slot = ('0'=>' ', '4'=>' ', '8'=>' ', 'c'=>' ');
Packit 5c3484
Packit 5c3484
        my $str = $type{'c'} . $type{'8'} . $type{'4'} . $type{'0'};
Packit 5c3484
        $str = $slottable{$str};
Packit 5c3484
        if (defined $str) {
Packit 5c3484
          $slot{'c'} = substr($str,0,1);
Packit 5c3484
          $slot{'8'} = substr($str,1,1);
Packit 5c3484
          $slot{'4'} = substr($str,2,1);
Packit 5c3484
          $slot{'0'} = substr($str,3,1);
Packit 5c3484
        }
Packit 5c3484
Packit 5c3484
        foreach my $i ('0', '4', '8', 'c') {
Packit 5c3484
          if ($slot{$i} eq $type{$i}) { $type{$i} = ' '; }
Packit 5c3484
          print $pre{$i}, ' ', lc($type{$i}),$slot{$i}, '  ', $post{$i}, "\n";
Packit 5c3484
        }
Packit 5c3484
Packit 5c3484
        %pre = ();
Packit 5c3484
        %type = ();
Packit 5c3484
        %post = ();
Packit 5c3484
      }
Packit 5c3484
    }
Packit 5c3484
  }
Packit 5c3484
Packit 5c3484
  close IN || die "Error from objdump (or objdump not available)\n";
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
coverage();
Packit 5c3484
check();
Packit 5c3484
Packit 5c3484
my @files;
Packit 5c3484
if ($#ARGV >= 0) {
Packit 5c3484
  @files = @ARGV;
Packit 5c3484
} else {
Packit 5c3484
  die
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
foreach (@files)  {
Packit 5c3484
    disassemble($_);
Packit 5c3484
}