m88k.s 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* m88k.s -- assembly support. */
  2. /*
  3. * QuickThreads -- Threads-building toolkit.
  4. * Copyright (c) 1993 by David Keppel
  5. *
  6. * Permission to use, copy, modify and distribute this software and
  7. * its documentation for any purpose and without fee is hereby
  8. * granted, provided that the above copyright notice and this notice
  9. * appear in all copies. This software is provided as a
  10. * proof-of-concept and for demonstration purposes; there is no
  11. * representation about the suitability of this software for any
  12. * purpose.
  13. */
  14. /* Callee-save r14..r25, r31(sp), r30(fp). r1 === return pc.
  15. * Argument registers r2..r9, return value r2..r3.
  16. *
  17. * On startup, restore regs so retpc === call to a function to start.
  18. *
  19. * We're going to call a function (r2) from within the context switch
  20. * routine. Call it on the new thread's stack on behalf of the old
  21. * thread.
  22. */
  23. .globl _qt_block
  24. .globl _qt_blocki
  25. .globl _qt_abort
  26. .globl _qt_start
  27. .globl _qt_vstart
  28. /*
  29. ** r2: ptr to function to call once curr is suspended
  30. ** and control is on r5's stack.
  31. ** r3: 1'th arg to *r2.
  32. ** r4: 2'th arg to *r2.
  33. ** r5: sp of thread to suspend.
  34. **
  35. ** The helper routine returns a value that is passed on as the
  36. ** return value from the blocking routine. Since we don't
  37. ** touch r2 between the helper's return and the end of
  38. ** function, we get this behavior for free.
  39. **
  40. ** Same entry for integer-only and floating-point, since there
  41. ** are no separate integer and floating-point registers.
  42. **
  43. ** Each procedure call sets aside a ``home region'' of 8 regs
  44. ** for r2-r9 for varargs. For context switches we don't use
  45. ** the ``home region'' for varargs so use it to save regs.
  46. ** Allocate 64 bytes of save space -- use 32 bytes of register
  47. ** save area passed in to us plus 32 bytes we allcated, use
  48. ** the other 32 bytes for save area for a save area to call
  49. ** the helper function.
  50. */
  51. _qt_block:
  52. _qt_blocki:
  53. sub r31, r31,64 /* Allocate reg save space. */
  54. st r1, r31,8+32 /* Save callee-save registers. */
  55. st r14, r31,12+32
  56. st.d r15, r31,16+32
  57. st.d r17, r31,24+32
  58. st.d r19, r31,32+32
  59. st.d r21, r31,40+32
  60. st.d r23, r31,48+32
  61. st r25, r31,56+32
  62. st r30, r31,60+32
  63. _qt_abort:
  64. addu r14, r31,0 /* Remember old sp. */
  65. addu r31, r5,0 /* Set new sp. */
  66. jsr.n r2 /* Call helper. */
  67. addu r2, r14,0 /* Pass old sp as an arg0 to helper. */
  68. ld r1, r31,8+32 /* Restore callee-save registers. */
  69. ld r14, r31,12+32
  70. ld.d r15, r31,16+32
  71. ld.d r17, r31,24+32
  72. ld.d r19, r31,32+32
  73. ld.d r21, r31,40+32
  74. ld.d r23, r31,48+32
  75. ld r25, r31,56+32
  76. ld r30, r31,60+32
  77. jmp.n r1 /* Return to new thread's caller. */
  78. addu r31, r31,64 /* Free register save space. */
  79. /*
  80. ** Non-varargs thread startup.
  81. ** See `m88k.h' for register use conventions.
  82. */
  83. _qt_start:
  84. addu r2, r14,0 /* Set user arg `pu'. */
  85. addu r3, r15,0 /* ... user function pt. */
  86. jsr.n r17 /* Call `only'. */
  87. addu r4, r16,0 /* ... user function userf. */
  88. bsr _qt_error /* `only' erroniously returned. */
  89. /*
  90. ** Varargs thread startup.
  91. ** See `m88k.h' for register use conventions.
  92. **
  93. ** Call the `startup' function with just argument `pt'.
  94. ** Then call `vuserf' with 8 register args plus any
  95. ** stack args.
  96. ** Then call `cleanup' with `pt' and the return value
  97. ** from `vuserf'.
  98. */
  99. _qt_vstart:
  100. addu r18, r30,0 /* Remember arg7 to `vuserf'. */
  101. addu r30, r0,0 /* Null-terminate call chain. */
  102. jsr.n r17 /* Call `startup'. */
  103. addu r2, r15,0 /* `pt' is arg0 to `startup'. */
  104. addu r2, r19,0 /* Set arg0. */
  105. addu r3, r20,0 /* Set arg1. */
  106. addu r4, r21,0 /* Set arg2. */
  107. addu r5, r22,0 /* Set arg3. */
  108. addu r6, r23,0 /* Set arg4. */
  109. addu r7, r24,0 /* Set arg5. */
  110. addu r8, r25,0 /* Set arg6. */
  111. jsr.n r16 /* Call `vuserf'. */
  112. addu r9, r18,0 /* Set arg7. */
  113. addu r3, r2,0 /* Ret. value is arg1 to `cleanup'. */
  114. jsr.n r14 /* Call `cleanup'. */
  115. addu r2, r15,0 /* `pt' is arg0 to `cleanup'. */
  116. bsr _qt_error /* `cleanup' erroniously returned. */