]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/ia64/sysdep.h
Update.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / ia64 / sysdep.h
1 /* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
4 Based on code originally written by David Mosberger-Tang
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 #include <sysdeps/unix/sysdep.h>
22 #include <sysdeps/ia64/sysdep.h>
23
24 /* For Linux we can use the system call table in the header file
25 /usr/include/asm/unistd.h
26 of the kernel. But these symbols do not follow the SYS_* syntax
27 so we have to redefine the `SYS_ify' macro here. */
28 #undef SYS_ify
29 #ifdef __STDC__
30 # define SYS_ify(syscall_name) __NR_##syscall_name
31 #else
32 # define SYS_ify(syscall_name) __NR_/**/syscall_name
33 #endif
34
35 /* This is a kludge to make syscalls.list find these under the names
36 pread and pwrite, since some kernel headers define those names
37 and some define the *64 names for the same system calls. */
38 #if !defined __NR_pread && defined __NR_pread64
39 # define __NR_pread __NR_pread64
40 #endif
41 #if !defined __NR_pwrite && defined __NR_pwrite64
42 # define __NR_pwrite __NR_pwrite64
43 #endif
44
45 #ifdef __ASSEMBLER__
46
47 #undef CALL_MCOUNT
48 #ifdef PROF
49 # define CALL_MCOUNT \
50 .data; \
51 1: data8 0; /* XXX fixme: use .xdata8 once labels work */ \
52 .previous; \
53 .prologue; \
54 .save ar.pfs, r40; \
55 alloc out0 = ar.pfs, 8, 0, 4, 0; \
56 mov out1 = gp; \
57 .save rp, out2; \
58 mov out2 = rp; \
59 .body; \
60 ;; \
61 addl out3 = @ltoff(1b), gp; \
62 br.call.sptk.many rp = _mcount \
63 ;;
64 #else
65 # define CALL_MCOUNT /* Do nothing. */
66 #endif
67
68 /* Linux uses a negative return value to indicate syscall errors, unlike
69 most Unices, which use the condition codes' carry flag.
70
71 Since version 2.1 the return value of a system call might be negative
72 even if the call succeeded. E.g., the `lseek' system call might return
73 a large offset. Therefore we must not anymore test for < 0, but test
74 for a real error by making sure the value in %d0 is a real error
75 number. Linus said he will make sure the no syscall returns a value
76 in -1 .. -4095 as a valid result so we can savely test with -4095. */
77
78 /* We don't want the label for the error handler to be visible in the symbol
79 table when we define it here. */
80 #define SYSCALL_ERROR_LABEL __syscall_error
81
82 #undef PSEUDO
83 #define PSEUDO(name, syscall_name, args) \
84 ENTRY(name) \
85 DO_CALL (SYS_ify(syscall_name)); \
86 cmp.eq p6,p0=-1,r10; \
87 (p6) br.cond.spnt.few __syscall_error;
88
89 #define DO_CALL(num) \
90 mov r15=num; \
91 break __BREAK_SYSCALL;
92
93 #undef PSEUDO_END
94 #define PSEUDO_END(name) .endp C_SYMBOL_NAME(name);
95
96 #undef END
97 #define END(name) \
98 .size C_SYMBOL_NAME(name), . - C_SYMBOL_NAME(name) ; \
99 .endp C_SYMBOL_NAME(name)
100
101 #define ret br.ret.sptk.few b0
102
103 #else /* not __ASSEMBLER__ */
104
105 /* On IA-64 we have stacked registers for passing arguments. The
106 "out" registers end up being the called function's "in"
107 registers.
108
109 Also, since we have plenty of registers we have two return values
110 from a syscall. r10 is set to -1 on error, whilst r8 contains the
111 (non-negative) errno on error or the return value on success.
112 */
113 #undef INLINE_SYSCALL
114 #define INLINE_SYSCALL(name, nr, args...) \
115 ({ \
116 register long _r8 asm ("r8"); \
117 register long _r10 asm ("r10"); \
118 register long _r15 asm ("r15") = __NR_##name; \
119 long _retval; \
120 LOAD_ARGS_##nr (args); \
121 __asm __volatile ("break %3;;\n\t" \
122 : "=r" (_r8), "=r" (_r10), "=r" (_r15) \
123 : "i" (__BREAK_SYSCALL), "2" (_r15) \
124 ASM_ARGS_##nr \
125 : "memory" ASM_CLOBBERS_##nr); \
126 _retval = _r8; \
127 if (_r10 == -1) \
128 { \
129 __set_errno (_retval); \
130 _retval = -1; \
131 } \
132 _retval; })
133
134 #undef INTERNAL_SYSCALL
135 #define INTERNAL_SYSCALL(name, nr, args...) \
136 ({ \
137 register long _r8 asm ("r8"); \
138 register long _r10 asm ("r10"); \
139 register long _r15 asm ("r15") = __NR_##name; \
140 long _retval; \
141 LOAD_ARGS_##nr (args); \
142 __asm __volatile ("break %3;;\n\t" \
143 : "=r" (_r8), "=r" (_r10), "=r" (_r15) \
144 : "i" (__BREAK_SYSCALL), "2" (_r15) \
145 ASM_ARGS_##nr \
146 : "memory" ASM_CLOBBERS_##nr); \
147 _retval = _r8; \
148 if (_r10 == -1) \
149 _retval = -_retval; \
150 _retval; })
151
152 #undef INTERNAL_SYSCALL_ERROR_P
153 #define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= -4095UL)
154
155 #undef INTERNAL_SYSCALL_ERRNO
156 #define INTERNAL_SYSCALL_ERRNO(val) (-(val))
157
158 #define LOAD_ARGS_0() do { } while (0)
159 #define LOAD_ARGS_1(out0) \
160 register long _out0 asm ("out0") = (long) (out0); \
161 LOAD_ARGS_0 ()
162 #define LOAD_ARGS_2(out0, out1) \
163 register long _out1 asm ("out1") = (long) (out1); \
164 LOAD_ARGS_1 (out0)
165 #define LOAD_ARGS_3(out0, out1, out2) \
166 register long _out2 asm ("out2") = (long) (out2); \
167 LOAD_ARGS_2 (out0, out1)
168 #define LOAD_ARGS_4(out0, out1, out2, out3) \
169 register long _out3 asm ("out3") = (long) (out3); \
170 LOAD_ARGS_3 (out0, out1, out2)
171 #define LOAD_ARGS_5(out0, out1, out2, out3, out4) \
172 register long _out4 asm ("out4") = (long) (out4); \
173 LOAD_ARGS_4 (out0, out1, out2, out3)
174
175 #define ASM_ARGS_0
176 #define ASM_ARGS_1 ASM_ARGS_0, "r" (_out0)
177 #define ASM_ARGS_2 ASM_ARGS_1, "r" (_out1)
178 #define ASM_ARGS_3 ASM_ARGS_2, "r" (_out2)
179 #define ASM_ARGS_4 ASM_ARGS_3, "r" (_out3)
180 #define ASM_ARGS_5 ASM_ARGS_4, "r" (_out4)
181
182 #define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0"
183 #define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1"
184 #define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2"
185 #define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3"
186 #define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4"
187 #define ASM_CLOBBERS_5 , "out5", "out6", "out7", \
188 /* Non-stacked integer registers, minus r8, r10, r15. */ \
189 "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \
190 "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \
191 "r28", "r29", "r30", "r31", \
192 /* Predicate registers. */ \
193 "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \
194 /* Non-rotating fp registers. */ \
195 "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
196 /* Branch registers. */ \
197 "b6", "b7"
198
199 #endif /* not __ASSEMBLER__ */