[project @ 1999-02-05 16:02:18 by simonm]
[ghc-hetmet.git] / ghc / includes / Regs.h
1 /* -----------------------------------------------------------------------------
2  * $Id: Regs.h,v 1.3 1999/02/05 16:02:26 simonm Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Registers used in STG code.  Might or might not correspond to
7  * actual machine registers.
8  *
9  * ---------------------------------------------------------------------------*/
10
11 #ifndef REGS_H
12 #define REGS_H
13
14 /*
15  * This file should do the right thing if we have no machine-registers
16  * defined, i.e. everything lives in the RegTable.
17  */
18
19 /* 
20  * This is the table that holds shadow-locations for all the STG
21  * registers.  The shadow locations are used when:
22  *
23  *     1) the particular register isn't mapped to a real machine
24  *        register, probably because there's a shortage of real registers.
25  *     2) caller-saves registers are saved across a CCall
26  */
27
28 typedef struct {
29   StgUnion        rR1;
30   StgUnion        rR2;
31   StgUnion        rR3;
32   StgUnion        rR4;
33   StgUnion        rR5;
34   StgUnion        rR6;
35   StgUnion        rR7;
36   StgUnion        rR8;
37   StgUnion        rR9;          /* used occasionally by heap/stack checks */
38   StgUnion        rR10;         /* used occasionally by heap/stack checks */
39   StgFloat        rF1;
40   StgFloat        rF2;
41   StgFloat        rF3;
42   StgFloat        rF4;
43   StgDouble       rD1;
44   StgDouble       rD2;
45   StgNat64        rL1;
46   StgPtr          rSp;
47   StgUpdateFrame *rSu;
48   StgPtr          rSpLim;
49   StgPtr          rHp;
50   StgPtr          rHpLim;
51 } StgRegTable;
52
53 extern StgRegTable  MainRegTable;
54
55 /*
56  * Registers Hp and HpLim are global across the entire system, and are
57  * copied into the RegTable before executing a thread.
58  *
59  * Registers Sp, Su, and SpLim are saved in the TSO for the
60  * thread, but are copied into the RegTable before executing a thread.
61  *
62  * All other registers are "general purpose", and are used for passing
63  * arguments to functions, and returning values.  The code generator
64  * knows how many of these are in real registers, and avoids
65  * generating code that uses non-real registers.  General purpose
66  * registers are never saved when returning to the scheduler, instead
67  * we save whatever is live at the time on the stack, and restore it
68  * later.  This should reduce the context switch time, amongst other
69  * things.
70  *
71  * For argument passing, the stack will be used in preference to
72  * pseudo-registers if the architecture has too few general purpose
73  * registers.
74  *
75  * Some special RTS functions like newArray and the Integer primitives
76  * expect their arguments to be in registers R1-Rn, so we use these
77  * (pseudo-)registers in those cases.
78  */
79
80 /* 
81  * Locations for saving per-thread registers.
82  */
83
84 #define SAVE_Sp             (CurrentTSO->sp)
85 #define SAVE_Su             (CurrentTSO->su)
86 #define SAVE_SpLim          (CurrentTSO->splim)
87
88 #define SAVE_Hp             (MainRegTable.rHp)
89 #define SAVE_HpLim          (MainRegTable.rHpLim)
90
91 /* We sometimes need to save registers across a C-call, eg. if they
92  * are clobbered in the standard calling convention.  We define the
93  * save locations for all registers in the register table.
94  */
95
96 #define SAVE_R1             (MainRegTable.rR1)
97 #define SAVE_R2             (MainRegTable.rR2)
98 #define SAVE_R3             (MainRegTable.rR3)
99 #define SAVE_R4             (MainRegTable.rR4)
100 #define SAVE_R5             (MainRegTable.rR5)
101 #define SAVE_R6             (MainRegTable.rR6)
102 #define SAVE_R7             (MainRegTable.rR7)
103 #define SAVE_R8             (MainRegTable.rR8)
104  
105 #define SAVE_F1             (MainRegTable.rF1)
106 #define SAVE_F2             (MainRegTable.rF2)
107 #define SAVE_F3             (MainRegTable.rF3)
108 #define SAVE_F4             (MainRegTable.rF4)
109
110 #define SAVE_D1             (MainRegTable.rD1)
111 #define SAVE_D2             (MainRegTable.rD2)
112
113 #define SAVE_L1             (MainRegTable.rL1)
114
115 /* -----------------------------------------------------------------------------
116  * Emit the GCC-specific register declarations for each machine
117  * register being used.  If any STG register isn't mapped to a machine
118  * register, then map it to an offset from BaseReg.
119  *
120  * First, the general purpose registers.  The idea is, if a particular
121  * general-purpose STG register can't be mapped to a real machine
122  * register, it won't be used at all.  Instead, we'll use the stack.
123  *
124  * This is an improvement on the way things used to be done, when all
125  * registers were mapped to locations in the register table, and stuff
126  * was being shifted from the stack to the register table and back
127  * again for no good reason (on register-poor architectures).
128  */
129
130 #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
131
132 #ifdef REG_R1
133 GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
134 #else
135 #define R1 (BaseReg->rR1)
136 #endif
137
138 #ifdef REG_R2
139 GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
140 #else
141 #define R2 (BaseReg->rR2)
142 #endif
143
144 #ifdef REG_R3
145 GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
146 #else
147 # define R3 (BaseReg->rR3)
148 #endif
149
150 #ifdef REG_R4
151 GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
152 #else
153 # define R4 (BaseReg->rR4)
154 #endif
155
156 #ifdef REG_R5
157 GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
158 #else
159 # define R5 (BaseReg->rR5)
160 #endif
161
162 #ifdef REG_R6
163 GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
164 #else
165 # define R6 (BaseReg->rR6)
166 #endif
167
168 #ifdef REG_R7
169 GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
170 #else
171 # define R7 (BaseReg->rR7)
172 #endif
173
174 #ifdef REG_R8
175 GLOBAL_REG_DECL(StgUnion,R8,REG_R8)
176 #else
177 # define R8 (BaseReg->rR8)
178 #endif
179
180 #ifdef REG_R9
181 GLOBAL_REG_DECL(StgUnion,R9,REG_R9)
182 #else
183 # define R9 (BaseReg->rR9)
184 #endif
185
186 #ifdef REG_R10
187 GLOBAL_REG_DECL(StgUnion,R10,REG_R10)
188 #else
189 # define R10 (BaseReg->rR10)
190 #endif
191
192 #ifdef REG_F1
193 GLOBAL_REG_DECL(StgFloat,F1,REG_F1)
194 #else
195 #define F1 (BaseReg->rF1)
196 #endif
197
198 #ifdef REG_F2
199 GLOBAL_REG_DECL(StgFloat,F2,REG_F2)
200 #else
201 #define F2 (BaseReg->rF2)
202 #endif
203
204 #ifdef REG_F3
205 GLOBAL_REG_DECL(StgFloat,F3,REG_F3)
206 #else
207 #define F3 (BaseReg->rF3)
208 #endif
209
210 #ifdef REG_F4
211 GLOBAL_REG_DECL(StgFloat,F4,REG_F4)
212 #else
213 #define F4 (BaseReg->rF4)
214 #endif
215
216 #ifdef REG_D1
217 GLOBAL_REG_DECL(StgDouble,D1,REG_D1)
218 #else
219 #define D1 (BaseReg->rD1)
220 #endif
221
222 #ifdef REG_D2
223 GLOBAL_REG_DECL(StgDouble,D2,REG_D2)
224 #else
225 #define D2 (BaseReg->rD2)
226 #endif
227
228 #ifdef REG_L1
229 GLOBAL_REG_DECL(StgNat64,L1,REG_L1)
230 #else
231 #define L1 (BaseReg->rL1)
232 #endif
233
234 /*
235  * If BaseReg isn't mapped to a machine register, just use the global
236  * address of the current register table (CurrentRegTable in
237  * concurrent Haskell, MainRegTable otherwise).
238  */
239
240 #ifdef REG_Base
241 GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base)
242 #else
243 #define BaseReg (&MainRegTable)
244 #endif
245
246 #ifdef REG_Sp
247 GLOBAL_REG_DECL(P_,Sp,REG_Sp)
248 #else
249 #define Sp (BaseReg->rSp)
250 #endif
251
252 #ifdef REG_Su
253 GLOBAL_REG_DECL(StgUpdateFrame *,Su,REG_Su)
254 #else
255 #define Su (BaseReg->rSu)
256 #endif
257
258 #ifdef REG_SpLim
259 GLOBAL_REG_DECL(P_,SpLim,REG_SpLim)
260 #else
261 #define SpLim (BaseReg->rSpLim)
262 #endif
263
264 #ifdef REG_Hp
265 GLOBAL_REG_DECL(P_,Hp,REG_Hp)
266 #else
267 #define Hp (BaseReg->rHp)
268 #endif
269
270 #ifdef REG_HpLim
271 GLOBAL_REG_DECL(P_,HpLim,REG_HpLim)
272 #else
273 #define HpLim (BaseReg->rHpLim)
274 #endif
275
276 /* -----------------------------------------------------------------------------
277    For any registers which are denoted "caller-saves" by the C calling
278    convention, we have to emit code to save and restore them across C
279    calls.
280    -------------------------------------------------------------------------- */
281
282 #ifdef CALLER_SAVES_R1
283 #define CALLER_SAVE_R1          SAVE_R1 = R1;
284 #define CALLER_RESTORE_R1       R1 = SAVE_R1;
285 #else
286 #define CALLER_SAVE_R1          /* nothing */
287 #define CALLER_RESTORE_R1       /* nothing */
288 #endif
289
290 #ifdef CALLER_SAVES_R2
291 #define CALLER_SAVE_R2          SAVE_R2 = R2;
292 #define CALLER_RESTORE_R2       R2 = SAVE_R2;
293 #else
294 #define CALLER_SAVE_R2          /* nothing */
295 #define CALLER_RESTORE_R2       /* nothing */
296 #endif
297
298 #ifdef CALLER_SAVES_R3
299 #define CALLER_SAVE_R3          SAVE_R3 = R3;
300 #define CALLER_RESTORE_R3       R3 = SAVE_R3;
301 #else
302 #define CALLER_SAVE_R3          /* nothing */
303 #define CALLER_RESTORE_R3       /* nothing */
304 #endif
305
306 #ifdef CALLER_SAVES_R4
307 #define CALLER_SAVE_R4          SAVE_R4 = R4;
308 #define CALLER_RESTORE_R4       R4 = SAVE_R4;
309 #else
310 #define CALLER_SAVE_R4          /* nothing */
311 #define CALLER_RESTORE_R4       /* nothing */
312 #endif
313
314 #ifdef CALLER_SAVES_R5
315 #define CALLER_SAVE_R5          SAVE_R5 = R5;
316 #define CALLER_RESTORE_R5       R5 = SAVE_R5;
317 #else
318 #define CALLER_SAVE_R5          /* nothing */
319 #define CALLER_RESTORE_R5       /* nothing */
320 #endif
321
322 #ifdef CALLER_SAVES_R6
323 #define CALLER_SAVE_R6          SAVE_R6 = R6;
324 #define CALLER_RESTORE_R6       R6 = SAVE_R6;
325 #else
326 #define CALLER_SAVE_R6          /* nothing */
327 #define CALLER_RESTORE_R6       /* nothing */
328 #endif
329
330 #ifdef CALLER_SAVES_R7
331 #define CALLER_SAVE_R7          SAVE_R7 = R7;
332 #define CALLER_RESTORE_R7       R7 = SAVE_R7;
333 #else
334 #define CALLER_SAVE_R7          /* nothing */
335 #define CALLER_RESTORE_R7       /* nothing */
336 #endif
337
338 #ifdef CALLER_SAVES_R8
339 #define CALLER_SAVE_R8          SAVE_R8 = R8;
340 #define CALLER_RESTORE_R8       R8 = SAVE_R8;
341 #else
342 #define CALLER_SAVE_R8          /* nothing */
343 #define CALLER_RESTORE_R8       /* nothing */
344 #endif
345
346 #ifdef CALLER_SAVES_R9
347 #define CALLER_SAVE_R9          SAVE_R9 = R9;
348 #define CALLER_RESTORE_R9       R9 = SAVE_R9;
349 #else
350 #define CALLER_SAVE_R9          /* nothing */
351 #define CALLER_RESTORE_R9       /* nothing */
352 #endif
353
354 #ifdef CALLER_SAVES_R10
355 #define CALLER_SAVE_R10         SAVE_R10 = R10;
356 #define CALLER_RESTORE_R10      R10 = SAVE_R10;
357 #else
358 #define CALLER_SAVE_R10         /* nothing */
359 #define CALLER_RESTORE_R10      /* nothing */
360 #endif
361
362 #ifdef CALLER_SAVES_F1
363 #define CALLER_SAVE_F1          SAVE_F1 = F1;
364 #define CALLER_RESTORE_F1       F1 = SAVE_F1;
365 #else
366 #define CALLER_SAVE_F1          /* nothing */
367 #define CALLER_RESTORE_F1       /* nothing */
368 #endif
369
370 #ifdef CALLER_SAVES_F2
371 #define CALLER_SAVE_F2          SAVE_F2 = F2;
372 #define CALLER_RESTORE_F2       F2 = SAVE_F2;
373 #else
374 #define CALLER_SAVE_F2          /* nothing */
375 #define CALLER_RESTORE_F2       /* nothing */
376 #endif
377
378 #ifdef CALLER_SAVES_F3
379 #define CALLER_SAVE_F3          SAVE_F3 = F3;
380 #define CALLER_RESTORE_F3       F3 = SAVE_F3;
381 #else
382 #define CALLER_SAVE_F3          /* nothing */
383 #define CALLER_RESTORE_F3       /* nothing */
384 #endif
385
386 #ifdef CALLER_SAVES_F4
387 #define CALLER_SAVE_F4          SAVE_F4 = F4;
388 #define CALLER_RESTORE_F4       F4 = SAVE_F4;
389 #else
390 #define CALLER_SAVE_F4          /* nothing */
391 #define CALLER_RESTORE_F4       /* nothing */
392 #endif
393
394 #ifdef CALLER_SAVES_D1
395 #define CALLER_SAVE_D1          SAVE_D1 = D1;
396 #define CALLER_RESTORE_D1       D1 = SAVE_D1;
397 #else
398 #define CALLER_SAVE_D1          /* nothing */
399 #define CALLER_RESTORE_D1       /* nothing */
400 #endif
401
402 #ifdef CALLER_SAVES_D2
403 #define CALLER_SAVE_D2          SAVE_D2 = D2;
404 #define CALLER_RESTORE_D2       D2 = SAVE_D2;
405 #else
406 #define CALLER_SAVE_D2          /* nothing */
407 #define CALLER_RESTORE_D2       /* nothing */
408 #endif
409
410 #ifdef CALLER_SAVES_L1
411 #define CALLER_SAVE_L1          SAVE_L1 = L1;
412 #define CALLER_RESTORE_L1       L1 = SAVE_L1;
413 #else
414 #define CALLER_SAVE_L1          /* nothing */
415 #define CALLER_RESTORE_L1       /* nothing */
416 #endif
417
418 #ifdef CALLER_SAVES_Sp
419 #define CALLER_SAVE_Sp          SAVE_Sp = Sp;
420 #define CALLER_RESTORE_Sp       Sp = SAVE_Sp;
421 #else
422 #define CALLER_SAVE_Sp          /* nothing */
423 #define CALLER_RESTORE_Sp       /* nothing */
424 #endif
425
426 #ifdef CALLER_SAVES_Su
427 #define CALLER_SAVE_Su          SAVE_Su = Su;
428 #define CALLER_RESTORE_Su       Su = SAVE_Su;
429 #else
430 #define CALLER_SAVE_Su          /* nothing */
431 #define CALLER_RESTORE_Su       /* nothing */
432 #endif
433
434 #ifdef CALLER_SAVES_SpLim
435 #define CALLER_SAVE_SpLim       SAVE_SpLim = SpLim;
436 #define CALLER_RESTORE_SpLim    SpLim = SAVE_SpLim;
437 #else
438 #define CALLER_SAVE_SpLim       /* nothing */
439 #define CALLER_RESTORE_SpLim    /* nothing */
440 #endif
441
442 #ifdef CALLER_SAVES_Hp
443 #define CALLER_SAVE_Hp          SAVE_Hp = Hp;
444 #define CALLER_RESTORE_Hp       Hp = SAVE_Hp;
445 #else
446 #define CALLER_SAVE_Hp          /* nothing */
447 #define CALLER_RESTORE_Hp       /* nothing */
448 #endif
449
450 #ifdef CALLER_SAVES_HpLim
451 #define CALLER_SAVE_HpLim       SAVE_HpLim = HpLim;
452 #define CALLER_RESTORE_HpLim    HpLim = SAVE_HpLim;
453 #else
454 #define CALLER_SAVE_HpLim       /* nothing */
455 #define CALLER_RESTORE_HpLim    /* nothing */
456 #endif
457
458 #ifdef CALLER_SAVES_Base
459 #define CALLER_SAVE_Base        /* nothing */
460 #define CALLER_RESTORE_Base     BaseReg = &MainRegTable;
461 #else
462 #define CALLER_SAVE_Base        /* nothing */
463 #define CALLER_RESTORE_Base     /* nothing */
464 #endif
465
466 /* ----------------------------------------------------------------------------
467    Handy bunches of saves/restores 
468    ------------------------------------------------------------------------  */
469
470 #define CALLER_SAVE_USER                        \
471   CALLER_SAVE_R1                                \
472   CALLER_SAVE_R2                                \
473   CALLER_SAVE_R3                                \
474   CALLER_SAVE_R4                                \
475   CALLER_SAVE_R5                                \
476   CALLER_SAVE_R6                                \
477   CALLER_SAVE_R7                                \
478   CALLER_SAVE_R8                                \
479   CALLER_SAVE_F1                                \
480   CALLER_SAVE_F2                                \
481   CALLER_SAVE_F3                                \
482   CALLER_SAVE_F4                                \
483   CALLER_SAVE_D1                                \
484   CALLER_SAVE_D2                                \
485   CALLER_SAVE_L1
486
487 #define CALLER_SAVE_SYSTEM                      \
488   CALLER_SAVE_Sp                                \
489   CALLER_SAVE_Su                                \
490   CALLER_SAVE_SpLim                             \
491   CALLER_SAVE_Hp                                \
492   CALLER_SAVE_HpLim
493
494 #define CALLER_RESTORE_USER                     \
495   CALLER_RESTORE_R1                             \
496   CALLER_RESTORE_R2                             \
497   CALLER_RESTORE_R3                             \
498   CALLER_RESTORE_R4                             \
499   CALLER_RESTORE_R5                             \
500   CALLER_RESTORE_R6                             \
501   CALLER_RESTORE_R7                             \
502   CALLER_RESTORE_R8                             \
503   CALLER_RESTORE_F1                             \
504   CALLER_RESTORE_F2                             \
505   CALLER_RESTORE_F3                             \
506   CALLER_RESTORE_F4                             \
507   CALLER_RESTORE_D1                             \
508   CALLER_RESTORE_D2                             \
509   CALLER_RESTORE_L1
510
511 #define CALLER_RESTORE_SYSTEM                   \
512   CALLER_RESTORE_Base                           \
513   CALLER_RESTORE_Sp                             \
514   CALLER_RESTORE_Su                             \
515   CALLER_RESTORE_SpLim                          \
516   CALLER_RESTORE_Hp                             \
517   CALLER_RESTORE_HpLim
518
519 #define CALLER_SAVE_ALL                         \
520   CALLER_SAVE_SYSTEM                            \
521   CALLER_SAVE_USER
522
523 #define CALLER_RESTORE_ALL                      \
524   CALLER_RESTORE_SYSTEM                         \
525   CALLER_RESTORE_USER
526
527 #endif /* REGS_H */
528