MIPSCHECK(1) Last changed: 4-27-99
mipscheck, r8kpp, r5kpp, u64check - Examines binaries for instruction
sequences
mipscheck [-v] [-condition[:action...] ... ] files
r8kpp [-v] [-condition[:action...] ... ] files
r5kpp [-v] [-condition[:action...] ... ] files
u64check [-v] [-condition[:action...] ... ] files
IRIX systems
mipscheck examines binaries for instruction sequences that may have
processor specific behavior. It reports which conditions it found,
and in certain cases, will modify the sequence so that the binary
behaves consistently on all platforms. On exit, mipscheck returns an
exit status which is the number of occurrences of the specified
condition(s) found.
-v Generates verbose output, including the address of each problem
found.
mipscheck Operates on object files, archives files, executables, and
DSOs.
Specifying r8kpp, r5kpp, u64check are alternative ways of invoking
mipscheck which imply default values designed specifically for the
specified architecture.
-pref[:action...] Look for and remove prefetch instructions.
The pref and prefx prefetch instructions are part of the mips4
instruction set. They are fully implemented on the r10000 and the
r5000 but are not supported on r8000 based machines. See the r8000
errata sheet for more details.
The default actions are: -pref:check:noforce:repair
-mfhilo[:action...]
Look for instructions that reference the HI or LO registers and
are one or two instructions after a mfhi or mflo instruction.
The mips1, mips2, and mips3 instruction sets specify that there
is a two instruction hazard between a mflo instruction and a
following instruction that references the LO register. This
hazard was removed from the mips4 instruction set (that is, it
was up to the processor to supply the hardware interlock). The
r8000 and the r10000 have this hardware interlock but the r5000
does not; this requires the compiler to continue to enforce the
scheduling hazard.
It is possible that Irix 6.1 64bit binaries may have this relaxed
instruction scheduling sequence. As of Irix 6.2, all SGI compilers
generate code that does not depend upon the processor handling the
hardware interlock, but rather the compilers schedule the instructions
to avoid it. See the r5000 errata sheet for more details.
The default actions are: -mfhilo:check:noforce:norepair
-cvtl[:action...]
Look for cvt.s.l and cvt.d.l instructions. These instructions
convert 64-bit integers to single or double floating point
format.
Revision [1.1] of the r5000 can misexecute cvt.s.l and cvt.d.l
instructions when the 64-bit integer input data is in either of the
following ranges:
0x7FF0 0000 0000 0000 to 0x7FFF FFFF FFFF FFFF
0x8000 0000 0000 0000 to 0x800F FFFF FFFF FFFF
When input data is in the preceding ranges, these instructions are
supposed to trap into the kernel where they will be emulated in
software. Unfortunately, they do not trap and they generate an
incorrect result. These instructions are fairly rare and are found in
mips3 and mips4 executables only; they are never in mips1 or mips2
programs. There is a work-around for this problem, implemented
entirely within the operating system kernel, which should be invisible
to all user programs. See the r5000 errata sheet for more details.
The default actions are: -cvtl:check:noforce:norepair
-fmulmul[:action]
Look for a floating point multiply immediately followed by a
floating point or integer multiply.
Very early versions of the r4300 (used only in the Nintendo
Ultra64 Game Player) could mis-execute the second multiply
instruction when the first multiply encountered a NaN or an
Infinity operand. See the r4300 errata sheet for more details.
The default actions are: -fmulmul:check:noforce:norepair
-idivmul[:action]
Look for integer divides and multiplies in branch-delay slots or
preceding a branch-target.
On the r10000, under extremely rare conditions, if an integer
multiply or integer divide is interrupted, the EPC (Exception
Program Counter) will point to the instruction following the
multiply/divide and the HI register will not be updated. There
is a work-around for this problem implemented entirely within the
operating system kernel, which should be invisible to all user
programs. See the r10000 errata sheet for more details.
The default actions are: -idivmul:check:noforce:norepair
Each condition has an optional colon (:) separated list of actions
associated with it. action can be any of the following:
check
Check for the specified condition (default action).
nocheck
Do not check for the specified condition.
force
Examine the instruction sections for the condition even if
mipscheck has other means of determining that the condition does
not exist. For example, an instruction sequence involving mips4
instructions could not exist in a mips3 executable. force
instructs mipscheck to search for the condition anyway.
noforce
Do not examine the instruction sequences unless necessary
(default action).
repair
Modify the instruction sequence so that it does not hit the
specified condition. This action is valid only with the -pref
condition.
norepair
Do not modify the code (default action).
If a condition is specified with no actions, mipscheck assumes the
default actions. For example, specifying -mfhilo is equivalent to
-mfhilo:check:noforce:norepair.
mipscheck terminates with an exit code set to the number of conditions
found. For example, if it found 10 -mfhilo problems, it would
terminate with an exit code of 10. In the case of r8kpp, this may be
a little misleading because the command has not only found each of the
problem conditions but it has repaired them as well. If you were to
run r8kpp on the binary a second time, no conditions would be reported
because the binary has been patched.
The following example shows how to build a mips4 binary and verify
that there are no prefetch instructions:
% cc -mips4 -n32 -o bean bean.c
% mipscheck -pref:check:norepair bean
% echo $status
The following example shows how to compile a file to be linked into an
Ultra64 Game program and verify that there are no dangerous multiply
pairs:
% cc -mips2 -32 -c bean.c
% mipscheck -fmulmul:check:norepair bean.o
% echo $status
This example examines the location of the cvtl problem(s) in the
/bin/sh program.
% mipscheck -v -cvtl:check:norepair:force /bin/sh
mipscheck [1.6]
/bin/sh: r5000 cvt.d.l cvt.s.l problem at 0x100138d0
cvtl found : 1
By invoking r8kpp, you are specifying that all r8000 specific
conditions should be checked for and repaired. This is equivalent to
specifying the following:
% mipscheck -pref:check:noforce:repair myprog
By invoking r5kpp, you are specifying that all r5000 specific
conditions should be checked for and reported. This is equivalent to
specifying the following:
% mipscheck -mfhilo:check:noforce:norepair \
-cvtl:check:noforce:repair myprog
By invoking u64check, you are specifying that all r4300 specific
conditions should be checked for and reported. This is equivalent to
specifying the following:
% mipscheck -fmulmul:check:noforce:norepair myprog
/usr/sbin/mipscheck mipscheck executable
/usr/sbin/r8kpp Symbolic link to /usr/sbin/mipscheck
/usr/sbin/r5kpp Symbolic link to /usr/sbin/mipscheck
/usr/sbin/u64check Symbolic link to /usr/sbin/mipscheck
The -fmulmul option may give a false positive in the case of a
floating point multiply instruction in a branch delay slot. The
mipscheck program does not look at the target of the branch and so
must assume that the branch target may be another multiply
instruction.
The -pref:force option will almost always give false positives because
it will report on every prefetch instruction found instead of just the
combinations of prefetches that can lead to mis-execution on an r8000.
Because mipscheck cannot examine input data for data-dependent
problems, it must report on instruction sequences that may fail under
the proper conditions. For example, mipscheck will report all cvt.d.l
instructions, not just the ones that may get bad input data.
Similarly, because mipscheck cannot know about tlb-miss and cache-miss
behavior, it must report on instruction sequences that might trigger
the r4000 branch-at-end-of-page problem even though the actual
conditions required to hit it are quite rare.
"Do I need to worry about this stuff?" is a valid question. In
general, the answer is no. But SGI developers and some customers who
have access to early revisions of systems may need this tool to help
identify and/or repair problems. The following are some relevant
cases:
1. Irix 6.1 binaries compiled with -n32 -mips4 that are moved to an
r5000 system should be checked with r5kpp. There should be no such
binaries in the field; but because experimental systems and
experimental compilers were available, it is possible that such
binaries exist.
2. The Irix 6.2 (and later) operating systems for r8000s will
automatically patch any running program to remove the prefetch
instructions. This will not affect the performance on an r8000 but
it will avoid the r8000 prefetch problem. In rare cases, the
kernel will not be able to avoid the problem and will request that
the user run the binary through r8kpp to execute the repair
permanently.
3. Ultra64 game developers should always run u64check to locate cases
where their assembly code violates the game player's hardware
restrictions.
4. Irix 6.2 binaries compiled using -mips3 or -mips4, using 64-bit
integers, and running on Revision [1.1] of the r5000 may, in rare
cases, encounter the cvtl problem. The kernel handles this case
but incurs a small overhead for checking on this condition. The
overhead should be negligible. If r5kpp finds no problem in an
executable, it will mark the executable as "clean", which helps the
kernel eliminate the overhead.
5. On all MIPS processors, when an instruction is interrupted, the EPC
(Exception Program Counter) points to the interrupted instruction.
The exception to that rule is when the interrupted instruction is
in a branch-delay slot, in which case the EPC points to the
previous branch instruction. On an r10000, if the kernel ever
detects a "bad" EPC for an interrupted integer multiply or integer
divide, the kernel will silently (and at no measurable performance
cost) repair the EPC and the damaged HI register. If the
interrupted instruction is in a branch-delay slot of an
unconditional branch, the kernel may not be able to repair the EPC
and will abort the program, reporting the result in the SYSLOG.
To make it easier for the kernel to detect and repair the EPC in these
cases, the compiler will not put an integer multiply or divide in a
branch delay slot of an unconditional branch, nor will it make the
following instruction a branch target. Versions 6.2 through 7.2 of
the SGI compilers occasionally break these rules when generating code
-mips4. This is not a problem but it makes it more difficult for the
kernel to detect and repair the problem. Compiler versions 7.2.1 and
later always obey these two rules.
elfdump(1)
http://www.mips.com for information on chips.
This man page is available only online.
[ Back ]
|