1 /* -----------------------------------------------------------------------------
2 * $Id: StgStdThunks.hc,v 1.3 1999/02/05 16:03:00 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 /* __ap_1_upd_info is a bit redundant, but there appears to be a bug
149 * in the compiler that means __ap_1 is generated occasionally (ToDo)
152 INFO_TABLE_SRT(__ap_1_upd_info,__ap_1_upd_entry,1,0,0,0,0,THUNK, const,EF_,0,0);
153 FN_(__ap_1_upd_entry) {
155 STK_CHK_NP(sizeofW(StgUpdateFrame),1,);
156 UPD_BH_UPDATABLE(R1.p);
157 PUSH_UPD_FRAME(R1.p,0);
158 R1.p=(P_)(R1.cl->payload[0]);
159 Sp = Sp - sizeofW(StgUpdateFrame);
160 JMP_(ENTRY_CODE(*R1.p));
164 INFO_TABLE_SRT(__ap_2_upd_info,__ap_2_upd_entry,2,0,0,0,0,THUNK, const,EF_,0,0);
165 FN_(__ap_2_upd_entry) {
167 STK_CHK_NP(sizeofW(StgUpdateFrame)+1,1,);
168 UPD_BH_UPDATABLE(R1.p);
169 PUSH_UPD_FRAME(R1.p,0);
170 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[1]);
171 R1.p=(P_)(R1.cl->payload[0]);
172 Sp = Sp - (sizeofW(StgUpdateFrame)+1);
173 JMP_(ENTRY_CODE(*R1.p));
177 INFO_TABLE_SRT(__ap_3_upd_info,__ap_3_upd_entry,3,0,0,0,0,THUNK, const,EF_,0,0);
178 FN_(__ap_3_upd_entry) {
180 STK_CHK_NP(sizeofW(StgUpdateFrame)+2,1,);
181 UPD_BH_UPDATABLE(R1.p);
182 PUSH_UPD_FRAME(R1.p,0);
183 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[2]);
184 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[1]);
185 R1.p=(P_)(R1.cl->payload[0]);
186 Sp = Sp - (sizeofW(StgUpdateFrame)+2);
187 JMP_(ENTRY_CODE(*R1.p));
191 INFO_TABLE_SRT(__ap_4_upd_info,__ap_4_upd_entry,4,0,0,0,0,THUNK, const,EF_,0,0);
192 FN_(__ap_4_upd_entry) {
194 STK_CHK_NP(sizeofW(StgUpdateFrame)+3,1,);
195 UPD_BH_UPDATABLE(R1.p);
196 PUSH_UPD_FRAME(R1.p,0);
197 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[3]);
198 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[2]);
199 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[1]);
200 R1.p=(P_)(R1.cl->payload[0]);
201 Sp = Sp - (sizeofW(StgUpdateFrame)+3);
202 JMP_(ENTRY_CODE(*R1.p));
206 INFO_TABLE_SRT(__ap_5_upd_info,__ap_5_upd_entry,5,0,0,0,0,THUNK, const,EF_,0,0);
207 FN_(__ap_5_upd_entry) {
209 STK_CHK_NP(sizeofW(StgUpdateFrame)+4,1,);
210 UPD_BH_UPDATABLE(R1.p);
211 PUSH_UPD_FRAME(R1.p,0);
212 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[4]);
213 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[3]);
214 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[2]);
215 Sp[-UF_SIZE-4]=(W_)(R1.cl->payload[1]);
216 R1.p=(P_)(R1.cl->payload[0]);
217 Sp = Sp - (sizeofW(StgUpdateFrame)+4);
218 JMP_(ENTRY_CODE(*R1.p));
222 INFO_TABLE_SRT(__ap_6_upd_info,__ap_6_upd_entry,6,0,0,0,0,THUNK, const,EF_,0,0);
223 FN_(__ap_6_upd_entry) {
225 STK_CHK_NP(sizeofW(StgUpdateFrame)+5,1,);
226 UPD_BH_UPDATABLE(R1.p);
227 PUSH_UPD_FRAME(R1.p,0);
228 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[5]);
229 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[4]);
230 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[3]);
231 Sp[-UF_SIZE-4]=(W_)(R1.cl->payload[2]);
232 Sp[-UF_SIZE-5]=(W_)(R1.cl->payload[1]);
233 R1.p=(P_)(R1.cl->payload[0]);
234 Sp = Sp - (sizeofW(StgUpdateFrame)+5);
235 JMP_(ENTRY_CODE(*R1.p));
239 INFO_TABLE_SRT(__ap_7_upd_info,__ap_7_upd_entry,7,0,0,0,0,THUNK, const,EF_,0,0);
240 FN_(__ap_7_upd_entry) {
242 STK_CHK_NP(sizeofW(StgUpdateFrame)+6,1,);
243 UPD_BH_UPDATABLE(R1.p);
244 PUSH_UPD_FRAME(R1.p,0);
245 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[6]);
246 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[5]);
247 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[4]);
248 Sp[-UF_SIZE-4]=(W_)(R1.cl->payload[3]);
249 Sp[-UF_SIZE-5]=(W_)(R1.cl->payload[2]);
250 Sp[-UF_SIZE-6]=(W_)(R1.cl->payload[1]);
251 R1.p=(P_)(R1.cl->payload[0]);
252 Sp = Sp - (sizeofW(StgUpdateFrame)+6);
253 JMP_(ENTRY_CODE(*R1.p));
257 INFO_TABLE_SRT(__ap_8_upd_info,__ap_8_upd_entry,8,0,0,0,0,THUNK, const,EF_,0,0);
258 FN_(__ap_8_upd_entry) {
260 STK_CHK_NP(sizeofW(StgUpdateFrame)+7,1,);
261 UPD_BH_UPDATABLE(R1.p);
262 PUSH_UPD_FRAME(R1.p,0);
263 Sp[-UF_SIZE-1]=(W_)(R1.cl->payload[7]);
264 Sp[-UF_SIZE-2]=(W_)(R1.cl->payload[6]);
265 Sp[-UF_SIZE-3]=(W_)(R1.cl->payload[5]);
266 Sp[-UF_SIZE-4]=(W_)(R1.cl->payload[4]);
267 Sp[-UF_SIZE-5]=(W_)(R1.cl->payload[3]);
268 Sp[-UF_SIZE-6]=(W_)(R1.cl->payload[2]);
269 Sp[-UF_SIZE-7]=(W_)(R1.cl->payload[1]);
270 R1.p=(P_)(R1.cl->payload[0]);
272 JMP_(ENTRY_CODE(*R1.p));