1 /* -----------------------------------------------------------------------------
2 * $Id: StgStdThunks.hc,v 1.4 1999/03/26 10:29:05 simonm Exp $
4 * (c) The GHC Team, 1998-1999
6 * Canned "Standard Form" Thunks
8 * ---------------------------------------------------------------------------*/
12 /* -----------------------------------------------------------------------------
13 The code for a thunk that simply extracts a field from a
14 single-constructor datatype depends only on the offset of the field
17 Here we define some canned "selector" thunks that do just that; any
18 selector thunk appearing in a program will refer to one of these
19 instead of being compiled independently.
21 The garbage collector spots selector thunks and reduces them if
22 possible, in order to avoid space leaks resulting from lazy pattern
24 -------------------------------------------------------------------------- */
26 #define UPD_FRAME_SIZE (sizeofW(StgUpdateFrame)+sizeofW(StgHeader))
27 #define NOUPD_FRAME_SIZE (sizeofW(StgHeader))
30 #define SAVE_CCCS(fs) CCS_HDR(Sp-fs)=CCCS
31 #define GET_SAVED_CCCS RESTORE_CCCS(CCS_HDR(Sp))
34 #define SAVE_CCCS(fs) /* empty */
35 #define GET_SAVED_CCCS /* empty */
39 #define SELECTOR_CODE_UPD(offset) \
40 IF_(__sel_ret_##offset##_upd_ret); \
41 INFO_TABLE_SRT_BITMAP(__sel_ret_##offset##_upd_info,__sel_ret_##offset##_upd_ret, RET_BITMAP, 0, 0, 0, RET_SMALL, static const, IF_, 0, 0); \
42 IF_(__sel_ret_##offset##_upd_ret) { \
44 R1.p=(P_)R1.cl->payload[offset]; \
46 Sp=Sp+sizeofW(StgHeader); \
47 JMP_(ENTRY_CODE(*R1.p)); \
51 EF_(__sel_##offset##_upd_entry); \
52 INFO_TABLE_SELECTOR(__sel_##offset##_upd_info, __sel_##offset##_upd_entry, offset, const, EF_, 0,0);\
53 EF_(__sel_##offset##_upd_entry) { \
55 STK_CHK_NP(UPD_FRAME_SIZE,1,); \
56 UPD_BH_UPDATABLE(R1.p); \
57 PUSH_UPD_FRAME(R1.p,0); \
58 SAVE_CCCS(UPD_FRAME_SIZE); \
59 Sp[-UPD_FRAME_SIZE]=(W_)__sel_ret_##offset##_upd_ret; \
60 R1.p = (P_)R1.cl->payload[0]; \
61 Sp=Sp-UPD_FRAME_SIZE; \
62 JMP_(ENTRY_CODE(*R1.p)); \
76 SELECTOR_CODE_UPD(10);
77 SELECTOR_CODE_UPD(11);
78 SELECTOR_CODE_UPD(12);
79 SELECTOR_CODE_UPD(13);
80 SELECTOR_CODE_UPD(14);
81 SELECTOR_CODE_UPD(15);
83 #define SELECTOR_CODE_NOUPD(offset) \
84 IF_(__sel_ret_##offset##_noupd_ret); \
85 INFO_TABLE_SRT_BITMAP(__sel_ret_##offset##_noupd_info, __sel_ret_##offset##_noupd_ret, RET_BITMAP, 0, 0, 0, RET_SMALL, static const, IF_, 0, 0); \
86 IF_(__sel_ret_##offset##_noupd_ret) { \
88 R1.p=(P_)R1.cl->payload[offset]; \
90 Sp=Sp+sizeofW(StgHeader); \
91 JMP_(ENTRY_CODE(*R1.p)); \
95 EF_(__sel_##offset##_noupd_entry); \
96 INFO_TABLE_SELECTOR(__sel_##offset##_noupd_info, __sel_##offset##_noupd_entry, offset, const, EF_, 0,0);\
97 EF_(__sel_##offset##_noupd_entry) { \
99 STK_CHK_NP(NOUPD_FRAME_SIZE,1,) \
100 SAVE_CCCS(NOUPD_FRAME_SIZE); \
101 Sp[-NOUPD_FRAME_SIZE]=(W_)__sel_ret_##offset##_noupd_ret; \
102 R1.p = (P_)R1.cl->payload[0]; \
103 Sp=Sp-NOUPD_FRAME_SIZE; \
104 JMP_(ENTRY_CODE(*R1.p)); \
108 SELECTOR_CODE_NOUPD(0);
109 SELECTOR_CODE_NOUPD(1);
110 SELECTOR_CODE_NOUPD(2);
111 SELECTOR_CODE_NOUPD(3);
112 SELECTOR_CODE_NOUPD(4);
113 SELECTOR_CODE_NOUPD(5);
114 SELECTOR_CODE_NOUPD(6);
115 SELECTOR_CODE_NOUPD(7);
116 SELECTOR_CODE_NOUPD(8);
117 SELECTOR_CODE_NOUPD(9);
118 SELECTOR_CODE_NOUPD(10);
119 SELECTOR_CODE_NOUPD(11);
120 SELECTOR_CODE_NOUPD(12);
121 SELECTOR_CODE_NOUPD(13);
122 SELECTOR_CODE_NOUPD(14);
123 SELECTOR_CODE_NOUPD(15);
125 /* -----------------------------------------------------------------------------
128 An apply thunk is a thunk of the form
130 let z = [x1...xn] \u x1...xn
133 We pre-compile some of these because the code is always the same.
135 These have to be independent of the update frame size, so the code
136 works when profiling etc.
137 -------------------------------------------------------------------------- */
139 FN_(__ap_1_upd_entry);
140 FN_(__ap_2_upd_entry);
141 FN_(__ap_3_upd_entry);
142 FN_(__ap_4_upd_entry);
143 FN_(__ap_5_upd_entry);
144 FN_(__ap_6_upd_entry);
145 FN_(__ap_7_upd_entry);
146 FN_(__ap_8_upd_entry);
148 #define UF_SIZE (sizeofW(StgUpdateFrame))
150 /* __ap_1_upd_info is a bit redundant, but there appears to be a bug
151 * in the compiler that means __ap_1 is generated occasionally (ToDo)
154 INFO_TABLE_SRT(__ap_1_upd_info,__ap_1_upd_entry,1,0,0,0,0,THUNK, const,EF_,0,0);
155 FN_(__ap_1_upd_entry) {
157 STK_CHK_NP(sizeofW(StgUpdateFrame),1,);
158 UPD_BH_UPDATABLE(R1.p);
159 PUSH_UPD_FRAME(R1.p,0);
160 R1.p=(P_)(R1.cl->payload[0]);
161 Sp = Sp - sizeofW(StgUpdateFrame);
162 JMP_(ENTRY_CODE(*R1.p));
166 INFO_TABLE_SRT(__ap_2_upd_info,__ap_2_upd_entry,2,0,0,0,0,THUNK, const,EF_,0,0);
167 FN_(__ap_2_upd_entry) {
169 STK_CHK_NP(sizeofW(StgUpdateFrame)+1,1,);
170 UPD_BH_UPDATABLE(R1.p);
171 PUSH_UPD_FRAME(R1.p,0);
172 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[1]);
173 R1.p=(P_)(R1.cl->payload[0]);
174 Sp = Sp - (sizeofW(StgUpdateFrame)+1);
175 JMP_(ENTRY_CODE(*R1.p));
179 INFO_TABLE_SRT(__ap_3_upd_info,__ap_3_upd_entry,3,0,0,0,0,THUNK, const,EF_,0,0);
180 FN_(__ap_3_upd_entry) {
182 STK_CHK_NP(sizeofW(StgUpdateFrame)+2,1,);
183 UPD_BH_UPDATABLE(R1.p);
184 PUSH_UPD_FRAME(R1.p,0);
185 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[2]);
186 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[1]);
187 R1.p=(P_)(R1.cl->payload[0]);
188 Sp = Sp - (sizeofW(StgUpdateFrame)+2);
189 JMP_(ENTRY_CODE(*R1.p));
193 INFO_TABLE_SRT(__ap_4_upd_info,__ap_4_upd_entry,4,0,0,0,0,THUNK, const,EF_,0,0);
194 FN_(__ap_4_upd_entry) {
196 STK_CHK_NP(sizeofW(StgUpdateFrame)+3,1,);
197 UPD_BH_UPDATABLE(R1.p);
198 PUSH_UPD_FRAME(R1.p,0);
199 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[3]);
200 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[2]);
201 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[1]);
202 R1.p=(P_)(R1.cl->payload[0]);
203 Sp = Sp - (sizeofW(StgUpdateFrame)+3);
204 JMP_(ENTRY_CODE(*R1.p));
208 INFO_TABLE_SRT(__ap_5_upd_info,__ap_5_upd_entry,5,0,0,0,0,THUNK, const,EF_,0,0);
209 FN_(__ap_5_upd_entry) {
211 STK_CHK_NP(sizeofW(StgUpdateFrame)+4,1,);
212 UPD_BH_UPDATABLE(R1.p);
213 PUSH_UPD_FRAME(R1.p,0);
214 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[4]);
215 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[3]);
216 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[2]);
217 Sp[-UF_SIZE-4]=(W_)(R1.cl->payload[1]);
218 R1.p=(P_)(R1.cl->payload[0]);
219 Sp = Sp - (sizeofW(StgUpdateFrame)+4);
220 JMP_(ENTRY_CODE(*R1.p));
224 INFO_TABLE_SRT(__ap_6_upd_info,__ap_6_upd_entry,6,0,0,0,0,THUNK, const,EF_,0,0);
225 FN_(__ap_6_upd_entry) {
227 STK_CHK_NP(sizeofW(StgUpdateFrame)+5,1,);
228 UPD_BH_UPDATABLE(R1.p);
229 PUSH_UPD_FRAME(R1.p,0);
230 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[5]);
231 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[4]);
232 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[3]);
233 Sp[-UF_SIZE-4]=(W_)(R1.cl->payload[2]);
234 Sp[-UF_SIZE-5]=(W_)(R1.cl->payload[1]);
235 R1.p=(P_)(R1.cl->payload[0]);
236 Sp = Sp - (sizeofW(StgUpdateFrame)+5);
237 JMP_(ENTRY_CODE(*R1.p));
241 INFO_TABLE_SRT(__ap_7_upd_info,__ap_7_upd_entry,7,0,0,0,0,THUNK, const,EF_,0,0);
242 FN_(__ap_7_upd_entry) {
244 STK_CHK_NP(sizeofW(StgUpdateFrame)+6,1,);
245 UPD_BH_UPDATABLE(R1.p);
246 PUSH_UPD_FRAME(R1.p,0);
247 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[6]);
248 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[5]);
249 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[4]);
250 Sp[-UF_SIZE-4]=(W_)(R1.cl->payload[3]);
251 Sp[-UF_SIZE-5]=(W_)(R1.cl->payload[2]);
252 Sp[-UF_SIZE-6]=(W_)(R1.cl->payload[1]);
253 R1.p=(P_)(R1.cl->payload[0]);
254 Sp = Sp - (sizeofW(StgUpdateFrame)+6);
255 JMP_(ENTRY_CODE(*R1.p));
259 INFO_TABLE_SRT(__ap_8_upd_info,__ap_8_upd_entry,8,0,0,0,0,THUNK, const,EF_,0,0);
260 FN_(__ap_8_upd_entry) {
262 STK_CHK_NP(sizeofW(StgUpdateFrame)+7,1,);
263 UPD_BH_UPDATABLE(R1.p);
264 PUSH_UPD_FRAME(R1.p,0);
265 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[7]);
266 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[6]);
267 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[5]);
268 Sp[-UF_SIZE-4]=(W_)(R1.cl->payload[4]);
269 Sp[-UF_SIZE-5]=(W_)(R1.cl->payload[3]);
270 Sp[-UF_SIZE-6]=(W_)(R1.cl->payload[2]);
271 Sp[-UF_SIZE-7]=(W_)(R1.cl->payload[1]);
272 R1.p=(P_)(R1.cl->payload[0]);
274 JMP_(ENTRY_CODE(*R1.p));