* sysdeps/unix/alpha/sysdep.h (INLINE_SYSCALL1): Use __builtin_expect.
[kopensolaris-gnu/glibc.git] / sysdeps / unix / alpha / sysdep.S
1 /* Copyright (C) 1993, 1996, 1998, 2002, 2003 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Brendan Kehoe (brendan@zen.org).
4
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.
9
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.
14
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.  */
19
20 #include <sysdep.h>
21 #include <features.h>
22
23 #if defined(__ELF__) && defined(PIC)
24         /* Put this at the end of libc's text segment so that all of
25            the direct branches from the syscalls are forward, and 
26            thus predicted not taken.  */
27         .section .text.last, "ax", @progbits
28 #else
29         .text
30 #endif
31
32 #ifdef PIC
33         /* When building a shared library, we branch here without
34            having loaded the GP.  Nor, since it was a direct branch,
35            have we loaded PV with our address.  Do both.  */
36 # define LOADGP         br pv, 1f; 1: ldgp gp, 0(pv)
37 # define PROLOGUE       .prologue 0
38 # define EPILOGUE
39 #else
40         /* When building the static library, we tail call here from
41            elsewhere, which might use a different GP.  The entertaining
42            part is that we have to return with the GP of our caller
43            in place, so that linker relaxation works properly.  */
44         /* ??? This is so ugly.  Consider always putting the errno
45            setting code with the syscall in the static case.  */
46 # define GPSAVEREG      t10
47 # define LOADGP         ldah    t11, 0(pv) !gpdisp!1;           \
48                         br      1f;                             \
49                         .subsection 2;                          \
50                         1: mov  gp, GPSAVEREG;                  \
51                         lda     gp, 0(t11) !gpdisp!1;           \
52                         br      2f;                             \
53                         .previous;                              \
54                         mov     gp, GPSAVEREG;                  \
55                         2:
56 # define PROLOGUE       .prologue 1
57 # define EPILOGUE       mov     GPSAVEREG, gp
58 #endif
59
60         .align 4
61         .globl __syscall_error
62         .ent __syscall_error
63 __syscall_error:
64
65 #if defined(_LIBC_REENTRANT) && USE___THREAD
66
67 #ifndef NOT_IN_libc
68 # define SYSCALL_ERROR_ERRNO __libc_errno
69 #else
70 # define SYSCALL_ERROR_ERRNO errno
71 #endif
72
73         LOADGP
74         PROLOGUE
75         mov     v0, t0
76         call_pal PAL_rduniq
77         ldq     t1, SYSCALL_ERROR_ERRNO(gp) !gottprel
78         addq    v0, t1, v0
79         stl     t0, 0(v0)
80         lda     v0, -1
81         EPILOGUE
82         ret
83
84 #elif defined(_LIBC_REENTRANT)
85
86         LOADGP
87         lda     sp, -32(sp)
88         .frame  sp, 32, ra, 0
89         stq     ra, 0(sp)
90         stq     v0, 8(sp)
91 #ifdef GPSAVEREG
92         stq     GPSAVEREG, 16(sp)
93 #endif
94         .mask   0x4000001, -32
95         PROLOGUE
96
97         /* Find our per-thread errno address  */
98 #ifdef PIC
99         bsr     ra, __errno_location    !samegp
100 #else
101         jsr     ra, __errno_location
102 #ifndef GPSAVEREG
103         ldgp    gp, 0(ra)
104 #endif
105 #endif
106
107         /* Store the error value.  */
108         ldq     t0, 8(sp)
109         stl     t0, 0(v0)
110
111         /* And kick back a -1.  */
112         ldi     v0, -1
113
114 #ifdef GPSAVEREG
115         ldq     GPSAVEREG, 16(sp)
116 #endif
117         ldq     ra, 0(sp)
118         lda     sp, 32(sp)
119         EPILOGUE
120         ret
121
122 #else
123
124         LOADGP
125         PROLOGUE
126         stl     v0, errno
127         lda     v0, -1
128         EPILOGUE
129         ret
130
131 #endif
132
133         .subsection 3
134         .end __syscall_error