1 1.1 joerg /* ===----- trampoline_setup.c - Implement __trampoline_setup -------------=== 2 1.1 joerg * 3 1.1 joerg * The LLVM Compiler Infrastructure 4 1.1 joerg * 5 1.1 joerg * This file is dual licensed under the MIT and the University of Illinois Open 6 1.1 joerg * Source Licenses. See LICENSE.TXT for details. 7 1.1 joerg * 8 1.1 joerg * ===----------------------------------------------------------------------=== 9 1.1 joerg */ 10 1.1 joerg 11 1.1 joerg #include "int_lib.h" 12 1.1 joerg 13 1.1 joerg extern void __clear_cache(void* start, void* end); 14 1.1 joerg 15 1.1 joerg /* 16 1.1 joerg * The ppc compiler generates calls to __trampoline_setup() when creating 17 1.1 joerg * trampoline functions on the stack for use with nested functions. 18 1.1 joerg * This function creates a custom 40-byte trampoline function on the stack 19 1.1 joerg * which loads r11 with a pointer to the outer function's locals 20 1.1 joerg * and then jumps to the target nested function. 21 1.1 joerg */ 22 1.1 joerg 23 1.1 joerg #if __ppc__ && !defined(__powerpc64__) 24 1.1.1.2 joerg COMPILER_RT_ABI void 25 1.1.1.2 joerg __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated, 26 1.1.1.2 joerg const void* realFunc, void* localsPtr) 27 1.1 joerg { 28 1.1 joerg /* should never happen, but if compiler did not allocate */ 29 1.1 joerg /* enough space on stack for the trampoline, abort */ 30 1.1 joerg if ( trampSizeAllocated < 40 ) 31 1.1 joerg compilerrt_abort(); 32 1.1 joerg 33 1.1 joerg /* create trampoline */ 34 1.1 joerg trampOnStack[0] = 0x7c0802a6; /* mflr r0 */ 35 1.1 joerg trampOnStack[1] = 0x4800000d; /* bl Lbase */ 36 1.1 joerg trampOnStack[2] = (uint32_t)realFunc; 37 1.1 joerg trampOnStack[3] = (uint32_t)localsPtr; 38 1.1 joerg trampOnStack[4] = 0x7d6802a6; /* Lbase: mflr r11 */ 39 1.1 joerg trampOnStack[5] = 0x818b0000; /* lwz r12,0(r11) */ 40 1.1 joerg trampOnStack[6] = 0x7c0803a6; /* mtlr r0 */ 41 1.1 joerg trampOnStack[7] = 0x7d8903a6; /* mtctr r12 */ 42 1.1 joerg trampOnStack[8] = 0x816b0004; /* lwz r11,4(r11) */ 43 1.1 joerg trampOnStack[9] = 0x4e800420; /* bctr */ 44 1.1 joerg 45 1.1 joerg /* clear instruction cache */ 46 1.1 joerg __clear_cache(trampOnStack, &trampOnStack[10]); 47 1.1 joerg } 48 1.1 joerg #endif /* __ppc__ && !defined(__powerpc64__) */ 49