setcontext.S 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive for
  4. * more details.
  5. *
  6. * Copyright (C) 2025 Kalray Inc.
  7. * Author(s): Julian Vetter <jvetter@kalrayinc.com>
  8. */
  9. #include <sysdep.h>
  10. #include "ucontext_i.h"
  11. .text
  12. /*
  13. * int setcontext (const ucontext_t *ucp)
  14. */
  15. ENTRY(__setcontext)
  16. get $r16 = $ra
  17. addd $r12 = $r12, -32
  18. ;;
  19. /* Save ucp pointer and $ra on the stack because we can't trash
  20. * any callee saved registers in case __setcontext returns */
  21. sd 16[$r12] = $r16
  22. ;;
  23. sd 24[$r12] = $r0
  24. ;;
  25. /* Bring back the signal status. */
  26. make $r0 = SIG_SETMASK
  27. addd $r1 = $r0, UCONTEXT_SIGMASK
  28. make $r2 = 0
  29. ;;
  30. /* sigprocmask(SIG_SETMASK, &(ucontext->uc_sigmask), NULL) */
  31. call sigprocmask
  32. ;;
  33. /* Check return value of sigprocmask */
  34. cb.deqz $r0 ? 1f
  35. /* Normally __setcontext does not return. But in case of an error it
  36. * returns with -1 and an appropriate errno */
  37. ld $r16 = 16[$r12]
  38. ;;
  39. set $ra = $r16
  40. addd $r12 = $r12, 32
  41. ;;
  42. goto __syscall_error
  43. ;;
  44. 1:
  45. /* Get back the ucp pointer */
  46. ld $r16 = 24[$r12]
  47. /* Reset the stack pointer (we can trash $ra here, because we will
  48. * never return to after __setcontext from this point onwards) */
  49. addd $r12 = $r12, 32
  50. ;;
  51. /* Restore callee saved registers */
  52. lq $r18r19 = (MCONTEXT_Q16 + 16)[$r16]
  53. ;;
  54. /* Setup $r20, $r21 for the __startcontext to work */
  55. lo $r20r21r22r23 = MCONTEXT_Q20[$r16]
  56. ;;
  57. lo $r24r25r26r27 = MCONTEXT_Q24[$r16]
  58. ;;
  59. lo $r28r29r30r31 = MCONTEXT_Q28[$r16]
  60. ;;
  61. /* Restore special registers */
  62. lo $r40r41r42r43 = MCONTEXT_LC_LE_LS_RA[$r16]
  63. ;;
  64. /* Now load argument registers */
  65. lo $r0r1r2r3 = MCONTEXT_Q0[$r16]
  66. set $lc = $r40
  67. ;;
  68. lo $r4r5r6r7 = MCONTEXT_Q4[$r16]
  69. set $le = $r41
  70. ;;
  71. lo $r8r9r10r11 = MCONTEXT_Q8[$r16]
  72. set $ls = $r42
  73. ;;
  74. /* Restore $sp */
  75. ld $r12 = MCONTEXT_Q12[$r16]
  76. /* Restore $ra which points to the $ra set by __getcontext or
  77. * to__startcontext if __makecontext was called in between */
  78. set $ra = $r43
  79. ;;
  80. ld $r40 = MCONTEXT_CS_SPC[$r16]
  81. ;;
  82. ld $r14 = (MCONTEXT_Q12 + 16)[$r16]
  83. set $cs = $r40
  84. ;;
  85. ret
  86. ;;
  87. END(setcontext)
  88. weak_alias(__setcontext, setcontext)
  89. ENTRY(__startcontext)
  90. icall $r21
  91. ;;
  92. copyd $r0 = $r20
  93. /* Check if the new context is 0 if so just call _exit */
  94. cb.deqz $r20 ? 1f
  95. ;;
  96. goto __setcontext
  97. ;;
  98. /* This should never be reached otherwise kill the thread */
  99. 1: goto _exit
  100. ;;
  101. END(__startcontext)