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>