sysdep.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. #define ENTRY(name) \
  24. ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
  25. ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function); \
  26. .align ALIGNARG(2); \
  27. LITERAL_POSITION; \
  28. C_LABEL(name) \
  29. entry sp, FRAMESIZE; \
  30. CALL_MCOUNT
  31. #define HIDDEN_ENTRY(name) \
  32. ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
  33. .hidden 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. entry sp, FRAMESIZE; \
  39. CALL_MCOUNT
  40. #undef END
  41. #define END(name) ASM_SIZE_DIRECTIVE(name)
  42. /* Local label name for asm code. */
  43. #ifndef L
  44. # ifdef HAVE_ELF
  45. # define L(name) .L##name
  46. # else
  47. # define L(name) name
  48. # endif
  49. #endif
  50. /* Define a macro for this directive so it can be removed in a few places. */
  51. #define LITERAL_POSITION .literal_position
  52. #undef JUMPTARGET
  53. #ifdef __PIC__
  54. /* The "@PLT" suffix is currently a no-op for non-shared linking, but
  55. it doesn't hurt to use it conditionally for PIC code in case that
  56. changes someday. */
  57. #define JUMPTARGET(name) name##@PLT
  58. #else
  59. #define JUMPTARGET(name) name
  60. #endif
  61. #ifndef FRAMESIZE
  62. #define FRAMESIZE 16
  63. #endif
  64. #define CALL_MCOUNT /* Do nothing. */
  65. /* Linux uses a negative return value to indicate syscall errors,
  66. unlike most Unices, which use the condition codes' carry flag.
  67. Since version 2.1 the return value of a system call might be
  68. negative even if the call succeeded. E.g., the `lseek' system call
  69. might return a large offset. Therefore we must not anymore test
  70. for < 0, but test for a real error by making sure the value in a2
  71. is a real error number. Linus said he will make sure the no syscall
  72. returns a value in -1 .. -4095 as a valid result so we can safely
  73. test with -4095. */
  74. /* We don't want the label for the error handler to be global when we define
  75. it here. */
  76. #define SYSCALL_ERROR_LABEL 0f
  77. #undef PSEUDO
  78. #define PSEUDO(name, syscall_name, args) \
  79. .text; \
  80. ENTRY (name) \
  81. DO_CALL (syscall_name, args); \
  82. movi a4, -4095; \
  83. bgeu a2, a4, SYSCALL_ERROR_LABEL; \
  84. .Lpseudo_end:
  85. #undef PSEUDO_END
  86. #define PSEUDO_END(name) \
  87. SYSCALL_ERROR_HANDLER \
  88. END (name)
  89. #undef PSEUDO_NOERRNO
  90. #define PSEUDO_NOERRNO(name, syscall_name, args) \
  91. .text; \
  92. ENTRY (name) \
  93. DO_CALL (syscall_name, args)
  94. #undef PSEUDO_END_NOERRNO
  95. #define PSEUDO_END_NOERRNO(name) \
  96. END (name)
  97. #undef ret_NOERRNO
  98. #define ret_NOERRNO retw
  99. /* The function has to return the error code. */
  100. #undef PSEUDO_ERRVAL
  101. #define PSEUDO_ERRVAL(name, syscall_name, args) \
  102. .text; \
  103. ENTRY (name) \
  104. DO_CALL (syscall_name, args); \
  105. neg a2, a2
  106. #undef PSEUDO_END_ERRVAL
  107. #define PSEUDO_END_ERRVAL(name) \
  108. END (name)
  109. #undef ret_ERRVAL
  110. #define ret_ERRVAL retw
  111. #if defined _LIBC_REENTRANT
  112. # if defined USE___THREAD
  113. # ifndef NOT_IN_libc
  114. # define SYSCALL_ERROR_ERRNO __libc_errno
  115. # else
  116. # define SYSCALL_ERROR_ERRNO errno
  117. # endif
  118. # define SYSCALL_ERROR_HANDLER \
  119. 0: rur a4, THREADPTR; \
  120. movi a3, SYSCALL_ERROR_ERRNO@TPOFF; \
  121. neg a2, a2; \
  122. add a4, a4, a3; \
  123. s32i a2, a4, 0; \
  124. movi a2, -1; \
  125. j .Lpseudo_end;
  126. # else /* !USE___THREAD */
  127. # define SYSCALL_ERROR_HANDLER \
  128. 0: neg a2, a2; \
  129. mov a6, a2; \
  130. movi a4, __errno_location@PLT; \
  131. callx4 a4; \
  132. s32i a2, a6, 0; \
  133. movi a2, -1; \
  134. j .Lpseudo_end;
  135. # endif /* !USE___THREAD */
  136. #else /* !_LIBC_REENTRANT */
  137. #define SYSCALL_ERROR_HANDLER \
  138. 0: movi a4, errno; \
  139. neg a2, a2; \
  140. s32i a2, a4, 0; \
  141. movi a2, -1; \
  142. j .Lpseudo_end;
  143. #endif /* _LIBC_REENTRANT */
  144. #endif /* __ASSEMBLER__ */
  145. /* Pointer mangling is not yet supported for Xtensa. */
  146. #define PTR_MANGLE(var) (void) (var)
  147. #define PTR_DEMANGLE(var) (void) (var)
  148. #endif /* _LINUX_XTENSA_SYSDEP_H */