]>
git.ipfire.org Git - thirdparty/glibc.git/blob - 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
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
21 #include <sysdeps/unix/sysdep.h>
22 #include <sysdeps/ia64/sysdep.h>
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. */
30 # define SYS_ify(syscall_name) __NR_##syscall_name
32 # define SYS_ify(syscall_name) __NR_/**/syscall_name
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
41 #if !defined __NR_pwrite && defined __NR_pwrite64
42 # define __NR_pwrite __NR_pwrite64
49 # define CALL_MCOUNT \
51 1: data8 0; /* XXX fixme: use .xdata8 once labels work */ \
55 alloc out0 = ar.pfs, 8, 0, 4, 0; \
61 addl out3 = @ltoff(1b), gp; \
62 br.call.sptk.many rp = _mcount \
65 # define CALL_MCOUNT /* Do nothing. */
68 /* Linux uses a negative return value to indicate syscall errors, unlike
69 most Unices, which use the condition codes' carry flag.
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. */
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
83 #define PSEUDO(name, syscall_name, args) \
85 DO_CALL (SYS_ify(syscall_name)); \
86 cmp.eq p6,p0=-1,r10; \
87 (p6) br.cond.spnt.few __syscall_error;
89 #define DO_CALL(num) \
91 break __BREAK_SYSCALL;
94 #define PSEUDO_END(name) .endp C_SYMBOL_NAME(name);
98 .size C_SYMBOL_NAME(name), . - C_SYMBOL_NAME(name) ; \
99 .endp C_SYMBOL_NAME(name)
101 #define ret br.ret.sptk.few b0
103 #else /* not __ASSEMBLER__ */
105 /* On IA-64 we have stacked registers for passing arguments. The
106 "out" registers end up being the called function's "in"
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.
113 #undef INLINE_SYSCALL
114 #define INLINE_SYSCALL(name, nr, args...) \
116 register long _r8 asm ("r8"); \
117 register long _r10 asm ("r10"); \
118 register long _r15 asm ("r15") = __NR_##name; \
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) \
125 : "memory" ASM_CLOBBERS_##nr); \
129 __set_errno (_retval); \
134 #undef INTERNAL_SYSCALL
135 #define INTERNAL_SYSCALL(name, nr, args...) \
137 register long _r8 asm ("r8"); \
138 register long _r10 asm ("r10"); \
139 register long _r15 asm ("r15") = __NR_##name; \
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) \
146 : "memory" ASM_CLOBBERS_##nr); \
149 _retval = -_retval; \
152 #undef INTERNAL_SYSCALL_ERROR_P
153 #define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= -4095UL)
155 #undef INTERNAL_SYSCALL_ERRNO
156 #define INTERNAL_SYSCALL_ERRNO(val) (-(val))
158 #define LOAD_ARGS_0() do { } while (0)
159 #define LOAD_ARGS_1(out0) \
160 register long _out0 asm ("out0") = (long) (out0); \
162 #define LOAD_ARGS_2(out0, out1) \
163 register long _out1 asm ("out1") = (long) (out1); \
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)
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)
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. */ \
199 #endif /* not __ASSEMBLER__ */