.
[glibc.git] / sysdeps / unix / alpha / sysdep.S
blobc67a6542f67a7b7bca5d43e0c0926dc11ffe3239
1 /* Copyright (C) 1993, 1996, 1998, 2002, 2003, 2004
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Brendan Kehoe (brendan@zen.org).
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
21 #include <sysdep.h>
22 #include <features.h>
24 #if defined(__ELF__) && defined(PIC)
25         /* Put this at the end of libc's text segment so that all of
26            the direct branches from the syscalls are forward, and 
27            thus predicted not taken.  */
28         .section .text.last, "ax", @progbits
29 #else
30         .text
31 #endif
33 #ifdef PIC
34         /* When building a shared library, we branch here without
35            having loaded the GP.  Nor, since it was a direct branch,
36            have we loaded PV with our address.  Do both.  */
37 # define LOADGP         br pv, 1f; 1: ldgp gp, 0(pv)
38 # define PROLOGUE       .prologue 0
39 # define EPILOGUE
40 #else
41         /* When building the static library, we tail call here from
42            elsewhere, which might use a different GP.  The entertaining
43            part is that we have to return with the GP of our caller
44            in place, so that linker relaxation works properly.  */
45         /* ??? This is so ugly.  Consider always putting the errno
46            setting code with the syscall in the static case.  */
47 # define GPSAVEREG      t10
48 # define LOADGP         ldah    t11, 0(pv) !gpdisp!1;           \
49                         br      1f;                             \
50                         .subsection 2;                          \
51                         1: mov  gp, GPSAVEREG;                  \
52                         lda     gp, 0(t11) !gpdisp!1;           \
53                         br      2f;                             \
54                         .previous;                              \
55                         mov     gp, GPSAVEREG;                  \
56                         2:
57 # define PROLOGUE       .prologue 1
58 # define EPILOGUE       mov     GPSAVEREG, gp
59 #endif
61         .align 4
62         .globl __syscall_error
63         .ent __syscall_error
64 __syscall_error:
66 #if defined(_LIBC_REENTRANT) && USE___THREAD
68 #ifndef NOT_IN_libc
69 # define SYSCALL_ERROR_ERRNO __libc_errno
70 #else
71 # define SYSCALL_ERROR_ERRNO errno
72 #endif
74         LOADGP
75         PROLOGUE
76         mov     v0, t0
77         call_pal PAL_rduniq
78         ldq     t1, SYSCALL_ERROR_ERRNO(gp) !gottprel
79         addq    v0, t1, v0
80         stl     t0, 0(v0)
81         lda     v0, -1
82         EPILOGUE
83         ret
85 #elif defined(_LIBC_REENTRANT)
87         LOADGP
88         lda     sp, -32(sp)
89         .frame  sp, 32, ra, 0
90         stq     ra, 0(sp)
91         stq     v0, 8(sp)
92 #ifdef GPSAVEREG
93         stq     GPSAVEREG, 16(sp)
94 #endif
95         .mask   0x4000001, -32
96         PROLOGUE
98         /* Find our per-thread errno address  */
99 #if defined PIC && !defined IS_IN_librt
100         bsr     ra, __errno_location    !samegp
101 #else
102         jsr     ra, __errno_location
103 #ifndef GPSAVEREG
104         ldgp    gp, 0(ra)
105 #endif
106 #endif
108         /* Store the error value.  */
109         ldq     t0, 8(sp)
110         stl     t0, 0(v0)
112         /* And kick back a -1.  */
113         ldi     v0, -1
115 #ifdef GPSAVEREG
116         ldq     GPSAVEREG, 16(sp)
117 #endif
118         ldq     ra, 0(sp)
119         lda     sp, 32(sp)
120         EPILOGUE
121         ret
123 #else
125         LOADGP
126         PROLOGUE
127         stl     v0, errno
128         lda     v0, -1
129         EPILOGUE
130         ret
132 #endif
134         .subsection 3
135         .end __syscall_error