dfc38f151ab78e550c78770134d215bf799d21c5
[platform/upstream/glibc.git] / sysdeps / unix / sysv / linux / sparc / sparc64 / sysdep.h
1 /* Copyright (C) 1997, 2000, 2002, 2003, 2004, 2006
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
5
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.
10
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.
15
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.  */
20
21 #ifndef _LINUX_SPARC64_SYSDEP_H
22 #define _LINUX_SPARC64_SYSDEP_H 1
23
24 #include <sysdeps/unix/sysdep.h>
25
26 #ifdef IS_IN_rtld
27 # include <dl-sysdep.h>         /* Defines RTLD_PRIVATE_ERRNO.  */
28 #endif
29 #include <tls.h>
30
31 #undef SYS_ify
32 #define SYS_ify(syscall_name) __NR_##syscall_name
33
34 /* This is a kludge to make syscalls.list find these under the names
35    pread and pwrite, since some kernel headers define those names
36    and some define the *64 names for the same system calls.  */
37 #if !defined __NR_pread && defined __NR_pread64
38 # define __NR_pread __NR_pread64
39 #endif
40 #if !defined __NR_pwrite && defined __NR_pwrite64
41 # define __NR_pwrite __NR_pwrite64
42 #endif
43
44 #ifdef __ASSEMBLER__
45
46 #define LOADSYSCALL(x) mov __NR_##x, %g1
47
48 /* Linux/SPARC uses a different trap number */
49 #undef PSEUDO
50 #undef PSEUDO_NOERRNO
51 #undef PSEUDO_ERRVAL
52 #undef ENTRY
53
54 #define ENTRY(name)                                                     \
55         .global C_SYMBOL_NAME(name);                                    \
56         .align 2;                                                       \
57         C_LABEL(name);                                                  \
58         .type name,@function;
59
60 #ifdef LINKER_HANDLES_R_SPARC_WDISP22
61 /* Unfortunately, we cannot do this yet.  Linker doesn't seem to
62    handle R_SPARC_WDISP22 against non-STB_LOCAL symbols properly .  */
63 # define SYSCALL_ERROR_HANDLER_ENTRY(handler)                           \
64         .section .gnu.linkonce.t.handler,"ax",@progbits;                \
65         .globl handler;                                                 \
66         .hidden handler;                                                \
67         .type handler,@function;                                        \
68 handler:
69 #else
70 # define SYSCALL_ERROR_HANDLER_ENTRY(handler)                           \
71         .subsection 3;                                                  \
72 handler:
73 #endif
74
75 #if RTLD_PRIVATE_ERRNO
76 # define SYSCALL_ERROR_HANDLER                                          \
77         .section .gnu.linkonce.t.__sparc64.get_pic.l7,"ax",@progbits;   \
78         .globl __sparc64.get_pic.l7;                                    \
79         .hidden __sparc64.get_pic.l7;                                   \
80         .type __sparc64.get_pic.l7,@function;                           \
81 __sparc64.get_pic.l7:                                                   \
82         retl;                                                           \
83          add    %o7, %l7, %l7;                                          \
84         .previous;                                                      \
85 SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                    \
86         save    %sp, -192, %sp;                                         \
87         sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), %l7;                      \
88         call    __sparc64.get_pic.l7;                                   \
89          add    %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7;                 \
90         sethi   %hi(rtld_errno), %g1;                                   \
91         or      %g1, %lo(rtld_errno), %g1;                              \
92         ldx     [%l7 + %g1], %l0;                                       \
93         st      %i0, [%l0];                                             \
94         jmpl    %i7+8, %g0;                                             \
95          restore %g0, -1, %o0;                                          \
96         .previous;
97 #elif USE___THREAD
98 # ifndef NOT_IN_libc
99 #  define SYSCALL_ERROR_ERRNO __libc_errno
100 # else
101 #  define SYSCALL_ERROR_ERRNO errno
102 # endif
103 # ifdef SHARED
104 #  define SYSCALL_ERROR_HANDLER                                         \
105         .section .gnu.linkonce.t.__sparc64.get_pic.l7,"ax",@progbits;   \
106         .globl __sparc64.get_pic.l7;                                    \
107         .hidden __sparc64.get_pic.l7;                                   \
108         .type __sparc64.get_pic.l7,@function;                           \
109 __sparc64.get_pic.l7:                                                   \
110         retl;                                                           \
111          add    %o7, %l7, %l7;                                          \
112         .previous;                                                      \
113 SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                    \
114         save    %sp,-192,%sp;                                           \
115         sethi   %tie_hi22(SYSCALL_ERROR_ERRNO), %l1;                    \
116         sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), %l7;                      \
117         call    __sparc64.get_pic.l7;                                   \
118          add    %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7;                 \
119         add     %l1, %tie_lo10(SYSCALL_ERROR_ERRNO), %l1;               \
120         ldx     [%l7 + %l1], %l1, %tie_ldx(SYSCALL_ERROR_ERRNO);        \
121         st      %i0, [%g7 + %l1], %tie_add(SYSCALL_ERROR_ERRNO);        \
122         jmpl    %i7+8, %g0;                                             \
123          restore %g0, -1, %o0;                                          \
124         .previous;
125 # else
126 #  define SYSCALL_ERROR_HANDLER                                         \
127 SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                    \
128         sethi   %tie_hi22(SYSCALL_ERROR_ERRNO), %g1;                    \
129         sethi   %hi(_GLOBAL_OFFSET_TABLE_), %g4;                        \
130         add     %g1, %tie_lo10(SYSCALL_ERROR_ERRNO), %g1;               \
131         add     %g4, %lo(_GLOBAL_OFFSET_TABLE_), %g4;                   \
132         ldx     [%g4 + %g1], %g1, %tie_ldx(SYSCALL_ERROR_ERRNO);        \
133         st      %o0, [%g7 + %g1], %tie_add(SYSCALL_ERROR_ERRNO);        \
134         jmpl    %o7+8, %g0;                                             \
135          mov    -1, %o0;                                                \
136         .previous;
137 # endif
138 #else
139 # define SYSCALL_ERROR_HANDLER                                          \
140 SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler)                    \
141         .global __errno_location;                                       \
142         .type   __errno_location,@function;                             \
143         save    %sp, -192, %sp;                                         \
144         call    __errno_location;                                       \
145          nop;                                                           \
146         st      %i0, [%o0];                                             \
147         jmpl    %i7+8, %g0;                                             \
148          restore %g0, -1, %o0;                                          \
149         .previous;
150 #endif
151
152 #define PSEUDO(name, syscall_name, args)                                \
153         .text;                                                          \
154         ENTRY(name);                                                    \
155         LOADSYSCALL(syscall_name);                                      \
156         ta      0x6d;                                                   \
157         bcs,pn  %xcc, __syscall_error_handler;                          \
158          nop;                                                           \
159         SYSCALL_ERROR_HANDLER
160
161 #define PSEUDO_NOERRNO(name, syscall_name, args)                        \
162         .text;                                                          \
163         ENTRY(name);                                                    \
164         LOADSYSCALL(syscall_name);                                      \
165         ta      0x6d
166
167 #define PSEUDO_ERRVAL(name, syscall_name, args)                         \
168         .text;                                                          \
169         ENTRY(name);                                                    \
170         LOADSYSCALL(syscall_name);                                      \
171         ta      0x6d
172
173 #undef PSEUDO_END
174 #define PSEUDO_END(name)                                                \
175         .size name,.-name
176
177 #undef PSEUDO_END_NOERRNO
178 #define PSEUDO_END_NOERRNO(name)                                        \
179         .size name,.-name
180
181 #undef PSEUDO_END_ERRVAL
182 #define PSEUDO_END_ERRVAL(name)                                         \
183         .size name,.-name
184
185 #undef END
186 #define END(name)                                                       \
187         .size name,.-name
188
189 /* Careful here!  This "ret" define can interfere; use jmpl if unsure.  */
190 #define ret             retl; nop
191 #define ret_NOERRNO     retl; nop
192 #define ret_ERRVAL      retl; nop
193 #define r0              %o0
194 #define r1              %o1
195 #define MOVE(x,y)       mov x, y
196
197 #else  /* __ASSEMBLER__ */
198
199 #define __SYSCALL_STRING                                                \
200         "ta     0x6d;"                                                  \
201         "bcc,pt %%xcc, 1f;"                                             \
202         " nop;"                                                         \
203         "save   %%sp, -192, %%sp;"                                      \
204         "call   __errno_location;"                                      \
205         " nop;"                                                         \
206         "st     %%i0,[%%o0];"                                           \
207         "restore %%g0, -1, %%o0;"                                       \
208         "1:"
209
210 #define __CLONE_SYSCALL_STRING                                          \
211         "ta     0x6d;"                                                  \
212         "bcc,pt %%xcc, 1f;"                                             \
213         " sub   %%o1, 1, %%o1;"                                         \
214         "save   %%sp, -192, %%sp;"                                      \
215         "call   __errno_location;"                                      \
216         " mov   -1, %%i1;"                                              \
217         "st     %%i0,[%%o0];"                                           \
218         "restore %%g0, -1, %%o0;"                                       \
219         "1:"                                                            \
220         "and    %%o0, %%o1, %%o0"
221
222 #define __INTERNAL_SYSCALL_STRING                                       \
223         "ta     0x6d;"                                                  \
224         "bcs,a,pt %%xcc, 1f;"                                           \
225         " sub   %%g0, %%o0, %%o0;"                                      \
226         "1:"
227
228 #define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6",                \
229         "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",                 \
230         "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",           \
231         "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",         \
232         "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",         \
233         "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",         \
234         "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",         \
235         "cc", "memory"
236
237 #include <sysdeps/unix/sysv/linux/sparc/sysdep.h>
238
239 #endif  /* __ASSEMBLER__ */
240
241 /* This is the offset from the %sp to the backing store above the
242    register windows.  So if you poke stack memory directly you add this.  */
243 #define STACK_BIAS      2047
244
245 /* Pointer mangling support.  */
246 #if defined NOT_IN_libc && defined IS_IN_rtld
247 /* We cannot use the thread descriptor because in ld.so we use setjmp
248    earlier than the descriptor is initialized.  */
249 #else
250 # ifdef __ASSEMBLER__
251 #  define PTR_MANGLE(dreg, reg, tmpreg) \
252   ldx   [%g7 + POINTER_GUARD], tmpreg; \
253   xor   reg, tmpreg, dreg
254 #  define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg)
255 #  define PTR_MANGLE2(dreg, reg, tmpreg) \
256   xor   reg, tmpreg, dreg
257 #  define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg)
258 # else
259 #  define PTR_MANGLE(var) \
260   (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
261 #  define PTR_DEMANGLE(var)     PTR_MANGLE (var)
262 # endif
263 #endif
264
265 #endif /* linux/sparc64/sysdep.h */