2006-01-29 Daniel Jacobowitz <dan@codesourcery.com>
[glibc-ports.git] / sysdeps / alpha / dl-trampoline.S
blobc52efbb3bc569506371b0546a7c15136bb91fc95
1 /* PLT trampolines.  Alpha 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>
22         .set noat
24 .macro savei regno, offset
25         stq     $\regno, \offset($30)
26         cfi_rel_offset(\regno, \offset)
27 .endm
29 .macro savef regno, offset
30         stt     $f\regno, \offset($30)
31         cfi_rel_offset(\regno+32, \offset)
32 .endm
34         .align  4
35         .globl  _dl_runtime_resolve_new
36         .ent    _dl_runtime_resolve_new
38 #undef FRAMESIZE
39 #define FRAMESIZE       14*8
41 _dl_runtime_resolve_new:
42         .frame  $30, FRAMESIZE, $26, 0
43         .mask   0x4000000, 0
45         ldah    $29, 0($27)             !gpdisp!1
46         lda     $30, -FRAMESIZE($30)
47         stq     $26, 0*8($30)
48         stq     $16, 2*8($30)
50         stq     $17, 3*8($30)
51         lda     $29, 0($29)             !gpdisp!1
52         stq     $18, 4*8($30)
53         mov     $28, $16                /* link_map from .got.plt */
55         stq     $19, 5*8($30)
56         mov     $25, $17                /* offset of reloc entry */
57         stq     $20, 6*8($30)
58         mov     $26, $18                /* return address */
60         stq     $21, 7*8($30)
61         stt     $f16, 8*8($30)
62         stt     $f17, 9*8($30)
63         stt     $f18, 10*8($30)
65         stt     $f19, 11*8($30)
66         stt     $f20, 12*8($30)
67         stt     $f21, 13*8($30)
68         .prologue 2
70         bsr     $26, _dl_fixup          !samegp
71         mov     $0, $27
73         ldq     $26, 0*8($30)
74         ldq     $16, 2*8($30)
75         ldq     $17, 3*8($30)
76         ldq     $18, 4*8($30)
77         ldq     $19, 5*8($30)
78         ldq     $20, 6*8($30)
79         ldq     $21, 7*8($30)
80         ldt     $f16, 8*8($30)
81         ldt     $f17, 9*8($30)
82         ldt     $f18, 10*8($30)
83         ldt     $f19, 11*8($30)
84         ldt     $f20, 12*8($30)
85         ldt     $f21, 13*8($30)
86         lda     $30, FRAMESIZE($30)
87         jmp     $31, ($27), 0
88         .end    _dl_runtime_resolve_new
90         .globl  _dl_runtime_profile_new
91         .type   _dl_runtime_profile_new, @function
93 #undef FRAMESIZE
94 #define FRAMESIZE       20*8
96         /* We save the registers in a different order than desired by
97            .mask/.fmask, so we have to use explicit cfi directives.  */
98         cfi_startproc
100 _dl_runtime_profile_new:
101         ldah    $29, 0($27)             !gpdisp!2
102         lda     $30, -FRAMESIZE($30)
103         savei   26, 0*8
104         stq     $16, 2*8($30)
106         stq     $17, 3*8($30)
107         lda     $29, 0($29)             !gpdisp!2
108         stq     $18, 4*8($30)
109         lda     $1, FRAMESIZE($30)      /* incoming sp value */
111         stq     $1, 1*8($30)
112         stq     $19, 5*8($30)
113         stq     $20, 6*8($30)
114         mov     $28, $16                /* link_map from .got.plt */
116         stq     $21, 7*8($30)
117         mov     $25, $17                /* offset of reloc entry */
118         stt     $f16, 8*8($30)
119         mov     $26, $18                /* return address */
121         stt     $f17, 9*8($30)
122         mov     $30, $19                /* La_alpha_regs address */
123         stt     $f18, 10*8($30)
124         lda     $20, 14*8($30)          /* framesize address */
126         stt     $f19, 11*8($30)
127         stt     $f20, 12*8($30)
128         stt     $f21, 13*8($30)
129         stq     $28, 16*8($30)
130         stq     $25, 17*8($30)
132         bsr     $26, _dl_profile_fixup  !samegp
133         mov     $0, $27
135         /* Discover if we're wrapping this call.  */
136         ldq     $18, 14*8($30)
137         bge     $18, 1f
139         ldq     $26, 0*8($30)
140         ldq     $16, 2*8($30)
141         ldq     $17, 3*8($30)
142         ldq     $18, 4*8($30)
143         ldq     $19, 5*8($30)
144         ldq     $20, 6*8($30)
145         ldq     $21, 7*8($30)
146         ldt     $f16, 8*8($30)
147         ldt     $f17, 9*8($30)
148         ldt     $f18, 10*8($30)
149         ldt     $f19, 11*8($30)
150         ldt     $f20, 12*8($30)
151         ldt     $f21, 13*8($30)
152         lda     $30, FRAMESIZE($30)
153         jmp     $31, ($27), 0
156         /* Create a frame pointer and allocate a new argument frame.  */
157         savei   15, 15*8
158         mov     $30, $15
159         cfi_def_cfa_register (15)
160         addq    $18, 15, $18
161         bic     $18, 15, $18
162         subq    $30, $18, $30
164         /* Save the call destination around memcpy.  */
165         stq     $0, 14*8($30)
167         /* Copy the stack arguments into place.  */
168         lda     $16, 0($30)
169         lda     $17, FRAMESIZE($15)
170         jsr     $26, memcpy
171         ldgp    $29, 0($26)
173         /* Reload the argument registers.  */
174         ldq     $27, 14*8($30)
175         ldq     $16, 2*8($15)
176         ldq     $17, 3*8($15)
177         ldq     $18, 4*8($15)
178         ldq     $19, 5*8($15)
179         ldq     $20, 6*8($15)
180         ldq     $21, 7*8($15)
181         ldt     $f16, 8*8($15)
182         ldt     $f17, 9*8($15)
183         ldt     $f18, 10*8($15)
184         ldt     $f19, 11*8($15)
185         ldt     $f20, 12*8($15)
186         ldt     $f21, 13*8($15)
188         jsr     $26, ($27), 0
189         ldgp    $29, 0($26)
191         /* Set up for call to _dl_call_pltexit.  */
192         ldq     $16, 16*8($15)
193         ldq     $17, 17*8($15)
194         stq     $0, 16*8($15)
195         lda     $18, 0($15)
196         stq     $1, 17*8($15)
197         lda     $19, 16*8($15)
198         stt     $f0, 18*8($15)
199         stt     $f1, 19*8($15)
200         bsr     $26, _dl_call_pltexit   !samegp
202         mov     $15, $30
203         cfi_def_cfa_register (30)
204         ldq     $26, 0($30)
205         ldq     $15, 15*8($30)
206         lda     $30, FRAMESIZE($30)
207         ret
209         cfi_endproc
210         .size   _dl_runtime_profile_new, .-_dl_runtime_profile_new
212         .align  4
213         .globl  _dl_runtime_resolve_old
214         .ent    _dl_runtime_resolve_old
216 #undef FRAMESIZE
217 #define FRAMESIZE       44*8
219 _dl_runtime_resolve_old:
220         lda     $30, -FRAMESIZE($30)
221         .frame  $30, FRAMESIZE, $26
222         /* Preserve all registers that C normally doesn't.  */
223         stq     $26, 0*8($30)
224         stq     $0, 1*8($30)
225         stq     $1, 2*8($30)
226         stq     $2, 3*8($30)
227         stq     $3, 4*8($30)
228         stq     $4, 5*8($30)
229         stq     $5, 6*8($30)
230         stq     $6, 7*8($30)
231         stq     $7, 8*8($30)
232         stq     $8, 9*8($30)
233         stq     $16, 10*8($30)
234         stq     $17, 11*8($30)
235         stq     $18, 12*8($30)
236         stq     $19, 13*8($30)
237         stq     $20, 14*8($30)
238         stq     $21, 15*8($30)
239         stq     $22, 16*8($30)
240         stq     $23, 17*8($30)
241         stq     $24, 18*8($30)
242         stq     $25, 19*8($30)
243         stq     $29, 20*8($30)
244         stt     $f0, 21*8($30)
245         stt     $f1, 22*8($30)
246         stt     $f10, 23*8($30)
247         stt     $f11, 24*8($30)
248         stt     $f12, 25*8($30)
249         stt     $f13, 26*8($30)
250         stt     $f14, 27*8($30)
251         stt     $f15, 28*8($30)
252         stt     $f16, 29*8($30)
253         stt     $f17, 30*8($30)
254         stt     $f18, 31*8($30)
255         stt     $f19, 32*8($30)
256         stt     $f20, 33*8($30)
257         stt     $f21, 34*8($30)
258         stt     $f22, 35*8($30)
259         stt     $f23, 36*8($30)
260         stt     $f24, 37*8($30)
261         stt     $f25, 38*8($30)
262         stt     $f26, 39*8($30)
263         stt     $f27, 40*8($30)
264         stt     $f28, 41*8($30)
265         stt     $f29, 42*8($30)
266         stt     $f30, 43*8($30)
267         .mask   0x27ff01ff, -FRAMESIZE
268         .fmask  0xfffffc03, -FRAMESIZE+21*8
269         /* Set up our GP.  */
270         br      $29, .+4
271         ldgp    $29, 0($29)
272         .prologue 0
273         /* Set up the arguments for _dl_fixup:
274            $16 = link_map out of plt0
275            $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
276            $18 = return address
277         */
278         subq    $28, $27, $17
279         ldq     $16, 8($27)
280         subq    $17, 20, $17
281         mov     $26, $18
282         addq    $17, $17, $17
283         bsr     $26, _dl_fixup  !samegp
285         /* Move the destination address into position.  */
286         mov     $0, $27
287         /* Restore program registers.  */
288         ldq     $26, 0*8($30)
289         ldq     $0, 1*8($30)
290         ldq     $1, 2*8($30)
291         ldq     $2, 3*8($30)
292         ldq     $3, 4*8($30)
293         ldq     $4, 5*8($30)
294         ldq     $5, 6*8($30)
295         ldq     $6, 7*8($30)
296         ldq     $7, 8*8($30)
297         ldq     $8, 9*8($30)
298         ldq     $16, 10*8($30)
299         ldq     $17, 11*8($30)
300         ldq     $18, 12*8($30)
301         ldq     $19, 13*8($30)
302         ldq     $20, 14*8($30)
303         ldq     $21, 15*8($30)
304         ldq     $22, 16*8($30)
305         ldq     $23, 17*8($30)
306         ldq     $24, 18*8($30)
307         ldq     $25, 19*8($30)
308         ldq     $29, 20*8($30)
309         ldt     $f0, 21*8($30)
310         ldt     $f1, 22*8($30)
311         ldt     $f10, 23*8($30)
312         ldt     $f11, 24*8($30)
313         ldt     $f12, 25*8($30)
314         ldt     $f13, 26*8($30)
315         ldt     $f14, 27*8($30)
316         ldt     $f15, 28*8($30)
317         ldt     $f16, 29*8($30)
318         ldt     $f17, 30*8($30)
319         ldt     $f18, 31*8($30)
320         ldt     $f19, 32*8($30)
321         ldt     $f20, 33*8($30)
322         ldt     $f21, 34*8($30)
323         ldt     $f22, 35*8($30)
324         ldt     $f23, 36*8($30)
325         ldt     $f24, 37*8($30)
326         ldt     $f25, 38*8($30)
327         ldt     $f26, 39*8($30)
328         ldt     $f27, 40*8($30)
329         ldt     $f28, 41*8($30)
330         ldt     $f29, 42*8($30)
331         ldt     $f30, 43*8($30)
332         /* Flush the Icache after having modified the .plt code.  */
333         imb
334         /* Clean up and turn control to the destination */
335         lda     $30, FRAMESIZE($30)
336         jmp     $31, ($27)
338         .end    _dl_runtime_resolve_old
340         .globl  _dl_runtime_profile_old
341         .usepv  _dl_runtime_profile_old, no
342         .type   _dl_runtime_profile_old, @function
344         /* We save the registers in a different order than desired by
345            .mask/.fmask, so we have to use explicit cfi directives.  */
346         cfi_startproc
348 #undef FRAMESIZE
349 #define FRAMESIZE       50*8
351         .align  4
352 _dl_runtime_profile_old:
353         lda     $30, -FRAMESIZE($30)
354         cfi_adjust_cfa_offset (FRAMESIZE)
356         /* Preserve all argument registers.  This also constructs the
357            La_alpha_regs structure.  */
358         savei   26, 0*8
359         savei   16, 2*8
360         savei   17, 3*8
361         savei   18, 4*8
362         savei   19, 5*8
363         savei   20, 6*8
364         savei   21, 7*8
365         lda     $16, FRAMESIZE($30)
366         savef   16, 8*8
367         savef   17, 9*8
368         savef   18, 10*8
369         savef   19, 11*8
370         savef   20, 12*8
371         savef   21, 13*8
372         stq     $16, 1*8($30)
374         /* Preserve all registers that C normally doesn't.  */
375         savei   0, 14*8
376         savei   1, 15*8
377         savei   2, 16*8
378         savei   3, 17*8
379         savei   4, 18*8
380         savei   5, 19*8
381         savei   6, 20*8
382         savei   7, 21*8
383         savei   8, 22*8
384         savei   22, 23*8
385         savei   23, 24*8
386         savei   24, 25*8
387         savei   25, 26*8
388         savei   29, 27*8
389         savef   0, 28*8
390         savef   1, 29*8
391         savef   10, 30*8
392         savef   11, 31*8
393         savef   12, 32*8
394         savef   13, 33*8
395         savef   14, 34*8
396         savef   15, 35*8
397         savef   22, 36*8
398         savef   23, 37*8
399         savef   24, 38*8
400         savef   25, 39*8
401         savef   26, 40*8
402         savef   27, 41*8
403         savef   28, 42*8
404         savef   29, 43*8
405         savef   30, 44*8
407         /* Set up our GP.  */
408         br      $29, .+4
409         ldgp    $29, 0($29)
411         /* Set up the arguments for _dl_profile_fixup:
412            $16 = link_map out of plt0
413            $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
414            $18 = return address
415            $19 = La_alpha_regs address
416            $20 = framesize address
417         */
418         subq    $28, $27, $17
419         ldq     $16, 8($27)
420         subq    $17, 20, $17
421         mov     $26, $18
422         addq    $17, $17, $17
423         lda     $19, 0($30)
424         lda     $20, 45*8($30)
425         stq     $16, 48*8($30)
426         stq     $17, 49*8($30)
428         bsr     $26, _dl_profile_fixup  !samegp
430         /* Discover if we're wrapping this call.  */
431         ldq     $18, 45*8($30)
432         bge     $18, 1f
434         /* Move the destination address into position.  */
435         mov     $0, $27
436         /* Restore program registers.  */
437         ldq     $26, 0*8($30)
438         ldq     $16, 2*8($30)
439         ldq     $17, 3*8($30)
440         ldq     $18, 4*8($30)
441         ldq     $19, 5*8($30)
442         ldq     $20, 6*8($30)
443         ldq     $21, 7*8($30)
444         ldt     $f16, 8*8($30)
445         ldt     $f17, 9*8($30)
446         ldt     $f18, 10*8($30)
447         ldt     $f19, 11*8($30)
448         ldt     $f20, 12*8($30)
449         ldt     $f21, 13*8($30)
450         ldq     $0, 14*8($30)
451         ldq     $1, 15*8($30)
452         ldq     $2, 16*8($30)
453         ldq     $3, 17*8($30)
454         ldq     $4, 18*8($30)
455         ldq     $5, 19*8($30)
456         ldq     $6, 20*8($30)
457         ldq     $7, 21*8($30)
458         ldq     $8, 22*8($30)
459         ldq     $22, 23*8($30)
460         ldq     $23, 24*8($30)
461         ldq     $24, 25*8($30)
462         ldq     $25, 26*8($30)
463         ldq     $29, 27*8($30)
464         ldt     $f0, 28*8($30)
465         ldt     $f1, 29*8($30)
466         ldt     $f10, 30*8($30)
467         ldt     $f11, 31*8($30)
468         ldt     $f12, 32*8($30)
469         ldt     $f13, 33*8($30)
470         ldt     $f14, 34*8($30)
471         ldt     $f15, 35*8($30)
472         ldt     $f22, 36*8($30)
473         ldt     $f23, 37*8($30)
474         ldt     $f24, 38*8($30)
475         ldt     $f25, 39*8($30)
476         ldt     $f26, 40*8($30)
477         ldt     $f27, 41*8($30)
478         ldt     $f28, 42*8($30)
479         ldt     $f29, 43*8($30)
480         ldt     $f30, 44*8($30)
482         /* Clean up and turn control to the destination.  */
483         lda     $30, FRAMESIZE($30)
484         jmp     $31, ($27)
487         /* Create a frame pointer and allocate a new argument frame.  */
488         savei   15, 45*8
489         mov     $30, $15
490         cfi_def_cfa_register (15)
491         addq    $18, 15, $18
492         bic     $18, 15, $18
493         subq    $30, $18, $30
495         /* Save the call destination around memcpy.  */
496         stq     $0, 46*8($30)
498         /* Copy the stack arguments into place.  */
499         lda     $16, 0($30)
500         lda     $17, FRAMESIZE($15)
501         jsr     $26, memcpy
502         ldgp    $29, 0($26)
504         /* Reload the argument registers.  */
505         ldq     $27, 46*8($30)
506         ldq     $16, 2*8($15)
507         ldq     $17, 3*8($15)
508         ldq     $18, 4*8($15)
509         ldq     $19, 5*8($15)
510         ldq     $20, 6*8($15)
511         ldq     $21, 7*8($15)
512         ldt     $f16, 8*8($15)
513         ldt     $f17, 9*8($15)
514         ldt     $f18, 10*8($15)
515         ldt     $f19, 11*8($15)
516         ldt     $f20, 12*8($15)
517         ldt     $f21, 13*8($15)
519         jsr     $26, ($27), 0
520         ldgp    $29, 0($26)
522         /* Set up for call to _dl_call_pltexit.  */
523         ldq     $16, 48*8($15)
524         ldq     $17, 49*8($15)
525         stq     $0, 46*8($15)
526         lda     $18, 0($15)
527         stq     $1, 47*8($15)
528         lda     $19, 46*8($15)
529         stt     $f0, 48*8($15)
530         stt     $f1, 49*8($15)
531         bsr     $26, _dl_call_pltexit   !samegp
533         mov     $15, $30
534         cfi_def_cfa_register (30)
535         ldq     $26, 0($30)
536         ldq     $15, 45*8($30)
537         lda     $30, FRAMESIZE($30)
538         ret
540         cfi_endproc
541         .size   _dl_runtime_profile_old, .-_dl_runtime_profile_old