On Wed, 2 Jun 2010, Ralf Baechle wrote:
> In addition to normal subroutine calls:
> o $a3 on syscall return will indicate success or error. 0 means success,
> non-zero means an error happened in which case $v0 will contain an
> errno.h error code.
> o Many syscalls deviate from this convention. For example the sigreturn
> family of syscalls doesn't return a result or error status.
> o pipe() will return the 2nd filedescriptor of the result in $v1.
> o vfork is even more weird.
> o The ABI differences mean there are many subtle difference between the
> syscall handlers.
All of the above plus $v0 holds the syscall number upon entry -- which
you may effectively consider the "zeroth argument" to the call (the code
field of the SYSCALL instruction is not used by Linux).
Also it is mandated by the syscall restart mechanism used by signal
delivery code that it must be the instruction physically immediately
preceding the SYSCALL operation that places the syscall number in $v0.
In most cases a LI operation is used, but this is not a requirement (such
as utilised by the syscall(3) library wrapper) as long as no temporary
registers are used to obtain the value, because in the case of a restart
these will have been clobbered by the syscall being restarted (so e.g. lw
$v0, 0x100($fp) is fine, but move $v0, $a3 is not).