fd1577e71a160bfa1a65a303436a40890cd8c614
[ghc.git] / includes / stg / Regs.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1998-2012
4 *
5 * Registers in the STG machine.
6 *
7 * Do not #include this file directly: #include "Rts.h" instead.
8 *
9 * To understand the structure of the RTS headers, see the wiki:
10 * http://hackage.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
11 *
12 * ---------------------------------------------------------------------------*/
13
14 #ifndef REGS_H
15 #define REGS_H
16
17 /*
18 * The STG machine has a collection of "registers", each one of which
19 * may or may not correspond to an actual machine register when
20 * running code.
21 *
22 * The register set is backed by a table in memory (struct
23 * StgRegTable). If a particular STG register is not mapped to a
24 * machine register, then the appropriate slot in this table is used
25 * instead.
26 *
27 * This table is itself pointed to by another register, BaseReg. If
28 * BaseReg is not in a machine register, then the register table is
29 * used from an absolute location (MainCapability).
30 *
31 */
32
33 typedef struct {
34 StgWord stgEagerBlackholeInfo;
35 StgFunPtr stgGCEnter1;
36 StgFunPtr stgGCFun;
37 } StgFunTable;
38
39 /*
40 * Vanilla registers are given this union type, which is purely so
41 * that we can cast the vanilla reg to a variety of types with the
42 * minimum of syntax. eg. R1.w instead of (StgWord)R1.
43 */
44 typedef union {
45 StgWord w;
46 StgAddr a;
47 StgChar c;
48 StgFloat f;
49 StgInt i;
50 StgPtr p;
51 } StgUnion;
52
53 /*
54 * This is the table that holds shadow-locations for all the STG
55 * registers. The shadow locations are used when:
56 *
57 * 1) the particular register isn't mapped to a real machine
58 * register, probably because there's a shortage of real registers.
59 * 2) caller-saves registers are saved across a CCall
60 */
61 typedef struct {
62 StgUnion rR1;
63 StgUnion rR2;
64 StgUnion rR3;
65 StgUnion rR4;
66 StgUnion rR5;
67 StgUnion rR6;
68 StgUnion rR7;
69 StgUnion rR8;
70 StgUnion rR9; /* used occasionally by heap/stack checks */
71 StgUnion rR10; /* used occasionally by heap/stack checks */
72 StgFloat rF1;
73 StgFloat rF2;
74 StgFloat rF3;
75 StgFloat rF4;
76 StgFloat rF5;
77 StgFloat rF6;
78 StgDouble rD1;
79 StgDouble rD2;
80 StgDouble rD3;
81 StgDouble rD4;
82 StgDouble rD5;
83 StgDouble rD6;
84 StgWord64 rL1;
85 StgPtr rSp;
86 StgPtr rSpLim;
87 StgPtr rHp;
88 StgPtr rHpLim;
89 struct CostCentreStack_ * rCCCS; /* current cost-centre-stack */
90 struct StgTSO_ * rCurrentTSO;
91 struct nursery_ * rNursery;
92 struct bdescr_ * rCurrentNursery; /* Hp/HpLim point into this block */
93 struct bdescr_ * rCurrentAlloc; /* for allocation using allocate() */
94 StgWord rHpAlloc; /* number of *bytes* being allocated in heap */
95 StgWord rRet; /* holds the return code of the thread */
96 } StgRegTable;
97
98 #if IN_STG_CODE
99
100 /*
101 * Registers Hp and HpLim are global across the entire system, and are
102 * copied into the RegTable or registers before executing a thread.
103 *
104 * Registers Sp and SpLim are saved in the TSO for the thread, but are
105 * copied into the RegTable or registers before executing a thread.
106 *
107 * All other registers are "general purpose", and are used for passing
108 * arguments to functions, and returning values. The code generator
109 * knows how many of these are in real registers, and avoids
110 * generating code that uses non-real registers. General purpose
111 * registers are never saved when returning to the scheduler, instead
112 * we save whatever is live at the time on the stack, and restore it
113 * later. This should reduce the context switch time, amongst other
114 * things.
115 *
116 * For argument passing, the stack will be used in preference to
117 * pseudo-registers if the architecture has too few general purpose
118 * registers.
119 *
120 * Some special RTS functions like newArray and the Integer primitives
121 * expect their arguments to be in registers R1-Rn, so we use these
122 * (pseudo-)registers in those cases.
123 */
124
125 /* -----------------------------------------------------------------------------
126 * Emit the GCC-specific register declarations for each machine
127 * register being used. If any STG register isn't mapped to a machine
128 * register, then map it to an offset from BaseReg.
129 *
130 * First, the general purpose registers. The idea is, if a particular
131 * general-purpose STG register can't be mapped to a real machine
132 * register, it won't be used at all. Instead, we'll use the stack.
133 */
134
135 /* define NO_REGS to omit register declarations - used in RTS C code
136 * that needs all the STG definitions but not the global register
137 * settings.
138 */
139 #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
140
141 #if defined(REG_R1) && !defined(NO_GLOBAL_REG_DECLS)
142 GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
143 #else
144 # define R1 (BaseReg->rR1)
145 #endif
146
147 #if defined(REG_R2) && !defined(NO_GLOBAL_REG_DECLS)
148 GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
149 #else
150 # define R2 (BaseReg->rR2)
151 #endif
152
153 #if defined(REG_R3) && !defined(NO_GLOBAL_REG_DECLS)
154 GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
155 #else
156 # define R3 (BaseReg->rR3)
157 #endif
158
159 #if defined(REG_R4) && !defined(NO_GLOBAL_REG_DECLS)
160 GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
161 #else
162 # define R4 (BaseReg->rR4)
163 #endif
164
165 #if defined(REG_R5) && !defined(NO_GLOBAL_REG_DECLS)
166 GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
167 #else
168 # define R5 (BaseReg->rR5)
169 #endif
170
171 #if defined(REG_R6) && !defined(NO_GLOBAL_REG_DECLS)
172 GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
173 #else
174 # define R6 (BaseReg->rR6)
175 #endif
176
177 #if defined(REG_R7) && !defined(NO_GLOBAL_REG_DECLS)
178 GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
179 #else
180 # define R7 (BaseReg->rR7)
181 #endif
182
183 #if defined(REG_R8) && !defined(NO_GLOBAL_REG_DECLS)
184 GLOBAL_REG_DECL(StgUnion,R8,REG_R8)
185 #else
186 # define R8 (BaseReg->rR8)
187 #endif
188
189 #if defined(REG_R9) && !defined(NO_GLOBAL_REG_DECLS)
190 GLOBAL_REG_DECL(StgUnion,R9,REG_R9)
191 #else
192 # define R9 (BaseReg->rR9)
193 #endif
194
195 #if defined(REG_R10) && !defined(NO_GLOBAL_REG_DECLS)
196 GLOBAL_REG_DECL(StgUnion,R10,REG_R10)
197 #else
198 # define R10 (BaseReg->rR10)
199 #endif
200
201 #if defined(REG_F1) && !defined(NO_GLOBAL_REG_DECLS)
202 GLOBAL_REG_DECL(StgFloat,F1,REG_F1)
203 #else
204 #define F1 (BaseReg->rF1)
205 #endif
206
207 #if defined(REG_F2) && !defined(NO_GLOBAL_REG_DECLS)
208 GLOBAL_REG_DECL(StgFloat,F2,REG_F2)
209 #else
210 #define F2 (BaseReg->rF2)
211 #endif
212
213 #if defined(REG_F3) && !defined(NO_GLOBAL_REG_DECLS)
214 GLOBAL_REG_DECL(StgFloat,F3,REG_F3)
215 #else
216 #define F3 (BaseReg->rF3)
217 #endif
218
219 #if defined(REG_F4) && !defined(NO_GLOBAL_REG_DECLS)
220 GLOBAL_REG_DECL(StgFloat,F4,REG_F4)
221 #else
222 #define F4 (BaseReg->rF4)
223 #endif
224
225 #if defined(REG_F5) && !defined(NO_GLOBAL_REG_DECLS)
226 GLOBAL_REG_DECL(StgFloat,F5,REG_F5)
227 #else
228 #define F5 (BaseReg->rF5)
229 #endif
230
231 #if defined(REG_F6) && !defined(NO_GLOBAL_REG_DECLS)
232 GLOBAL_REG_DECL(StgFloat,F6,REG_F6)
233 #else
234 #define F6 (BaseReg->rF6)
235 #endif
236
237 #if defined(REG_D1) && !defined(NO_GLOBAL_REG_DECLS)
238 GLOBAL_REG_DECL(StgDouble,D1,REG_D1)
239 #else
240 #define D1 (BaseReg->rD1)
241 #endif
242
243 #if defined(REG_D2) && !defined(NO_GLOBAL_REG_DECLS)
244 GLOBAL_REG_DECL(StgDouble,D2,REG_D2)
245 #else
246 #define D2 (BaseReg->rD2)
247 #endif
248
249 #if defined(REG_D3) && !defined(NO_GLOBAL_REG_DECLS)
250 GLOBAL_REG_DECL(StgDouble,D3,REG_D3)
251 #else
252 #define D3 (BaseReg->rD3)
253 #endif
254
255 #if defined(REG_D4) && !defined(NO_GLOBAL_REG_DECLS)
256 GLOBAL_REG_DECL(StgDouble,D4,REG_D4)
257 #else
258 #define D4 (BaseReg->rD4)
259 #endif
260
261 #if defined(REG_D5) && !defined(NO_GLOBAL_REG_DECLS)
262 GLOBAL_REG_DECL(StgDouble,D5,REG_D5)
263 #else
264 #define D5 (BaseReg->rD5)
265 #endif
266
267 #if defined(REG_D6) && !defined(NO_GLOBAL_REG_DECLS)
268 GLOBAL_REG_DECL(StgDouble,D6,REG_D6)
269 #else
270 #define D6 (BaseReg->rD6)
271 #endif
272
273 #if defined(REG_L1) && !defined(NO_GLOBAL_REG_DECLS)
274 GLOBAL_REG_DECL(StgWord64,L1,REG_L1)
275 #else
276 #define L1 (BaseReg->rL1)
277 #endif
278
279 /*
280 * If BaseReg isn't mapped to a machine register, just use the global
281 * address of the current register table (CurrentRegTable in
282 * concurrent Haskell, MainRegTable otherwise).
283 */
284
285 /* A capability is a combination of a FunTable and a RegTable. In STG
286 * code, BaseReg normally points to the RegTable portion of this
287 * structure, so that we can index both forwards and backwards to take
288 * advantage of shorter instruction forms on some archs (eg. x86).
289 * This is a cut-down version of the Capability structure; the full
290 * version is defined in Capability.h.
291 */
292 struct PartCapability_ {
293 StgFunTable f;
294 StgRegTable r;
295 };
296
297 /* No such thing as a MainCapability under THREADED_RTS - each thread must have
298 * its own Capability.
299 */
300 #if IN_STG_CODE && !(defined(THREADED_RTS) && !defined(NOSMP))
301 extern W_ MainCapability[];
302 #endif
303
304 /*
305 * Assigning to BaseReg (the ASSIGN_BaseReg macro): this happens on
306 * return from a "safe" foreign call, when the thread might be running
307 * on a new Capability. Obviously if BaseReg is not a register, then
308 * we are restricted to a single Capability (this invariant is enforced
309 * in Capability.c:initCapabilities), and assigning to BaseReg can be omitted.
310 */
311
312 #if defined(REG_Base) && !defined(NO_GLOBAL_REG_DECLS)
313 GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base)
314 #define ASSIGN_BaseReg(e) (BaseReg = (e))
315 #else
316 #if defined(THREADED_RTS) && !defined(NOSMP)
317 #error BaseReg must be in a register for THREADED_RTS
318 #endif
319 #define BaseReg (&((struct PartCapability_ *)MainCapability)->r)
320 #define ASSIGN_BaseReg(e) (e)
321 #endif
322
323 #if defined(REG_Sp) && !defined(NO_GLOBAL_REG_DECLS)
324 GLOBAL_REG_DECL(P_,Sp,REG_Sp)
325 #else
326 #define Sp (BaseReg->rSp)
327 #endif
328
329 #if defined(REG_SpLim) && !defined(NO_GLOBAL_REG_DECLS)
330 GLOBAL_REG_DECL(P_,SpLim,REG_SpLim)
331 #else
332 #define SpLim (BaseReg->rSpLim)
333 #endif
334
335 #if defined(REG_Hp) && !defined(NO_GLOBAL_REG_DECLS)
336 GLOBAL_REG_DECL(P_,Hp,REG_Hp)
337 #else
338 #define Hp (BaseReg->rHp)
339 #endif
340
341 #if defined(REG_HpLim) && !defined(NO_GLOBAL_REG_DECLS)
342 #error HpLim cannot be in a register
343 #else
344 #define HpLim (BaseReg->rHpLim)
345 #endif
346
347 #if defined(REG_CCCS) && !defined(NO_GLOBAL_REG_DECLS)
348 GLOBAL_REG_DECL(struct CostCentreStack_ *,CCCS,REG_CCCS)
349 #else
350 #define CCCS (BaseReg->rCCCS)
351 #endif
352
353 #if defined(REG_CurrentTSO) && !defined(NO_GLOBAL_REG_DECLS)
354 GLOBAL_REG_DECL(struct _StgTSO *,CurrentTSO,REG_CurrentTSO)
355 #else
356 #define CurrentTSO (BaseReg->rCurrentTSO)
357 #endif
358
359 #if defined(REG_CurrentNursery) && !defined(NO_GLOBAL_REG_DECLS)
360 GLOBAL_REG_DECL(bdescr *,CurrentNursery,REG_CurrentNursery)
361 #else
362 #define CurrentNursery (BaseReg->rCurrentNursery)
363 #endif
364
365 #if defined(REG_HpAlloc) && !defined(NO_GLOBAL_REG_DECLS)
366 GLOBAL_REG_DECL(bdescr *,HpAlloc,REG_HpAlloc)
367 #else
368 #define HpAlloc (BaseReg->rHpAlloc)
369 #endif
370
371 /* -----------------------------------------------------------------------------
372 Get absolute function pointers from the register table, to save
373 code space. On x86,
374
375 jmp *-12(%ebx)
376
377 is shorter than
378
379 jmp absolute_address
380
381 as long as the offset is within the range of a signed byte
382 (-128..+127). So we pick some common absolute_addresses and put
383 them in the register table. As a bonus, linking time should also
384 be reduced.
385
386 Other possible candidates in order of importance:
387
388 stg_upd_frame_info
389 stg_CAF_BLACKHOLE_info
390 stg_IND_STATIC_info
391
392 anything else probably isn't worth the effort.
393
394 -------------------------------------------------------------------------- */
395
396
397 #define FunReg ((StgFunTable *)((void *)BaseReg - STG_FIELD_OFFSET(struct PartCapability_, r)))
398
399 #define stg_EAGER_BLACKHOLE_info (FunReg->stgEagerBlackholeInfo)
400 #define stg_gc_enter_1 (FunReg->stgGCEnter1)
401 #define stg_gc_fun (FunReg->stgGCFun)
402
403 #endif /* IN_STG_CODE */
404
405 #endif /* REGS_H */