getcontext.S 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. /* Copyright (C) 20[B01-2013 Free Software Foundation, Inc.
  6. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
  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. <http://www.gnu.org/licenses/>. */
  18. #include <sysdep.h>
  19. #include "ucontext_i.h"
  20. /* __getcontext (const ucontext_t *ucp)
  21. Saves the machine context in UCP such that when it is activated,
  22. it appears as if __getcontext() returned again.
  23. This implementation is intended to be used for *synchronous* context
  24. switches only. Therefore, it does not have to save anything
  25. other than the PRESERVED state. */
  26. ENTRY(__getcontext)
  27. swi $lp, [$r0 + UCONTEXT_PC]
  28. addi $r15, $r0, UCONTEXT_GREGS
  29. xor $r1, $r1, $r1
  30. smw.bim $r1, [$r15], $r1
  31. smw.bim $r1, [$r15], $r14
  32. addi $r15, $r15, 4
  33. smw.bim $r16, [$r15], $r25, #0xf
  34. move $r4, $r0
  35. /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */
  36. move $r0, SIG_BLOCK
  37. move $r1, 0
  38. addi $r2, $r4, UCONTEXT_SIGMASK
  39. move $r3, _NSIG8
  40. syscall SYS_ify(rt_sigprocmask)
  41. bnez $r0, 1f
  42. #ifdef __NDS32_ABI_2FP_PLUS__
  43. addi $r2, $r4, UCONTEXT_FDREGS
  44. /* Process for FPU registers. */
  45. fmfcfg $r20 /* Keep $fpcfg in $r20. */
  46. slli $r20, $r20, #28
  47. srli $r20, $r20, #30 /* Set $r20 as $fpcfg.freg. */
  48. /* Case switch for $r20 as $fpcfg.freg. */
  49. beqz $r20, .LCFG0 /* Branch if $fpcfg.freg = 0b00. */
  50. xori $r15, $r20, #0b10
  51. beqz $r15, .LCFG2 /* Branch if $fpcfg.freg = 0b10. */
  52. srli $r20, $r20, #0b01
  53. beqz $r20, .LCFG1 /* Branch if $fpcfg.freg = 0b01. */
  54. /* Fall-through if $fpcfg.freg = 0b11. */
  55. .LCFG3:
  56. fsdi $fd31, [$r2 + 248]
  57. fsdi $fd30, [$r2 + 240]
  58. fsdi $fd29, [$r2 + 232]
  59. fsdi $fd28, [$r2 + 224]
  60. fsdi $fd27, [$r2 + 216]
  61. fsdi $fd26, [$r2 + 208]
  62. fsdi $fd25, [$r2 + 200]
  63. fsdi $fd24, [$r2 + 192]
  64. .LCFG2:
  65. fsdi $fd10, [$r2 + 80]
  66. fsdi $fd9, [$r2 + 72]
  67. fsdi $fd8, [$r2 + 64]
  68. .LCFG1:
  69. fsdi $fd7, [$r2 + 56]
  70. fsdi $fd6, [$r2 + 48]
  71. fsdi $fd5, [$r2 + 40]
  72. fsdi $fd4, [$r2 + 32]
  73. .LCFG0:
  74. fsdi $fd3, [$r2 + 24]
  75. /*save fpcsr*/
  76. fmfcsr $r1
  77. swi $r1, [$r2 + 0x100]
  78. #endif /* __NDS32_ABI_2FP_PLUS__ */
  79. /* Set __getcontext return value to 0. */
  80. xor $r0, $r0, $r0
  81. /* Return first_return: 1 */
  82. addi $r1, $r0, 1
  83. ret
  84. 1:
  85. move $r0, -1
  86. ret
  87. END(__getcontext)
  88. weak_alias (__getcontext, getcontext)