Import Upstream version 20180207
[hcoop/debian/mlton.git] / include / c-chunk.h
1 /* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 * Copyright (C) 1997-2000 NEC Research Institute.
4 *
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
7 */
8
9 #ifndef _C_CHUNK_H_
10 #define _C_CHUNK_H_
11
12 #include <stdio.h>
13
14 #include "ml-types.h"
15 #include "c-types.h"
16 #include "c-common.h"
17
18 #ifndef TRUE
19 #define TRUE 1
20 #endif
21
22 #ifndef FALSE
23 #define FALSE 0
24 #endif
25
26 #ifndef DEBUG_CCODEGEN
27 #define DEBUG_CCODEGEN FALSE
28 #endif
29
30 #define GCState ((Pointer)&gcState)
31 #define ExnStack *(size_t*)(GCState + ExnStackOffset)
32 #define FrontierMem *(Pointer*)(GCState + FrontierOffset)
33 #define Frontier frontier
34 #define StackBottom *(Pointer*)(GCState + StackBottomOffset)
35 #define StackTopMem *(Pointer*)(GCState + StackTopOffset)
36 #define StackTop stackTop
37
38 /* ------------------------------------------------- */
39 /* Memory */
40 /* ------------------------------------------------- */
41
42 #define C(ty, x) (*(ty*)(x))
43 #define G(ty, i) (global##ty [i])
44 #define GPNR(i) G(ObjptrNonRoot, i)
45 #define O(ty, b, o) (*(ty*)((b) + (o)))
46 #define X(ty, b, i, s, o) (*(ty*)((b) + ((i) * (s)) + (o)))
47 #define S(ty, i) *(ty*)(StackTop + (i))
48
49 /* ------------------------------------------------- */
50 /* Tests */
51 /* ------------------------------------------------- */
52
53 #define IsInt(p) (0x3 & (int)(p))
54
55 #define BZ(x, l) \
56 do { \
57 if (DEBUG_CCODEGEN) \
58 fprintf (stderr, "%s:%d: BZ(%d, %s)\n", \
59 __FILE__, __LINE__, (x), #l); \
60 if (0 == (x)) goto l; \
61 } while (0)
62
63 #define BNZ(x, l) \
64 do { \
65 if (DEBUG_CCODEGEN) \
66 fprintf (stderr, "%s:%d: BNZ(%d, %s)\n", \
67 __FILE__, __LINE__, (x), #l); \
68 if (x) goto l; \
69 } while (0)
70
71 #define FlushFrontier() \
72 do { \
73 FrontierMem = Frontier; \
74 } while (0)
75
76 #define FlushStackTop() \
77 do { \
78 StackTopMem = StackTop; \
79 } while (0)
80
81 #define CacheFrontier() \
82 do { \
83 Frontier = FrontierMem; \
84 } while (0)
85
86 #define CacheStackTop() \
87 do { \
88 StackTop = StackTopMem; \
89 } while (0)
90
91 /* ------------------------------------------------- */
92 /* Chunk */
93 /* ------------------------------------------------- */
94
95 #if (defined (__sun__) && defined (REGISTER_FRONTIER_STACKTOP))
96 #define Chunk(n) \
97 DeclareChunk(n) { \
98 struct cont cont; \
99 register unsigned int frontier asm("g5"); \
100 uintptr_t l_nextFun = nextFun; \
101 register unsigned int stackTop asm("g6");
102 #else
103 #define Chunk(n) \
104 DeclareChunk(n) { \
105 struct cont cont; \
106 Pointer frontier; \
107 uintptr_t l_nextFun = nextFun; \
108 Pointer stackTop;
109 #endif
110
111 #define ChunkSwitch(n) \
112 if (DEBUG_CCODEGEN) \
113 fprintf (stderr, "%s:%d: entering chunk %d l_nextFun = %d\n", \
114 __FILE__, __LINE__, n, (int)l_nextFun); \
115 CacheFrontier(); \
116 CacheStackTop(); \
117 while (1) { \
118 top: \
119 switch (l_nextFun) {
120
121 #define EndChunk \
122 default: \
123 /* interchunk return */ \
124 nextFun = l_nextFun; \
125 cont.nextChunk = (void*)nextChunks[nextFun]; \
126 leaveChunk: \
127 FlushFrontier(); \
128 FlushStackTop(); \
129 return cont; \
130 } /* end switch (l_nextFun) */ \
131 } /* end while (1) */ \
132 } /* end chunk */
133
134 /* ------------------------------------------------- */
135 /* Calling SML from C */
136 /* ------------------------------------------------- */
137
138 #define Thread_returnToC() \
139 do { \
140 if (DEBUG_CCODEGEN) \
141 fprintf (stderr, "%s:%d: Thread_returnToC()\n", \
142 __FILE__, __LINE__); \
143 returnToC = TRUE; \
144 return cont; \
145 } while (0)
146
147 /* ------------------------------------------------- */
148 /* farJump */
149 /* ------------------------------------------------- */
150
151 #define FarJump(n, l) \
152 do { \
153 PrepFarJump(n, l); \
154 goto leaveChunk; \
155 } while (0)
156
157 /* ------------------------------------------------- */
158 /* Stack */
159 /* ------------------------------------------------- */
160
161 #define Push(bytes) \
162 do { \
163 if (DEBUG_CCODEGEN) \
164 fprintf (stderr, "%s:%d: Push (%d)\n", \
165 __FILE__, __LINE__, bytes); \
166 StackTop += (bytes); \
167 } while (0)
168
169 #define Return() \
170 do { \
171 l_nextFun = *(uintptr_t*)(StackTop - sizeof(void*)); \
172 if (DEBUG_CCODEGEN) \
173 fprintf (stderr, "%s:%d: Return() l_nextFun = %d\n", \
174 __FILE__, __LINE__, (int)l_nextFun); \
175 goto top; \
176 } while (0)
177
178 #define Raise() \
179 do { \
180 if (DEBUG_CCODEGEN) \
181 fprintf (stderr, "%s:%d: Raise\n", \
182 __FILE__, __LINE__); \
183 StackTop = StackBottom + ExnStack; \
184 Return(); \
185 } while (0) \
186
187 /* ------------------------------------------------- */
188 /* Primitives */
189 /* ------------------------------------------------- */
190
191 #ifndef MLTON_CODEGEN_STATIC_INLINE
192 #define MLTON_CODEGEN_STATIC_INLINE static inline
193 #endif
194 /* Declare inlined math functions, since <math.h> isn't included.
195 */
196 #ifndef MLTON_CODEGEN_MATHFN
197 #define MLTON_CODEGEN_MATHFN(decl) decl
198 #endif
199 /* WordS<N>_quot and WordS<N>_rem can't be inlined with the C-codegen,
200 * because the gcc optimizer sometimes produces incorrect results when
201 * one of the arguments is a constant.
202 */
203 #ifndef MLTON_CODEGEN_WORDSQUOTREM
204 #define MLTON_CODEGEN_WORDSQUOTREM(func) PRIVATE
205 #endif
206 #ifndef MLTON_CODEGEN_WORDSQUOTREM_IMPL
207 #define MLTON_CODEGEN_WORDSQUOTREM_IMPL(func)
208 #endif
209 /* Declare memcpy, since <string.h> isn't included.
210 */
211 #ifndef MLTON_CODEGEN_MEMCPY
212 #define MLTON_CODEGEN_MEMCPY(decl)
213 #endif
214 MLTON_CODEGEN_MEMCPY(void * memcpy(void *, const void*, size_t);)
215 #include "basis-ffi.h"
216 #include "basis/coerce.h"
217 #include "basis/cpointer.h"
218 #include "basis/Real/Real-ops.h"
219 #include "basis/Real/Math-fns.h"
220 #include "basis/Word/Word-ops.h"
221 #include "basis/Word/Word-consts.h"
222 #include "basis/Word/Word-check.h"
223
224 /* ------------------------------------------------- */
225 /* Word */
226 /* ------------------------------------------------- */
227
228 #define WordS_addCheckCX(size, dst, cW, xW, l) \
229 do { \
230 WordS##size c = cW; \
231 WordS##size x = xW; \
232 WordS_addCheckBodyCX(size, c, x, goto l, dst = c + x); \
233 } while (0)
234 #define WordS8_addCheckCX(dst, c, x, l) WordS_addCheckCX(8, dst, c, x, l)
235 #define WordS16_addCheckCX(dst, c, x, l) WordS_addCheckCX(16, dst, c, x, l)
236 #define WordS32_addCheckCX(dst, c, x, l) WordS_addCheckCX(32, dst, c, x, l)
237 #define WordS64_addCheckCX(dst, c, x, l) WordS_addCheckCX(64, dst, c, x, l)
238
239 #define WordS8_addCheckXC(dst, x, c, l) WordS8_addCheckCX(dst, c, x, l)
240 #define WordS16_addCheckXC(dst, x, c, l) WordS16_addCheckCX(dst, c, x, l)
241 #define WordS32_addCheckXC(dst, x, c, l) WordS32_addCheckCX(dst, c, x, l)
242 #define WordS64_addCheckXC(dst, x, c, l) WordS64_addCheckCX(dst, c, x, l)
243
244 #define WordS8_addCheck WordS8_addCheckXC
245 #define WordS16_addCheck WordS16_addCheckXC
246 #define WordS32_addCheck WordS32_addCheckXC
247 #define WordS64_addCheck WordS64_addCheckXC
248
249
250 #define WordU_addCheckCX(size, dst, cW, xW, l) \
251 do { \
252 WordU##size c = cW; \
253 WordU##size x = xW; \
254 WordU_addCheckBodyCX(size, c, x, goto l, dst = c + x); \
255 } while (0)
256 #define WordU8_addCheckCX(dst, c, x, l) WordU_addCheckCX(8, dst, c, x, l)
257 #define WordU16_addCheckCX(dst, c, x, l) WordU_addCheckCX(16, dst, c, x, l)
258 #define WordU32_addCheckCX(dst, c, x, l) WordU_addCheckCX(32, dst, c, x, l)
259 #define WordU64_addCheckCX(dst, c, x, l) WordU_addCheckCX(64, dst, c, x, l)
260
261 #define WordU8_addCheckXC(dst, x, c, l) WordU8_addCheckCX(dst, c, x, l)
262 #define WordU16_addCheckXC(dst, x, c, l) WordU16_addCheckCX(dst, c, x, l)
263 #define WordU32_addCheckXC(dst, x, c, l) WordU32_addCheckCX(dst, c, x, l)
264 #define WordU64_addCheckXC(dst, x, c, l) WordU64_addCheckCX(dst, c, x, l)
265
266 #define WordU8_addCheck WordU8_addCheckXC
267 #define WordU16_addCheck WordU16_addCheckXC
268 #define WordU32_addCheck WordU32_addCheckXC
269 #define WordU64_addCheck WordU64_addCheckXC
270
271
272 #define WordS_negCheck(size, dst, xW, l) \
273 do { \
274 WordS##size x = xW; \
275 WordS_negCheckBody(size, x, goto l, dst = -x); \
276 } while (0)
277 #define Word8_negCheck(dst, x, l) WordS_negCheck(8, dst, x, l)
278 #define Word16_negCheck(dst, x, l) WordS_negCheck(16, dst, x, l)
279 #define Word32_negCheck(dst, x, l) WordS_negCheck(32, dst, x, l)
280 #define Word64_negCheck(dst, x, l) WordS_negCheck(64, dst, x, l)
281
282
283 #define WordS_subCheckCX(size, dst, cW, xW, l) \
284 do { \
285 WordS##size c = cW; \
286 WordS##size x = xW; \
287 WordS_subCheckBodyCX(size, c, x, goto l, dst = c - x); \
288 } while (0)
289 #define WordS8_subCheckCX(dst, c, x, l) WordS_subCheckCX(8, dst, c, x, l)
290 #define WordS16_subCheckCX(dst, c, x, l) WordS_subCheckCX(16, dst, c, x, l)
291 #define WordS32_subCheckCX(dst, c, x, l) WordS_subCheckCX(32, dst, c, x, l)
292 #define WordS64_subCheckCX(dst, c, x, l) WordS_subCheckCX(64, dst, c, x, l)
293
294 #define WordS_subCheckXC(size, dst, xW, cW, l) \
295 do { \
296 WordS##size x = xW; \
297 WordS##size c = cW; \
298 WordS_subCheckBodyXC(size, x, c, goto l, dst = x - c); \
299 } while (0)
300 #define WordS8_subCheckXC(dst, x, c, l) WordS_subCheckXC(8, dst, x, c, l)
301 #define WordS16_subCheckXC(dst, x, c, l) WordS_subCheckXC(16, dst, x, c, l)
302 #define WordS32_subCheckXC(dst, x, c, l) WordS_subCheckXC(32, dst, x, c, l)
303 #define WordS64_subCheckXC(dst, x, c, l) WordS_subCheckXC(64, dst, x, c, l)
304
305 #define WordS8_subCheck WordS8_subCheckXC
306 #define WordS16_subCheck WordS16_subCheckXC
307 #define WordS32_subCheck WordS32_subCheckXC
308 #define WordS64_subCheck WordS64_subCheckXC
309
310
311 #define WordS_mulCheck(size, dst, xW, yW, l) \
312 do { \
313 WordS##size x = xW; \
314 WordS##size y = yW; \
315 WordS_mulCheckBody(size, x, y, goto l, dst = x * y); \
316 } while (0)
317 #define WordS8_mulCheck(dst, x, y, l) WordS_mulCheck(8, dst, x, y, l)
318 #define WordS16_mulCheck(dst, x, y, l) WordS_mulCheck(16, dst, x, y, l)
319 #define WordS32_mulCheck(dst, x, y, l) WordS_mulCheck(32, dst, x, y, l)
320 #define WordS64_mulCheck(dst, x, y, l) WordS_mulCheck(64, dst, x, y, l)
321
322 #define WordU_mulCheck(size, dst, xW, yW, l) \
323 do { \
324 WordU##size x = xW; \
325 WordU##size y = yW; \
326 WordU_mulCheckBody(size, x, y, goto l, dst = x * y); \
327 } while (0)
328 #define WordU8_mulCheck(dst, x, y, l) WordU_mulCheck(8, dst, x, y, l)
329 #define WordU16_mulCheck(dst, x, y, l) WordU_mulCheck(16, dst, x, y, l)
330 #define WordU32_mulCheck(dst, x, y, l) WordU_mulCheck(32, dst, x, y, l)
331 #define WordU64_mulCheck(dst, x, y, l) WordU_mulCheck(64, dst, x, y, l)
332
333 #endif /* #ifndef _C_CHUNK_H_ */