PPC calling convention -- how to provide an environment pointer?

This is not, strictly speaking, an LLVM issue, but it is an
implementation matter that a compiler using LLVM needs to handle. I've
got resolutions for other platforms, but I'm not seeing how to get this
done for PowerPC, and I'ld appreciate suggestions or pointers.

For BitC procedures that require an environment pointer, our general
approach has been to construct a heap-allocated assembly code fragment.
This fragment operates as follows:

   loads the environment pointer into a register that is
     call clobbered but not perturbed by the preamble.
   branches to a stub procedure

The stub procedure then:

   copies the env ptr from the transient register into a local, and
   calls an implementation procedure that expects the environment
     as an explicit argument, passing the other arguments along
     unmodified.
   [This stub exists entirely because of register rotation in the
    calling convention.]

On every architecture that we have considered prior to PowerPC, there
have been at least two registers that we could safely abuse in the
heap-allocated fragment. Typically these are registers that are held
back for use by the dynamic linking logic for the target architecture.

At the moment, we're looking at the MachO/Darwin calling convention and
we're pretty stumped about which, if any, of the registers can be
borrowed safely in this way.

Can anyone suggest an appropriate way to do this, or point us at some
existing implementation of something similar that we can study?

Thanks.

shap

The two that come to my mind are R2 and the count register (CTR) but
both have their drawbacks. The PPC64 ABI uses R2 as the table of
contents pointer but could reasonably be hijacked for an environment
pointer if you don't use a TOC (which LLVM doesn't). However the use and
sanctity of R2 varies across the different PPC ABIs so it might not be a
good choice.

If I recall correctly CTR has no ABI-specific rules for preservation
across calls so if you don't need it to persist you could get away with
using it provided you don't need it to do an indirect branch to your
stub.