Commit | Line | Data |
---|---|---|
24a647d7 MD |
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 | ||
14 | #ifndef QT_SPARC_H | |
15 | #define QT_SPARC_H | |
16 | ||
17 | typedef unsigned long qt_word_t; | |
18 | ||
19 | /* Stack layout on the sparc: | |
20 | ||
21 | non-varargs: | |
22 | ||
23 | +--- | |
24 | | <blank space for alignment> | |
25 | | %o7 == return address -> qt_start | |
26 | | %i7 | |
27 | | %i6 == frame pointer -> 0 (NULL-terminated stack frame chain) | |
28 | | %i5 -> only | |
29 | | %i4 -> userf | |
30 | | %i3 | |
31 | | %i2 -> pt | |
32 | | %i1 -> pu | |
33 | | %i0 | |
34 | | %l7 | |
35 | | %l6 | |
36 | | %l5 | |
37 | | %l4 | |
38 | | %l3 | |
39 | | %l2 | |
40 | | %l1 | |
41 | | %l0 <--- qt_t.sp | |
42 | +--- | |
43 | ||
44 | varargs: | |
45 | ||
46 | | : | |
47 | | : | |
48 | | argument list | |
49 | | one-word aggregate return pointer | |
50 | +--- | |
51 | | <blank space for alignment> | |
52 | | %o7 == return address -> qt_vstart | |
53 | | %i7 | |
54 | | %i6 == frame pointer -> 0 (NULL-terminated stack frame chain) | |
55 | | %i5 -> startup | |
56 | | %i4 -> userf | |
57 | | %i3 -> cleanup | |
58 | | %i2 -> pt | |
59 | | %i1 | |
60 | | %i0 | |
61 | | %l7 | |
62 | | %l6 | |
63 | | %l5 | |
64 | | %l4 | |
65 | | %l3 | |
66 | | %l2 | |
67 | | %l1 | |
68 | | %l0 <--- qt_t.sp | |
69 | +--- | |
70 | ||
71 | */ | |
72 | ||
73 | ||
74 | /* What to do to start a thread running. */ | |
75 | extern void qt_start (void); | |
76 | extern void qt_vstart (void); | |
77 | ||
78 | ||
79 | /* Hold 17 saved registers + 1 word for alignment. */ | |
80 | #define QT_STKBASE (18 * 4) | |
81 | #define QT_VSTKBASE QT_STKBASE | |
82 | ||
83 | ||
84 | /* Stack must be doubleword aligned. */ | |
85 | #define QT_STKALIGN (8) /* Doubleword aligned. */ | |
86 | ||
87 | #define QT_ONLY_INDEX (QT_I5) | |
88 | #define QT_USER_INDEX (QT_I4) | |
89 | #define QT_ARGT_INDEX (QT_I2) | |
90 | #define QT_ARGU_INDEX (QT_I1) | |
91 | ||
92 | #define QT_VSTARTUP_INDEX (QT_I5) | |
93 | #define QT_VUSERF_INDEX (QT_I4) | |
94 | #define QT_VCLEANUP_INDEX (QT_I3) | |
95 | #define QT_VARGT_INDEX (QT_I2) | |
96 | ||
97 | #define QT_O7 (16) | |
98 | #define QT_I6 (14) | |
99 | #define QT_I5 (13) | |
100 | #define QT_I4 (12) | |
101 | #define QT_I3 (11) | |
102 | #define QT_I2 (10) | |
103 | #define QT_I1 ( 9) | |
104 | ||
105 | ||
106 | /* The thread will ``return'' to the `qt_start' routine to get things | |
107 | going. The normal return sequence takes us to QT_O7+8, so we | |
108 | pre-subtract 8. The frame pointer chain is 0-terminated to prevent | |
109 | the trap handler from chasing off in to random memory when flushing | |
110 | stack windows. */ | |
111 | ||
112 | #define QT_ARGS_MD(top) \ | |
113 | (QT_SPUT ((top), QT_O7, ((void *)(((int)qt_start)-8))), \ | |
114 | QT_SPUT ((top), QT_I6, 0)) | |
115 | ||
116 | ||
117 | /* The varargs startup routine always reads 6 words of arguments | |
118 | (6 argument registers) from the stack, offset by one word to | |
119 | allow for an aggregate return area pointer. If the varargs | |
120 | routine actually pushed fewer words than that, qt_vstart could read | |
121 | off the top of the stack. To prevent errors, we always allocate 8 | |
122 | words. The space is often just wasted. */ | |
123 | ||
124 | #define QT_VARGS_MD0(sp, vabytes) \ | |
125 | ((qt_t *)(((char *)(sp)) - 8*4 - QT_STKROUNDUP(vabytes))) | |
126 | ||
127 | #define QT_VARGS_MD1(sp) \ | |
128 | (QT_SPUT (sp, QT_O7, ((void *)(((int)qt_vstart)-8)))) | |
129 | ||
130 | /* The SPARC has wierdo calling conventions which stores a hidden | |
131 | parameter for returning aggregate values, so the rest of the | |
132 | parameters are shoved up the stack by one place. */ | |
133 | #define QT_VARGS_ADJUST(sp) (((char *)sp)+4) | |
134 | ||
135 | #define QT_VARGS_DEFAULT | |
136 | ||
137 | ||
138 | #define QT_GROW_DOWN | |
139 | ||
140 | #endif /* ndef QT_SPARC_H */ |