Blame sysdeps/unix/sysv/linux/ia64/sysdep.h

Packit 6c4009
/* Copyright (C) 1999-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
Packit 6c4009
   Based on code originally written by David Mosberger-Tang
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#ifndef _LINUX_IA64_SYSDEP_H
Packit 6c4009
#define _LINUX_IA64_SYSDEP_H 1
Packit 6c4009
Packit 6c4009
#include <sysdeps/unix/sysdep.h>
Packit 6c4009
#include <sysdeps/unix/sysv/linux/sysdep.h>
Packit 6c4009
#include <sysdeps/ia64/sysdep.h>
Packit 6c4009
#include <dl-sysdep.h>
Packit 6c4009
#include <tls.h>
Packit 6c4009
Packit 6c4009
/* In order to get __set_errno() definition in INLINE_SYSCALL.  */
Packit 6c4009
#ifndef __ASSEMBLER__
Packit 6c4009
#include <errno.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* As of GAS v2.4.90.0.7, including a ".align" directive inside a
Packit 6c4009
   function will cause bad unwind info to be emitted (GAS doesn't know
Packit 6c4009
   how to account for the padding introduced by the .align directive).
Packit 6c4009
   Turning on this macro will work around this bug by introducing the
Packit 6c4009
   necessary padding explicitly. */
Packit 6c4009
#define GAS_ALIGN_BREAKS_UNWIND_INFO
Packit 6c4009
Packit 6c4009
/* For Linux we can use the system call table in the header file
Packit 6c4009
	/usr/include/asm/unistd.h
Packit 6c4009
   of the kernel.  But these symbols do not follow the SYS_* syntax
Packit 6c4009
   so we have to redefine the `SYS_ify' macro here.  */
Packit 6c4009
#undef SYS_ify
Packit 6c4009
#define SYS_ify(syscall_name)	__NR_##syscall_name
Packit 6c4009
Packit 6c4009
/* This is a kludge to make syscalls.list find these under the names
Packit 6c4009
   pread and pwrite, since some kernel headers define those names
Packit 6c4009
   and some define the *64 names for the same system calls.  */
Packit 6c4009
#if !defined __NR_pread && defined __NR_pread64
Packit 6c4009
# define __NR_pread __NR_pread64
Packit 6c4009
#endif
Packit 6c4009
#if !defined __NR_pwrite && defined __NR_pwrite64
Packit 6c4009
# define __NR_pwrite __NR_pwrite64
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* This is to help the old kernel headers where __NR_semtimedop is not
Packit 6c4009
   available.  */
Packit 6c4009
#ifndef __NR_semtimedop
Packit 6c4009
# define __NR_semtimedop 1247
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#if defined USE_DL_SYSINFO \
Packit 6c4009
	&& (IS_IN (libc) \
Packit 6c4009
	    || IS_IN (libpthread) || IS_IN (librt))
Packit 6c4009
# define IA64_USE_NEW_STUB
Packit 6c4009
#else
Packit 6c4009
# undef IA64_USE_NEW_STUB
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef __ASSEMBLER__
Packit 6c4009
Packit 6c4009
#undef CALL_MCOUNT
Packit 6c4009
#ifdef PROF
Packit 6c4009
# define CALL_MCOUNT							\
Packit 6c4009
	.data;								\
Packit 6c4009
1:	data8 0;	/* XXX fixme: use .xdata8 once labels work */	\
Packit 6c4009
	.previous;							\
Packit 6c4009
	.prologue;							\
Packit 6c4009
	.save ar.pfs, r40;						\
Packit 6c4009
	alloc out0 = ar.pfs, 8, 0, 4, 0;				\
Packit 6c4009
	mov out1 = gp;							\
Packit 6c4009
	.save rp, out2;							\
Packit 6c4009
	mov out2 = rp;							\
Packit 6c4009
	.body;								\
Packit 6c4009
	;;								\
Packit 6c4009
	addl out3 = @ltoff(1b), gp;					\
Packit 6c4009
	br.call.sptk.many rp = _mcount					\
Packit 6c4009
	;;
Packit 6c4009
#else
Packit 6c4009
# define CALL_MCOUNT	/* Do nothing. */
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Linux uses a negative return value to indicate syscall errors, unlike
Packit 6c4009
   most Unices, which use the condition codes' carry flag.
Packit 6c4009
Packit 6c4009
   Since version 2.1 the return value of a system call might be negative
Packit 6c4009
   even if the call succeeded.  E.g., the `lseek' system call might return
Packit 6c4009
   a large offset.  Therefore we must not anymore test for < 0, but test
Packit 6c4009
   for a real error by making sure the value in %d0 is a real error
Packit 6c4009
   number.  Linus said he will make sure the no syscall returns a value
Packit 6c4009
   in -1 .. -4095 as a valid result so we can savely test with -4095.  */
Packit 6c4009
Packit 6c4009
/* We don't want the label for the error handler to be visible in the symbol
Packit 6c4009
   table when we define it here.  */
Packit 6c4009
#define SYSCALL_ERROR_LABEL __syscall_error
Packit 6c4009
Packit 6c4009
#undef PSEUDO
Packit 6c4009
#define	PSEUDO(name, syscall_name, args)	\
Packit 6c4009
  ENTRY(name)					\
Packit 6c4009
    DO_CALL (SYS_ify(syscall_name));		\
Packit 6c4009
	cmp.eq p6,p0=-1,r10;			\
Packit 6c4009
(p6)	br.cond.spnt.few __syscall_error;
Packit 6c4009
Packit 6c4009
#define DO_CALL_VIA_BREAK(num)			\
Packit 6c4009
	mov r15=num;				\
Packit 6c4009
	break __BREAK_SYSCALL
Packit 6c4009
Packit 6c4009
#ifdef IA64_USE_NEW_STUB
Packit 6c4009
# ifdef SHARED
Packit 6c4009
#  define DO_CALL(num)				\
Packit 6c4009
	.prologue;				\
Packit 6c4009
	adds r2 = SYSINFO_OFFSET, r13;;		\
Packit 6c4009
	ld8 r2 = [r2];				\
Packit 6c4009
	.save ar.pfs, r11;			\
Packit 6c4009
	mov r11 = ar.pfs;;			\
Packit 6c4009
	.body;					\
Packit 6c4009
	mov r15 = num;				\
Packit 6c4009
	mov b7 = r2;				\
Packit 6c4009
	br.call.sptk.many b6 = b7;;		\
Packit 6c4009
	.restore sp;				\
Packit 6c4009
	mov ar.pfs = r11;			\
Packit 6c4009
	.prologue;				\
Packit 6c4009
	.body
Packit 6c4009
# else /* !SHARED */
Packit 6c4009
#  define DO_CALL(num)				\
Packit 6c4009
	.prologue;				\
Packit 6c4009
	mov r15 = num;				\
Packit 6c4009
	movl r2 = _dl_sysinfo;;			\
Packit 6c4009
	ld8 r2 = [r2];				\
Packit 6c4009
	.save ar.pfs, r11;			\
Packit 6c4009
	mov r11 = ar.pfs;;			\
Packit 6c4009
	.body;					\
Packit 6c4009
	mov b7 = r2;				\
Packit 6c4009
	br.call.sptk.many b6 = b7;;		\
Packit 6c4009
	.restore sp;				\
Packit 6c4009
	mov ar.pfs = r11;			\
Packit 6c4009
	.prologue;				\
Packit 6c4009
	.body
Packit 6c4009
# endif
Packit 6c4009
#else
Packit 6c4009
# define DO_CALL(num)				DO_CALL_VIA_BREAK(num)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#undef PSEUDO_END
Packit 6c4009
#define PSEUDO_END(name)	.endp C_SYMBOL_NAME(name);
Packit 6c4009
Packit 6c4009
#undef PSEUDO_NOERRNO
Packit 6c4009
#define	PSEUDO_NOERRNO(name, syscall_name, args)	\
Packit 6c4009
  ENTRY(name)						\
Packit 6c4009
    DO_CALL (SYS_ify(syscall_name));
Packit 6c4009
Packit 6c4009
#undef PSEUDO_END_NOERRNO
Packit 6c4009
#define PSEUDO_END_NOERRNO(name)	.endp C_SYMBOL_NAME(name);
Packit 6c4009
Packit 6c4009
#undef PSEUDO_ERRVAL
Packit 6c4009
#define	PSEUDO_ERRVAL(name, syscall_name, args)	\
Packit 6c4009
  ENTRY(name)					\
Packit 6c4009
    DO_CALL (SYS_ify(syscall_name));		\
Packit 6c4009
	cmp.eq p6,p0=-1,r10;			\
Packit 6c4009
(p6)	mov r10=r8;
Packit 6c4009
Packit 6c4009
Packit 6c4009
#undef PSEUDO_END_ERRVAL
Packit 6c4009
#define PSEUDO_END_ERRVAL(name)	.endp C_SYMBOL_NAME(name);
Packit 6c4009
Packit 6c4009
#undef END
Packit 6c4009
#define END(name)						\
Packit 6c4009
	.size	C_SYMBOL_NAME(name), . - C_SYMBOL_NAME(name) ;	\
Packit 6c4009
	.endp	C_SYMBOL_NAME(name)
Packit 6c4009
Packit 6c4009
#define ret			br.ret.sptk.few b0
Packit 6c4009
#define ret_NOERRNO		ret
Packit 6c4009
#define ret_ERRVAL		ret
Packit 6c4009
Packit 6c4009
#else /* not __ASSEMBLER__ */
Packit 6c4009
Packit 6c4009
#define BREAK_INSN_1(num) "break " #num ";;\n\t"
Packit 6c4009
#define BREAK_INSN(num) BREAK_INSN_1(num)
Packit 6c4009
Packit 6c4009
/* On IA-64 we have stacked registers for passing arguments.  The
Packit 6c4009
   "out" registers end up being the called function's "in"
Packit 6c4009
   registers.
Packit 6c4009
Packit 6c4009
   Also, since we have plenty of registers we have two return values
Packit 6c4009
   from a syscall.  r10 is set to -1 on error, whilst r8 contains the
Packit 6c4009
   (non-negative) errno on error or the return value on success.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
#ifdef IA64_USE_NEW_STUB
Packit 6c4009
Packit 6c4009
# define DO_INLINE_SYSCALL_NCS(name, nr, args...)			      \
Packit 6c4009
    LOAD_ARGS_##nr (args)						      \
Packit 6c4009
    register long _r8 __asm ("r8");					      \
Packit 6c4009
    register long _r10 __asm ("r10");					      \
Packit 6c4009
    register long _r15 __asm ("r15") = name;				      \
Packit 6c4009
    register void *_b7 __asm ("b7") = ((tcbhead_t *)__thread_self)->__private;\
Packit 6c4009
    long _retval;							      \
Packit 6c4009
    LOAD_REGS_##nr							      \
Packit 6c4009
    /*									      \
Packit 6c4009
     * Don't specify any unwind info here.  We mark ar.pfs as		      \
Packit 6c4009
     * clobbered.  This will force the compiler to save ar.pfs		      \
Packit 6c4009
     * somewhere and emit appropriate unwind info for that save.	      \
Packit 6c4009
     */									      \
Packit 6c4009
    __asm __volatile ("br.call.sptk.many b6=%0;;\n"			      \
Packit 6c4009
		      : "=b"(_b7), "=r" (_r8), "=r" (_r10), "=r" (_r15)	      \
Packit 6c4009
			ASM_OUTARGS_##nr				      \
Packit 6c4009
		      : "0" (_b7), "3" (_r15) ASM_ARGS_##nr		      \
Packit 6c4009
		      : "memory", "ar.pfs" ASM_CLOBBERS_##nr);		      \
Packit 6c4009
    _retval = _r8;
Packit 6c4009
Packit 6c4009
#else /* !IA64_USE_NEW_STUB */
Packit 6c4009
Packit 6c4009
# define DO_INLINE_SYSCALL_NCS(name, nr, args...)		\
Packit 6c4009
    LOAD_ARGS_##nr (args)					\
Packit 6c4009
    register long _r8 asm ("r8");				\
Packit 6c4009
    register long _r10 asm ("r10");				\
Packit 6c4009
    register long _r15 asm ("r15") = name;			\
Packit 6c4009
    long _retval;						\
Packit 6c4009
    LOAD_REGS_##nr						\
Packit 6c4009
    __asm __volatile (BREAK_INSN (__BREAK_SYSCALL)		\
Packit 6c4009
		      : "=r" (_r8), "=r" (_r10), "=r" (_r15)	\
Packit 6c4009
			ASM_OUTARGS_##nr			\
Packit 6c4009
		      : "2" (_r15) ASM_ARGS_##nr		\
Packit 6c4009
		      : "memory" ASM_CLOBBERS_##nr);		\
Packit 6c4009
    _retval = _r8;
Packit 6c4009
Packit 6c4009
#endif /* !IA64_USE_NEW_STUB */
Packit 6c4009
Packit 6c4009
#define DO_INLINE_SYSCALL(name, nr, args...)	\
Packit 6c4009
  DO_INLINE_SYSCALL_NCS (__NR_##name, nr, ##args)
Packit 6c4009
Packit 6c4009
#undef INLINE_SYSCALL
Packit 6c4009
#define INLINE_SYSCALL(name, nr, args...)		\
Packit 6c4009
  ({							\
Packit 6c4009
    DO_INLINE_SYSCALL_NCS (__NR_##name, nr, args)	\
Packit 6c4009
    if (_r10 == -1)					\
Packit 6c4009
      {							\
Packit 6c4009
	__set_errno (_retval);				\
Packit 6c4009
	_retval = -1;					\
Packit 6c4009
      }							\
Packit 6c4009
    _retval; })
Packit 6c4009
Packit 6c4009
#undef INTERNAL_SYSCALL_DECL
Packit 6c4009
#define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused))
Packit 6c4009
Packit 6c4009
#undef INTERNAL_SYSCALL
Packit 6c4009
#define INTERNAL_SYSCALL_NCS(name, err, nr, args...)	\
Packit 6c4009
  ({							\
Packit 6c4009
    DO_INLINE_SYSCALL_NCS (name, nr, args)		\
Packit 6c4009
    err = _r10;						\
Packit 6c4009
    _retval; })
Packit 6c4009
#define INTERNAL_SYSCALL(name, err, nr, args...)	\
Packit 6c4009
  INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
Packit 6c4009
Packit 6c4009
#undef INTERNAL_SYSCALL_ERROR_P
Packit 6c4009
#define INTERNAL_SYSCALL_ERROR_P(val, err)		\
Packit 6c4009
  ({ (void) (val);					\
Packit 6c4009
     (err == -1);					\
Packit 6c4009
  })
Packit 6c4009
Packit 6c4009
#undef INTERNAL_SYSCALL_ERRNO
Packit 6c4009
#define INTERNAL_SYSCALL_ERRNO(val, err)	(val)
Packit 6c4009
Packit 6c4009
#define LOAD_ARGS_0()
Packit 6c4009
#define LOAD_REGS_0
Packit 6c4009
#define LOAD_ARGS_1(a1)					\
Packit 6c4009
  long _arg1 = (long) (a1);				\
Packit 6c4009
  LOAD_ARGS_0 ()
Packit 6c4009
#define LOAD_REGS_1					\
Packit 6c4009
  register long _out0 asm ("out0") = _arg1;		\
Packit 6c4009
  LOAD_REGS_0
Packit 6c4009
#define LOAD_ARGS_2(a1, a2)				\
Packit 6c4009
  long _arg2 = (long) (a2);				\
Packit 6c4009
  LOAD_ARGS_1 (a1)
Packit 6c4009
#define LOAD_REGS_2					\
Packit 6c4009
  register long _out1 asm ("out1") = _arg2;		\
Packit 6c4009
  LOAD_REGS_1
Packit 6c4009
#define LOAD_ARGS_3(a1, a2, a3)				\
Packit 6c4009
  long _arg3 = (long) (a3);				\
Packit 6c4009
  LOAD_ARGS_2 (a1, a2)
Packit 6c4009
#define LOAD_REGS_3					\
Packit 6c4009
  register long _out2 asm ("out2") = _arg3;		\
Packit 6c4009
  LOAD_REGS_2
Packit 6c4009
#define LOAD_ARGS_4(a1, a2, a3, a4)			\
Packit 6c4009
  long _arg4 = (long) (a4);				\
Packit 6c4009
  LOAD_ARGS_3 (a1, a2, a3)
Packit 6c4009
#define LOAD_REGS_4					\
Packit 6c4009
  register long _out3 asm ("out3") = _arg4;		\
Packit 6c4009
  LOAD_REGS_3
Packit 6c4009
#define LOAD_ARGS_5(a1, a2, a3, a4, a5)			\
Packit 6c4009
  long _arg5 = (long) (a5);				\
Packit 6c4009
  LOAD_ARGS_4 (a1, a2, a3, a4)
Packit 6c4009
#define LOAD_REGS_5					\
Packit 6c4009
  register long _out4 asm ("out4") = _arg5;		\
Packit 6c4009
  LOAD_REGS_4
Packit 6c4009
#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)		\
Packit 6c4009
  long _arg6 = (long) (a6);	    			\
Packit 6c4009
  LOAD_ARGS_5 (a1, a2, a3, a4, a5)
Packit 6c4009
#define LOAD_REGS_6					\
Packit 6c4009
  register long _out5 asm ("out5") = _arg6;		\
Packit 6c4009
  LOAD_REGS_5
Packit 6c4009
Packit 6c4009
#define ASM_OUTARGS_0
Packit 6c4009
#define ASM_OUTARGS_1	ASM_OUTARGS_0, "=r" (_out0)
Packit 6c4009
#define ASM_OUTARGS_2	ASM_OUTARGS_1, "=r" (_out1)
Packit 6c4009
#define ASM_OUTARGS_3	ASM_OUTARGS_2, "=r" (_out2)
Packit 6c4009
#define ASM_OUTARGS_4	ASM_OUTARGS_3, "=r" (_out3)
Packit 6c4009
#define ASM_OUTARGS_5	ASM_OUTARGS_4, "=r" (_out4)
Packit 6c4009
#define ASM_OUTARGS_6	ASM_OUTARGS_5, "=r" (_out5)
Packit 6c4009
Packit 6c4009
#ifdef IA64_USE_NEW_STUB
Packit 6c4009
#define ASM_ARGS_0
Packit 6c4009
#define ASM_ARGS_1	ASM_ARGS_0, "4" (_out0)
Packit 6c4009
#define ASM_ARGS_2	ASM_ARGS_1, "5" (_out1)
Packit 6c4009
#define ASM_ARGS_3	ASM_ARGS_2, "6" (_out2)
Packit 6c4009
#define ASM_ARGS_4	ASM_ARGS_3, "7" (_out3)
Packit 6c4009
#define ASM_ARGS_5	ASM_ARGS_4, "8" (_out4)
Packit 6c4009
#define ASM_ARGS_6	ASM_ARGS_5, "9" (_out5)
Packit 6c4009
#else
Packit 6c4009
#define ASM_ARGS_0
Packit 6c4009
#define ASM_ARGS_1	ASM_ARGS_0, "3" (_out0)
Packit 6c4009
#define ASM_ARGS_2	ASM_ARGS_1, "4" (_out1)
Packit 6c4009
#define ASM_ARGS_3	ASM_ARGS_2, "5" (_out2)
Packit 6c4009
#define ASM_ARGS_4	ASM_ARGS_3, "6" (_out3)
Packit 6c4009
#define ASM_ARGS_5	ASM_ARGS_4, "7" (_out4)
Packit 6c4009
#define ASM_ARGS_6	ASM_ARGS_5, "8" (_out5)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#define ASM_CLOBBERS_0	ASM_CLOBBERS_1, "out0"
Packit 6c4009
#define ASM_CLOBBERS_1	ASM_CLOBBERS_2, "out1"
Packit 6c4009
#define ASM_CLOBBERS_2	ASM_CLOBBERS_3, "out2"
Packit 6c4009
#define ASM_CLOBBERS_3	ASM_CLOBBERS_4, "out3"
Packit 6c4009
#define ASM_CLOBBERS_4	ASM_CLOBBERS_5, "out4"
Packit 6c4009
#define ASM_CLOBBERS_5	ASM_CLOBBERS_6, "out5"
Packit 6c4009
#define ASM_CLOBBERS_6_COMMON	, "out6", "out7",			\
Packit 6c4009
  /* Non-stacked integer registers, minus r8, r10, r15.  */		\
Packit 6c4009
  "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18",	\
Packit 6c4009
  "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27",	\
Packit 6c4009
  "r28", "r29", "r30", "r31",						\
Packit 6c4009
  /* Predicate registers.  */						\
Packit 6c4009
  "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",	\
Packit 6c4009
  /* Non-rotating fp registers.  */					\
Packit 6c4009
  "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",	\
Packit 6c4009
  /* Branch registers.  */						\
Packit 6c4009
  "b6"
Packit 6c4009
Packit 6c4009
#ifdef IA64_USE_NEW_STUB
Packit 6c4009
# define ASM_CLOBBERS_6	ASM_CLOBBERS_6_COMMON
Packit 6c4009
#else
Packit 6c4009
# define ASM_CLOBBERS_6	ASM_CLOBBERS_6_COMMON , "b7"
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#endif /* not __ASSEMBLER__ */
Packit 6c4009
Packit 6c4009
/* Pointer mangling support.  */
Packit 6c4009
#if IS_IN (rtld)
Packit 6c4009
/* We cannot use the thread descriptor because in ld.so we use setjmp
Packit 6c4009
   earlier than the descriptor is initialized.  */
Packit 6c4009
#else
Packit 6c4009
# ifdef __ASSEMBLER__
Packit 6c4009
#  define PTR_MANGLE(reg, tmpreg) \
Packit 6c4009
        add	tmpreg=-16,r13		\
Packit 6c4009
        ;;				\
Packit 6c4009
        ld8	tmpreg=[tmpreg]		\
Packit 6c4009
        ;;				\
Packit 6c4009
        xor	reg=reg, tmpreg
Packit 6c4009
#  define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg)
Packit 6c4009
# else
Packit 6c4009
#  define PTR_MANGLE(var) \
Packit 6c4009
  (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
Packit 6c4009
#  define PTR_DEMANGLE(var)	PTR_MANGLE (var)
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#endif /* linux/ia64/sysdep.h */