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

Message: 5
Date: Mon, 26 Jan 2009 21:47:12 -0500
From: "Jonathan S. Shapiro" <shap@eros-os.com>
Subject: [LLVMdev] PPC calling convention -- how to provide an
  environment pointer?
To: LLVM Developers Mailing List <llvmdev@cs.uiuc.edu>
Message-ID: <1233024432.24380.11.camel@vmx>
Content-Type: text/plain

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

I assume you're talking about the 32-bit PowerPC.

AFAIK, the OS X dynamic linker does not "own" any registers. Here are some links to the Darwin ABI. Let me know if these links don't work for you:

  http://developer.apple.com/documentation/developertools/Conceptual/LowLevelABI/100-32-bit_PowerPC_Function_Calling_Conventions/32bitPowerPC.html

  http://developer.apple.com/documentation/developertools/Conceptual/LowLevelABI/Mac_OS_X_ABI_Function_Call_Guide.pdf

You may be able to use R11, R12, or R0. I assume you're aware that R0 reads as zero in some instruction fields; AFAIK, Darwin only uses R0 as a zero.

Good Luck,

stuart

I assume you're talking about the 32-bit PowerPC.

Also 64-bit, but the two register usage conventions are very close.

Someone previously pointed out that R0 is usable as a scratch register,
and the CTR can be used. CTR *must* be used for the branch destination
out of the ASM trampoline. R0 ends up getting used a lot for constant
loads; we can (and in fact must) use it as a scratch register, but we
cannot rely on it surviving past the prologue of the target function.

AFAIK, the OS X dynamic linker does not "own" any registers. Here are
some links to the Darwin ABI...

In SVR4 ABI, R11 and R12 can be used. In Darwin, these are reserved for
uses associated with dynamic code generation and/or indirect call using
dynamic code generation, which is conceptually related.

The part that is not clear to me is whether a call made by a C function
in Darwin is required to avoid R11 and R12 in order to allow for the
possibility that dynamic code generation may happen. As long as this is
required, we can safely use R11 or R12 for our purposes. That would be
great.

I should perhaps explain that the use-case which is driving the asm
design is a call from C code into a BitC procedure that requires a
closure record pointer. The problem is:

  1. The C code is oblivious about the need for this "extra" argument,
     and so cannot be expected to plan for it in register allocation.

  2. We're trying to do a "generic" implementation at this point for
     reasons of simplicity, but even if we were willing to do an
     implementation that uses knowledge of the full calling convention,
     there are still cases in which none of the "official" argument
     registers is unused.

  3. The design of most calling conventions doesn't consider the
     requirements of modern language call compatibility, and
     therefore doesn't reserve any register for this purpose.

So it sounds like we can use R11 or R12 provided none of the function
prologues also expect to use these. On SVR4 ABI this is true. Is it also
true for Darwin?

If not, is there some other technique that we should consider? The
obvious alternative would spill GPR3 into the parameter region, use
that, and then reload after saving the ENV ptr, but I'm not clear
whether the caller is obligated to have a parameter area in the case
where *none* of its callees take any arguments.

So: are R11 and R12 reserved enough on Darwin to be safe for our
purposes?

Thanks!

shap

You cannot use R11 or R12 under Darwin, except
a) for calls to functions in the same object file (or calls to functions in other object files of which you are certain that they will be linked together with the current object file); and
b) if you are certain that the function will be within range of all "bl" instructions that refer to it at link time

The reason is indeed that otherwise a stub is required. Such stubs are normally generated for each and every call by the compiler, but optimised away by the linker (also by the standard Mac OS X linker) when the target of a "bl" is known at static link time and within range of the "bl" instruction. Apple's gcc used R11 to pass the caller's stack frame to nested functions.

So in general, you cannot use them. What you can use on Darwin however, is R2 (unlike on SVR4, R2 is not reserved on Darwin; and it's also not used by any call stubs).

Here are de ABI docs: http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/100-32-bit_PowerPC_Function_Calling_Conventions/32bitPowerPC.html

Jonas