ticky enhancements
[ghc.git] / rts / AutoApply.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The University of Glasgow 2002-2004
4 *
5 * Helper bits for the generic apply code (AutoApply.hc)
6 *
7 * -------------------------------------------------------------------------- */
8
9 #ifndef AUTOAPPLY_H
10 #define AUTOAPPLY_H
11
12 // Build a new PAP: function is in R1
13 // ret addr and m arguments taking up n words are on the stack.
14 // NB. x is a dummy argument attached to the 'for' label so that
15 // BUILD_PAP can be used multiple times in the same function.
16 #define BUILD_PAP(m,n,f,x) \
17 W_ pap; \
18 W_ size; \
19 W_ i; \
20 size = SIZEOF_StgPAP + WDS(n); \
21 HP_CHK_NP_ASSIGN_SP0(size,f); \
22 TICK_ALLOC_PAP(size, 0); \
23 pap = Hp + WDS(1) - size; \
24 SET_HDR(pap, stg_PAP_info, CCCS); \
25 StgPAP_arity(pap) = HALF_W_(arity - m); \
26 StgPAP_fun(pap) = R1; \
27 StgPAP_n_args(pap) = HALF_W_(n); \
28 i = 0; \
29 for##x: \
30 if (i < n) { \
31 StgPAP_payload(pap,i) = Sp(1+i); \
32 i = i + 1; \
33 goto for##x; \
34 } \
35 R1 = pap; \
36 Sp_adj(1 + n); \
37 jump %ENTRY_CODE(Sp(0)) [R1];
38
39 // Copy the old PAP, build a new one with the extra arg(s)
40 // ret addr and m arguments taking up n words are on the stack.
41 // NB. x is a dummy argument attached to the 'for' label so that
42 // BUILD_PAP can be used multiple times in the same function.
43 #define NEW_PAP(m,n,f,x) \
44 W_ pap; \
45 W_ new_pap; \
46 W_ size; \
47 W_ i; \
48 pap = R1; \
49 size = SIZEOF_StgPAP + WDS(TO_W_(StgPAP_n_args(pap))) + WDS(n); \
50 HP_CHK_NP_ASSIGN_SP0(size,f); \
51 TICK_ALLOC_PAP(size, 0); \
52 new_pap = Hp + WDS(1) - size; \
53 SET_HDR(new_pap, stg_PAP_info, CCCS); \
54 StgPAP_arity(new_pap) = HALF_W_(arity - m); \
55 W_ n_args; \
56 n_args = TO_W_(StgPAP_n_args(pap)); \
57 StgPAP_n_args(new_pap) = HALF_W_(n_args + n); \
58 StgPAP_fun(new_pap) = StgPAP_fun(pap); \
59 i = 0; \
60 for1##x: \
61 if (i < n_args) { \
62 StgPAP_payload(new_pap,i) = StgPAP_payload(pap,i); \
63 i = i + 1; \
64 goto for1##x; \
65 } \
66 i = 0; \
67 for2##x: \
68 if (i < n) { \
69 StgPAP_payload(new_pap,n_args+i) = Sp(1+i); \
70 i = i + 1; \
71 goto for2##x; \
72 } \
73 R1 = new_pap; \
74 Sp_adj(n+1); \
75 jump %ENTRY_CODE(Sp(0)) [R1];
76
77 // Jump to target, saving CCCS and restoring it on return
78 #if defined(PROFILING)
79 #define jump_SAVE_CCCS(target) \
80 Sp(-1) = CCCS; \
81 Sp(-2) = stg_restore_cccs_info; \
82 Sp_adj(-2); \
83 jump (target) [R1]
84 #else
85 #define jump_SAVE_CCCS(target) jump (target) [R1]
86 #endif
87
88 #endif /* APPLY_H */
89