190075Sobrien/* Special support for trampolines 290075Sobrien * 390075Sobrien * Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc. 490075Sobrien * Written By Michael Meissner 590075Sobrien * 690075Sobrien * This file is free software; you can redistribute it and/or modify it 790075Sobrien * under the terms of the GNU General Public License as published by the 890075Sobrien * Free Software Foundation; either version 2, or (at your option) any 990075Sobrien * later version. 1090075Sobrien * 1190075Sobrien * In addition to the permissions in the GNU General Public License, the 1290075Sobrien * Free Software Foundation gives you unlimited permission to link the 1390075Sobrien * compiled version of this file with other programs, and to distribute 1490075Sobrien * those programs without any restriction coming from the use of this 1590075Sobrien * file. (The General Public License restrictions do apply in other 1690075Sobrien * respects; for example, they cover modification of the file, and 1790075Sobrien * distribution when not linked into another program.) 1890075Sobrien * 1990075Sobrien * This file is distributed in the hope that it will be useful, but 2090075Sobrien * WITHOUT ANY WARRANTY; without even the implied warranty of 2190075Sobrien * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 2290075Sobrien * General Public License for more details. 2390075Sobrien * 2490075Sobrien * You should have received a copy of the GNU General Public License 2590075Sobrien * along with this program; see the file COPYING. If not, write to 26169689Skan * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 27169689Skan * Boston, MA 02110-1301, USA. 2890075Sobrien * 2990075Sobrien * As a special exception, if you link this library with files 3090075Sobrien * compiled with GCC to produce an executable, this does not cause 3190075Sobrien * the resulting executable to be covered by the GNU General Public License. 3290075Sobrien * This exception does not however invalidate any other reasons why 3390075Sobrien * the executable file might be covered by the GNU General Public License. 3490075Sobrien */ 3590075Sobrien 3690075Sobrien/* Set up trampolines. */ 3790075Sobrien 3890075Sobrien .file "tramp.asm" 3990075Sobrien .section ".text" 4090075Sobrien #include "ppc-asm.h" 4190075Sobrien 42132718Skan#ifndef __powerpc64__ 4390075Sobrien .type trampoline_initial,@object 4490075Sobrien .align 2 4590075Sobrientrampoline_initial: 4690075Sobrien mflr r0 47169689Skan bcl 20,31,1f 4890075Sobrien.Lfunc = .-trampoline_initial 4990075Sobrien .long 0 /* will be replaced with function address */ 5090075Sobrien.Lchain = .-trampoline_initial 5190075Sobrien .long 0 /* will be replaced with static chain */ 5290075Sobrien1: mflr r11 5390075Sobrien mtlr r0 5490075Sobrien lwz r0,0(r11) /* function address */ 5590075Sobrien lwz r11,4(r11) /* static chain */ 5690075Sobrien mtctr r0 5790075Sobrien bctr 5890075Sobrien 5990075Sobrientrampoline_size = .-trampoline_initial 6090075Sobrien .size trampoline_initial,trampoline_size 6190075Sobrien 6290075Sobrien 6390075Sobrien/* R3 = stack address to store trampoline */ 6490075Sobrien/* R4 = length of trampoline area */ 6590075Sobrien/* R5 = function address */ 6690075Sobrien/* R6 = static chain */ 6790075Sobrien 6890075SobrienFUNC_START(__trampoline_setup) 6990075Sobrien mflr r0 /* save return address */ 70169689Skan bcl 20,31,.LCF0 /* load up __trampoline_initial into r7 */ 7190075Sobrien.LCF0: 7290075Sobrien mflr r11 7390075Sobrien addi r7,r11,trampoline_initial-4-.LCF0 /* trampoline address -4 */ 7490075Sobrien 7590075Sobrien li r8,trampoline_size /* verify that the trampoline is big enough */ 7690075Sobrien cmpw cr1,r8,r4 7790075Sobrien srwi r4,r4,2 /* # words to move */ 7890075Sobrien addi r9,r3,-4 /* adjust pointer for lwzu */ 7990075Sobrien mtctr r4 8090075Sobrien blt cr1,.Labort 8190075Sobrien 8290075Sobrien mtlr r0 8390075Sobrien 8490075Sobrien /* Copy the instructions to the stack */ 8590075Sobrien.Lmove: 8690075Sobrien lwzu r10,4(r7) 8790075Sobrien stwu r10,4(r9) 8890075Sobrien bdnz .Lmove 8990075Sobrien 9090075Sobrien /* Store correct function and static chain */ 9190075Sobrien stw r5,.Lfunc(r3) 9290075Sobrien stw r6,.Lchain(r3) 9390075Sobrien 9490075Sobrien /* Now flush both caches */ 9590075Sobrien mtctr r4 9690075Sobrien.Lcache: 9790075Sobrien icbi 0,r3 9890075Sobrien dcbf 0,r3 9990075Sobrien addi r3,r3,4 10090075Sobrien bdnz .Lcache 10190075Sobrien 10290075Sobrien /* Finally synchronize things & return */ 10390075Sobrien sync 10490075Sobrien isync 10590075Sobrien blr 10690075Sobrien 10790075Sobrien.Labort: 108169689Skan#if defined SHARED && defined HAVE_AS_REL16 109169689Skan bcl 20,31,1f 110169689Skan1: mflr r30 111169689Skan addis r30,r30,_GLOBAL_OFFSET_TABLE_-1b@ha 112169689Skan addi r30,r30,_GLOBAL_OFFSET_TABLE_-1b@l 113169689Skan#endif 11490075Sobrien bl JUMP_TARGET(abort) 11590075SobrienFUNC_END(__trampoline_setup) 11690075Sobrien 117132718Skan#endif 118217396Skib 119217396Skib .section .note.GNU-stack,"",%progbits 120