axp.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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_AXP_H
  14. #define QT_AXP_H
  15. #define QT_GROW_DOWN
  16. typedef unsigned long qt_word_t;
  17. /* Stack layout on the Alpha:
  18. Integer:
  19. Caller-save: r0..r8, r22..r25, r27..r29
  20. argument/caller-save: r16..r21
  21. callee-save: r9..r15
  22. return pc *callee-save*: r26
  23. stack pointer: r30
  24. zero: r31
  25. Floating-point:
  26. Caller-save: f0..f1, f10..f15
  27. argument/caller-save: f16..f21, f22..f30
  28. callee-save: f2..f9
  29. zero: f31
  30. Non-varargs:
  31. +---
  32. | padding
  33. | f9
  34. | f8
  35. | f7
  36. | f6
  37. | f5
  38. | f4
  39. | f3
  40. | f2
  41. | r26
  42. +---
  43. | padding
  44. | r29
  45. | r15
  46. | r14
  47. | r13
  48. | r12 on startup === `only'
  49. | r11 on startup === `userf'
  50. | r10 on startup === `qt'
  51. | r9 on startup === `qu'
  52. | r26 on startup === qt_start <--- qt.sp
  53. +---
  54. Conventions for varargs startup:
  55. | :
  56. | arg6
  57. | iarg5
  58. | :
  59. | iarg0
  60. | farg5
  61. | :
  62. | farg0
  63. +---
  64. | padding
  65. | r29
  66. | r15
  67. | r14
  68. | r13
  69. | r12 on startup === `startup'
  70. | r11 on startup === `vuserf'
  71. | r10 on startup === `cleanup'
  72. | r9 on startup === `qt'
  73. | r26 on startup === qt_vstart <--- qt.sp
  74. +---
  75. Note: this is a pretty cheap/sleazy way to get things going,
  76. but ``there must be a better way.'' For instance, some varargs
  77. parameters could be loaded in to integer registers, or the return
  78. address could be stored on top of the stack. */
  79. /* Stack must be 16-byte aligned. */
  80. #define QT_STKALIGN (16)
  81. /* How much space is allocated to hold all the crud for
  82. initialization: 7 registers times 8 bytes/register. */
  83. #define QT_STKBASE (10 * 8)
  84. #define QT_VSTKBASE QT_STKBASE
  85. /* Offsets of various registers. */
  86. #define QT_R26 0
  87. #define QT_R9 1
  88. #define QT_R10 2
  89. #define QT_R11 3
  90. #define QT_R12 4
  91. /* When a never-before-run thread is restored, the return pc points
  92. to a fragment of code that starts the thread running. For
  93. non-vargs functions, it just calls the client's `only' function.
  94. For varargs functions, it calls the startup, user, and cleanup
  95. functions.
  96. The varargs startup routine always reads 12 8-byte arguments from
  97. the stack. If fewer argumets were pushed, the startup routine
  98. would read off the top of the stack. To prevent errors we always
  99. allocate enough space. When there are fewer args, the preallocated
  100. words are simply wasted. */
  101. extern void qt_start(void);
  102. #define QT_ARGS_MD(sp) (QT_SPUT (sp, QT_R26, qt_start))
  103. /* The AXP uses a struct for `va_list', so pass a pointer to the
  104. struct. This may break some uses of `QT_VARGS', but then we never
  105. claimed it was totally portable. */
  106. typedef void (qt_function_t)(void);
  107. struct qt_t;
  108. struct va_list;
  109. extern struct qt_t *qt_vargs (struct qt_t *sp, int nbytes,
  110. struct va_list *vargs, void *pt,
  111. qt_function_t *startup,
  112. qt_function_t *vuserf,
  113. qt_function_t *cleanup);
  114. #define QT_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
  115. (qt_vargs (sp, nbytes, (struct va_list *)(&(vargs)), pt, \
  116. (qt_function_t *) startup, (qt_function_t *)vuserf, \
  117. (qt_function_t *)cleanup));
  118. /* The *index* (positive offset) of where to put each value. */
  119. #define QT_ONLY_INDEX (QT_R12)
  120. #define QT_USER_INDEX (QT_R11)
  121. #define QT_ARGT_INDEX (QT_R10)
  122. #define QT_ARGU_INDEX (QT_R9)
  123. #define QT_VCLEANUP_INDEX (QT_R10)
  124. #define QT_VUSERF_INDEX (QT_R11)
  125. #define QT_VSTARTUP_INDEX (QT_R12)
  126. #define QT_VARGT_INDEX (QT_R9)
  127. #endif /* ndef QT_AXP_H */