OSDN Git Service

Replace FSF snail mail address with URLs
[uclinux-h8/uClibc.git] / libc / sysdeps / linux / xtensa / sysdep.h
1 /* Assembler macros for Xtensa processors.
2    Copyright (C) 2001, 2007 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <sys/syscall.h>
20
21 #ifdef __ASSEMBLER__
22
23 #define ALIGNARG(log2) 1 << log2
24 #define ASM_TYPE_DIRECTIVE(name, typearg) .type name, typearg
25 #define ASM_SIZE_DIRECTIVE(name) .size name, . - name
26
27 #ifdef __STDC__
28 #define C_LABEL(name)   name :
29 #else
30 #define C_LABEL(name)   name/**/:
31 #endif
32
33 #define ENTRY(name)                                                     \
34   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);                             \
35   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function);                  \
36   .align ALIGNARG(2);                                                   \
37   LITERAL_POSITION;                                                     \
38   C_LABEL(name)                                                         \
39   entry sp, FRAMESIZE;                                                  \
40   CALL_MCOUNT
41
42 #define HIDDEN_ENTRY(name)                                              \
43   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);                             \
44   .hidden C_SYMBOL_NAME(name);                                          \
45   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function);                  \
46   .align ALIGNARG(2);                                                   \
47   LITERAL_POSITION;                                                     \
48   C_LABEL(name)                                                         \
49   entry sp, FRAMESIZE;                                                  \
50   CALL_MCOUNT
51
52 #undef END
53 #define END(name) ASM_SIZE_DIRECTIVE(name)
54
55 /* Define a macro for this directive so it can be removed in a few places.  */
56 #define LITERAL_POSITION .literal_position
57
58 #undef JUMPTARGET
59 #ifdef __PIC__
60 /* The "@PLT" suffix is currently a no-op for non-shared linking, but
61    it doesn't hurt to use it conditionally for PIC code in case that
62    changes someday.  */
63 #define JUMPTARGET(name) name##@PLT
64 #else
65 #define JUMPTARGET(name) name
66 #endif
67
68 #define FRAMESIZE 16
69 #define CALL_MCOUNT             /* Do nothing.  */
70
71
72 /* Linux uses a negative return value to indicate syscall errors,
73    unlike most Unices, which use the condition codes' carry flag.
74
75    Since version 2.1 the return value of a system call might be
76    negative even if the call succeeded.  E.g., the `lseek' system call
77    might return a large offset.  Therefore we must not anymore test
78    for < 0, but test for a real error by making sure the value in a2
79    is a real error number.  Linus said he will make sure the no syscall
80    returns a value in -1 .. -4095 as a valid result so we can safely
81    test with -4095.  */
82
83 /* We don't want the label for the error handler to be global when we define
84    it here.  */
85 #define SYSCALL_ERROR_LABEL 0f
86
87 #undef  PSEUDO
88 #define PSEUDO(name, syscall_name, args)                                      \
89   .text;                                                                      \
90   ENTRY (name)                                                                \
91         DO_CALL (syscall_name, args);                                         \
92         movi    a4, -4095;                                                    \
93         bgeu    a2, a4, SYSCALL_ERROR_LABEL;                                  \
94   .Lpseudo_end:
95
96 #undef  PSEUDO_END
97 #define PSEUDO_END(name)                                                      \
98   SYSCALL_ERROR_HANDLER                                                       \
99   END (name)
100
101 #undef  PSEUDO_NOERRNO
102 #define PSEUDO_NOERRNO(name, syscall_name, args)                              \
103   .text;                                                                      \
104   ENTRY (name)                                                                \
105         DO_CALL (syscall_name, args)
106
107 #undef  PSEUDO_END_NOERRNO
108 #define PSEUDO_END_NOERRNO(name)                                              \
109   END (name)
110
111 #undef  ret_NOERRNO
112 #define ret_NOERRNO retw
113
114 /* The function has to return the error code.  */
115 #undef  PSEUDO_ERRVAL
116 #define PSEUDO_ERRVAL(name, syscall_name, args)                               \
117   .text;                                                                      \
118   ENTRY (name)                                                                \
119         DO_CALL (syscall_name, args);                                         \
120         neg     a2, a2
121
122 #undef  PSEUDO_END_ERRVAL
123 #define PSEUDO_END_ERRVAL(name)                                               \
124   END (name)
125
126 #define ret_ERRVAL retw
127
128 #if defined RTLD_PRIVATE_ERRNO
129 # define SYSCALL_ERROR_HANDLER                                                \
130 0:      movi    a4, rtld_errno;                                               \
131         neg     a2, a2;                                                       \
132         s32i    a2, a4, 0;                                                    \
133         movi    a2, -1;                                                       \
134         j       .Lpseudo_end;
135
136 #elif defined _LIBC_REENTRANT
137
138 # if defined USE___THREAD
139 #  ifndef NOT_IN_libc
140 #   define SYSCALL_ERROR_ERRNO __libc_errno
141 #  else
142 #   define SYSCALL_ERROR_ERRNO errno
143 #  endif
144 #  define SYSCALL_ERROR_HANDLER                                               \
145 0:      rur     a4, THREADPTR;                                                \
146         movi    a3, SYSCALL_ERROR_ERRNO@TPOFF;                                \
147         neg     a2, a2;                                                       \
148         add     a4, a4, a3;                                                   \
149         s32i    a2, a4, 0;                                                    \
150         movi    a2, -1;                                                       \
151         j       .Lpseudo_end;
152 # else /* !USE___THREAD */
153 #  define SYSCALL_ERROR_HANDLER                                               \
154 0:      neg     a2, a2;                                                       \
155         mov     a6, a2;                                                       \
156         movi    a4, __errno_location@PLT;                                     \
157         callx4  a4;                                                           \
158         s32i    a2, a6, 0;                                                    \
159         movi    a2, -1;                                                       \
160         j       .Lpseudo_end;
161 # endif /* !USE___THREAD */
162 #else /* !_LIBC_REENTRANT */
163 #define SYSCALL_ERROR_HANDLER                                                 \
164 0:      movi    a4, errno;                                                    \
165         neg     a2, a2;                                                       \
166         s32i    a2, a4, 0;                                                    \
167         movi    a2, -1;                                                       \
168         j       .Lpseudo_end;
169 #endif /* _LIBC_REENTRANT */
170
171 #endif  /* __ASSEMBLER__ */