1
0
mirror of https://github.com/c64scene-ar/llvm-6502.git synced 2025-03-28 21:38:44 +00:00

Write CompilationCallback as an explicit assembly stub to avoid getting GCC's

prolog.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18220 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2004-11-24 21:01:46 +00:00
parent 892afa9556
commit 73278080c8

@ -47,29 +47,44 @@ static void EmitBranchToAt(void *At, void *To, bool isCall) {
AtI[3] = BUILD_BCTR(isCall); // bctr/bctrl AtI[3] = BUILD_BCTR(isCall); // bctr/bctrl
} }
static void CompilationCallback() { extern "C" void PPC32CompilationCallback();
// Save R3-R31, since we want to restore arguments and nonvolatile regs used
// by the compiler. We also save and restore the FP regs, although this is
// probably just paranoia (gcc is unlikely to emit code that uses them for
// for this function.
#if defined(__POWERPC__) || defined (__ppc__) || defined(_POWER) #if defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)
unsigned IntRegs[29]; // CompilationCallback stub - We can't use a C function with inline assembly in
double FPRegs[13]; // it, because we the prolog/epilog inserted by GCC won't work for us. Instead,
__asm__ __volatile__ ( // write our own wrapper, which does things our way, so we have complete control
"stmw r3, 0(%0)\n" // over register saving and restoring.
"stfd f1, 0(%1)\n" "stfd f2, 8(%1)\n" "stfd f3, 16(%1)\n" asm(
"stfd f4, 24(%1)\n" "stfd f5, 32(%1)\n" "stfd f6, 40(%1)\n" ".text\n"
"stfd f7, 48(%1)\n" "stfd f8, 56(%1)\n" "stfd f9, 64(%1)\n" ".align 2\n"
"stfd f10, 72(%1)\n" "stfd f11, 80(%1)\n" "stfd f12, 88(%1)\n" ".globl _PPC32CompilationCallback\n"
"stfd f13, 96(%1)\n" :: "b" (IntRegs), "b" (FPRegs) ); "_PPC32CompilationCallback:\n"
/// FIXME: Need to safe and restore the rest of the FP regs! // Make space for 29 ints r[3-31] and 14 doubles f[0-13]
"stwu r1, -272(r1)\n"
"mflr r11\n"
"stw r11, 280(r1)\n" // Set up a proper stack frame
"stmw r3, 156(r1)\n" // Save all of the integer registers
// Save all call-clobbered FP regs.
"stfd f1, 44(r1)\n" "stfd f2, 52(r1)\n" "stfd f3, 60(r1)\n"
"stfd f4, 68(r1)\n" "stfd f5, 76(r1)\n" "stfd f6, 84(r1)\n"
"stfd f7, 92(r1)\n" "stfd f8, 100(r1)\n" "stfd f9, 108(r1)\n"
"stfd f10, 116(r1)\n" "stfd f11, 124(r1)\n" "stfd f12, 132(r1)\n"
"stfd f13, 140(r1)\n"
// Now that everything is saved, go to the C compilation callback function,
// passing the address of the intregs and fpregs.
"addi r3, r1, 156\n" // &IntRegs[0]
"addi r4, r1, 44\n" // &FPRegs[0]
"bl _PPC32CompilationCallbackC\n"
);
#endif #endif
unsigned *CameFromStub = (unsigned*)__builtin_return_address(0); extern "C" void PPC32CompilationCallbackC(unsigned *IntRegs, double *FPRegs) {
unsigned *CameFromOrig = (unsigned*)__builtin_return_address(1); unsigned *CameFromStub = (unsigned*)__builtin_return_address(0+1);
unsigned *CameFromOrig = (unsigned*)__builtin_return_address(1+1);
unsigned *CCStackPtr = (unsigned*)__builtin_frame_address(0); unsigned *CCStackPtr = (unsigned*)__builtin_frame_address(0);
//unsigned *StubStackPtr = (unsigned*)__builtin_frame_address(1); //unsigned *StubStackPtr = (unsigned*)__builtin_frame_address(1);
unsigned *OrigStackPtr = (unsigned*)__builtin_frame_address(2); unsigned *OrigStackPtr = (unsigned*)__builtin_frame_address(2+1);
// Adjust pointer to the branch, not the return address. // Adjust pointer to the branch, not the return address.
--CameFromStub; --CameFromStub;
@ -135,13 +150,13 @@ static void CompilationCallback() {
TargetJITInfo::LazyResolverFn TargetJITInfo::LazyResolverFn
PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) { PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) {
JITCompilerFunction = Fn; JITCompilerFunction = Fn;
return CompilationCallback; return PPC32CompilationCallback;
} }
void *PPC32JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) { void *PPC32JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
// If this is just a call to an external function, emit a branch instead of a // If this is just a call to an external function, emit a branch instead of a
// call. The code is the same except for one bit of the last instruction. // call. The code is the same except for one bit of the last instruction.
if (Fn != CompilationCallback) { if (Fn != PPC32CompilationCallback) {
MCE.startFunctionStub(4*4); MCE.startFunctionStub(4*4);
void *Addr = (void*)(intptr_t)MCE.getCurrentPCValue(); void *Addr = (void*)(intptr_t)MCE.getCurrentPCValue();
MCE.emitWord(0); MCE.emitWord(0);