=================================================================== RCS file: /home/cvs/OpenXM_contrib/gmp/mpn/x86/k6/Attic/cross.pl,v retrieving revision 1.1 retrieving revision 1.1.1.2 diff -u -p -r1.1 -r1.1.1.2 --- OpenXM_contrib/gmp/mpn/x86/k6/Attic/cross.pl 2000/09/09 14:12:42 1.1 +++ OpenXM_contrib/gmp/mpn/x86/k6/Attic/cross.pl 2003/08/25 16:06:27 1.1.1.2 @@ -1,6 +1,6 @@ #! /usr/bin/perl -# Copyright (C) 2000 Free Software Foundation, Inc. +# Copyright 2000, 2001 Free Software Foundation, Inc. # # This file is part of the GNU MP Library. # @@ -29,10 +29,17 @@ # With no arguments, all .o files corresponding to .asm files are processed. # This is good in the mpn object directory of a k6*-*-* build. # -# As far as fixing problems goes, any cache line crossing problems in loops -# get attention, but as a rule it's too tedious to rearrange code or slip in -# nops to fix every problem in setup or finishup code. +# Code alignments of 8 bytes or more are handled. When 32 is used, cache +# line boundaries will fall in at offsets 0x20,0x40,etc and problems are +# flagged at those locations. When 16 is used, the line boundaries can also +# fall at offsets 0x10,0x30,0x50,etc, depending where the file is loaded, so +# problems are identified there too. Likewise when 8 byte alignment is used +# problems are flagged additionally at 0x08,0x18,0x28,etc. # +# Usually 32 byte alignment is used for k6 routines, but less is certainly +# possible if through good luck, or a little tweaking, cache line crossing +# problems can be avoided at the extra locations. +# # Bugs: # # Instructions without mod/rm bytes or which are already vector decoded are @@ -41,13 +48,19 @@ # though. # # There's no messages for using the vector decoded addressing mode (%esi), -# but that mode is easy to avoid when coding. +# but that's easy to avoid when coding. +# +# Future: +# +# Warn about jump targets that are poorly aligned (less than 2 instructions +# before a cache line boundary). use strict; sub disassemble { my ($file) = @_; my ($addr,$b1,$b2,$b3, $prefix,$opcode,$modrm); + my $align; open (IN, "objdump -Srfh $file |") || die "Cannot open pipe from objdump\n"; @@ -55,8 +68,10 @@ sub disassemble { print; if (/^[ \t]*[0-9]+[ \t]+\.text[ \t]/ && /2\*\*([0-9]+)$/) { - if ($1 < 5) { - print "ZZ need at least 2**5 for predictable cache line crossing\n"; + $align = 1 << $1; + if ($align < 8) { + print "ZZ cross.pl cannot handle alignment < 2**3\n"; + $align = 8 } } @@ -88,21 +103,27 @@ sub disassemble { if ($prefix =~ /0f/ && $opcode !~ /^8/ # jcond disp32 && $modrm =~ /^[0-3][4c]/) { - print "ZZ ($file) >3 bytes to determine instruction length\n"; + print "ZZ ($file) >3 bytes to determine instruction length [K6]\n"; } # with just an opcode, starting 1f mod 20h - if ($addr =~ /[13579bdf]f$/ + if (($align==32 && $addr =~ /[13579bdf]f$/ + || $align==16 && $addr =~ /f$/ + || $align==8 && $addr =~ /[7f]$/) && $prefix !~ /0f/ && $opcode !~ /1[012345]/ # adc && $opcode !~ /1[89abcd]/ # sbb + && $opcode !~ /^4/ # inc/dec reg + && $opcode !~ /^5/ # push/pop reg && $opcode !~ /68/ # push $imm32 && $opcode !~ /^7/ # jcond disp8 && $opcode !~ /a[89]/ # test+imm && $opcode !~ /a[a-f]/ # stos/lods/scas && $opcode !~ /b8/ # movl $imm32,%eax + && $opcode !~ /d[0123]/ # rcl && $opcode !~ /e[0123]/ # loop/loopz/loopnz/jcxz - && $opcode !~ /e[b9]/ # jmp disp8/disp32 + && $opcode !~ /e8/ # call disp32 + && $opcode !~ /e[9b]/ # jmp disp32/disp8 && $opcode !~ /f[89abcd]/ # clc,stc,cli,sti,cld,std && !($opcode =~ /f[67]/ # grp 1 && $modrm =~ /^[2367abef]/) # mul, imul, div, idiv @@ -111,15 +132,26 @@ sub disassemble { } # with an 0F prefix, anything starting at 1f mod 20h - if ($addr =~ /[13579bdf][f]$/ - && $prefix =~ /0f/) { + if (($align==32 && $addr =~ /[13579bdf][f]$/ + || $align==16 && $addr =~ /f$/ + || $align==8 && $addr =~ /[7f]$/) + && $prefix =~ /0f/ + && $opcode !~ /af/ # imul + && $opcode !~ /a[45]/ # shldl + && $opcode !~ /a[cd]/ # shrdl + ) { print "ZZ ($file) prefix/opcode cross 32-byte boundary\n"; } # with an 0F prefix, anything with mod/rm starting at 1e mod 20h - if ($addr =~ /[13579bdf][e]$/ + if (($align==32 && $addr =~ /[13579bdf][e]$/ + || $align==16 && $addr =~ /[e]$/ + || $align==8 && $addr =~ /[6e]$/) && $prefix =~ /0f/ && $opcode !~ /^8/ # jcond disp32 + && $opcode !~ /af/ # imull reg,reg + && $opcode !~ /a[45]/ # shldl + && $opcode !~ /a[cd]/ # shrdl && $modrm !~ /^$/) { print "ZZ ($file) prefix/opcode/modrm cross 32-byte boundary\n"; }