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