md_linux2.S 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. /* SPDX-License-Identifier: MIT */
  2. /* Copyright (c) 2021-2022 The SRS Authors */
  3. /* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */
  4. #if !defined(MD_ST_NO_ASM)
  5. #if defined(__aarch64__)
  6. /****************************************************************/
  7. /* See https://developer.arm.com/documentation/102374/0100/Function-calls */
  8. /* See https://developer.arm.com/documentation/102374/0100/Procedure-Call-Standard */
  9. /* See https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#machine-registers */
  10. /* See https://wiki.cdot.senecacollege.ca/wiki/AArch64_Register_and_Instruction_Quick_Start */
  11. /* See https://chromium.googlesource.com/native_client/nacl-glibc/+/glibc-2.21/sysdeps/aarch64/__longjmp.S */
  12. /* See https://chromium.googlesource.com/native_client/nacl-glibc/+/glibc-2.21/sysdeps/aarch64/setjmp.S */
  13. /* The called routine is expected to preserve r19-r28 *** These registers are generally
  14. safe to use in your program. */
  15. #define JB_X19 0
  16. #define JB_X20 1
  17. #define JB_X21 2
  18. #define JB_X22 3
  19. #define JB_X23 4
  20. #define JB_X24 5
  21. #define JB_X25 6
  22. #define JB_X26 7
  23. #define JB_X27 8
  24. #define JB_X28 9
  25. /* r29 and r30 are used as the frame register and link register (avoid) */
  26. #define JB_X29 10
  27. #define JB_LR 11
  28. /* Register '31' is one of two registers depending on the instruction context:
  29. For instructions dealing with the stack, it is the stack pointer, named rsp */
  30. #define JB_SP 13
  31. /* FP registers */
  32. #define JB_D8 14
  33. #define JB_D9 15
  34. #define JB_D10 16
  35. #define JB_D11 17
  36. #define JB_D12 18
  37. #define JB_D13 19
  38. #define JB_D14 20
  39. #define JB_D15 21
  40. .file "md.S"
  41. .text
  42. /* _st_md_cxt_save(__jmp_buf env) */
  43. .globl _st_md_cxt_save
  44. .type _st_md_cxt_save, %function
  45. .align 4
  46. _st_md_cxt_save:
  47. stp x19, x20, [x0, #JB_X19<<3]
  48. stp x21, x22, [x0, #JB_X21<<3]
  49. stp x23, x24, [x0, #JB_X23<<3]
  50. stp x25, x26, [x0, #JB_X25<<3]
  51. stp x27, x28, [x0, #JB_X27<<3]
  52. stp x29, x30, [x0, #JB_X29<<3]
  53. stp d8, d9, [x0, #JB_D8<<3]
  54. stp d10, d11, [x0, #JB_D10<<3]
  55. stp d12, d13, [x0, #JB_D12<<3]
  56. stp d14, d15, [x0, #JB_D14<<3]
  57. mov x2, sp
  58. str x2, [x0, #JB_SP<<3]
  59. mov x0, #0
  60. ret
  61. .size _st_md_cxt_save, .-_st_md_cxt_save
  62. /****************************************************************/
  63. /* _st_md_cxt_restore(__jmp_buf env, int val) */
  64. .globl _st_md_cxt_restore
  65. .type _st_md_cxt_restore, %function
  66. .align 4
  67. _st_md_cxt_restore:
  68. ldp x19, x20, [x0, #JB_X19<<3]
  69. ldp x21, x22, [x0, #JB_X21<<3]
  70. ldp x23, x24, [x0, #JB_X23<<3]
  71. ldp x25, x26, [x0, #JB_X25<<3]
  72. ldp x27, x28, [x0, #JB_X27<<3]
  73. ldp x29, x30, [x0, #JB_X29<<3]
  74. ldp d8, d9, [x0, #JB_D8<<3]
  75. ldp d10, d11, [x0, #JB_D10<<3]
  76. ldp d12, d13, [x0, #JB_D12<<3]
  77. ldp d14, d15, [x0, #JB_D14<<3]
  78. ldr x5, [x0, #JB_SP<<3]
  79. mov sp, x5
  80. cmp x1, #0
  81. mov x0, #1
  82. csel x0, x1, x0, ne
  83. /* Use br instead of ret because ret is guaranteed to mispredict */
  84. br x30
  85. .size _st_md_cxt_restore, .-_st_md_cxt_restore
  86. /****************************************************************/
  87. #elif defined(__arm__)
  88. /****************************************************************/
  89. /* https://github.com/ossrs/srs/issues/1282#issuecomment-445539513 */
  90. /* Register list for a ldm/stm instruction to load/store
  91. the general registers from a __jmp_buf. */
  92. # define JMP_BUF_REGLIST {v1-v6, sl, fp, sp, lr}
  93. .file "md.S"
  94. .text
  95. /* _st_md_cxt_save(__jmp_buf env) */
  96. .globl _st_md_cxt_save
  97. .type _st_md_cxt_save, %function
  98. .align 2
  99. _st_md_cxt_save:
  100. mov ip, r0
  101. /* Save registers */
  102. stmia ip!, JMP_BUF_REGLIST
  103. #ifdef __VFP_FP__
  104. /* Store the VFP registers. */
  105. /* Following instruction is vstmia ip!, {d8-d15}. */
  106. stc p11, cr8, [ip], #64
  107. #endif
  108. #ifdef __IWMMXT__
  109. /* Save the call-preserved iWMMXt registers. */
  110. /* Following instructions are wstrd wr10, [ip], #8 (etc.) */
  111. stcl p1, cr10, [r12], #8
  112. stcl p1, cr11, [r12], #8
  113. stcl p1, cr12, [r12], #8
  114. stcl p1, cr13, [r12], #8
  115. stcl p1, cr14, [r12], #8
  116. stcl p1, cr15, [r12], #8
  117. #endif
  118. mov r0, #0
  119. bx lr
  120. .size _st_md_cxt_save, .-_st_md_cxt_save
  121. /****************************************************************/
  122. /* _st_md_cxt_restore(__jmp_buf env, int val) */
  123. .globl _st_md_cxt_restore
  124. .type _st_md_cxt_restore, %function
  125. .align 2
  126. _st_md_cxt_restore:
  127. mov ip, r0
  128. /* Restore registers */
  129. ldmia ip!, JMP_BUF_REGLIST
  130. #ifdef __VFP_FP__
  131. /* Restore the VFP registers. */
  132. /* Following instruction is vldmia ip!, {d8-d15}. */
  133. ldc p11, cr8, [r12], #64
  134. #endif
  135. #ifdef __IWMMXT__
  136. /* Restore the call-preserved iWMMXt registers. */
  137. /* Following instructions are wldrd wr10, [ip], #8 (etc.) */
  138. ldcl p1, cr10, [r12], #8
  139. ldcl p1, cr11, [r12], #8
  140. ldcl p1, cr12, [r12], #8
  141. ldcl p1, cr13, [r12], #8
  142. ldcl p1, cr14, [r12], #8
  143. ldcl p1, cr15, [r12], #8
  144. #endif
  145. movs r0, r1 /* get the return value in place */
  146. moveq r0, #1 /* can't let setjmp() return zero! */
  147. bx lr
  148. .size _st_md_cxt_restore, .-_st_md_cxt_restore
  149. /****************************************************************/
  150. #elif defined(__riscv)
  151. /****************************************************************/
  152. /*
  153. * Internal __jmp_buf layout
  154. * riscv-asm: https://github.com/riscv/riscv-asm-manual/blob/master/riscv-asm.md
  155. */
  156. #define JB_SP 0 /* A0, SP, Stack pointer */
  157. #define JB_RA 1 /* RA, Return address */
  158. #define JB_FP 2 /* FP/S0 Frame pointer */
  159. #define JB_S1 3 /* S1 Saved register*/
  160. #define JB_S2 4 /* S2-S11, Saved register */
  161. #define JB_S3 5 /* S2-S11, Saved register */
  162. #define JB_S4 6 /* S2-S11, Saved register */
  163. #define JB_S5 7 /* S2-S11, Saved register */
  164. #define JB_S6 8 /* S2-S11, Saved register */
  165. #define JB_S7 9 /* S2-S11, Saved register */
  166. #define JB_S8 10 /* S2-S11, Saved register */
  167. #define JB_S9 11 /* S2-S11, Saved register */
  168. #define JB_S10 12 /* S2-S11, Saved register */
  169. #define JB_S11 13 /* S2-S11, Saved register */
  170. .file "md_linux.S"
  171. .text
  172. /* _st_md_cxt_save(__jmp_buf env) */ /* The env is $a0, https://en.wikipedia.org/wiki/RISC-V#Register_sets */
  173. .globl _st_md_cxt_save
  174. .type _st_md_cxt_save, %function
  175. .align 2
  176. _st_md_cxt_save:
  177. sd sp, JB_SP * 8(a0)
  178. sd ra, JB_RA * 8(a0)
  179. sd s0, JB_FP * 8(a0)
  180. sd s1, JB_S1 * 8(a0)
  181. sd s2, JB_S2 * 8(a0)
  182. sd s3, JB_S3 * 8(a0)
  183. sd s4, JB_S4 * 8(a0)
  184. sd s5, JB_S5 * 8(a0)
  185. sd s6, JB_S6 * 8(a0)
  186. sd s7, JB_S7 * 8(a0)
  187. sd s8, JB_S8 * 8(a0)
  188. sd s9, JB_S9 * 8(a0)
  189. sd s10, JB_S10 * 8(a0)
  190. sd s11, JB_S11 * 8(a0)
  191. li a0, 0
  192. jr ra
  193. .size _st_md_cxt_save, .-_st_md_cxt_save
  194. /****************************************************************/
  195. /* _st_md_cxt_restore(__jmp_buf env, int val) */
  196. .globl _st_md_cxt_restore
  197. .type _st_md_cxt_restore, %function
  198. .align 2
  199. _st_md_cxt_restore:
  200. ld sp, JB_SP * 8(a0)
  201. ld ra, JB_RA * 8(a0)
  202. ld s0, JB_FP * 8(a0)
  203. ld s1, JB_S1 * 8(a0)
  204. ld s2, JB_S2 * 8(a0)
  205. ld s3, JB_S3 * 8(a0)
  206. ld s4, JB_S4 * 8(a0)
  207. ld s5, JB_S5 * 8(a0)
  208. ld s6, JB_S6 * 8(a0)
  209. ld s7, JB_S7 * 8(a0)
  210. ld s8, JB_S8 * 8(a0)
  211. ld s9, JB_S9 * 8(a0)
  212. ld s10, JB_S10 * 8(a0)
  213. ld s11, JB_S11 * 8(a0)
  214. li a0, 1
  215. jr ra
  216. .size _st_md_cxt_restore, .-_st_md_cxt_restore
  217. /****************************************************************/
  218. #elif defined(__mips64)
  219. /****************************************************************/
  220. /* For MIPS64, see https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MIPS_Architecture_MIPS64_InstructionSet_%20AFP_P_MD00087_06.05.pdf */
  221. /*
  222. * Internal __jmp_buf layout
  223. */
  224. #define JB_SP 0 /* Stack pointer */
  225. #define JB_RA 11 /* Return address */
  226. #define JB_GP 1 /* Global pointer */
  227. #define JB_S0 3 /* S0-S7, Saved temporaries */
  228. #define JB_S1 4 /* S0-S7, Saved temporaries */
  229. #define JB_S2 5 /* S0-S7, Saved temporaries */
  230. #define JB_S3 6 /* S0-S7, Saved temporaries */
  231. #define JB_S4 7 /* S0-S7, Saved temporaries */
  232. #define JB_S5 8 /* S0-S7, Saved temporaries */
  233. #define JB_S6 9 /* S0-S7, Saved temporaries */
  234. #define JB_S7 10 /* S0-S7, Saved temporaries */
  235. #define JB_FP 2 /* FP/S8 Frame pointer */
  236. .file "md_linux.S"
  237. .text
  238. /* _st_md_cxt_save(__jmp_buf env) */ /* The env is $a0, https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions */
  239. .globl _st_md_cxt_save
  240. .type _st_md_cxt_save, %function
  241. .align 2
  242. _st_md_cxt_save:
  243. sd $sp, 0($a0) /* Save sp to env[0], *(long*)($a0+ 0) =sp */
  244. sd $ra, 8($a0) /* Save ra to env[1], *(long*)($a0+ 8)=ra, the return address, https://chortle.ccsu.edu/AssemblyTutorial/Chapter-26/ass26_4.html */
  245. sd $gp, 16($a0) /* Save gp to env[2], *(long*)($a0+16) =gp */
  246. sd $s0, 24($a0) /* Save s0 to env[3], *(long*)($a0+24)=s0 */
  247. sd $s1, 32($a0) /* Save s1 to env[4], *(long*)($a0+32)=s1 */
  248. sd $s2, 40($a0) /* Save s2 to env[5], *(long*)($a0+40)=s2 */
  249. sd $s3, 48($a0) /* Save s3 to env[6], *(long*)($a0+48)=s3 */
  250. sd $s4, 56($a0) /* Save s4 to env[7], *(long*)($a0+56)=s4 */
  251. sd $s5, 64($a0) /* Save s5 to env[8], *(long*)($a0+64)=s5 */
  252. sd $s6, 72($a0) /* Save s6 to env[9], *(long*)($a0+72)=s6 */
  253. sd $s7, 80($a0) /* Save s7 to env[10], *(long*)($a0+80)=s7 */
  254. sd $fp, 88($a0) /* Save fp to env[11], *(long*)($a0+88) =fp */
  255. li $v0, 0 /* Set return value to 0 */
  256. jr $ra /* Return */
  257. .size _st_md_cxt_save, .-_st_md_cxt_save
  258. /****************************************************************/
  259. /* _st_md_cxt_restore(__jmp_buf env, int val) */
  260. .globl _st_md_cxt_restore
  261. .type _st_md_cxt_restore, %function
  262. .align 2
  263. _st_md_cxt_restore:
  264. ld $sp, 0($a0) /* Load sp from env[0], sp=*(long*)($a0+ 0) */
  265. ld $ra, 8($a0) /* Load sp from env[1], ra=*(long*)($a0+ 8), the saved return address */
  266. ld $gp, 16($a0) /* Load sp from env[2], gp=*(long*)($a0+16) */
  267. ld $s0, 24($a0) /* Load sp from env[3], s0=*(long*)($a0+24) */
  268. ld $s1, 32($a0) /* Load sp from env[4], s1=*(long*)($a0+32) */
  269. ld $s2, 40($a0) /* Load sp from env[5], s2=*(long*)($a0+40) */
  270. ld $s3, 48($a0) /* Load sp from env[6], s3=*(long*)($a0+48) */
  271. ld $s4, 56($a0) /* Load sp from env[7], s4=*(long*)($a0+56) */
  272. ld $s5, 64($a0) /* Load sp from env[8], s5=*(long*)($a0+64) */
  273. ld $s6, 72($a0) /* Load sp from env[9], s6=*(long*)($a0+72) */
  274. ld $s7, 80($a0) /* Load sp from env[10], s7=*(long*)($a0+80) */
  275. ld $fp, 88($a0) /* Load sp from env[2], fp=*(long*)($a0+88) */
  276. li $v0, 1 /* Set return value to 1 */
  277. jr $ra /* Return to the saved return address */
  278. .size _st_md_cxt_restore, .-_st_md_cxt_restore
  279. /****************************************************************/
  280. #elif defined(__mips__)
  281. /****************************************************************/
  282. /* For MIPS32, see https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00565-2B-MIPS32-QRC-01.01.pdf */
  283. /*
  284. * Internal __jmp_buf layout
  285. */
  286. #define JB_SP 0 /* Stack pointer */
  287. #define JB_RA 11 /* Return address */
  288. #define JB_GP 1 /* Global pointer */
  289. #define JB_S0 3 /* S0-S7, Saved temporaries */
  290. #define JB_S1 4 /* S0-S7, Saved temporaries */
  291. #define JB_S2 5 /* S0-S7, Saved temporaries */
  292. #define JB_S3 6 /* S0-S7, Saved temporaries */
  293. #define JB_S4 7 /* S0-S7, Saved temporaries */
  294. #define JB_S5 8 /* S0-S7, Saved temporaries */
  295. #define JB_S6 9 /* S0-S7, Saved temporaries */
  296. #define JB_S7 10 /* S0-S7, Saved temporaries */
  297. #define JB_FP 2 /* FP/S8 Frame pointer */
  298. .file "md_linux.S"
  299. .text
  300. /* _st_md_cxt_save(__jmp_buf env) */ /* The env is $a0, https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions */
  301. .globl _st_md_cxt_save
  302. .type _st_md_cxt_save, %function
  303. .align 2
  304. _st_md_cxt_save:
  305. sw $sp, 0($a0) /* Save sp to env[0], *(long*)($a0+0) =sp */
  306. sw $ra, 4($a0) /* Save ra to env[1], *(long*)($a0+4)=ra, the return address, https://chortle.ccsu.edu/AssemblyTutorial/Chapter-26/ass26_4.html */
  307. sw $gp, 8($a0) /* Save gp to env[2], *(long*)($a0+8) =gp */
  308. sw $s0, 12($a0) /* Save s0 to env[3], *(long*)($a0+12)=s0 */
  309. sw $s1, 16($a0) /* Save s1 to env[4], *(long*)($a0+16)=s1 */
  310. sw $s2, 20($a0) /* Save s2 to env[5], *(long*)($a0+20)=s2 */
  311. sw $s3, 24($a0) /* Save s3 to env[6], *(long*)($a0+24)=s3 */
  312. sw $s4, 28($a0) /* Save s4 to env[7], *(long*)($a0+28)=s4 */
  313. sw $s5, 32($a0) /* Save s5 to env[8], *(long*)($a0+32)=s5 */
  314. sw $s6, 36($a0) /* Save s6 to env[9], *(long*)($a0+36)=s6 */
  315. sw $s7, 40($a0) /* Save s7 to env[10], *(long*)($a0+40)=s7 */
  316. sw $fp, 44($a0) /* Save fp to env[11], *(long*)($a0+44) =fp */
  317. li $v0, 0 /* Set return value to 0 */
  318. jr $ra /* Return */
  319. .size _st_md_cxt_save, .-_st_md_cxt_save
  320. /****************************************************************/
  321. /* _st_md_cxt_restore(__jmp_buf env, int val) */
  322. .globl _st_md_cxt_restore
  323. .type _st_md_cxt_restore, %function
  324. .align 2
  325. _st_md_cxt_restore:
  326. lw $sp, 0($a0) /* Load sp from env[0], sp=*(long*)($a0+0) */
  327. lw $ra, 4($a0) /* Load sp from env[1], ra=*(long*)($a0+4), the saved return address */
  328. lw $gp, 8($a0) /* Load sp from env[2], gp=*(long*)($a0+8) */
  329. lw $s0, 12($a0) /* Load sp from env[3], s0=*(long*)($a0+12) */
  330. lw $s1, 16($a0) /* Load sp from env[4], s1=*(long*)($a0+16) */
  331. lw $s2, 20($a0) /* Load sp from env[5], s2=*(long*)($a0+20) */
  332. lw $s3, 24($a0) /* Load sp from env[6], s3=*(long*)($a0+24) */
  333. lw $s4, 28($a0) /* Load sp from env[7], s4=*(long*)($a0+28) */
  334. lw $s5, 32($a0) /* Load sp from env[8], s5=*(long*)($a0+32) */
  335. lw $s6, 36($a0) /* Load sp from env[9], s6=*(long*)($a0+36) */
  336. lw $s7, 40($a0) /* Load sp from env[10], s7=*(long*)($a0+40) */
  337. lw $fp, 44($a0) /* Load sp from env[2], fp=*(long*)($a0+44) */
  338. li $v0, 1 /* Set return value to 1 */
  339. jr $ra /* Return to the saved return address */
  340. .size _st_md_cxt_restore, .-_st_md_cxt_restore
  341. /****************************************************************/
  342. #elif defined(__loongarch64)
  343. /****************************************************************/
  344. /*
  345. * Internal __jmp_buf layout
  346. */
  347. #define JB_SP 0 /* R3, SP, Stack pointer */
  348. #define JB_RA 1 /* R1, RA, Return address */
  349. #define JB_FP 2 /* FP/R22 Frame pointer */
  350. #define JB_S0 3 /* R23-R31, S0-S8, Subroutine register variable */
  351. #define JB_S1 4 /* R23-R31, S0-S8, Subroutine register variable */
  352. #define JB_S2 5 /* R23-R31, S0-S8, Subroutine register variable */
  353. #define JB_S3 6 /* R23-R31, S0-S8, Subroutine register variable */
  354. #define JB_S4 7 /* R23-R31, S0-S8, Subroutine register variable */
  355. #define JB_S5 8 /* R23-R31, S0-S8, Subroutine register variable */
  356. #define JB_S6 9 /* R23-R31, S0-S8, Subroutine register variable */
  357. #define JB_S7 10 /* R23-R31, S0-S8, Subroutine register variable */
  358. #define JB_S8 11 /* R23-R31, S0-S8, Subroutine register variable */
  359. .file "md_linux.S"
  360. .text
  361. /* _st_md_cxt_save(__jmp_buf env) */ /* The env is $r4, https://github.com/ossrs/state-threads/issues/24#porting */
  362. .globl _st_md_cxt_save
  363. .type _st_md_cxt_save, %function
  364. .align 2
  365. _st_md_cxt_save:
  366. st.d $r3, $r4, 0 /* Save sp to env[0], *(long*)($r4+0) = sp */
  367. st.d $r1, $r4, 8 /* Save ra to env[1], *(long*)($r4+8) = r1 */
  368. st.d $r22, $r4, 16 /* Save fp to env[2], *(long*)($r4+16) = r22 */
  369. st.d $r23, $r4, 24 /* Save r23 to env[3], *(long*)($r4+24) = r23 */
  370. st.d $r24, $r4, 32 /* Save r24 to env[4], *(long*)($r4+32) = r24 */
  371. st.d $r25, $r4, 40 /* Save r25 to env[5], *(long*)($r4+40) = r25 */
  372. st.d $r26, $r4, 48 /* Save r26 to env[6], *(long*)($r4+48) = r26 */
  373. st.d $r27, $r4, 56 /* Save r27 to env[7], *(long*)($r4+56) = r27 */
  374. st.d $r28, $r4, 64 /* Save r28 to env[8], *(long*)($r4+64) = r28 */
  375. st.d $r29, $r4, 72 /* Save r29 to env[9], *(long*)($r4+72) = r29 */
  376. st.d $r30, $r4, 80 /* Save r30 to env[10], *(long*)($r4+80) = r30 */
  377. st.d $r31, $r4, 88 /* Save r31 to env[11], *(long*)($r4+88) = r31 */
  378. addi.w $r12, $r0, 0 /* Set return value to 0 */
  379. move $r4, $r12 /* Set return value to 0 */
  380. jirl $r0, $r1, 0 /* Return */
  381. .size _st_md_cxt_save, .-_st_md_cxt_save
  382. /****************************************************************/
  383. /* _st_md_cxt_restore(__jmp_buf env, int val) */
  384. .globl _st_md_cxt_restore
  385. .type _st_md_cxt_restore, %function
  386. .align 2
  387. _st_md_cxt_restore:
  388. ld.d $r3, $r4, 0 /* Load sp from env[0], sp=*(long*)($r4+0) */
  389. ld.d $r1, $r4, 8 /* Load ra from env[1], r1=*(long*)($r4+8) */
  390. ld.d $r22, $r4, 16 /* Load fp from env[2], r22=*(long*)($r4+16) */
  391. ld.d $r23, $r4, 24 /* Load r23 from env[3], r23=*(long*)($r4+24) */
  392. ld.d $r24, $r4, 32 /* Load r24 from env[4], r24=*(long*)($r4+32) */
  393. ld.d $r25, $r4, 40 /* Load r25 from env[5], r25=*(long*)($r4+40) */
  394. ld.d $r26, $r4, 48 /* Load r26 from env[6], r26=*(long*)($r4+48) */
  395. ld.d $r27, $r4, 56 /* Load r27 from env[7], r27=*(long*)($r4+56) */
  396. ld.d $r28, $r4, 64 /* Load r28 from env[8], r28=*(long*)($r4+64) */
  397. ld.d $r29, $r4, 72 /* Load r29 from env[9], r29=*(long*)($r4+72) */
  398. ld.d $r30, $r4, 80 /* Load r30 from env[10], r30=*(long*)($r4+80) */
  399. ld.d $r31, $r4, 88 /* Load r31 from env[11], r31=*(long*)($r4+88) */
  400. addi.w $r12, $r0, 1 /* Set return value to 1 */
  401. move $r4, $r12 /* Set return value to 1 */
  402. jirl $r0, $r1, 0 /* Return to the saved return address */
  403. .size _st_md_cxt_restore, .-_st_md_cxt_restore
  404. /****************************************************************/
  405. #endif
  406. #endif