syscalls.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (C) 2026 Waldemar Brodkorb <wbx@uclibc-ng.org>
  3. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  4. */
  5. /* Assembly macros for LoongArch.
  6. Copyright (C) 2022-2026 Free Software Foundation, Inc.
  7. The GNU C Library is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The GNU C Library is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. Lesser General Public License for more details.
  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. <https://www.gnu.org/licenses/>. */
  18. #include <sys/regdef.h>
  19. #define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
  20. internal_syscall##nr (number, err, args)
  21. #define internal_syscall0(number, err, dummy...) \
  22. ({ \
  23. long int _sys_result; \
  24. \
  25. { \
  26. register long int __a7 __asm__ ("$a7") = number; \
  27. register long int __a0 __asm__ ("$a0"); \
  28. __asm__ volatile ("syscall 0\n\t" \
  29. : "=r"(__a0) \
  30. : "r"(__a7) \
  31. : __SYSCALL_CLOBBERS); \
  32. _sys_result = __a0; \
  33. } \
  34. _sys_result; \
  35. })
  36. #define internal_syscall1(number, err, arg0) \
  37. ({ \
  38. long int _sys_result; \
  39. \
  40. { \
  41. long int _arg0 = (long int) (arg0); \
  42. register long int __a7 __asm__ ("$a7") = number; \
  43. register long int __a0 __asm__ ("$a0") = _arg0; \
  44. __asm__ volatile ("syscall 0\n\t" \
  45. : "+r"(__a0) \
  46. : "r"(__a7) \
  47. : __SYSCALL_CLOBBERS); \
  48. _sys_result = __a0; \
  49. } \
  50. _sys_result; \
  51. })
  52. #define internal_syscall2(number, err, arg0, arg1) \
  53. ({ \
  54. long int _sys_result; \
  55. \
  56. { \
  57. long int _arg0 = (long int) (arg0); \
  58. long int _arg1 = (long int) (arg1); \
  59. register long int __a7 __asm__ ("$a7") = number; \
  60. register long int __a0 __asm__ ("$a0") = _arg0; \
  61. register long int __a1 __asm__ ("$a1") = _arg1; \
  62. __asm__ volatile ("syscall 0\n\t" \
  63. : "+r"(__a0) \
  64. : "r"(__a7), "r"(__a1) \
  65. : __SYSCALL_CLOBBERS); \
  66. _sys_result = __a0; \
  67. } \
  68. _sys_result; \
  69. })
  70. #define internal_syscall3(number, err, arg0, arg1, arg2) \
  71. ({ \
  72. long int _sys_result; \
  73. \
  74. { \
  75. long int _arg0 = (long int) (arg0); \
  76. long int _arg1 = (long int) (arg1); \
  77. long int _arg2 = (long int) (arg2); \
  78. register long int __a7 __asm__ ("$a7") = number; \
  79. register long int __a0 __asm__ ("$a0") = _arg0; \
  80. register long int __a1 __asm__ ("$a1") = _arg1; \
  81. register long int __a2 __asm__ ("$a2") = _arg2; \
  82. __asm__ volatile ("syscall 0\n\t" \
  83. : "+r"(__a0) \
  84. : "r"(__a7), "r"(__a1), "r"(__a2) \
  85. : __SYSCALL_CLOBBERS); \
  86. _sys_result = __a0; \
  87. } \
  88. _sys_result; \
  89. })
  90. #define internal_syscall4(number, err, arg0, arg1, arg2, arg3) \
  91. ({ \
  92. long int _sys_result; \
  93. \
  94. { \
  95. long int _arg0 = (long int) (arg0); \
  96. long int _arg1 = (long int) (arg1); \
  97. long int _arg2 = (long int) (arg2); \
  98. long int _arg3 = (long int) (arg3); \
  99. register long int __a7 __asm__ ("$a7") = number; \
  100. register long int __a0 __asm__ ("$a0") = _arg0; \
  101. register long int __a1 __asm__ ("$a1") = _arg1; \
  102. register long int __a2 __asm__ ("$a2") = _arg2; \
  103. register long int __a3 __asm__ ("$a3") = _arg3; \
  104. __asm__ volatile ("syscall 0\n\t" \
  105. : "+r"(__a0) \
  106. : "r"(__a7), "r"(__a1), "r"(__a2), "r"(__a3) \
  107. : __SYSCALL_CLOBBERS); \
  108. _sys_result = __a0; \
  109. } \
  110. _sys_result; \
  111. })
  112. #define internal_syscall5(number, err, arg0, arg1, arg2, arg3, arg4) \
  113. ({ \
  114. long int _sys_result; \
  115. \
  116. { \
  117. long int _arg0 = (long int) (arg0); \
  118. long int _arg1 = (long int) (arg1); \
  119. long int _arg2 = (long int) (arg2); \
  120. long int _arg3 = (long int) (arg3); \
  121. long int _arg4 = (long int) (arg4); \
  122. register long int __a7 __asm__ ("$a7") = number; \
  123. register long int __a0 __asm__ ("$a0") = _arg0; \
  124. register long int __a1 __asm__ ("$a1") = _arg1; \
  125. register long int __a2 __asm__ ("$a2") = _arg2; \
  126. register long int __a3 __asm__ ("$a3") = _arg3; \
  127. register long int __a4 __asm__ ("$a4") = _arg4; \
  128. __asm__ volatile ("syscall 0\n\t" \
  129. : "+r"(__a0) \
  130. : "r"(__a7), "r"(__a1), "r"(__a2), \
  131. "r"(__a3), "r"(__a4) \
  132. : __SYSCALL_CLOBBERS); \
  133. _sys_result = __a0; \
  134. } \
  135. _sys_result; \
  136. })
  137. #define internal_syscall6(number, err, arg0, arg1, arg2, arg3, arg4, arg5) \
  138. ({ \
  139. long int _sys_result; \
  140. \
  141. { \
  142. long int _arg0 = (long int) (arg0); \
  143. long int _arg1 = (long int) (arg1); \
  144. long int _arg2 = (long int) (arg2); \
  145. long int _arg3 = (long int) (arg3); \
  146. long int _arg4 = (long int) (arg4); \
  147. long int _arg5 = (long int) (arg5); \
  148. register long int __a7 __asm__ ("$a7") = number; \
  149. register long int __a0 __asm__ ("$a0") = _arg0; \
  150. register long int __a1 __asm__ ("$a1") = _arg1; \
  151. register long int __a2 __asm__ ("$a2") = _arg2; \
  152. register long int __a3 __asm__ ("$a3") = _arg3; \
  153. register long int __a4 __asm__ ("$a4") = _arg4; \
  154. register long int __a5 __asm__ ("$a5") = _arg5; \
  155. __asm__ volatile ("syscall 0\n\t" \
  156. : "+r"(__a0) \
  157. : "r"(__a7), "r"(__a1), "r"(__a2), "r"(__a3), \
  158. "r"(__a4), "r"(__a5) \
  159. : __SYSCALL_CLOBBERS); \
  160. _sys_result = __a0; \
  161. } \
  162. _sys_result; \
  163. })
  164. #define internal_syscall7(number, err, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
  165. ({ \
  166. long int _sys_result; \
  167. \
  168. { \
  169. long int _arg0 = (long int) (arg0); \
  170. long int _arg1 = (long int) (arg1); \
  171. long int _arg2 = (long int) (arg2); \
  172. long int _arg3 = (long int) (arg3); \
  173. long int _arg4 = (long int) (arg4); \
  174. long int _arg5 = (long int) (arg5); \
  175. long int _arg6 = (long int) (arg6); \
  176. register long int __a7 __asm__ ("$a7") = number; \
  177. register long int __a0 __asm__ ("$a0") = _arg0; \
  178. register long int __a1 __asm__ ("$a1") = _arg1; \
  179. register long int __a2 __asm__ ("$a2") = _arg2; \
  180. register long int __a3 __asm__ ("$a3") = _arg3; \
  181. register long int __a4 __asm__ ("$a4") = _arg4; \
  182. register long int __a5 __asm__ ("$a5") = _arg5; \
  183. register long int __a6 __asm__ ("$a6") = _arg6; \
  184. __asm__ volatile ("syscall 0\n\t" \
  185. : "+r"(__a0) \
  186. : "r"(__a7), "r"(__a1), "r"(__a2), "r"(__a3), \
  187. "r"(__a4), "r"(__a5), "r"(__a6) \
  188. : __SYSCALL_CLOBBERS); \
  189. _sys_result = __a0; \
  190. } \
  191. _sys_result; \
  192. })
  193. #define __SYSCALL_CLOBBERS \
  194. "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"