Subject: some success with binutils 2.9.1 as and kernels...
To: None <port-pmax@netbsd.org>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: port-mips
Date: 03/07/1999 02:08:17
I took the biutils 2.9.1 tc-mips.c and replaced the code which handle
the assembler macro-instruction "divu" (with integer register operands)
with the old 2.8.1 code (ie, for

test_frag:
        divu    $4,$4,$2
        mfhi    $6

it emits
	divu    $zero,$a0,$v0
	bnez    $v0,10 <test_frag+10>
	nop
	break   0x7
	mflo    $a0
	mfhi    $a2

rather than the virgin 2.9.1
	bnez    $v0,c <test_frag+c>
	divu    $zero,$a0,$v0
	break   0x7
	mflo    $a0
	mfhi    $a2


A GENERIC kernel built linked with the modified binutils-2.9.1 seems
to work; i'm trying a `make build' on it now.

But i really dont understand why the sequence above fails when used in
the kernel. i dont see how there are any more hazards or interlock
problems with one vis-a-vis the other.  The bug also seems to be non-
deterministic: it odesn't happen in the same place.

It makes me wonder if it's tied up with the divu being in a delay
slot. (divu takes some 75 cycles on an r4000 or r4400, so its Aa good
candidate for a exception).  Maybe there's a subtle bug in how we
handle exceptions in branch-delay slots?