2005-01-28 Martin Schwidefsky <schwidefsky@de.ibm.com>
[glibc.git] / sysdeps / ia64 / dl-trampoline.S
blob12d7652e4452d686530eb932dbf50de26326a99d
1 /* PLT trampolines.  ia64 version.
2    Copyright (C) 2005 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 #include <sysdep.h>
23    This code is used in dl-runtime.c to call the `fixup' function
24    and then redirect to the address it returns. `fixup()' takes two
25    arguments, however profile_fixup() takes three.
27    The ABI specifies that we will never see more than 8 input
28    registers to a function call, thus it is safe to simply allocate
29    those, and simpler than playing stack games.  */
31 ENTRY(_dl_runtime_resolve)
32         { .mmi
33           .prologue
34           .save ar.pfs, r40
35           alloc loc0 = ar.pfs, 8, 6, 3, 0
36           adds r2 = -144, r12
37           adds r3 = -128, r12
38         }
39         { .mii
40           .fframe 160
41           adds r12 = -160, r12
42           .save rp, r41
43           mov loc1 = b0
44           .body
45           mov out2 = b0         /* needed by fixup_profile */
46           ;;
47         }
48         { .mfb
49           mov loc2 = r8         /* preserve struct value register */
50           nop.f 0
51           nop.b 0
52         }
53         { .mii
54           mov loc3 = r9         /* preserve language specific register */
55           mov loc4 = r10        /* preserve language specific register */
56           mov loc5 = r11        /* preserve language specific register */
57         }
58         { .mmi
59           stf.spill [r2] = f8, 32
60           stf.spill [r3] = f9, 32
61           mov out0 = r16
62           ;;
63         }
64         { .mmi
65           stf.spill [r2] = f10, 32
66           stf.spill [r3] = f11, 32
67           shl out1 = r15, 4
68           ;;
69         }
70         { .mmi
71           stf.spill [r2] = f12, 32
72           stf.spill [r3] = f13, 32
73           shladd out1 = r15, 3, out1
74           ;;
75         }
76         { .mmb
77           stf.spill [r2] = f14
78           stf.spill [r3] = f15
79           br.call.sptk.many b0 = fixup
80         }
81         { .mii
82           ld8 r9 = [ret0], 8
83           adds r2 = 16, r12
84           adds r3 = 32, r12
85           ;;
86         }
87         { .mmi
88           ldf.fill f8 = [r2], 32
89           ldf.fill f9 = [r3], 32
90           mov b0 = loc1
91           ;;
92         }
93         { .mmi
94           ldf.fill f10 = [r2], 32
95           ldf.fill f11 = [r3], 32
96           mov b6 = r9
97           ;;
98         }
99         { .mmi
100           ldf.fill f12 = [r2], 32
101           ldf.fill f13 = [r3], 32
102           mov ar.pfs = loc0
103           ;;
104         }
105         { .mmi
106           ldf.fill f14 = [r2], 32
107           ldf.fill f15 = [r3], 32
108           .restore sp           /* pop the unwind frame state */
109           adds r12 = 160, r12
110           ;;
111         }
112         { .mii
113           mov r9 = loc3         /* restore language specific register */
114           mov r10 = loc4        /* restore language specific register */
115           mov r11 = loc5        /* restore language specific register */
116         }
117         { .mii
118           ld8 gp = [ret0]
119           mov r8 = loc2         /* restore struct value register */
120           ;;
121         }
122         /* An alloc is needed for the break system call to work.
123            We don't care about the old value of the pfs register.  */
124         { .mmb
125           .prologue
126           .body
127           alloc r2 = ar.pfs, 0, 0, 8, 0
128           br.sptk.many b6
129           ;;
130         }
131 END (_dl_runtime_resolve)
134 ENTRY(_dl_runtime_profile)
135         { .mmi
136           .prologue
137           .save ar.pfs, r40
138           alloc loc0 = ar.pfs, 8, 6, 3, 0
139           adds r2 = -144, r12
140           adds r3 = -128, r12
141         }
142         { .mii
143           .fframe 160
144           adds r12 = -160, r12
145           .save rp, r41
146           mov loc1 = b0
147           .body
148           mov out2 = b0         /* needed by fixup_profile */
149           ;;
150         }
151         { .mfb
152           mov loc2 = r8         /* preserve struct value register */
153           nop.f 0
154           nop.b 0
155         }
156         { .mii
157           mov loc3 = r9         /* preserve language specific register */
158           mov loc4 = r10        /* preserve language specific register */
159           mov loc5 = r11        /* preserve language specific register */
160         }
161         { .mmi
162           stf.spill [r2] = f8, 32
163           stf.spill [r3] = f9, 32
164           mov out0 = r16
165           ;;
166         }
167         { .mmi
168           stf.spill [r2] = f10, 32
169           stf.spill [r3] = f11, 32
170           shl out1 = r15, 4
171           ;;
172         }
173         { .mmi
174           stf.spill [r2] = f12, 32
175           stf.spill [r3] = f13, 32
176           shladd out1 = r15, 3, out1
177           ;;
178         }
179         { .mmb
180           stf.spill [r2] = f14
181           stf.spill [r3] = f15
182           br.call.sptk.many b0 = profile_fixup
183         }
184         { .mii
185           ld8 r9 = [ret0], 8
186           adds r2 = 16, r12
187           adds r3 = 32, r12
188           ;;
189         }
190         { .mmi
191           ldf.fill f8 = [r2], 32
192           ldf.fill f9 = [r3], 32
193           mov b0 = loc1
194           ;;
195         }
196         { .mmi
197           ldf.fill f10 = [r2], 32
198           ldf.fill f11 = [r3], 32
199           mov b6 = r9
200           ;;
201         }
202         { .mmi
203           ldf.fill f12 = [r2], 32
204           ldf.fill f13 = [r3], 32
205           mov ar.pfs = loc0
206           ;;
207         }
208         { .mmi
209           ldf.fill f14 = [r2], 32
210           ldf.fill f15 = [r3], 32
211           .restore sp           /* pop the unwind frame state */
212           adds r12 = 160, r12
213           ;;
214         }
215         { .mii
216           mov r9 = loc3         /* restore language specific register */
217           mov r10 = loc4        /* restore language specific register */
218           mov r11 = loc5        /* restore language specific register */
219         }
220         { .mii
221           ld8 gp = [ret0]
222           mov r8 = loc2         /* restore struct value register */
223           ;;
224         }
225         /* An alloc is needed for the break system call to work.
226            We don't care about the old value of the pfs register.  */
227         { .mmb
228           .prologue
229           .body
230           alloc r2 = ar.pfs, 0, 0, 8, 0
231           br.sptk.many b6
232           ;;
233         }
234 END (_dl_runtime_profile)