1*c87b03e5Sespie/*  Special support for trampolines
2*c87b03e5Sespie *
3*c87b03e5Sespie *   Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
4*c87b03e5Sespie *   Written By Michael Meissner
5*c87b03e5Sespie *
6*c87b03e5Sespie * This file is free software; you can redistribute it and/or modify it
7*c87b03e5Sespie * under the terms of the GNU General Public License as published by the
8*c87b03e5Sespie * Free Software Foundation; either version 2, or (at your option) any
9*c87b03e5Sespie * later version.
10*c87b03e5Sespie *
11*c87b03e5Sespie * In addition to the permissions in the GNU General Public License, the
12*c87b03e5Sespie * Free Software Foundation gives you unlimited permission to link the
13*c87b03e5Sespie * compiled version of this file with other programs, and to distribute
14*c87b03e5Sespie * those programs without any restriction coming from the use of this
15*c87b03e5Sespie * file.  (The General Public License restrictions do apply in other
16*c87b03e5Sespie * respects; for example, they cover modification of the file, and
17*c87b03e5Sespie * distribution when not linked into another program.)
18*c87b03e5Sespie *
19*c87b03e5Sespie * This file is distributed in the hope that it will be useful, but
20*c87b03e5Sespie * WITHOUT ANY WARRANTY; without even the implied warranty of
21*c87b03e5Sespie * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22*c87b03e5Sespie * General Public License for more details.
23*c87b03e5Sespie *
24*c87b03e5Sespie * You should have received a copy of the GNU General Public License
25*c87b03e5Sespie * along with this program; see the file COPYING.  If not, write to
26*c87b03e5Sespie * the Free Software Foundation, 59 Temple Place - Suite 330,
27*c87b03e5Sespie * Boston, MA 02111-1307, USA.
28*c87b03e5Sespie *
29*c87b03e5Sespie *  As a special exception, if you link this library with files
30*c87b03e5Sespie *  compiled with GCC to produce an executable, this does not cause the
31*c87b03e5Sespie *  resulting executable to be covered by the GNU General Public License.
32*c87b03e5Sespie *  This exception does not however invalidate any other reasons why the
33*c87b03e5Sespie *  executable file might be covered by the GNU General Public License.
34*c87b03e5Sespie */
35*c87b03e5Sespie
36*c87b03e5Sespie/* Set up trampolines.  */
37*c87b03e5Sespie
38*c87b03e5Sespie.text
39*c87b03e5Sespie	.align	2
40*c87b03e5SespieLtrampoline_initial:
41*c87b03e5Sespie	mflr	r0
42*c87b03e5Sespie	bl	1f
43*c87b03e5SespieLfunc = .-Ltrampoline_initial
44*c87b03e5Sespie	.long	0		/* will be replaced with function address */
45*c87b03e5SespieLchain = .-Ltrampoline_initial
46*c87b03e5Sespie	.long	0		/* will be replaced with static chain */
47*c87b03e5Sespie1:	mflr	r11
48*c87b03e5Sespie	lwz	r12,0(r11)	/* function address */
49*c87b03e5Sespie	mtlr	r0
50*c87b03e5Sespie	mtctr	r12
51*c87b03e5Sespie	lwz	r11,4(r11)	/* static chain */
52*c87b03e5Sespie	bctr
53*c87b03e5Sespie
54*c87b03e5Sespietrampoline_size = .-Ltrampoline_initial
55*c87b03e5Sespie
56*c87b03e5Sespie/* R3 = stack address to store trampoline */
57*c87b03e5Sespie/* R4 = length of trampoline area */
58*c87b03e5Sespie/* R5 = function address */
59*c87b03e5Sespie/* R6 = static chain */
60*c87b03e5Sespie
61*c87b03e5Sespie	.globl ___trampoline_setup
62*c87b03e5Sespie___trampoline_setup:
63*c87b03e5Sespie	mflr	r0		/* save return address */
64*c87b03e5Sespie        bcl 20,31,LCF0		/* load up __trampoline_initial into r7 */
65*c87b03e5SespieLCF0:
66*c87b03e5Sespie        mflr	r11
67*c87b03e5Sespie        addis	r7,r11,ha16(LTRAMP-LCF0)
68*c87b03e5Sespie	lwz	r7,lo16(LTRAMP-LCF0)(r7)
69*c87b03e5Sespie	subi	r7,r7,4
70*c87b03e5Sespie	li	r8,trampoline_size	/* verify trampoline big enough */
71*c87b03e5Sespie	cmpw	cr1,r8,r4
72*c87b03e5Sespie	srwi	r4,r4,2		/* # words to move */
73*c87b03e5Sespie	addi	r9,r3,-4	/* adjust pointer for lwzu */
74*c87b03e5Sespie	mtctr	r4
75*c87b03e5Sespie	blt	cr1,Labort
76*c87b03e5Sespie
77*c87b03e5Sespie	mtlr	r0
78*c87b03e5Sespie
79*c87b03e5Sespie	/* Copy the instructions to the stack */
80*c87b03e5SespieLmove:
81*c87b03e5Sespie	lwzu	r10,4(r7)
82*c87b03e5Sespie	stwu	r10,4(r9)
83*c87b03e5Sespie	bdnz	Lmove
84*c87b03e5Sespie
85*c87b03e5Sespie	/* Store correct function and static chain */
86*c87b03e5Sespie	stw	r5,Lfunc(r3)
87*c87b03e5Sespie	stw	r6,Lchain(r3)
88*c87b03e5Sespie
89*c87b03e5Sespie	/* Now flush both caches */
90*c87b03e5Sespie	mtctr	r4
91*c87b03e5SespieLcache:
92*c87b03e5Sespie	icbi	0,r3
93*c87b03e5Sespie	dcbf	0,r3
94*c87b03e5Sespie	addi	r3,r3,4
95*c87b03e5Sespie	bdnz	Lcache
96*c87b03e5Sespie
97*c87b03e5Sespie	/* Finally synchronize things & return */
98*c87b03e5Sespie	sync
99*c87b03e5Sespie	isync
100*c87b03e5Sespie	blr
101*c87b03e5Sespie
102*c87b03e5SespieLabort:
103*c87b03e5Sespie#ifdef __DYNAMIC__
104*c87b03e5Sespie	bl	L_abort$stub
105*c87b03e5Sespie.data
106*c87b03e5Sespie.picsymbol_stub
107*c87b03e5SespieL_abort$stub:
108*c87b03e5Sespie        .indirect_symbol _abort
109*c87b03e5Sespie        mflr r0
110*c87b03e5Sespie        bcl 20,31,L0$_abort
111*c87b03e5SespieL0$_abort:
112*c87b03e5Sespie        mflr r11
113*c87b03e5Sespie        addis r11,r11,ha16(L_abort$lazy_ptr-L0$_abort)
114*c87b03e5Sespie        mtlr r0
115*c87b03e5Sespie        lwz r12,lo16(L_abort$lazy_ptr-L0$_abort)(r11)
116*c87b03e5Sespie        mtctr r12
117*c87b03e5Sespie        addi r11,r11,lo16(L_abort$lazy_ptr-L0$_abort)
118*c87b03e5Sespie        bctr
119*c87b03e5Sespie.data
120*c87b03e5Sespie.lazy_symbol_pointer
121*c87b03e5SespieL_abort$lazy_ptr:
122*c87b03e5Sespie        .indirect_symbol _abort
123*c87b03e5Sespie        .long dyld_stub_binding_helper
124*c87b03e5Sespie#else
125*c87b03e5Sespie	bl	_abort
126*c87b03e5Sespie#endif
127*c87b03e5Sespie.data
128*c87b03e5Sespie	.align 2
129*c87b03e5SespieLTRAMP:
130*c87b03e5Sespie	.long Ltrampoline_initial
131*c87b03e5Sespie
132