2013-12-29 Janus Weil <janus@gcc.gnu.org>
[official-gcc.git] / libgcc / config / rs6000 / darwin-tramp.S
blob8b2c238a3193b3831ec041133b0dea61814907ed
1 /*  Special support for trampolines
2  *
3  *   Copyright (C) 1996-2013 Free Software Foundation, Inc.
4  *   Written By Michael Meissner
5  * 
6  * This file is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 3, or (at your option) any
9  * later version.
10  * 
11  * This file is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  * 
16  * Under Section 7 of GPL version 3, you are granted additional
17  * permissions described in the GCC Runtime Library Exception, version
18  * 3.1, as published by the Free Software Foundation.
19  *
20  * You should have received a copy of the GNU General Public License and
21  * a copy of the GCC Runtime Library Exception along with this program;
22  * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23  * <http://www.gnu.org/licenses/>.
24  */ 
26 #include "darwin-asm.h"
28 /* Set up trampolines.  */
30 .text
31         .align  LOG2_GPR_BYTES
32 Ltrampoline_initial:
33         mflr    r0
34         bl      1f
35 Lfunc = .-Ltrampoline_initial
36         .g_long 0               /* will be replaced with function address */
37 Lchain = .-Ltrampoline_initial
38         .g_long 0               /* will be replaced with static chain */
39 1:      mflr    r11
40         lg      r12,0(r11)      /* function address */
41         mtlr    r0
42         mtctr   r12
43         lg      r11,GPR_BYTES(r11)      /* static chain */
44         bctr
46 trampoline_size = .-Ltrampoline_initial
48 /* R3 = stack address to store trampoline */
49 /* R4 = length of trampoline area */
50 /* R5 = function address */
51 /* R6 = static chain */
53         .globl ___trampoline_setup
54 ___trampoline_setup:
55         mflr    r0              /* save return address */
56         bcl 20,31,LCF0          /* load up __trampoline_initial into r7 */
57 LCF0:
58         mflr    r11
59         addis   r7,r11,ha16(LTRAMP-LCF0)
60         lg      r7,lo16(LTRAMP-LCF0)(r7)
61         subi    r7,r7,4
62         li      r8,trampoline_size      /* verify trampoline big enough */
63         cmpg    cr1,r8,r4
64         srwi    r4,r4,2                 /* # words to move (insns always 4-byte) */
65         addi    r9,r3,-4        /* adjust pointer for lgu */
66         mtctr   r4
67         blt     cr1,Labort
69         mtlr    r0
71         /* Copy the instructions to the stack */
72 Lmove:
73         lwzu    r10,4(r7)
74         stwu    r10,4(r9)
75         bdnz    Lmove
77         /* Store correct function and static chain */
78         stg     r5,Lfunc(r3)
79         stg     r6,Lchain(r3)
81         /* Now flush both caches */
82         mtctr   r4
83 Lcache:
84         icbi    0,r3
85         dcbf    0,r3
86         addi    r3,r3,4
87         bdnz    Lcache
89         /* Ensure cache-flushing has finished.  */
90         sync
91         isync
93         /* Make stack writeable.  */
94         b       ___enable_execute_stack
96 Labort:
97 #ifdef __DYNAMIC__
98         bl      L_abort$stub
99 .data
100 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
101         .align 2
102 L_abort$stub:
103         .indirect_symbol _abort
104         mflr r0
105         bcl 20,31,L0$_abort
106 L0$_abort:
107         mflr r11
108         addis r11,r11,ha16(L_abort$lazy_ptr-L0$_abort)
109         mtlr r0
110         lgu r12,lo16(L_abort$lazy_ptr-L0$_abort)(r11)
111         mtctr r12
112         bctr
113 .data
114 .lazy_symbol_pointer
115 L_abort$lazy_ptr:
116         .indirect_symbol _abort
117         .g_long dyld_stub_binding_helper
118 #else
119         bl      _abort
120 #endif
121 .data
122         .align LOG2_GPR_BYTES
123 LTRAMP:
124         .g_long Ltrampoline_initial