/* Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999. Based on code originally written by David Mosberger-Tang The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _LINUX_IA64_SYSDEP_H #define _LINUX_IA64_SYSDEP_H 1 #include <common/sysdep.h> #include <features.h> #include <asm/unistd.h> #ifdef __ASSEMBLER__ /* Macros to help writing .prologue directives in assembly code. */ #define ASM_UNW_PRLG_RP 0x8 #define ASM_UNW_PRLG_PFS 0x4 #define ASM_UNW_PRLG_PSP 0x2 #define ASM_UNW_PRLG_PR 0x1 #define ASM_UNW_PRLG_GRSAVE(ninputs) (32+(ninputs)) #ifdef __STDC__ #define C_LABEL(name) name : #else #define C_LABEL(name) name/**/: #endif #define CALL_MCOUNT #define ENTRY(name) \ .text; \ .align 32; \ .proc C_SYMBOL_NAME(name); \ .global C_SYMBOL_NAME(name); \ C_LABEL(name) \ CALL_MCOUNT #define HIDDEN_ENTRY(name) \ .text; \ .align 32; \ .proc C_SYMBOL_NAME(name); \ .global C_SYMBOL_NAME(name); \ .hidden C_SYMBOL_NAME(name); \ C_LABEL(name) \ CALL_MCOUNT #define LEAF(name) \ .text; \ .align 32; \ .proc C_SYMBOL_NAME(name); \ .global name; \ C_LABEL(name) /* Mark the end of function SYM. */ #undef END #define END(sym) .endp C_SYMBOL_NAME(sym) /* For Linux we can use the system call table in the header file /usr/include/asm/unistd.h of the kernel. But these symbols do not follow the SYS_* syntax so we have to redefine the `SYS_ify' macro here. */ #undef SYS_ify #ifdef __STDC__ # define SYS_ify(syscall_name) __NR_##syscall_name #else # define SYS_ify(syscall_name) __NR_/**/syscall_name #endif /* Linux uses a negative return value to indicate syscall errors, unlike most Unices, which use the condition codes' carry flag. Since version 2.1 the return value of a system call might be negative even if the call succeeded. E.g., the `lseek' system call might return a large offset. Therefore we must not anymore test for < 0, but test for a real error by making sure the value in %d0 is a real error number. Linus said he will make sure the no syscall returns a value in -1 .. -4095 as a valid result so we can savely test with -4095. */ /* We don't want the label for the error handler to be visible in the symbol table when we define it here. */ #define SYSCALL_ERROR_LABEL __syscall_error #undef PSEUDO #define PSEUDO(name, syscall_name, args) \ ENTRY(name) \ DO_CALL (SYS_ify(syscall_name)); \ cmp.eq p6,p0=-1,r10; \ (p6) br.cond.spnt.few __syscall_error; #define DO_CALL_VIA_BREAK(num) \ mov r15=num; \ break __BREAK_SYSCALL #ifdef IA64_USE_NEW_STUB # ifdef SHARED # define DO_CALL(num) \ .prologue; \ adds r2 = SYSINFO_OFFSET, r13;; \ ld8 r2 = [r2]; \ .save ar.pfs, r11; \ mov r11 = ar.pfs;; \ .body; \ mov r15 = num; \ mov b7 = r2; \ br.call.sptk.many b6 = b7;; \ .restore sp; \ mov ar.pfs = r11; \ .prologue; \ .body # else /* !SHARED */ # define DO_CALL(num) \ .prologue; \ mov r15 = num; \ movl r2 = _dl_sysinfo;; \ ld8 r2 = [r2]; \ .save ar.pfs, r11; \ mov r11 = ar.pfs;; \ .body; \ mov b7 = r2; \ br.call.sptk.many b6 = b7;; \ .restore sp; \ mov ar.pfs = r11; \ .prologue; \ .body # endif #else # define DO_CALL(num) DO_CALL_VIA_BREAK(num) #endif #undef PSEUDO_END #define PSEUDO_END(name) .endp C_SYMBOL_NAME(name); #undef PSEUDO_NOERRNO #define PSEUDO_NOERRNO(name, syscall_name, args) \ ENTRY(name) \ DO_CALL (SYS_ify(syscall_name)); #undef PSEUDO_END_NOERRNO #define PSEUDO_END_NOERRNO(name) .endp C_SYMBOL_NAME(name); #undef PSEUDO_ERRVAL #define PSEUDO_ERRVAL(name, syscall_name, args) \ ENTRY(name) \ DO_CALL (SYS_ify(syscall_name)); \ cmp.eq p6,p0=-1,r10; \ (p6) mov r10=r8; #undef PSEUDO_END_ERRVAL #define PSEUDO_END_ERRVAL(name) .endp C_SYMBOL_NAME(name); #undef END #define END(name) \ .size C_SYMBOL_NAME(name), . - C_SYMBOL_NAME(name) ; \ .endp C_SYMBOL_NAME(name) #define ret br.ret.sptk.few b0 #define ret_NOERRNO ret #endif /* not __ASSEMBLER__ */ #endif /* linux/ia64/sysdep.h */