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 | /* | |
15 | * This file (pa-risc.h) is part of the port of QuickThreads for the | |
16 | * PA-RISC 1.1 architecture. This file is a machine dependent header | |
17 | * file. It was written in 1994 by Uwe Reder | |
18 | * (`uereder@cip.informatik.uni-erlangen.de') for the Operating Systems | |
19 | * Department (IMMD4) at the University of Erlangen/Nuernberg Germany. | |
20 | */ | |
21 | ||
22 | ||
23 | #ifndef QT_PA_RISC_H | |
24 | #define QT_PA_RISC_H | |
25 | ||
26 | #include <qt.h> | |
27 | ||
28 | /* size of an integer-register (32 bit) */ | |
29 | typedef unsigned long qt_word_t; | |
30 | ||
31 | /* PA-RISC's stack grows up */ | |
32 | #define QT_GROW_UP | |
33 | ||
34 | /* Stack layout on PA-RISC according to PA-RISC Procedure Calling Conventions: | |
35 | ||
36 | Callee-save registers are: gr3-gr18, fr12-fr21. | |
37 | Also save gr2, return pointer. | |
38 | ||
39 | +--- | |
40 | | fr12 Each floating register is a double word (8 bytes). | |
41 | | fr13 Floating registers are only saved if `qt_block' is | |
42 | | fr14 called, in which case it saves the floating-point | |
43 | | fr15 registers then calls `qt_blocki' to save the integer | |
44 | | fr16 registers. | |
45 | | fr17 | |
46 | | fr18 | |
47 | | fr19 | |
48 | | fr20 | |
49 | | fr21 | |
50 | | <arg word 3> fixed arguments (must be allocated; may remain unused) | |
51 | | <arg word 2> | |
52 | | <arg word 1> | |
53 | | <arg word 0> | |
54 | | <LPT> frame marker | |
55 | | <LPT'> | |
56 | | <RP'> | |
57 | | <Current RP> | |
58 | | <Static Link> | |
59 | | <Clean Up> | |
60 | | <RP''> | |
61 | | <Previous SP> | |
62 | +--- | |
63 | | gr3 word each (4 bytes) | |
64 | | gr4 | |
65 | | gr5 | |
66 | | gr6 | |
67 | | gr7 | |
68 | | gr8 | |
69 | | gr9 | |
70 | | gr10 | |
71 | | gr11 | |
72 | | gr12 | |
73 | | gr13 | |
74 | | gr14 | |
75 | | gr15 | |
76 | | gr16 | |
77 | | gr17 | |
78 | | gr18 | |
79 | | <16 bytes filled in (sp has to be 64-bytes aligned)> | |
80 | | <arg word 3> fixed arguments (must be allocated; may remain unused) | |
81 | | <arg word 2> | |
82 | | <arg word 1> | |
83 | | <arg word 0> | |
84 | | <LPT> frame marker | |
85 | | <LPT'> | |
86 | | <RP'> | |
87 | | <Current RP> | |
88 | | <Static Link> | |
89 | | <Clean Up> | |
90 | | <RP''> | |
91 | | <Previous SP> | |
92 | +--- <--- sp | |
93 | */ | |
94 | ||
95 | /* When a never-before-run thread is restored, the return pc points | |
96 | to a fragment of code that starts the thread running. For | |
97 | non-vargs functions, it just calls the client's `only' function. | |
98 | For varargs functions, it calls the startup, user, and cleanup | |
99 | functions. */ | |
100 | ||
101 | /* Note: Procedue Labels on PA-RISC | |
102 | ||
103 | <--2--><-------28---------><1-><1-> | |
104 | ----------------------------------- | |
105 | | SID | Adress Part | L | X | | |
106 | ----------------------------------- | |
107 | ||
108 | On HP-UX the L field is used to flag wheather the procedure | |
109 | label (plabel) is a pointer to an LT entry or to the entry point | |
110 | of the procedure (PA-RISC Procedure Calling Conventions Reference | |
111 | Manual, 5.3.2 Procedure Labels and Dynamic Calls). */ | |
112 | ||
113 | #define QT_PA_RISC_READ_PLABEL(plabel) \ | |
114 | ( (((int)plabel) & 2) ? \ | |
115 | ( (*((int *)(((int)plabel) & 0xfffffffc)))) : ((int)plabel) ) | |
116 | ||
117 | /* Stack must be 64 bytes aligned. */ | |
118 | #define QT_STKALIGN (64) | |
119 | ||
120 | /* Internal helper for putting stuff on stack (negative index!). */ | |
121 | #define QT_SPUT(top, at, val) \ | |
122 | (((qt_word_t *)(top))[-(at)] = (qt_word_t)(val)) | |
123 | ||
124 | /* Offsets of various registers which are modified on the stack. | |
125 | rp (return-pointer) has to be stored in the frame-marker-area | |
126 | of the "older" stack-segment. */ | |
127 | ||
128 | #define QT_crp (12+4+16+5) | |
129 | #define QT_15 (12+4+4) | |
130 | #define QT_16 (12+4+3) | |
131 | #define QT_17 (12+4+2) | |
132 | #define QT_18 (12+4+1) | |
133 | ||
134 | ||
135 | /** This stuff is for NON-VARARGS. **/ | |
136 | ||
137 | /* Stack looks like this (2 stack frames): | |
138 | ||
139 | <--- 64-bytes aligned --><------- 64-bytes aligned ------------> | |
140 | | || | | |
141 | <--16--><------48-------><----16*4-----><--16-><------48-------> | |
142 | || | || | | || | |
143 | ||filler|arg|frame-marker||register-save|filler|arg|frame-marker|| | |
144 | ------------------------------------------------------------------ | |
145 | */ | |
146 | ||
147 | #define QT_STKBASE (16+48+(16*sizeof(qt_word_t))+16+48) | |
148 | ||
149 | /* The index, relative to sp, of where to put each value. */ | |
150 | #define QT_ONLY_INDEX (QT_15) | |
151 | #define QT_USER_INDEX (QT_16) | |
152 | #define QT_ARGT_INDEX (QT_17) | |
153 | #define QT_ARGU_INDEX (QT_18) | |
154 | ||
155 | extern void qt_start(void); | |
156 | #define QT_ARGS_MD(sp) \ | |
157 | (QT_SPUT (sp, QT_crp, QT_PA_RISC_READ_PLABEL(qt_start))) | |
158 | ||
159 | ||
160 | /** This is for VARARGS. **/ | |
161 | ||
162 | #define QT_VARGS_DEFAULT | |
163 | ||
164 | /* Stack looks like this (2 stack frames): | |
165 | ||
166 | <------ 64-bytes aligned -------><--------- 64-bytes aligned ----------> | |
167 | | || | | |
168 | <---?--><--?---><16><----32-----><----16*4-----><-16--><16><----32-----> | |
169 | || | | | || | | | || | |
170 | ||filler|varargs|arg|frame-marker||register-save|filler|arg|frame-marker|| | |
171 | -------------------------------------------------------------------------- | |
172 | */ | |
173 | ||
174 | /* Sp is moved to the end of the first stack frame. */ | |
175 | #define QT_VARGS_MD0(sp, vasize) \ | |
176 | ((qt_t *)(((char *)sp) + QT_STKROUNDUP(vasize + 4*4 + 32))) | |
177 | ||
178 | /* To reach the arguments from the end of the first stack frame use 32 | |
179 | as a negative adjustment. */ | |
180 | #define QT_VARGS_ADJUST(sp) ((qt_t *)(((char *)sp) - 32)) | |
181 | ||
182 | /* Offset to reach the end of the second stack frame. */ | |
183 | #define QT_VSTKBASE ((16*sizeof(qt_word_t)) + 16 + 4*4 + 32) | |
184 | ||
185 | extern void qt_vstart(void); | |
186 | #define QT_VARGS_MD1(sp) \ | |
187 | (QT_SPUT (sp, QT_crp, QT_PA_RISC_READ_PLABEL(qt_vstart))) | |
188 | ||
189 | #define QT_VARGT_INDEX (QT_15) | |
190 | #define QT_VSTARTUP_INDEX (QT_16) | |
191 | #define QT_VUSERF_INDEX (QT_17) | |
192 | #define QT_VCLEANUP_INDEX (QT_18) | |
193 | ||
194 | #endif /* ndef QT_PA_RISC_H */ |