trampoline_setup.c revision 215125
1202188Sed/* ===----- trampoline_setup.c - Implement __trampoline_setup -------------=== 2202188Sed * 3202188Sed * The LLVM Compiler Infrastructure 4202188Sed * 5202188Sed * This file is distributed under the University of Illinois Open Source 6202188Sed * License. See LICENSE.TXT for details. 7202188Sed * 8202188Sed * ===----------------------------------------------------------------------=== 9202188Sed */ 10202188Sed 11202188Sed#include <stdint.h> 12202188Sed#include <stdlib.h> 13202188Sed 14202188Sed#include "int_lib.h" 15202188Sed 16202188Sedextern void __clear_cache(void* start, void* end); 17202188Sed 18202188Sed/* 19202188Sed * The ppc compiler generates calls to __trampoline_setup() when creating 20202188Sed * trampoline functions on the stack for use with nested functions. 21202188Sed * This function creates a custom 40-byte trampoline function on the stack 22202188Sed * which loads r11 with a pointer to the outer function's locals 23202188Sed * and then jumps to the target nested function. 24202188Sed */ 25202188Sed 26202188Sed#if __ppc__ && !defined(__powerpc64__) 27202188Sedvoid __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated, 28202188Sed const void* realFunc, void* localsPtr) 29202188Sed{ 30202188Sed /* should never happen, but if compiler did not allocate */ 31202188Sed /* enough space on stack for the trampoline, abort */ 32202188Sed if ( trampSizeAllocated < 40 ) 33202188Sed compilerrt_abort(); 34215310Sed 35202188Sed /* create trampoline */ 36202188Sed trampOnStack[0] = 0x7c0802a6; /* mflr r0 */ 37202188Sed trampOnStack[1] = 0x4800000d; /* bl Lbase */ 38202188Sed trampOnStack[2] = (uint32_t)realFunc; 39202188Sed trampOnStack[3] = (uint32_t)localsPtr; 40202188Sed trampOnStack[4] = 0x7d6802a6; /* Lbase: mflr r11 */ 41202188Sed trampOnStack[5] = 0x818b0000; /* lwz r12,0(r11) */ 42202188Sed trampOnStack[6] = 0x7c0803a6; /* mtlr r0 */ 43202188Sed trampOnStack[7] = 0x7d8903a6; /* mtctr r12 */ 44202188Sed trampOnStack[8] = 0x816b0004; /* lwz r11,4(r11) */ 45202188Sed trampOnStack[9] = 0x4e800420; /* bctr */ 46219045Sed 47218846Sed /* clear instruction cache */ 48202188Sed __clear_cache(trampOnStack, &trampOnStack[10]); 49202188Sed} 50202188Sed#endif /* __ppc__ */ 51202188Sed