lco-x86-64.S 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /* lco: a coroutine library for C that minimalises stack usage
  2. Copyright (C) 2018 lco author
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. .text
  15. .global _lco_switch
  16. .global _lco_call
  17. /* I do not have much experience with x86-64 assembly, it might be optimisable. */
  18. _lco_switch:
  19. /* %rdi: void *next_sp, %rsi: void **current_sp */
  20. /* Function prologue */
  21. sub $64,%rsp
  22. /* Save callee-saved registers */
  23. movq %rbx, (%rsp)
  24. /* Save the stack pointer in *current_sp */
  25. /* movq %rsp, 8(%rsp) */
  26. movq %rsp, (%rsi)
  27. movq %rbp, 8(%rsp)
  28. movq %r12, 16(%rsp)
  29. movq %r13, 24(%rsp)
  30. movq %r14, 32(%rsp)
  31. movq %r15, 40(%rsp)
  32. /* TODO: there is some padding (reduce stack usage) */
  33. /* save x87 control word (XXX exceptions) */
  34. fnstcw 48(%rsp)
  35. /* save status bits of mxcsr */
  36. stmxcsr 56(%rsp)
  37. /* ret is used to switch to the caller */
  38. /* Everything except the stack pointer has been saved. */
  39. /* Resume the other coroutine by changing the stack. */
  40. movq %rdi, %rsp
  41. /* Restore the registers, once we are in a different coroutine or OS thread. */
  42. /* _lco_switch_continue: */
  43. /* Registers: %rsp: the stack, with saved registers */
  44. /* Restore callee-saved registers */
  45. movq (%rsp), %rbx
  46. movq 8(%rsp), %rbp
  47. movq 16(%rsp), %r12
  48. movq 24(%rsp), %r13
  49. movq 32(%rsp), %r14
  50. movq 40(%rsp), %r15
  51. /* Load x87 control word (XXX exceptions) */
  52. fldcw 48(%rsp)
  53. /* Load status bits of mxcsr */
  54. ldmxcsr 56(%rsp)
  55. /* Function epilogue */
  56. add $64,%rsp
  57. /* TODO: retpoline, Spectre */
  58. retq
  59. _lco_call:
  60. /* Registers: %rbx: co */
  61. movq %rbx, %rdi
  62. /* co->entry is the first field */
  63. jmpq *(%rbx)