2f27c639c81dbb35c5613967313a3a7d73ea91ce
[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 StgWord128 rXMM1;
85 StgWord128 rXMM2;
86 StgWord128 rXMM3;
87 StgWord128 rXMM4;
88 StgWord128 rXMM5;
89 StgWord128 rXMM6;
90 StgWord256 rYMM1;
91 StgWord256 rYMM2;
92 StgWord256 rYMM3;
93 StgWord256 rYMM4;
94 StgWord256 rYMM5;
95 StgWord256 rYMM6;
96 StgWord64 rL1;
97 StgPtr rSp;
98 StgPtr rSpLim;
99 StgPtr rHp;
100 StgPtr rHpLim;
101 struct CostCentreStack_ * rCCCS; /* current cost-centre-stack */
102 struct StgTSO_ * rCurrentTSO;
103 struct nursery_ * rNursery;
104 struct bdescr_ * rCurrentNursery; /* Hp/HpLim point into this block */
105 struct bdescr_ * rCurrentAlloc; /* for allocation using allocate() */
106 StgWord rHpAlloc; /* number of *bytes* being allocated in heap */
107 StgWord rRet; /* holds the return code of the thread */
108 } StgRegTable;
109
110 #if IN_STG_CODE
111
112 /*
113 * Registers Hp and HpLim are global across the entire system, and are
114 * copied into the RegTable or registers before executing a thread.
115 *
116 * Registers Sp and SpLim are saved in the TSO for the thread, but are
117 * copied into the RegTable or registers before executing a thread.
118 *
119 * All other registers are "general purpose", and are used for passing
120 * arguments to functions, and returning values. The code generator
121 * knows how many of these are in real registers, and avoids
122 * generating code that uses non-real registers. General purpose
123 * registers are never saved when returning to the scheduler, instead
124 * we save whatever is live at the time on the stack, and restore it
125 * later. This should reduce the context switch time, amongst other
126 * things.
127 *
128 * For argument passing, the stack will be used in preference to
129 * pseudo-registers if the architecture has too few general purpose
130 * registers.
131 *
132 * Some special RTS functions like newArray and the Integer primitives
133 * expect their arguments to be in registers R1-Rn, so we use these
134 * (pseudo-)registers in those cases.
135 */
136
137 /* -----------------------------------------------------------------------------
138 * Emit the GCC-specific register declarations for each machine
139 * register being used. If any STG register isn't mapped to a machine
140 * register, then map it to an offset from BaseReg.
141 *
142 * First, the general purpose registers. The idea is, if a particular
143 * general-purpose STG register can't be mapped to a real machine
144 * register, it won't be used at all. Instead, we'll use the stack.
145 */
146
147 /* define NO_REGS to omit register declarations - used in RTS C code
148 * that needs all the STG definitions but not the global register
149 * settings.
150 */
151 #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
152
153 #if defined(REG_R1) && !defined(NO_GLOBAL_REG_DECLS)
154 GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
155 #else
156 # define R1 (BaseReg->rR1)
157 #endif
158
159 #if defined(REG_R2) && !defined(NO_GLOBAL_REG_DECLS)
160 GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
161 #else
162 # define R2 (BaseReg->rR2)
163 #endif
164
165 #if defined(REG_R3) && !defined(NO_GLOBAL_REG_DECLS)
166 GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
167 #else
168 # define R3 (BaseReg->rR3)
169 #endif
170
171 #if defined(REG_R4) && !defined(NO_GLOBAL_REG_DECLS)
172 GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
173 #else
174 # define R4 (BaseReg->rR4)
175 #endif
176
177 #if defined(REG_R5) && !defined(NO_GLOBAL_REG_DECLS)
178 GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
179 #else
180 # define R5 (BaseReg->rR5)
181 #endif
182
183 #if defined(REG_R6) && !defined(NO_GLOBAL_REG_DECLS)
184 GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
185 #else
186 # define R6 (BaseReg->rR6)
187 #endif
188
189 #if defined(REG_R7) && !defined(NO_GLOBAL_REG_DECLS)
190 GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
191 #else
192 # define R7 (BaseReg->rR7)
193 #endif
194
195 #if defined(REG_R8) && !defined(NO_GLOBAL_REG_DECLS)
196 GLOBAL_REG_DECL(StgUnion,R8,REG_R8)
197 #else
198 # define R8 (BaseReg->rR8)
199 #endif
200
201 #if defined(REG_R9) && !defined(NO_GLOBAL_REG_DECLS)
202 GLOBAL_REG_DECL(StgUnion,R9,REG_R9)
203 #else
204 # define R9 (BaseReg->rR9)
205 #endif
206
207 #if defined(REG_R10) && !defined(NO_GLOBAL_REG_DECLS)
208 GLOBAL_REG_DECL(StgUnion,R10,REG_R10)
209 #else
210 # define R10 (BaseReg->rR10)
211 #endif
212
213 #if defined(REG_F1) && !defined(NO_GLOBAL_REG_DECLS)
214 GLOBAL_REG_DECL(StgFloat,F1,REG_F1)
215 #else
216 #define F1 (BaseReg->rF1)
217 #endif
218
219 #if defined(REG_F2) && !defined(NO_GLOBAL_REG_DECLS)
220 GLOBAL_REG_DECL(StgFloat,F2,REG_F2)
221 #else
222 #define F2 (BaseReg->rF2)
223 #endif
224
225 #if defined(REG_F3) && !defined(NO_GLOBAL_REG_DECLS)
226 GLOBAL_REG_DECL(StgFloat,F3,REG_F3)
227 #else
228 #define F3 (BaseReg->rF3)
229 #endif
230
231 #if defined(REG_F4) && !defined(NO_GLOBAL_REG_DECLS)
232 GLOBAL_REG_DECL(StgFloat,F4,REG_F4)
233 #else
234 #define F4 (BaseReg->rF4)
235 #endif
236
237 #if defined(REG_F5) && !defined(NO_GLOBAL_REG_DECLS)
238 GLOBAL_REG_DECL(StgFloat,F5,REG_F5)
239 #else
240 #define F5 (BaseReg->rF5)
241 #endif
242
243 #if defined(REG_F6) && !defined(NO_GLOBAL_REG_DECLS)
244 GLOBAL_REG_DECL(StgFloat,F6,REG_F6)
245 #else
246 #define F6 (BaseReg->rF6)
247 #endif
248
249 #if defined(REG_D1) && !defined(NO_GLOBAL_REG_DECLS)
250 GLOBAL_REG_DECL(StgDouble,D1,REG_D1)
251 #else
252 #define D1 (BaseReg->rD1)
253 #endif
254
255 #if defined(REG_D2) && !defined(NO_GLOBAL_REG_DECLS)
256 GLOBAL_REG_DECL(StgDouble,D2,REG_D2)
257 #else
258 #define D2 (BaseReg->rD2)
259 #endif
260
261 #if defined(REG_D3) && !defined(NO_GLOBAL_REG_DECLS)
262 GLOBAL_REG_DECL(StgDouble,D3,REG_D3)
263 #else
264 #define D3 (BaseReg->rD3)
265 #endif
266
267 #if defined(REG_D4) && !defined(NO_GLOBAL_REG_DECLS)
268 GLOBAL_REG_DECL(StgDouble,D4,REG_D4)
269 #else
270 #define D4 (BaseReg->rD4)
271 #endif
272
273 #if defined(REG_D5) && !defined(NO_GLOBAL_REG_DECLS)
274 GLOBAL_REG_DECL(StgDouble,D5,REG_D5)
275 #else
276 #define D5 (BaseReg->rD5)
277 #endif
278
279 #if defined(REG_D6) && !defined(NO_GLOBAL_REG_DECLS)
280 GLOBAL_REG_DECL(StgDouble,D6,REG_D6)
281 #else
282 #define D6 (BaseReg->rD6)
283 #endif
284
285 #if defined(REG_XMM1) && !defined(NO_GLOBAL_REG_DECLS)
286 GLOBAL_REG_DECL(StgWord128,XMM1,REG_XMM1)
287 #else
288 #define XMM1 (BaseReg->rXMM1)
289 #endif
290
291 #if defined(REG_XMM2) && !defined(NO_GLOBAL_REG_DECLS)
292 GLOBAL_REG_DECL(StgWord128,XMM2,REG_XMM2)
293 #else
294 #define XMM2 (BaseReg->rXMM2)
295 #endif
296
297 #if defined(REG_XMM3) && !defined(NO_GLOBAL_REG_DECLS)
298 GLOBAL_REG_DECL(StgWord128,XMM3,REG_XMM3)
299 #else
300 #define XMM3 (BaseReg->rXMM3)
301 #endif
302
303 #if defined(REG_XMM4) && !defined(NO_GLOBAL_REG_DECLS)
304 GLOBAL_REG_DECL(StgWord128,XMM4,REG_XMM4)
305 #else
306 #define XMM4 (BaseReg->rXMM4)
307 #endif
308
309 #if defined(REG_XMM5) && !defined(NO_GLOBAL_REG_DECLS)
310 GLOBAL_REG_DECL(StgWord128,XMM5,REG_XMM5)
311 #else
312 #define XMM5 (BaseReg->rXMM5)
313 #endif
314
315 #if defined(REG_XMM6) && !defined(NO_GLOBAL_REG_DECLS)
316 GLOBAL_REG_DECL(StgWord128,XMM6,REG_XMM6)
317 #else
318 #define XMM6 (BaseReg->rXMM6)
319 #endif
320
321 #if defined(REG_YMM1) && !defined(NO_GLOBAL_REG_DECLS)
322 GLOBAL_REG_DECL(StgWord256,YMM1,REG_YMM1)
323 #else
324 #define YMM1 (BaseReg->rYMM1)
325 #endif
326
327 #if defined(REG_YMM2) && !defined(NO_GLOBAL_REG_DECLS)
328 GLOBAL_REG_DECL(StgWord256,YMM2,REG_YMM2)
329 #else
330 #define YMM2 (BaseReg->rYMM2)
331 #endif
332
333 #if defined(REG_YMM3) && !defined(NO_GLOBAL_REG_DECLS)
334 GLOBAL_REG_DECL(StgWord256,YMM3,REG_YMM3)
335 #else
336 #define YMM3 (BaseReg->rYMM3)
337 #endif
338
339 #if defined(REG_YMM4) && !defined(NO_GLOBAL_REG_DECLS)
340 GLOBAL_REG_DECL(StgWord256,YMM4,REG_YMM4)
341 #else
342 #define YMM4 (BaseReg->rYMM4)
343 #endif
344
345 #if defined(REG_YMM5) && !defined(NO_GLOBAL_REG_DECLS)
346 GLOBAL_REG_DECL(StgWord256,YMM5,REG_YMM5)
347 #else
348 #define YMM5 (BaseReg->rYMM5)
349 #endif
350
351 #if defined(REG_YMM6) && !defined(NO_GLOBAL_REG_DECLS)
352 GLOBAL_REG_DECL(StgWord256,YMM6,REG_YMM6)
353 #else
354 #define YMM6 (BaseReg->rYMM6)
355 #endif
356
357 #if defined(REG_L1) && !defined(NO_GLOBAL_REG_DECLS)
358 GLOBAL_REG_DECL(StgWord64,L1,REG_L1)
359 #else
360 #define L1 (BaseReg->rL1)
361 #endif
362
363 /*
364 * If BaseReg isn't mapped to a machine register, just use the global
365 * address of the current register table (CurrentRegTable in
366 * concurrent Haskell, MainRegTable otherwise).
367 */
368
369 /* A capability is a combination of a FunTable and a RegTable. In STG
370 * code, BaseReg normally points to the RegTable portion of this
371 * structure, so that we can index both forwards and backwards to take
372 * advantage of shorter instruction forms on some archs (eg. x86).
373 * This is a cut-down version of the Capability structure; the full
374 * version is defined in Capability.h.
375 */
376 struct PartCapability_ {
377 StgFunTable f;
378 StgRegTable r;
379 };
380
381 /* No such thing as a MainCapability under THREADED_RTS - each thread must have
382 * its own Capability.
383 */
384 #if IN_STG_CODE && !(defined(THREADED_RTS) && !defined(NOSMP))
385 extern W_ MainCapability[];
386 #endif
387
388 /*
389 * Assigning to BaseReg (the ASSIGN_BaseReg macro): this happens on
390 * return from a "safe" foreign call, when the thread might be running
391 * on a new Capability. Obviously if BaseReg is not a register, then
392 * we are restricted to a single Capability (this invariant is enforced
393 * in Capability.c:initCapabilities), and assigning to BaseReg can be omitted.
394 */
395
396 #if defined(REG_Base) && !defined(NO_GLOBAL_REG_DECLS)
397 GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base)
398 #define ASSIGN_BaseReg(e) (BaseReg = (e))
399 #else
400 #if defined(THREADED_RTS) && !defined(NOSMP)
401 #error BaseReg must be in a register for THREADED_RTS
402 #endif
403 #define BaseReg (&((struct PartCapability_ *)MainCapability)->r)
404 #define ASSIGN_BaseReg(e) (e)
405 #endif
406
407 #if defined(REG_Sp) && !defined(NO_GLOBAL_REG_DECLS)
408 GLOBAL_REG_DECL(P_,Sp,REG_Sp)
409 #else
410 #define Sp (BaseReg->rSp)
411 #endif
412
413 #if defined(REG_SpLim) && !defined(NO_GLOBAL_REG_DECLS)
414 GLOBAL_REG_DECL(P_,SpLim,REG_SpLim)
415 #else
416 #define SpLim (BaseReg->rSpLim)
417 #endif
418
419 #if defined(REG_Hp) && !defined(NO_GLOBAL_REG_DECLS)
420 GLOBAL_REG_DECL(P_,Hp,REG_Hp)
421 #else
422 #define Hp (BaseReg->rHp)
423 #endif
424
425 #if defined(REG_HpLim) && !defined(NO_GLOBAL_REG_DECLS)
426 #error HpLim cannot be in a register
427 #else
428 #define HpLim (BaseReg->rHpLim)
429 #endif
430
431 #if defined(REG_CCCS) && !defined(NO_GLOBAL_REG_DECLS)
432 GLOBAL_REG_DECL(struct CostCentreStack_ *,CCCS,REG_CCCS)
433 #else
434 #define CCCS (BaseReg->rCCCS)
435 #endif
436
437 #if defined(REG_CurrentTSO) && !defined(NO_GLOBAL_REG_DECLS)
438 GLOBAL_REG_DECL(struct _StgTSO *,CurrentTSO,REG_CurrentTSO)
439 #else
440 #define CurrentTSO (BaseReg->rCurrentTSO)
441 #endif
442
443 #if defined(REG_CurrentNursery) && !defined(NO_GLOBAL_REG_DECLS)
444 GLOBAL_REG_DECL(bdescr *,CurrentNursery,REG_CurrentNursery)
445 #else
446 #define CurrentNursery (BaseReg->rCurrentNursery)
447 #endif
448
449 #if defined(REG_HpAlloc) && !defined(NO_GLOBAL_REG_DECLS)
450 GLOBAL_REG_DECL(bdescr *,HpAlloc,REG_HpAlloc)
451 #else
452 #define HpAlloc (BaseReg->rHpAlloc)
453 #endif
454
455 /* -----------------------------------------------------------------------------
456 Get absolute function pointers from the register table, to save
457 code space. On x86,
458
459 jmp *-12(%ebx)
460
461 is shorter than
462
463 jmp absolute_address
464
465 as long as the offset is within the range of a signed byte
466 (-128..+127). So we pick some common absolute_addresses and put
467 them in the register table. As a bonus, linking time should also
468 be reduced.
469
470 Other possible candidates in order of importance:
471
472 stg_upd_frame_info
473 stg_CAF_BLACKHOLE_info
474 stg_IND_STATIC_info
475
476 anything else probably isn't worth the effort.
477
478 -------------------------------------------------------------------------- */
479
480
481 #define FunReg ((StgFunTable *)((void *)BaseReg - STG_FIELD_OFFSET(struct PartCapability_, r)))
482
483 #define stg_EAGER_BLACKHOLE_info (FunReg->stgEagerBlackholeInfo)
484 #define stg_gc_enter_1 (FunReg->stgGCEnter1)
485 #define stg_gc_fun (FunReg->stgGCFun)
486
487 #endif /* IN_STG_CODE */
488
489 #endif /* REGS_H */