[kaffe] mipsel JIT3
Kevin D. Kissell
kevink at mips.com
Fri Mar 5 09:29:03 PST 2004
> I must have still been confused about using CVS properly back then.
> Could you repost the patch, so that I can check it into CVS HEAD?
The system I use for kaffe development is down, and I'm up against some
other deadlines that make it far from certain that I'll get around to reconstructing
the environment and the patch any time soon. I'd strongly suggest that Casey
try the following on his sources, rather than wait for me to get around to it.
Go into kaffe/config/mips and edit jit.h. In the definition of REGISTER_SET
(which goes on for a ways) where you see the string RFD in the rows for the
FP argument passing registers f12 and f14, change that to "RFD|Reserved".
It would also be wise to change "RIL" to "RIL|Reserved" in the rows for
integer registers i4, i5, i6, and i7. This will prevent a spill bug which causes
arguments passed to JIT functions to be clobbered. Or at least it used to
in the 1.0.7+ sources.
This bug might not have been caught by the regression tests if it hadn't
been for another significant defect of the MIPS JIT. JIT3 makes
heroic efforts to track and preserve registers that contain interesting
values for as long as possible. So every time you invoke rreg_float(),
the register allocator (which was up in the architecture independent code)
assigns a new register. If that register was previously used, it will be
spilled to the stack. I guess the idea was that, if you never used up
the full compliment of registers, you'd never have to spill. Unfortunately,
it didn't take into account the fact that some register values have very
short lifetimes, and the net result is that the entire register compliment
can be forced into spills by a series of throw-away register uses.
Specifically, in the definition of push_float kaffe/config/mips/jit3-mips.def,
when NR_ARGUMENTS has been exceeded and we're passing
arguments on the stack (the "then it gets easy" case), each new
argument push invokes rreg_float(1), which allocates a FP register
for the push. It's strictly a temporary value that can never be recycled,
but if you pass 16 arguments, you'll clobber 16 distinct FPRs. I replaced
the "rreg_float(1)" instance in push_float, and the "rreg_double(1)"
with "rreg_ideal_float(1, REG_f16)" and "rreg_ideal_double(1, REG_f16)"
respectively. This forced (well, sucessfully requested) that the designated
floating temp register in the MIPS calling convention be used each time.
The behavior was still sub-optimal, but preserved a lot more "live"
registers than the way it had been when I found it.
I'm going to resurrect my kaffe development environment one of these
days and see if I can't help out more effectively on this stuff, but I can't
imagine getting to it before the end of the month.
More information about the kaffe