sysdep.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright (C) 2016-2017 Andes Technology, Inc.
  3. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  4. */
  5. #ifndef _LINUX_NDS32_SYSDEP_H
  6. #define _LINUX_NDS32_SYSDEP_H 1
  7. #include <common/sysdep.h>
  8. #ifdef __ASSEMBLER__
  9. /* Define an entry point visible from C. */
  10. # ifdef PIC
  11. # define ENTRY(name) \
  12. .pic \
  13. .align 2; \
  14. .globl C_SYMBOL_NAME(name); \
  15. .func C_SYMBOL_NAME(name); \
  16. .type C_SYMBOL_NAME(name), @function; \
  17. C_SYMBOL_NAME(name): \
  18. cfi_startproc;
  19. # else
  20. # define ENTRY(name) \
  21. .align 2; \
  22. .globl C_SYMBOL_NAME(name); \
  23. .func C_SYMBOL_NAME(name); \
  24. .type C_SYMBOL_NAME(name), @function; \
  25. C_SYMBOL_NAME(name): \
  26. cfi_startproc;
  27. # endif
  28. #undef END
  29. #define END(name) \
  30. cfi_endproc; \
  31. .endfunc; \
  32. .size C_SYMBOL_NAME(name), .-C_SYMBOL_NAME(name)
  33. /* If compiled for profiling, call `mcount' at the start of each function. */
  34. # ifdef HAVE_ELF
  35. #undef NO_UNDERSCORES
  36. #define NO_UNDERSCORES
  37. # endif
  38. # ifdef NO_UNDERSCORES
  39. #define syscall_error __syscall_error
  40. # endif
  41. #define SYS_ify(syscall_name) (__NR_##syscall_name)
  42. #define __do_syscall(syscall_name) \
  43. syscall SYS_ify(syscall_name);
  44. # ifdef PIC
  45. # define PSEUDO(name, syscall_name, args) \
  46. .pic; \
  47. .align 2; \
  48. 99: mfusr $r15, $PC; \
  49. sethi $r1, hi20(_GLOBAL_OFFSET_TABLE_ + 4); \
  50. ori $r1, $r1, lo12(_GLOBAL_OFFSET_TABLE_ + 8); \
  51. add $r1, $r15, $r1; \
  52. sethi $r15, hi20(SYSCALL_ERROR@PLT); \
  53. ori $r15, $r15, lo12(SYSCALL_ERROR@PLT); \
  54. add $r15, $r15, $r1; \
  55. jr $r15; \
  56. nop; \
  57. ENTRY(name); \
  58. __do_syscall(syscall_name); \
  59. bgez $r0, 2f; \
  60. sltsi $r1, $r0, -4096; \
  61. beqz $r1, 99b; \
  62. 2:
  63. # else
  64. # define PSEUDO(name, syscall_name, args) \
  65. .align 2; \
  66. 99: j SYSCALL_ERROR; \
  67. nop; \
  68. ENTRY(name); \
  69. __do_syscall(syscall_name); \
  70. bgez $r0, 2f; \
  71. sltsi $r1, $r0, -4096; \
  72. beqz $r1, 99b; \
  73. 2:
  74. # endif
  75. #define PSEUDO_NOERRNO(name, syscall_name, args) \
  76. ENTRY(name); \
  77. __do_syscall(syscall_name);
  78. #undef PSEUDO_END
  79. #define PSEUDO_END(sym) \
  80. SYSCALL_ERROR_HANDLER \
  81. END(sym)
  82. #undef PSEUDO_END_ERRVAL
  83. #define PSEUDO_END_ERRVAL(sym) END(sym)
  84. #define PSEUDO_ERRVAL(name, syscall_name, args) PSEUDO_NOERRNO(name, syscall_name, args)
  85. #define ret_ERRVAL ret
  86. #define ret_NOERRNO ret
  87. #if defined NOT_IN_libc
  88. #define SYSCALL_ERROR __local_syscall_error
  89. #ifdef PIC
  90. #define SYSCALL_ERROR_HANDLER \
  91. __local_syscall_error: \
  92. pushm $gp, $lp; \
  93. cfi_adjust_cfa_offset(8) \
  94. cfi_rel_offset(gp, 0) \
  95. cfi_rel_offset(lp, 4) \
  96. mfusr $r15, $PC; \
  97. sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4); \
  98. ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8); \
  99. add $gp, $gp, $r15; \
  100. neg $r0, $r0; \
  101. push $r0; \
  102. cfi_adjust_cfa_offset(4) \
  103. cfi_rel_offset(r0, 0) \
  104. addi $sp, $sp, -4; \
  105. bal C_SYMBOL_NAME(__errno_location@PLT); \
  106. addi $sp, $sp, 4; \
  107. pop $r1; \
  108. cfi_adjust_cfa_offset(-4); \
  109. cfi_restore(r1); \
  110. swi $r1, [$r0]; \
  111. li $r0, -1; \
  112. popm $gp, $lp; \
  113. cfi_adjust_cfa_offset(-8); \
  114. cfi_restore(lp); \
  115. cfi_restore(gp); \
  116. 1: ret;
  117. #else
  118. #define SYSCALL_ERROR_HANDLER \
  119. __local_syscall_error: \
  120. push $lp; \
  121. cfi_adjust_cfa_offset(4) \
  122. cfi_rel_offset(lp, 0) \
  123. neg $r0, $r0; \
  124. push $r0; \
  125. cfi_adjust_cfa_offset(4) \
  126. cfi_rel_offset(r0, 0) \
  127. addi $sp, $sp, -4; \
  128. bal C_SYMBOL_NAME(__errno_location); \
  129. addi $sp, $sp, 4; \
  130. pop $r1; \
  131. cfi_adjust_cfa_offset(-4); \
  132. cfi_restore(r1); \
  133. swi $r1, [$r0]; \
  134. li $r0, -1; \
  135. pop $lp; \
  136. cfi_adjust_cfa_offset(-4); \
  137. cfi_restore(lp); \
  138. ret;
  139. #endif
  140. #else
  141. #define SYSCALL_ERROR_HANDLER
  142. #define SYSCALL_ERROR __syscall_error
  143. #endif
  144. #endif /* __ASSEMBLER__ */
  145. #endif //_LINUX_NDS32_SYSDEP_H