1 /* src/vm/jit/parse.h - parser header
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Author: Christian Thalinger
29 Changes: Edwin Steiner
31 $Id: parse.h 5096 2006-07-10 14:02:25Z twisti $
42 #include "vm/global.h"
43 #include "vm/jit/codegen-common.h"
46 /* macros for verifier checks during parsing **********************************/
48 #if defined(ENABLE_VERIFIER)
50 /* We have to check local variables indices here because they are */
51 /* used in stack.c to index the locals array. */
53 #define INDEX_ONEWORD(num) \
55 if (((num) < 0) || ((num) >= m->maxlocals)) \
56 goto throw_illegal_local_variable_number; \
59 #define INDEX_TWOWORD(num) \
61 if (((num) < 0) || (((num) + 1) >= m->maxlocals)) \
62 goto throw_illegal_local_variable_number; \
65 /* CHECK_BYTECODE_INDEX(i) checks whether i is a valid bytecode index. */
66 /* The end of the bytecode (i == m->jcodelength) is considered valid. */
68 #define CHECK_BYTECODE_INDEX(i) \
70 if (((i) < 0) || ((i) >= m->jcodelength)) \
71 goto throw_invalid_bytecode_index; \
74 /* CHECK_BYTECODE_INDEX_EXCLUSIVE is used for the exclusive ends */
75 /* of exception handler ranges. */
76 #define CHECK_BYTECODE_INDEX_EXCLUSIVE(i) \
78 if ((i) < 0 || (i) > m->jcodelength) \
79 goto throw_invalid_bytecode_index; \
82 #else /* !define(ENABLE_VERIFIER) */
84 #define INDEX_ONEWORD(num)
85 #define INDEX_TWOWORD(num)
86 #define CHECK_BYTECODE_INDEX(i)
87 #define CHECK_BYTECODE_INDEX_EXCLUSIVE(i)
89 #endif /* define(ENABLE_VERIFIER) */
92 /* basic block generating macro ***********************************************/
94 #define new_block_insert(i) \
96 if (!(jd->new_basicblockindex[(i)] & 1)) { \
98 jd->new_basicblockindex[(i)] |= 1; \
102 #define block_insert(i) \
104 if (!(m->basicblockindex[(i)] & 1)) { \
106 m->basicblockindex[(i)] |= 1; \
111 /* intermediate code generating macros ****************************************/
113 /* These macros ALWAYS set the following fields of *iptr to valid values: */
118 /* These macros do NOT touch the following fields of *iptr, unless a value is */
119 /* given for them: */
124 /* The _PREPARE macros omit the PINC, so you can set additional fields */
126 /* CAUTION: Some of the _PREPARE macros don't set iptr->flags! */
131 /* CAUTION: You must set iptr->flags yourself when using this! */
132 #define NEW_OP_PREPARE(o) \
134 iptr->line = currentline;
136 #define NEW_OP_PREPARE_ZEROFLAGS(o) \
138 iptr->line = currentline; \
139 iptr->flags.bits = 0;
142 NEW_OP_PREPARE_ZEROFLAGS(o); \
145 #define NEW_OP_LOADCONST_I(v) \
146 NEW_OP_PREPARE_ZEROFLAGS(ICMD_ICONST); \
147 iptr->sx.val.i = (v); \
150 #define NEW_OP_LOADCONST_L(v) \
151 NEW_OP_PREPARE_ZEROFLAGS(ICMD_LCONST); \
152 iptr->sx.val.l = (v); \
155 #define NEW_OP_LOADCONST_F(v) \
156 NEW_OP_PREPARE_ZEROFLAGS(ICMD_FCONST); \
157 iptr->sx.val.f = (v); \
160 #define NEW_OP_LOADCONST_D(v) \
161 NEW_OP_PREPARE_ZEROFLAGS(ICMD_DCONST); \
162 iptr->sx.val.d = (v); \
165 #define NEW_OP_LOADCONST_NULL() \
166 NEW_OP_PREPARE_ZEROFLAGS(ICMD_ACONST); \
167 iptr->sx.val.anyptr = NULL; \
170 #define NEW_OP_LOADCONST_STRING(v) \
171 NEW_OP_PREPARE_ZEROFLAGS(ICMD_ACONST); \
172 iptr->sx.val.stringconst = (v); \
175 #define NEW_OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, extraflags) \
176 NEW_OP_PREPARE(ICMD_ACONST); \
178 iptr->sx.val.c.cls = (c); \
179 iptr->flags.bits = INS_FLAG_CLASS | (extraflags); \
182 iptr->sx.val.c.ref = (cr); \
183 iptr->flags.bits = INS_FLAG_CLASS | INS_FLAG_UNRESOLVED \
188 #define NEW_OP_S3_CLASSINFO_OR_CLASSREF(o, c, cr, extraflags) \
191 iptr->sx.s23.s3.c.cls= (c); \
192 iptr->flags.bits = (extraflags); \
195 iptr->sx.s23.s3.c.ref= (cr); \
196 iptr->flags.bits = INS_FLAG_UNRESOLVED | (extraflags); \
200 #define NEW_OP_INSINDEX(o, iindex) \
201 NEW_OP_PREPARE_ZEROFLAGS(o); \
202 iptr->dst.insindex = (iindex); \
205 #define NEW_OP_LOCALINDEX(o,index) \
206 NEW_OP_PREPARE_ZEROFLAGS(o); \
207 iptr->s1.localindex = (index); \
210 #define NEW_OP_LOCALINDEX_I(o,index,v) \
211 NEW_OP_PREPARE_ZEROFLAGS(o); \
212 iptr->s1.localindex = (index); \
213 iptr->sx.val.i = (v); \
216 #define NEW_OP_LOAD_ONEWORD(o,index) \
218 INDEX_ONEWORD(index); \
219 NEW_OP_LOCALINDEX(o,index); \
222 #define NEW_OP_LOAD_TWOWORD(o,index) \
224 INDEX_TWOWORD(index); \
225 NEW_OP_LOCALINDEX(o,index); \
228 #define NEW_OP_STORE_ONEWORD(o,index) \
230 INDEX_ONEWORD(index); \
231 NEW_OP_LOCALINDEX(o,index); \
234 #define NEW_OP_STORE_TWOWORD(o,index) \
236 INDEX_TWOWORD(index); \
237 NEW_OP_LOCALINDEX(o,index); \
240 #define NEW_OP_BUILTIN_CHECK_EXCEPTION(bte) \
241 jd->isleafmethod = false; \
242 NEW_OP_PREPARE_ZEROFLAGS(ICMD_BUILTIN); \
243 iptr->sx.s23.s3.bte = (bte); \
246 #define NEW_OP_BUILTIN_NO_EXCEPTION(bte) \
247 jd->isleafmethod = false; \
248 NEW_OP_PREPARE(ICMD_BUILTIN); \
249 iptr->sx.s23.s3.bte = (bte); \
250 iptr->flags.bits = INS_FLAG_NOCHECK; \
253 #define NEW_OP_BUILTIN_ARITHMETIC(opcode, bte) \
254 jd->isleafmethod = false; \
255 NEW_OP_PREPARE_ZEROFLAGS(opcode); \
256 iptr->sx.s23.s3.bte = (bte); \
259 /* CAUTION: You must set iptr->flags yourself when using this! */
260 #define NEW_OP_FMIREF_PREPARE(o, fmiref) \
262 iptr->sx.s23.s3.fmiref = (fmiref);
264 /* old macros for intermediate code generation ********************************/
266 #define LOADCONST_I(v) \
267 iptr->opc = ICMD_ICONST; \
269 iptr->line = currentline; \
272 #define LOADCONST_L(v) \
273 iptr->opc = ICMD_LCONST; \
275 iptr->line = currentline; \
278 #define LOADCONST_F(v) \
279 iptr->opc = ICMD_FCONST; \
281 iptr->line = currentline; \
284 #define LOADCONST_D(v) \
285 iptr->opc = ICMD_DCONST; \
287 iptr->line = currentline; \
290 #define LOADCONST_A(v) \
291 iptr->opc = ICMD_ACONST; \
293 iptr->line = currentline; \
296 /* ACONST instructions generated as arguments for builtin functions
297 * have op1 set to non-zero. This is used for stack overflow checking
299 /* XXX in the new instruction format use a flag for this */
300 /* XXX target used temporarily as flag */
301 #define LOADCONST_A_BUILTIN(c,cr) \
302 iptr->opc = ICMD_ACONST; \
304 iptr->line = currentline; \
306 iptr->val.a = c; iptr->target = (void*) 0x02; \
309 iptr->val.a = cr; iptr->target = (void*) 0x03; \
315 iptr->line = currentline; \
321 iptr->line = currentline; \
324 #define OP2I(o,o1,v) \
328 iptr->line = currentline; \
331 #define OP2A_NOINC(o,o1,v,l) \
337 #define OP2A(o,o1,v,l) \
338 OP2A_NOINC(o,o1,v,l); \
341 #define OP2AT(o,o1,v,t,l) \
342 OP2A_NOINC(o,o1,v,l); \
343 iptr->target = (t); \
346 #define BUILTIN(v,o1,t,l) \
347 jd->isleafmethod = false; \
348 iptr->opc = ICMD_BUILTIN; \
351 iptr->target = (t); \
355 #define OP1LOAD_ONEWORD(o,o1) \
361 #define OP1LOAD_TWOWORD(o,o1) \
367 #define OP1STORE_ONEWORD(o,o1) \
373 #define OP1STORE_TWOWORD(o,o1) \
380 /* macros for byte code fetching ***********************************************
382 fetch a byte code of given size from position p in code array jcode
384 *******************************************************************************/
386 #define code_get_u1(p,m) m->jcode[p]
387 #define code_get_s1(p,m) ((s1)m->jcode[p])
388 #define code_get_u2(p,m) ((((u2)m->jcode[p]) << 8) + m->jcode[p + 1])
389 #define code_get_s2(p,m) ((s2)((((u2)m->jcode[p]) << 8) + m->jcode[p + 1]))
390 #define code_get_u4(p,m) ((((u4)m->jcode[p]) << 24) + (((u4)m->jcode[p + 1]) << 16) \
391 +(((u4)m->jcode[p + 2]) << 8) + m->jcode[p + 3])
392 #define code_get_s4(p,m) ((s4)((((u4)m->jcode[p]) << 24) + (((u4)m->jcode[p + 1]) << 16) \
393 +(((u4)m->jcode[p + 2]) << 8) + m->jcode[p + 3]))
394 /* XXX read 32bit aligned big-endian values directly */
397 /* function prototypes ********************************************************/
399 bool parse(jitdata *jd);
401 #endif /* _PARSE_H */
405 * These are local overrides for various environment variables in Emacs.
406 * Please do not remove this and leave it at the end of the file, where
407 * Emacs will automagically detect them.
408 * ---------------------------------------------------------------------
411 * indent-tabs-mode: t
415 * vim:noexpandtab:sw=4:ts=4: