|
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 |
}
|