Issue #349 new
Valery Ushakov
created an issue

JIT does not work on Power, as seen on NetBSD/powerpc (pull request #10) and AIX/power (pull request #17).

It looks like the JIT-generated code conflicts with gcc generated code w.r.t. usage of callee-saved registers. The first hurdle is that when xec() calls comvec, the latter clobbers %r31. When comvec returns, p->R = R; assignment segfaults because the code in xec() to compute &p->R uses %r31 that has been clobbered.

I have fixed that with a wrapper that saves/restores all callee-saved registers around a call to comvec. The next hurdle after that is that R.MP seems to be clobbered when we return from the jitted code, so the next time MP is used it crashes.

ATTN: @Yaroslav Kolomiiets

Comments (5)

  1. Charles Forsyth

    the quickest way seems to be to move mp to R5, avoiding R13, and save R14-R31 in preamble, restoring on each use of xpc to return to the C environment, which you might already be doing in your wrapper.. Nothing cares all that much which registers are used, except for R0, SP, SB, since the Plan 9 environment has most registers dead on entry to a called function. R4 can be used I think instead of R31 for Rlink. When the JIT calls out to surrounding C code, in punt, it saves and restores the few values it needs (partly because it might never return if there's an exception), so that part should be ok. It's really the path through comvec that matters, so your wrapper approach was about right.

  2. Valery Ushakov reporter

    So the second bug was that macjit is never set, so SETR0() ends up doing nothing and when jitted code runs its %r0 is not zero. That was the source of garbage in f->mp.

    After I've changed SETR0 to always clear %r0, jit works!

    The only other place where macjit is checked is ICVTFW.

  3. Valery Ushakov reporter

    Right, but it's set by MacOS configs that also set dontcompile, which forces JIT to be turned off. ... which makes me wonder if "mac" in "macjit" means "MacOS" and not "macros" (as in MacRET and friends).

    I gather from the comment to Rzero that Plan9/Inferno keep %r0 as an always-zero register, kinda like sparc's %g0 but in ABI, not hardware. That makes sense. But what about its second use? What makes MacCVTFW plan9-specific?

  4. Valery Ushakov reporter

    I have committed the fix to my pull request branch. It's saves/restores all callee-saved registers and CR indiscriminately. A dozen of instructions can be shaved off if only the registers that the compiler actually uses are preserved.

  5. Log in to comment