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