[BACK]Return to cross.pl CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpn / x86 / k6

Annotation of OpenXM_contrib/gmp/mpn/x86/k6/cross.pl, Revision 1.1

1.1     ! maekawa     1: #! /usr/bin/perl
        !             2:
        !             3: # Copyright (C) 2000 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 the GNU Lesser General Public License as published
        !             9: # by the Free Software Foundation; either version 2.1 of the License, or (at
        !            10: # your option) any later version.
        !            11: #
        !            12: # The GNU MP Library is distributed in the hope that it will be useful, but
        !            13: # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            14: # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
        !            15: # License for more details.
        !            16: #
        !            17: # You should have received a copy of the GNU Lesser General Public License
        !            18: # along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
        !            19: # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
        !            20: # MA 02111-1307, USA.
        !            21:
        !            22:
        !            23: # Usage: cross.pl [filename.o]...
        !            24: #
        !            25: # Produce an annotated disassembly of the given object files, indicating
        !            26: # certain code alignment and addressing mode problems afflicting K6 chips.
        !            27: # "ZZ" is used on all annotations, so this can be searched for.
        !            28: #
        !            29: # With no arguments, all .o files corresponding to .asm files are processed.
        !            30: # This is good in the mpn object directory of a k6*-*-* build.
        !            31: #
        !            32: # As far as fixing problems goes, any cache line crossing problems in loops
        !            33: # get attention, but as a rule it's too tedious to rearrange code or slip in
        !            34: # nops to fix every problem in setup or finishup code.
        !            35: #
        !            36: # Bugs:
        !            37: #
        !            38: # Instructions without mod/rm bytes or which are already vector decoded are
        !            39: # unaffected by cache line boundary crossing, but not all of these have yet
        !            40: # been put in as exceptions.  All that occur in practice in GMP are present
        !            41: # though.
        !            42: #
        !            43: # There's no messages for using the vector decoded addressing mode (%esi),
        !            44: # but that mode is easy to avoid when coding.
        !            45:
        !            46: use strict;
        !            47:
        !            48: sub disassemble {
        !            49:     my ($file) = @_;
        !            50:     my ($addr,$b1,$b2,$b3, $prefix,$opcode,$modrm);
        !            51:
        !            52:     open (IN, "objdump -Srfh $file |")
        !            53:        || die "Cannot open pipe from objdump\n";
        !            54:     while (<IN>) {
        !            55:        print;
        !            56:
        !            57:        if (/^[ \t]*[0-9]+[ \t]+\.text[ \t]/ && /2\*\*([0-9]+)$/) {
        !            58:            if ($1 < 5) {
        !            59:                print "ZZ need at least 2**5 for predictable cache line crossing\n";
        !            60:            }
        !            61:        }
        !            62:
        !            63:        if (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)[ \t]+([0-9a-f]+)[ \t]+([0-9a-f]+)/) {
        !            64:            ($addr,$b1,$b2,$b3) = ($1,$2,$3,$4);
        !            65:
        !            66:        } elsif (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)[ \t]+([0-9a-f]+)/) {
        !            67:            ($addr,$b1,$b2,$b3) = ($1,$2,$3,'');
        !            68:
        !            69:        } elsif (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)/) {
        !            70:            ($addr,$b1,$b2,$b3) = ($1,$2,'','');
        !            71:
        !            72:        } else {
        !            73:            next;
        !            74:        }
        !            75:
        !            76:        if ($b1 =~ /0f/) {
        !            77:            $prefix = $b1;
        !            78:            $opcode = $b2;
        !            79:            $modrm = $b3;
        !            80:        } else {
        !            81:            $prefix = '';
        !            82:            $opcode = $b1;
        !            83:            $modrm = $b2;
        !            84:        }
        !            85:
        !            86:        # modrm of the form 00-xxx-100 with an 0F prefix is the problem case
        !            87:        # for K6 and pre-CXT K6-2
        !            88:        if ($prefix =~ /0f/
        !            89:            && $opcode !~ /^8/         # jcond disp32
        !            90:            && $modrm =~ /^[0-3][4c]/) {
        !            91:            print "ZZ ($file) >3 bytes to determine instruction length\n";
        !            92:        }
        !            93:
        !            94:        # with just an opcode, starting 1f mod 20h
        !            95:        if ($addr =~ /[13579bdf]f$/
        !            96:            && $prefix !~ /0f/
        !            97:            && $opcode !~ /1[012345]/ # adc
        !            98:            && $opcode !~ /1[89abcd]/ # sbb
        !            99:            && $opcode !~ /68/        # push $imm32
        !           100:            && $opcode !~ /^7/        # jcond disp8
        !           101:            && $opcode !~ /a[89]/     # test+imm
        !           102:            && $opcode !~ /a[a-f]/    # stos/lods/scas
        !           103:            && $opcode !~ /b8/        # movl $imm32,%eax
        !           104:            && $opcode !~ /e[0123]/   # loop/loopz/loopnz/jcxz
        !           105:            && $opcode !~ /e[b9]/     # jmp disp8/disp32
        !           106:            && $opcode !~ /f[89abcd]/ # clc,stc,cli,sti,cld,std
        !           107:            && !($opcode =~ /f[67]/          # grp 1
        !           108:                 && $modrm =~ /^[2367abef]/) # mul, imul, div, idiv
        !           109:            && $modrm !~ /^$/) {
        !           110:            print "ZZ ($file) opcode/modrm cross 32-byte boundary\n";
        !           111:        }
        !           112:
        !           113:        # with an 0F prefix, anything starting at 1f mod 20h
        !           114:        if ($addr =~ /[13579bdf][f]$/
        !           115:            && $prefix =~ /0f/) {
        !           116:            print "ZZ ($file) prefix/opcode cross 32-byte boundary\n";
        !           117:        }
        !           118:
        !           119:        # with an 0F prefix, anything with mod/rm starting at 1e mod 20h
        !           120:        if ($addr =~ /[13579bdf][e]$/
        !           121:            && $prefix =~ /0f/
        !           122:             && $opcode !~ /^8/        # jcond disp32
        !           123:            && $modrm !~ /^$/) {
        !           124:            print "ZZ ($file) prefix/opcode/modrm cross 32-byte boundary\n";
        !           125:        }
        !           126:     }
        !           127:     close IN || die "Error from objdump (or objdump not available)\n";
        !           128: }
        !           129:
        !           130:
        !           131: my @files;
        !           132: if ($#ARGV >= 0) {
        !           133:     @files = @ARGV;
        !           134: } else {
        !           135:     @files = glob "*.asm";
        !           136:     map {s/.asm/.o/} @files;
        !           137: }
        !           138:
        !           139: foreach (@files)  {
        !           140:     disassemble($_);
        !           141: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>