sysdep.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #ifndef _LINUX_XTENSA_SYSDEP_H
  16. #define _LINUX_XTENSA_SYSDEP_H 1
  17. #include <common/sysdep.h>
  18. #include <sys/syscall.h>
  19. #ifdef __ASSEMBLER__
  20. #define ALIGNARG(log2) 1 << log2
  21. #define ASM_TYPE_DIRECTIVE(name, typearg) .type name, typearg
  22. #define ASM_SIZE_DIRECTIVE(name) .size name, . - name
  23. #if defined(__XTENSA_WINDOWED_ABI__)
  24. #define abi_entry(reg, frame_size) entry reg, frame_size
  25. #define abi_ret retw
  26. #elif defined(__XTENSA_CALL0_ABI__)
  27. #define abi_entry(reg, frame_size)
  28. #define abi_ret ret
  29. #else
  30. #error Unsupported Xtensa ABI
  31. #endif
  32. #define ENTRY_PREFIX(name) \
  33. .globl C_SYMBOL_NAME(name); \
  34. ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function); \
  35. .align ALIGNARG(2); \
  36. LITERAL_POSITION; \
  37. C_LABEL(name)
  38. #define ENTRY(name) \
  39. ENTRY_PREFIX(name) \
  40. abi_entry(sp, FRAMESIZE);
  41. #define HIDDEN_ENTRY(name) \
  42. .globl C_SYMBOL_NAME(name); \
  43. .hidden C_SYMBOL_NAME(name); \
  44. ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function); \
  45. .align ALIGNARG(2); \
  46. LITERAL_POSITION; \
  47. C_LABEL(name) \
  48. abi_entry(sp, FRAMESIZE);
  49. #undef END
  50. #define END(name) ASM_SIZE_DIRECTIVE(name)
  51. /* Local label name for asm code. */
  52. #ifndef L
  53. # ifdef HAVE_ELF
  54. # define L(name) .L##name
  55. # else
  56. # define L(name) name
  57. # endif
  58. #endif
  59. /* Define a macro for this directive so it can be removed in a few places. */
  60. #define LITERAL_POSITION .literal_position
  61. #undef JUMPTARGET
  62. #if defined(__FDPIC__)
  63. #define JUMPTARGET(name) name##@GOTOFFFUNCDESC
  64. #define FDPIC_LOAD_FUNCDESC(call_target, funcdesc) \
  65. l32i a11, funcdesc, 4; \
  66. l32i call_target, funcdesc, 0
  67. #define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)\
  68. add call_target, got_base, jumptarget; \
  69. FDPIC_LOAD_FUNCDESC(call_target, call_target)
  70. #elif defined(__PIC__)
  71. /* The "@PLT" suffix is currently a no-op for non-shared linking, but
  72. it doesn't hurt to use it conditionally for PIC code in case that
  73. changes someday. */
  74. #define JUMPTARGET(name) name##@PLT
  75. #define FDPIC_LOAD_FUNCDESC(call_target, funcdesc)
  76. #define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)
  77. #else
  78. #define JUMPTARGET(name) name
  79. #define FDPIC_LOAD_FUNCDESC(call_target, funcdesc)
  80. #define FDPIC_LOAD_JUMPTARGET(call_target, got_base, jumptarget)
  81. #endif
  82. #ifndef FRAMESIZE
  83. #if defined(__XTENSA_WINDOWED_ABI__)
  84. #define FRAMESIZE 16
  85. #elif defined(__XTENSA_CALL0_ABI__)
  86. #define FRAMESIZE 0
  87. #else
  88. #error Unsupported Xtensa ABI
  89. #endif
  90. #endif
  91. /* Linux uses a negative return value to indicate syscall errors,
  92. unlike most Unices, which use the condition codes' carry flag.
  93. Since version 2.1 the return value of a system call might be
  94. negative even if the call succeeded. E.g., the `lseek' system call
  95. might return a large offset. Therefore we must not anymore test
  96. for < 0, but test for a real error by making sure the value in a2
  97. is a real error number. Linus said he will make sure the no syscall
  98. returns a value in -1 .. -4095 as a valid result so we can safely
  99. test with -4095. */
  100. /* We don't want the label for the error handler to be global when we define
  101. it here. */
  102. #define SYSCALL_ERROR_LABEL 0f
  103. #undef PSEUDO
  104. #define PSEUDO(name, syscall_name, args) \
  105. .text; \
  106. ENTRY (name) \
  107. DO_CALL (syscall_name, args); \
  108. movi a4, -4095; \
  109. bgeu a2, a4, SYSCALL_ERROR_LABEL; \
  110. .Lpseudo_end:
  111. #undef PSEUDO_END
  112. #define PSEUDO_END(name) \
  113. SYSCALL_ERROR_HANDLER \
  114. END (name)
  115. #undef PSEUDO_NOERRNO
  116. #define PSEUDO_NOERRNO(name, syscall_name, args) \
  117. .text; \
  118. ENTRY (name) \
  119. DO_CALL (syscall_name, args)
  120. #undef PSEUDO_END_NOERRNO
  121. #define PSEUDO_END_NOERRNO(name) \
  122. END (name)
  123. #undef ret_NOERRNO
  124. #define ret_NOERRNO abi_ret
  125. /* The function has to return the error code. */
  126. #undef PSEUDO_ERRVAL
  127. #define PSEUDO_ERRVAL(name, syscall_name, args) \
  128. .text; \
  129. ENTRY (name) \
  130. DO_CALL (syscall_name, args); \
  131. neg a2, a2
  132. #undef PSEUDO_END_ERRVAL
  133. #define PSEUDO_END_ERRVAL(name) \
  134. END (name)
  135. #undef ret_ERRVAL
  136. #define ret_ERRVAL abi_ret
  137. #if defined _LIBC_REENTRANT
  138. # if defined USE___THREAD
  139. #ifdef __FDPIC__
  140. # define SYSCALL_ERROR_ERRNO errno
  141. # define SYSCALL_ERROR_HANDLER \
  142. 0: rur a4, THREADPTR; \
  143. movi a3, SYSCALL_ERROR_ERRNO@GOTTPOFF; \
  144. .reloc ., R_XTENSA_TLS_TPOFF_PTR, SYSCALL_ERROR_ERRNO; \
  145. add a3, a3, a11; \
  146. .reloc ., R_XTENSA_TLS_TPOFF_LOAD, SYSCALL_ERROR_ERRNO; \
  147. l32i a3, a3, 0; \
  148. neg a2, a2; \
  149. add a4, a4, a3; \
  150. s32i a2, a4, 0; \
  151. movi a2, -1; \
  152. j .Lpseudo_end;
  153. #else
  154. # define SYSCALL_ERROR_ERRNO errno
  155. # define SYSCALL_ERROR_HANDLER \
  156. 0: rur a4, THREADPTR; \
  157. movi a3, SYSCALL_ERROR_ERRNO@TPOFF; \
  158. neg a2, a2; \
  159. add a4, a4, a3; \
  160. s32i a2, a4, 0; \
  161. movi a2, -1; \
  162. j .Lpseudo_end;
  163. #endif
  164. # else /* !USE___THREAD */
  165. #if defined(__XTENSA_WINDOWED_ABI__)
  166. # define SYSCALL_ERROR_HANDLER \
  167. 0: neg a2, a2; \
  168. mov a6, a2; \
  169. movi a4, JUMPTARGET(__errno_location); \
  170. callx4 a4; \
  171. s32i a2, a6, 0; \
  172. movi a2, -1; \
  173. j .Lpseudo_end;
  174. #elif defined(__XTENSA_CALL0_ABI__)
  175. # define SYSCALL_ERROR_HANDLER \
  176. 0: neg a2, a2; \
  177. addi a1, a1, -16; \
  178. s32i a0, a1, 0; \
  179. s32i a2, a1, 4; \
  180. movi a0, JUMPTARGET(__errno_location); \
  181. FDPIC_LOAD_JUMPTARGET(a0, a11, a0); \
  182. callx0 a0; \
  183. l32i a0, a1, 0; \
  184. l32i a3, a1, 4; \
  185. addi a1, a1, 16; \
  186. s32i a3, a2, 0; \
  187. movi a2, -1; \
  188. j .Lpseudo_end;
  189. #else
  190. #error Unsupported Xtensa ABI
  191. #endif
  192. # endif /* !USE___THREAD */
  193. #else /* !_LIBC_REENTRANT */
  194. #ifdef __FDPIC__
  195. #define SYSCALL_ERROR_HANDLER \
  196. 0: movi a4, errno@GOT; \
  197. add a4, a4, a11; \
  198. l32i a4, a4, 0; \
  199. neg a2, a2; \
  200. s32i a2, a4, 0; \
  201. movi a2, -1; \
  202. j .Lpseudo_end;
  203. #else
  204. #define SYSCALL_ERROR_HANDLER \
  205. 0: movi a4, errno; \
  206. neg a2, a2; \
  207. s32i a2, a4, 0; \
  208. movi a2, -1; \
  209. j .Lpseudo_end;
  210. #endif /* __FDPIC__ */
  211. #endif /* _LIBC_REENTRANT */
  212. #endif /* __ASSEMBLER__ */
  213. #endif /* _LINUX_XTENSA_SYSDEP_H */