Annotation of OpenXM_contrib/gmp/mpn/x86/k6/cross.pl, Revision 1.1.1.2
1.1 maekawa 1: #! /usr/bin/perl
2:
1.1.1.2 ! ohara 3: # Copyright 2000, 2001 Free Software Foundation, Inc.
1.1 maekawa 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: #
1.1.1.2 ! ohara 32: # Code alignments of 8 bytes or more are handled. When 32 is used, cache
! 33: # line boundaries will fall in at offsets 0x20,0x40,etc and problems are
! 34: # flagged at those locations. When 16 is used, the line boundaries can also
! 35: # fall at offsets 0x10,0x30,0x50,etc, depending where the file is loaded, so
! 36: # problems are identified there too. Likewise when 8 byte alignment is used
! 37: # problems are flagged additionally at 0x08,0x18,0x28,etc.
! 38: #
! 39: # Usually 32 byte alignment is used for k6 routines, but less is certainly
! 40: # possible if through good luck, or a little tweaking, cache line crossing
! 41: # problems can be avoided at the extra locations.
1.1 maekawa 42: #
43: # Bugs:
44: #
45: # Instructions without mod/rm bytes or which are already vector decoded are
46: # unaffected by cache line boundary crossing, but not all of these have yet
47: # been put in as exceptions. All that occur in practice in GMP are present
48: # though.
49: #
50: # There's no messages for using the vector decoded addressing mode (%esi),
1.1.1.2 ! ohara 51: # but that's easy to avoid when coding.
! 52: #
! 53: # Future:
! 54: #
! 55: # Warn about jump targets that are poorly aligned (less than 2 instructions
! 56: # before a cache line boundary).
1.1 maekawa 57:
58: use strict;
59:
60: sub disassemble {
61: my ($file) = @_;
62: my ($addr,$b1,$b2,$b3, $prefix,$opcode,$modrm);
1.1.1.2 ! ohara 63: my $align;
1.1 maekawa 64:
65: open (IN, "objdump -Srfh $file |")
66: || die "Cannot open pipe from objdump\n";
67: while (<IN>) {
68: print;
69:
70: if (/^[ \t]*[0-9]+[ \t]+\.text[ \t]/ && /2\*\*([0-9]+)$/) {
1.1.1.2 ! ohara 71: $align = 1 << $1;
! 72: if ($align < 8) {
! 73: print "ZZ cross.pl cannot handle alignment < 2**3\n";
! 74: $align = 8
1.1 maekawa 75: }
76: }
77:
78: if (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)[ \t]+([0-9a-f]+)[ \t]+([0-9a-f]+)/) {
79: ($addr,$b1,$b2,$b3) = ($1,$2,$3,$4);
80:
81: } elsif (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)[ \t]+([0-9a-f]+)/) {
82: ($addr,$b1,$b2,$b3) = ($1,$2,$3,'');
83:
84: } elsif (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)/) {
85: ($addr,$b1,$b2,$b3) = ($1,$2,'','');
86:
87: } else {
88: next;
89: }
90:
91: if ($b1 =~ /0f/) {
92: $prefix = $b1;
93: $opcode = $b2;
94: $modrm = $b3;
95: } else {
96: $prefix = '';
97: $opcode = $b1;
98: $modrm = $b2;
99: }
100:
101: # modrm of the form 00-xxx-100 with an 0F prefix is the problem case
102: # for K6 and pre-CXT K6-2
103: if ($prefix =~ /0f/
104: && $opcode !~ /^8/ # jcond disp32
105: && $modrm =~ /^[0-3][4c]/) {
1.1.1.2 ! ohara 106: print "ZZ ($file) >3 bytes to determine instruction length [K6]\n";
1.1 maekawa 107: }
108:
109: # with just an opcode, starting 1f mod 20h
1.1.1.2 ! ohara 110: if (($align==32 && $addr =~ /[13579bdf]f$/
! 111: || $align==16 && $addr =~ /f$/
! 112: || $align==8 && $addr =~ /[7f]$/)
1.1 maekawa 113: && $prefix !~ /0f/
114: && $opcode !~ /1[012345]/ # adc
115: && $opcode !~ /1[89abcd]/ # sbb
1.1.1.2 ! ohara 116: && $opcode !~ /^4/ # inc/dec reg
! 117: && $opcode !~ /^5/ # push/pop reg
1.1 maekawa 118: && $opcode !~ /68/ # push $imm32
119: && $opcode !~ /^7/ # jcond disp8
120: && $opcode !~ /a[89]/ # test+imm
121: && $opcode !~ /a[a-f]/ # stos/lods/scas
122: && $opcode !~ /b8/ # movl $imm32,%eax
1.1.1.2 ! ohara 123: && $opcode !~ /d[0123]/ # rcl
1.1 maekawa 124: && $opcode !~ /e[0123]/ # loop/loopz/loopnz/jcxz
1.1.1.2 ! ohara 125: && $opcode !~ /e8/ # call disp32
! 126: && $opcode !~ /e[9b]/ # jmp disp32/disp8
1.1 maekawa 127: && $opcode !~ /f[89abcd]/ # clc,stc,cli,sti,cld,std
128: && !($opcode =~ /f[67]/ # grp 1
129: && $modrm =~ /^[2367abef]/) # mul, imul, div, idiv
130: && $modrm !~ /^$/) {
131: print "ZZ ($file) opcode/modrm cross 32-byte boundary\n";
132: }
133:
134: # with an 0F prefix, anything starting at 1f mod 20h
1.1.1.2 ! ohara 135: if (($align==32 && $addr =~ /[13579bdf][f]$/
! 136: || $align==16 && $addr =~ /f$/
! 137: || $align==8 && $addr =~ /[7f]$/)
! 138: && $prefix =~ /0f/
! 139: && $opcode !~ /af/ # imul
! 140: && $opcode !~ /a[45]/ # shldl
! 141: && $opcode !~ /a[cd]/ # shrdl
! 142: ) {
1.1 maekawa 143: print "ZZ ($file) prefix/opcode cross 32-byte boundary\n";
144: }
145:
146: # with an 0F prefix, anything with mod/rm starting at 1e mod 20h
1.1.1.2 ! ohara 147: if (($align==32 && $addr =~ /[13579bdf][e]$/
! 148: || $align==16 && $addr =~ /[e]$/
! 149: || $align==8 && $addr =~ /[6e]$/)
1.1 maekawa 150: && $prefix =~ /0f/
151: && $opcode !~ /^8/ # jcond disp32
1.1.1.2 ! ohara 152: && $opcode !~ /af/ # imull reg,reg
! 153: && $opcode !~ /a[45]/ # shldl
! 154: && $opcode !~ /a[cd]/ # shrdl
1.1 maekawa 155: && $modrm !~ /^$/) {
156: print "ZZ ($file) prefix/opcode/modrm cross 32-byte boundary\n";
157: }
158: }
159: close IN || die "Error from objdump (or objdump not available)\n";
160: }
161:
162:
163: my @files;
164: if ($#ARGV >= 0) {
165: @files = @ARGV;
166: } else {
167: @files = glob "*.asm";
168: map {s/.asm/.o/} @files;
169: }
170:
171: foreach (@files) {
172: disassemble($_);
173: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>