Produce new-style Cmm from the Cmm parser
[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 StgDouble rD1;
77 StgDouble rD2;
78 StgWord64 rL1;
79 StgPtr rSp;
80 StgPtr rSpLim;
81 StgPtr rHp;
82 StgPtr rHpLim;
83 struct CostCentreStack_ * rCCCS; /* current cost-centre-stack */
84 struct StgTSO_ * rCurrentTSO;
85 struct nursery_ * rNursery;
86 struct bdescr_ * rCurrentNursery; /* Hp/HpLim point into this block */
87 struct bdescr_ * rCurrentAlloc; /* for allocation using allocate() */
88 StgWord rHpAlloc; /* number of *bytes* being allocated in heap */
89 StgWord rRet; /* holds the return code of the thread */
90 } StgRegTable;
91
92 #if IN_STG_CODE
93
94 /*
95 * Registers Hp and HpLim are global across the entire system, and are
96 * copied into the RegTable or registers before executing a thread.
97 *
98 * Registers Sp and SpLim are saved in the TSO for the thread, but are
99 * copied into the RegTable or registers before executing a thread.
100 *
101 * All other registers are "general purpose", and are used for passing
102 * arguments to functions, and returning values. The code generator
103 * knows how many of these are in real registers, and avoids
104 * generating code that uses non-real registers. General purpose
105 * registers are never saved when returning to the scheduler, instead
106 * we save whatever is live at the time on the stack, and restore it
107 * later. This should reduce the context switch time, amongst other
108 * things.
109 *
110 * For argument passing, the stack will be used in preference to
111 * pseudo-registers if the architecture has too few general purpose
112 * registers.
113 *
114 * Some special RTS functions like newArray and the Integer primitives
115 * expect their arguments to be in registers R1-Rn, so we use these
116 * (pseudo-)registers in those cases.
117 */
118
119 /* -----------------------------------------------------------------------------
120 * Emit the GCC-specific register declarations for each machine
121 * register being used. If any STG register isn't mapped to a machine
122 * register, then map it to an offset from BaseReg.
123 *
124 * First, the general purpose registers. The idea is, if a particular
125 * general-purpose STG register can't be mapped to a real machine
126 * register, it won't be used at all. Instead, we'll use the stack.
127 */
128
129 /* define NO_REGS to omit register declarations - used in RTS C code
130 * that needs all the STG definitions but not the global register
131 * settings.
132 */
133 #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
134
135 #if defined(REG_R1) && !defined(NO_GLOBAL_REG_DECLS)
136 GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
137 #else
138 # define R1 (BaseReg->rR1)
139 #endif
140
141 #if defined(REG_R2) && !defined(NO_GLOBAL_REG_DECLS)
142 GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
143 #else
144 # define R2 (BaseReg->rR2)
145 #endif
146
147 #if defined(REG_R3) && !defined(NO_GLOBAL_REG_DECLS)
148 GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
149 #else
150 # define R3 (BaseReg->rR3)
151 #endif
152
153 #if defined(REG_R4) && !defined(NO_GLOBAL_REG_DECLS)
154 GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
155 #else
156 # define R4 (BaseReg->rR4)
157 #endif
158
159 #if defined(REG_R5) && !defined(NO_GLOBAL_REG_DECLS)
160 GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
161 #else
162 # define R5 (BaseReg->rR5)
163 #endif
164
165 #if defined(REG_R6) && !defined(NO_GLOBAL_REG_DECLS)
166 GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
167 #else
168 # define R6 (BaseReg->rR6)
169 #endif
170
171 #if defined(REG_R7) && !defined(NO_GLOBAL_REG_DECLS)
172 GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
173 #else
174 # define R7 (BaseReg->rR7)
175 #endif
176
177 #if defined(REG_R8) && !defined(NO_GLOBAL_REG_DECLS)
178 GLOBAL_REG_DECL(StgUnion,R8,REG_R8)
179 #else
180 # define R8 (BaseReg->rR8)
181 #endif
182
183 #if defined(REG_R9) && !defined(NO_GLOBAL_REG_DECLS)
184 GLOBAL_REG_DECL(StgUnion,R9,REG_R9)
185 #else
186 # define R9 (BaseReg->rR9)
187 #endif
188
189 #if defined(REG_R10) && !defined(NO_GLOBAL_REG_DECLS)
190 GLOBAL_REG_DECL(StgUnion,R10,REG_R10)
191 #else
192 # define R10 (BaseReg->rR10)
193 #endif
194
195 #if defined(REG_F1) && !defined(NO_GLOBAL_REG_DECLS)
196 GLOBAL_REG_DECL(StgFloat,F1,REG_F1)
197 #else
198 #define F1 (BaseReg->rF1)
199 #endif
200
201 #if defined(REG_F2) && !defined(NO_GLOBAL_REG_DECLS)
202 GLOBAL_REG_DECL(StgFloat,F2,REG_F2)
203 #else
204 #define F2 (BaseReg->rF2)
205 #endif
206
207 #if defined(REG_F3) && !defined(NO_GLOBAL_REG_DECLS)
208 GLOBAL_REG_DECL(StgFloat,F3,REG_F3)
209 #else
210 #define F3 (BaseReg->rF3)
211 #endif
212
213 #if defined(REG_F4) && !defined(NO_GLOBAL_REG_DECLS)
214 GLOBAL_REG_DECL(StgFloat,F4,REG_F4)
215 #else
216 #define F4 (BaseReg->rF4)
217 #endif
218
219 #if defined(REG_D1) && !defined(NO_GLOBAL_REG_DECLS)
220 GLOBAL_REG_DECL(StgDouble,D1,REG_D1)
221 #else
222 #define D1 (BaseReg->rD1)
223 #endif
224
225 #if defined(REG_D2) && !defined(NO_GLOBAL_REG_DECLS)
226 GLOBAL_REG_DECL(StgDouble,D2,REG_D2)
227 #else
228 #define D2 (BaseReg->rD2)
229 #endif
230
231 #if defined(REG_L1) && !defined(NO_GLOBAL_REG_DECLS)
232 GLOBAL_REG_DECL(StgWord64,L1,REG_L1)
233 #else
234 #define L1 (BaseReg->rL1)
235 #endif
236
237 /*
238 * If BaseReg isn't mapped to a machine register, just use the global
239 * address of the current register table (CurrentRegTable in
240 * concurrent Haskell, MainRegTable otherwise).
241 */
242
243 /* A capability is a combination of a FunTable and a RegTable. In STG
244 * code, BaseReg normally points to the RegTable portion of this
245 * structure, so that we can index both forwards and backwards to take
246 * advantage of shorter instruction forms on some archs (eg. x86).
247 * This is a cut-down version of the Capability structure; the full
248 * version is defined in Capability.h.
249 */
250 struct PartCapability_ {
251 StgFunTable f;
252 StgRegTable r;
253 };
254
255 /* No such thing as a MainCapability under THREADED_RTS - each thread must have
256 * its own Capability.
257 */
258 #if IN_STG_CODE && !(defined(THREADED_RTS) && !defined(NOSMP))
259 extern W_ MainCapability[];
260 #endif
261
262 /*
263 * Assigning to BaseReg (the ASSIGN_BaseReg macro): this happens on
264 * return from a "safe" foreign call, when the thread might be running
265 * on a new Capability. Obviously if BaseReg is not a register, then
266 * we are restricted to a single Capability (this invariant is enforced
267 * in Capability.c:initCapabilities), and assigning to BaseReg can be omitted.
268 */
269
270 #if defined(REG_Base) && !defined(NO_GLOBAL_REG_DECLS)
271 GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base)
272 #define ASSIGN_BaseReg(e) (BaseReg = (e))
273 #else
274 #if defined(THREADED_RTS) && !defined(NOSMP)
275 #error BaseReg must be in a register for THREADED_RTS
276 #endif
277 #define BaseReg (&((struct PartCapability_ *)MainCapability)->r)
278 #define ASSIGN_BaseReg(e) (e)
279 #endif
280
281 #if defined(REG_Sp) && !defined(NO_GLOBAL_REG_DECLS)
282 GLOBAL_REG_DECL(P_,Sp,REG_Sp)
283 #else
284 #define Sp (BaseReg->rSp)
285 #endif
286
287 #if defined(REG_SpLim) && !defined(NO_GLOBAL_REG_DECLS)
288 GLOBAL_REG_DECL(P_,SpLim,REG_SpLim)
289 #else
290 #define SpLim (BaseReg->rSpLim)
291 #endif
292
293 #if defined(REG_Hp) && !defined(NO_GLOBAL_REG_DECLS)
294 GLOBAL_REG_DECL(P_,Hp,REG_Hp)
295 #else
296 #define Hp (BaseReg->rHp)
297 #endif
298
299 #if defined(REG_HpLim) && !defined(NO_GLOBAL_REG_DECLS)
300 #error HpLim cannot be in a register
301 #else
302 #define HpLim (BaseReg->rHpLim)
303 #endif
304
305 #if defined(REG_CCCS) && !defined(NO_GLOBAL_REG_DECLS)
306 GLOBAL_REG_DECL(struct CostCentreStack_ *,CCCS,REG_CCCS)
307 #else
308 #define CCCS (BaseReg->rCCCS)
309 #endif
310
311 #if defined(REG_CurrentTSO) && !defined(NO_GLOBAL_REG_DECLS)
312 GLOBAL_REG_DECL(struct _StgTSO *,CurrentTSO,REG_CurrentTSO)
313 #else
314 #define CurrentTSO (BaseReg->rCurrentTSO)
315 #endif
316
317 #if defined(REG_CurrentNursery) && !defined(NO_GLOBAL_REG_DECLS)
318 GLOBAL_REG_DECL(bdescr *,CurrentNursery,REG_CurrentNursery)
319 #else
320 #define CurrentNursery (BaseReg->rCurrentNursery)
321 #endif
322
323 #if defined(REG_HpAlloc) && !defined(NO_GLOBAL_REG_DECLS)
324 GLOBAL_REG_DECL(bdescr *,HpAlloc,REG_HpAlloc)
325 #else
326 #define HpAlloc (BaseReg->rHpAlloc)
327 #endif
328
329 /* -----------------------------------------------------------------------------
330 Get absolute function pointers from the register table, to save
331 code space. On x86,
332
333 jmp *-12(%ebx)
334
335 is shorter than
336
337 jmp absolute_address
338
339 as long as the offset is within the range of a signed byte
340 (-128..+127). So we pick some common absolute_addresses and put
341 them in the register table. As a bonus, linking time should also
342 be reduced.
343
344 Other possible candidates in order of importance:
345
346 stg_upd_frame_info
347 stg_CAF_BLACKHOLE_info
348 stg_IND_STATIC_info
349
350 anything else probably isn't worth the effort.
351
352 -------------------------------------------------------------------------- */
353
354
355 #define FunReg ((StgFunTable *)((void *)BaseReg - STG_FIELD_OFFSET(struct PartCapability_, r)))
356
357 #define stg_EAGER_BLACKHOLE_info (FunReg->stgEagerBlackholeInfo)
358 #define stg_gc_enter_1 (FunReg->stgGCEnter1)
359 #define stg_gc_fun (FunReg->stgGCFun)
360
361 #endif /* IN_STG_CODE */
362
363 #endif /* REGS_H */