Update.
[platform/upstream/glibc.git] / sysdeps / unix / sysv / linux / powerpc / sysdep.h
1 /* Copyright (C) 1992, 1997 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #include <sysdeps/unix/sysdep.h>
20
21 /* For Linux we can use the system call table in the header file
22         /usr/include/asm/unistd.h
23    of the kernel.  But these symbols do not follow the SYS_* syntax
24    so we have to redefine the `SYS_ify' macro here.  */
25 #undef SYS_ify
26 #ifdef __STDC__
27 # define SYS_ify(syscall_name)  __NR_##syscall_name
28 #else
29 # define SYS_ify(syscall_name)  __NR_/**/syscall_name
30 #endif
31
32 #ifdef ASSEMBLER
33
34 /* This seems to always be the case on PPC.  */
35 #define ALIGNARG(log2) log2
36 /* For ELF we need the `.type' directive to make shared libs work right.  */
37 #define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
38 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name
39
40 /* If compiled for profiling, call `_mcount' at the start of each function.  */
41 #ifdef  PROF
42 /* The mcount code relies on a the return address being on the stack
43    to locate our caller and so it can restore it; so store one just
44    for its benefit.  */
45 #ifdef PIC
46 #define CALL_MCOUNT                                                           \
47   .pushsection;                                                               \
48   .section ".data";                                                           \
49   .align ALIGNARG(2);                                                         \
50 0:.long 0;                                                                    \
51   .previous;                                                                  \
52   mflr  %r0;                                                                  \
53   stw   %r0,4(%r1);                                                           \
54   bl    _GLOBAL_OFFSET_TABLE_@local-4;                                        \
55   mflr  %r11;                                                                 \
56   lwz   %r0,0b@got(%r11);                                                     \
57   bl    JUMPTARGET(_mcount);
58 #else  /* PIC */
59 #define CALL_MCOUNT                                                           \
60   .section ".data";                                                           \
61   .align ALIGNARG(2);                                                         \
62 0:.long 0;                                                                    \
63   .previous;                                                                  \
64   mflr  %r0;                                                                  \
65   lis   %r11,0b@ha;                                                           \
66   stw   %r0,4(%r1);                                                           \
67   addi  %r0,%r11,0b@l;                                                        \
68   bl    JUMPTARGET(_mcount);
69 #endif /* PIC */
70 #else  /* PROF */
71 #define CALL_MCOUNT             /* Do nothing.  */
72 #endif /* PROF */
73
74 #define ENTRY(name)                                                           \
75   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);                                   \
76   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)                          \
77   .align ALIGNARG(2);                                                         \
78   C_LABEL(name)                                                               \
79   CALL_MCOUNT
80
81 #define EALIGN_W_0  /* No words to insert.  */
82 #define EALIGN_W_1  nop
83 #define EALIGN_W_2  nop;nop
84 #define EALIGN_W_3  nop;nop;nop
85 #define EALIGN_W_4  EALIGN_W_3;nop
86 #define EALIGN_W_5  EALIGN_W_4;nop
87 #define EALIGN_W_6  EALIGN_W_5;nop
88 #define EALIGN_W_7  EALIGN_W_6;nop
89
90 /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
91    past a 2^align boundary.  */
92 #ifdef PROF
93 #define EALIGN(name, alignt, words)                                           \
94   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);                                   \
95   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)                          \
96   .align ALIGNARG(2);                                                         \
97   C_LABEL(name)                                                               \
98   CALL_MCOUNT                                                                 \
99   b 0f;                                                                       \
100   .align ALIGNARG(alignt);                                                    \
101   EALIGN_W_##words;                                                           \
102   0:
103 #else /* PROF */
104 #define EALIGN(name, alignt, words)                                           \
105   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);                                   \
106   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)                          \
107   .align ALIGNARG(alignt);                                                    \
108   EALIGN_W_##words;                                                           \
109   C_LABEL(name)
110 #endif
111
112 #undef  END
113 #define END(name)                                                             \
114   ASM_SIZE_DIRECTIVE(name)
115
116 #define DO_CALL(syscall)                                                      \
117     li 0,syscall;                                                             \
118     sc
119
120 #ifdef PIC
121 #define JUMPTARGET(name) name##@plt
122 #else
123 #define JUMPTARGET(name) name
124 #endif
125
126 #define PSEUDO(name, syscall_name, args)                                      \
127   .section ".text";                                                           \
128   ENTRY (name)                                                                \
129     DO_CALL (SYS_ify (syscall_name));
130
131 #define PSEUDO_RET                                                            \
132     bnslr;                                                                    \
133     b JUMPTARGET(__syscall_error)
134 #define ret PSEUDO_RET
135
136 #undef  PSEUDO_END
137 #define PSEUDO_END(name)                                                      \
138   END (name)
139
140 /* Local labels stripped out by the linker.  */
141 #define L(x) .L##x
142
143 #endif  /* ASSEMBLER */