[BZ #40]
[platform/upstream/linaro-glibc.git] / sysdeps / unix / sysv / linux / sparc / sparc32 / sysdep.h
1 /* Copyright (C) 1997, 2002, 2003, 2004 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, January 1997.
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 #ifndef _LINUX_SPARC32_SYSDEP_H
21 #define _LINUX_SPARC32_SYSDEP_H 1
22
23 #include <sysdeps/unix/sparc/sysdep.h>
24
25 #ifdef IS_IN_rtld
26 # include <dl-sysdep.h>         /* Defines RTLD_PRIVATE_ERRNO.  */
27 #endif
28 #include <tls.h>
29
30 #undef SYS_ify
31 #define SYS_ify(syscall_name) __NR_##syscall_name
32
33 #ifdef __ASSEMBLER__
34
35 #define LOADSYSCALL(x) mov __NR_##x, %g1
36
37 /* Linux/SPARC uses a different trap number */
38 #undef PSEUDO
39 #undef PSEUDO_NOERRNO
40 #undef PSEUDO_ERRVAL
41 #undef ENTRY
42 #undef END
43 #undef LOC
44
45 #define ENTRY(name) \
46         .global C_SYMBOL_NAME(name); \
47         .align 4;\
48         C_LABEL(name);\
49         .type name,@function;
50
51 #define END(name) \
52         .size name, . - name
53
54 #define LOC(name)  .L##name
55
56 #ifdef LINKER_HANDLES_R_SPARC_WDISP22
57 /* Unfortunately, we cannot do this yet.  Linker doesn't seem to
58    handle R_SPARC_WDISP22 against non-STB_LOCAL symbols properly .  */
59 # define SYSCALL_ERROR_HANDLER_ENTRY(handler)                           \
60         .section .gnu.linkonce.t.handler,"ax",@progbits;                \
61         .globl handler;                                                 \
62         .hidden handler;                                                \
63         .type handler,@function;                                        \
64 handler:
65 #else
66 # define SYSCALL_ERROR_HANDLER_ENTRY(handler)                           \
67         .subsection 3;                                                  \
68 handler:
69 #endif
70
71 #if RTLD_PRIVATE_ERRNO
72 # define SYSCALL_ERROR_HANDLER                                          \
73         .section .gnu.linkonce.t.__sparc_get_pic_l7,"ax",@progbits;     \
74         .globl __sparc_get_pic_l7;                                      \
75         .hidden __sparc_get_pic_l7;                                     \
76         .type __sparc_get_pic_l7,@function;                             \
77 __sparc_get_pic_l7:                                                     \
78         retl;                                                           \
79          add    %o7, %l7, %l7;                                          \
80         .previous;                                                      \
81 SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                    \
82         save    %sp,-96,%sp;                                            \
83         sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), %l7;                      \
84         call    __sparc_get_pic_l7;                                     \
85          add    %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7;                 \
86         ld      [%l7 + errno], %l0;                                     \
87         st      %i0, [%l0];                                             \
88         jmpl    %i7+8, %g0;                                             \
89          restore %g0, -1, %o0;                                          \
90         .previous;
91 #elif USE___THREAD
92 # ifndef NOT_IN_libc
93 #  define SYSCALL_ERROR_ERRNO __libc_errno
94 # else
95 #  define SYSCALL_ERROR_ERRNO errno
96 # endif
97 # ifdef SHARED
98 #  define SYSCALL_ERROR_HANDLER                                         \
99         .section .gnu.linkonce.t.__sparc_get_pic_l7,"ax",@progbits;     \
100         .globl __sparc_get_pic_l7;                                      \
101         .hidden __sparc_get_pic_l7;                                     \
102         .type __sparc_get_pic_l7,@function;                             \
103 __sparc_get_pic_l7:                                                     \
104         retl;                                                           \
105          add    %o7, %l7, %l7;                                          \
106         .previous;                                                      \
107 SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                    \
108         save    %sp,-96,%sp;                                            \
109         sethi   %tie_hi22(SYSCALL_ERROR_ERRNO), %l1;                    \
110         sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), %l7;                      \
111         call    __sparc_get_pic_l7;                                     \
112          add    %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7;                 \
113         add     %l1, %tie_lo10(SYSCALL_ERROR_ERRNO), %l1;               \
114         ld      [%l7 + %l1], %l1, %tie_ld(SYSCALL_ERROR_ERRNO);         \
115         st      %i0, [%g7 + %l1], %tie_add(SYSCALL_ERROR_ERRNO);        \
116         jmpl    %i7+8, %g0;                                             \
117          restore %g0, -1, %o0;                                          \
118         .previous;
119 # else
120 #  define SYSCALL_ERROR_HANDLER                                         \
121 SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                    \
122         sethi   %tie_hi22(SYSCALL_ERROR_ERRNO), %g1;                    \
123         sethi   %hi(_GLOBAL_OFFSET_TABLE_), %g2;                        \
124         add     %g1, %tie_lo10(SYSCALL_ERROR_ERRNO), %g1;               \
125         add     %g2, %lo(_GLOBAL_OFFSET_TABLE_), %g2;                   \
126         ld      [%g2 + %g1], %g1, %tie_ld(SYSCALL_ERROR_ERRNO);         \
127         st      %o0, [%g7 + %g1], %tie_add(SYSCALL_ERROR_ERRNO);        \
128         jmpl    %o7+8, %g0;                                             \
129          mov    -1, %o0;                                                \
130         .previous;
131 # endif
132 #else
133 # define SYSCALL_ERROR_HANDLER                                          \
134 SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                    \
135         .global __errno_location;                                       \
136         .type   __errno_location,@function;                             \
137         save   %sp, -96, %sp;                                           \
138         call   __errno_location;                                        \
139          nop;                                                           \
140         st      %i0, [%o0];                                             \
141         jmpl    %i7+8, %g0;                                             \
142          restore %g0, -1, %o0;                                          \
143         .previous;
144 #endif
145
146 #define PSEUDO(name, syscall_name, args)                        \
147         .text;                                                  \
148         ENTRY(name);                                            \
149         LOADSYSCALL(syscall_name);                              \
150         ta 0x10;                                                \
151         bcs __syscall_error_handler;                            \
152          nop;                                                   \
153         SYSCALL_ERROR_HANDLER
154
155 #define PSEUDO_NOERRNO(name, syscall_name, args)                \
156         .text;                                                  \
157         ENTRY(name);                                            \
158         LOADSYSCALL(syscall_name);                              \
159         ta 0x10
160
161 #define PSEUDO_ERRVAL(name, syscall_name, args)                 \
162         .text;                                                  \
163         ENTRY(name);                                            \
164         LOADSYSCALL(syscall_name);                              \
165         ta 0x10
166
167 #else  /* __ASSEMBLER__ */
168
169 #define __SYSCALL_STRING                                                \
170         "ta     0x10;"                                                  \
171         "bcs    2f;"                                                    \
172         " nop;"                                                         \
173         "1:"                                                            \
174         ".subsection 2;"                                                \
175         "2:"                                                            \
176         "save   %%sp, -192, %%sp;"                                      \
177         "call   __errno_location;"                                      \
178         " nop;"                                                         \
179         "st     %%i0,[%%o0];"                                           \
180         "ba     1b;"                                                    \
181         " restore %%g0, -1, %%o0;"                                      \
182         ".previous;"
183
184 #define __CLONE_SYSCALL_STRING                                          \
185         "ta     0x10;"                                                  \
186         "bcs    2f;"                                                    \
187         " sub   %%o1, 1, %%o1;"                                         \
188         "and    %%o0, %%o1, %%o0;"                                      \
189         "1:"                                                            \
190         ".subsection 2;"                                                \
191         "2:"                                                            \
192         "save   %%sp, -192, %%sp;"                                      \
193         "call   __errno_location;"                                      \
194         " nop;"                                                         \
195         "st     %%i0, [%%o0];"                                          \
196         "ba     1b;"                                                    \
197         " restore %%g0, -1, %%o0;"                                      \
198         ".previous;"
199
200 #define __INTERNAL_SYSCALL_STRING                                       \
201         "ta     0x10;"                                                  \
202         "bcs,a  1f;"                                                    \
203         " sub   %%g0, %%o0, %%o0;"                                      \
204         "1:"
205
206 #define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6",                \
207         "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",                 \
208         "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",           \
209         "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",         \
210         "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",         \
211         "cc", "memory"
212
213 #include <sysdeps/unix/sysv/linux/sparc/sysdep.h>
214
215 #endif  /* __ASSEMBLER__ */
216
217 #endif /* linux/sparc/sysdep.h */