mips.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * QuickThreads -- Threads-building toolkit.
  3. * Copyright (c) 1993 by David Keppel
  4. *
  5. * Permission to use, copy, modify and distribute this software and
  6. * its documentation for any purpose and without fee is hereby
  7. * granted, provided that the above copyright notice and this notice
  8. * appear in all copies. This software is provided as a
  9. * proof-of-concept and for demonstration purposes; there is no
  10. * representation about the suitability of this software for any
  11. * purpose.
  12. */
  13. #ifndef QT_MIPS_H
  14. #define QT_MIPS_H
  15. typedef unsigned long qt_word_t;
  16. #define QT_GROW_DOWN
  17. /* Stack layout on the mips:
  18. Callee-save registers are: $16-$23, $30; $f20-$f30.
  19. Also save $31, return pc.
  20. Non-varargs:
  21. +---
  22. | $f30 The first clump is only saved if `qt_block'
  23. | $f28 is called, in which case it saves the fp regs
  24. | $f26 then calls `qt_blocki' to save the int regs.
  25. | $f24
  26. | $f22
  27. | $f20
  28. | $31 === return pc in `qt_block'
  29. +---
  30. | $31 === return pc; on startup == qt_start
  31. | $30
  32. | $23
  33. | $22
  34. | $21
  35. | $20
  36. | $19 on startup === only
  37. | $18 on startup === $a2 === userf
  38. | $17 on startup === $a1 === pt
  39. | $16 on startup === $a0 === pu
  40. | <a3> save area req'd by MIPS calling convention
  41. | <a2> save area req'd by MIPS calling convention
  42. | <a1> save area req'd by MIPS calling convention
  43. | <a0> save area req'd by MIPS calling convention <--- sp
  44. +---
  45. Conventions for varargs:
  46. | args ...
  47. +---
  48. | :
  49. | :
  50. | $21
  51. | $20
  52. | $19 on startup === `userf'
  53. | $18 on startup === `startup'
  54. | $17 on startup === `pt'
  55. | $16 on startup === `cleanup'
  56. | <a3>
  57. | <a2>
  58. | <a1>
  59. | <a0> <--- sp
  60. +---
  61. Note: if we wanted to, we could muck about and try to get the 4
  62. argument registers loaded in to, e.g., $22, $23, $30, and $31,
  63. and the return pc in, say, $20. Then, the first 4 args would
  64. not need to be loaded from memory, they could just use
  65. register-to-register copies. */
  66. /* Stack must be doubleword aligned. */
  67. #define QT_STKALIGN (8) /* Doubleword aligned. */
  68. /* How much space is allocated to hold all the crud for
  69. initialization: $16-$23, $30, $31. Just do an integer restore,
  70. no need to restore floating-point. Four words are needed for the
  71. argument save area for the helper function that will be called for
  72. the old thread, just before the new thread starts to run. */
  73. #define QT_STKBASE (14 * 4)
  74. #define QT_VSTKBASE QT_STKBASE
  75. /* Offsets of various registers. */
  76. #define QT_31 (9+4)
  77. #define QT_19 (3+4)
  78. #define QT_18 (2+4)
  79. #define QT_17 (1+4)
  80. #define QT_16 (0+4)
  81. /* When a never-before-run thread is restored, the return pc points
  82. to a fragment of code that starts the thread running. For
  83. non-vargs functions, it just calls the client's `only' function.
  84. For varargs functions, it calls the startup, user, and cleanup
  85. functions.
  86. The varargs startup routine always reads 4 words of arguments from
  87. the stack. If there are less than 4 words of arguments, then the
  88. startup routine can read off the top of the stack. To prevent
  89. errors we always allocate 4 words. If there are more than 3 words
  90. of arguments, the 4 preallocated words are simply wasted. */
  91. extern void qt_start(void);
  92. #define QT_ARGS_MD(sp) (QT_SPUT (sp, QT_31, qt_start))
  93. #define QT_VARGS_MD0(sp, vabytes) \
  94. ((qt_t *)(((char *)(sp)) - 4*4 - QT_STKROUNDUP(vabytes)))
  95. extern void qt_vstart(void);
  96. #define QT_VARGS_MD1(sp) (QT_SPUT (sp, QT_31, qt_vstart))
  97. #define QT_VARGS_DEFAULT
  98. /* The *index* (positive offset) of where to put each value. */
  99. #define QT_ONLY_INDEX (QT_19)
  100. #define QT_USER_INDEX (QT_18)
  101. #define QT_ARGT_INDEX (QT_17)
  102. #define QT_ARGU_INDEX (QT_16)
  103. #define QT_VCLEANUP_INDEX (QT_16)
  104. #define QT_VUSERF_INDEX (QT_19)
  105. #define QT_VSTARTUP_INDEX (QT_18)
  106. #define QT_VARGT_INDEX (QT_17)
  107. #endif /* ndef QT_MIPS_H */