* Removed all Id tags.
[cacao.git] / src / vm / jit / parse.h
1 /* src/vm/jit/parse.h - parser header
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Author:  Christian Thalinger
28             Edwin Steiner
29
30 */
31
32
33 #ifndef _PARSE_H
34 #define _PARSE_H
35
36 #include "config.h"
37 #include "vm/types.h"
38
39 #include "vm/global.h"
40 #include "vm/jit/codegen-common.h"
41
42
43 /* macros for verifier checks during parsing **********************************/
44
45 #if defined(ENABLE_VERIFIER)
46
47 /* We have to check local variables indices here because they are             */
48 /* used in stack.c to index the locals array.                                 */
49
50 #define INDEX_ONEWORD(num) \
51     do { \
52         if (((num) < 0) || ((num) >= m->maxlocals)) \
53             goto throw_illegal_local_variable_number; \
54     } while (0)
55
56 #define INDEX_TWOWORD(num) \
57     do { \
58         if (((num) < 0) || (((num) + 1) >= m->maxlocals)) \
59             goto throw_illegal_local_variable_number; \
60     } while (0)
61
62 /* CHECK_BYTECODE_INDEX(i) checks whether i is a valid bytecode index.        */
63 /* The end of the bytecode (i == m->jcodelength) is considered valid.         */
64
65 #define CHECK_BYTECODE_INDEX(i) \
66     do { \
67         if (((i) < 0) || ((i) >= m->jcodelength)) \
68                         goto throw_invalid_bytecode_index; \
69     } while (0)
70
71 /* CHECK_BYTECODE_INDEX_EXCLUSIVE is used for the exclusive ends               */
72 /* of exception handler ranges.                                                */
73 #define CHECK_BYTECODE_INDEX_EXCLUSIVE(i) \
74     do { \
75         if ((i) < 0 || (i) > m->jcodelength) \
76                         goto throw_invalid_bytecode_index; \
77     } while (0)
78
79 #else /* !defined(ENABLE_VERIFIER) */
80
81 #define INDEX_ONEWORD(num)
82 #define INDEX_TWOWORD(num)
83 #define CHECK_BYTECODE_INDEX(i)
84 #define CHECK_BYTECODE_INDEX_EXCLUSIVE(i)
85
86 #endif /* defined(ENABLE_VERIFIER) */
87
88
89 /* basic block generating macro ***********************************************/
90
91 #define MARK_BASICBLOCK(pd, i)                                       \
92     do {                                                             \
93         (pd)->basicblockstart[(i)] = 1;                              \
94     } while (0)
95
96 #define INSTRUCTIONS_CHECK(i)                                        \
97     if ((ircount + (i)) > pd.instructionslength)                     \
98         iptr = parse_realloc_instructions(&pd, ircount, (i))
99
100
101 /* intermediate code generating macros ****************************************/
102
103 /* These macros ALWAYS set the following fields of *iptr to valid values:     */
104 /*     iptr->opc                                                              */
105 /*     iptr->flags                                                            */
106 /*     iptr->line                                                             */
107
108 /* These macros do NOT touch the following fields of *iptr, unless a value is */
109 /* given for them:                                                            */
110 /*     iptr->s1                                                               */
111 /*     iptr->sx                                                               */
112 /*     iptr->dst                                                              */
113
114 /* The _PREPARE macros omit the PINC, so you can set additional fields        */
115 /* afterwards.                                                                */
116
117 #define PINC                                                         \
118     iptr++; ircount++
119
120 #define OP_PREPARE_FLAGS(o, f)                                       \
121     iptr->opc         = (o);                                         \
122     iptr->line        = currentline;                                 \
123     iptr->flags.bits |= (f) | (ircount << INS_FLAG_ID_SHIFT);
124
125 #define OP_PREPARE_ZEROFLAGS(o)                                      \
126     OP_PREPARE_FLAGS(o, 0)
127
128 #define OP_PREPARE(o)                                                \
129     OP_PREPARE_ZEROFLAGS(o)
130
131 #define OP(o)                                                        \
132     OP_PREPARE_ZEROFLAGS(o);                                         \
133     PINC
134
135 #define OP_CHECK_EXCEPTION(o)                                        \
136     OP_PREPARE_FLAGS(o, INS_FLAG_CHECK);                             \
137     PINC
138
139 #define OP_LOADCONST_I(v)                                            \
140     OP_PREPARE_ZEROFLAGS(ICMD_ICONST);                               \
141     iptr->sx.val.i           = (v);                                  \
142     PINC
143
144 #define OP_LOADCONST_L(v)                                            \
145     OP_PREPARE_ZEROFLAGS(ICMD_LCONST);                               \
146     iptr->sx.val.l           = (v);                                  \
147     PINC
148
149 #define OP_LOADCONST_F(v)                                            \
150     OP_PREPARE_ZEROFLAGS(ICMD_FCONST);                               \
151     iptr->sx.val.f           = (v);                                  \
152     PINC
153
154 #define OP_LOADCONST_D(v)                                            \
155     OP_PREPARE_ZEROFLAGS(ICMD_DCONST);                               \
156     iptr->sx.val.d           = (v);                                  \
157     PINC
158
159 #define OP_LOADCONST_NULL()                                          \
160     OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK);                   \
161     iptr->sx.val.anyptr      = NULL;                                 \
162     PINC
163
164 #define OP_LOADCONST_STRING(v)                                       \
165     OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK);                   \
166     iptr->sx.val.stringconst = (v);                                  \
167     PINC
168
169 #define OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS(cl, cr, extraflags) \
170     OP_PREPARE(ICMD_ACONST);                                         \
171     if (cl) {                                                        \
172         iptr->sx.val.c.cls   = (cl);                                 \
173         iptr->flags.bits     |= INS_FLAG_CLASS | (extraflags);       \
174     }                                                                \
175     else {                                                           \
176         iptr->sx.val.c.ref   = (cr);                                 \
177         iptr->flags.bits     |= INS_FLAG_CLASS | INS_FLAG_UNRESOLVED \
178                              | (extraflags);                         \
179     }                                                                \
180     PINC
181
182 #define OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr)              \
183     OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS((c), (cr), INS_FLAG_CHECK)
184
185 #define OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr)            \
186     OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS((c), (cr), 0)
187
188 #define OP_S3_CLASSINFO_OR_CLASSREF(o, c, cr, extraflags)            \
189     OP_PREPARE(o);                                                   \
190     if (c) {                                                         \
191         iptr->sx.s23.s3.c.cls= (c);                                  \
192         iptr->flags.bits     |= (extraflags);                        \
193     }                                                                \
194     else {                                                           \
195         iptr->sx.s23.s3.c.ref= (cr);                                 \
196         iptr->flags.bits     |= INS_FLAG_UNRESOLVED | (extraflags);  \
197     }                                                                \
198     PINC
199
200 #define OP_INSINDEX(o, iindex)                                       \
201     OP_PREPARE_ZEROFLAGS(o);                                         \
202     iptr->dst.insindex       = (iindex);                             \
203     PINC
204
205 # define OP_LOCALINDEX(o,index)                                      \
206     OP_PREPARE_ZEROFLAGS(o);                                         \
207     iptr->s1.varindex      = (index);                                \
208     PINC
209
210 # define OP_LOCALINDEX_I(o,index,v)                                  \
211     OP_PREPARE_ZEROFLAGS(o);                                         \
212     iptr->s1.varindex      = (index);                                \
213     iptr->sx.val.i           = (v);                                  \
214     PINC
215
216 # define LOCALTYPE_USED(index,type)                                  \
217     do {                                                             \
218         local_map[(index) * 5 + (type)] = 1;                         \
219     } while (0)
220
221 #define OP_LOAD_ONEWORD(o,index,type)                                \
222     do {                                                             \
223         INDEX_ONEWORD(index);                                        \
224         OP_LOCALINDEX(o,index);                                      \
225         LOCALTYPE_USED(index,type);                                  \
226     } while (0)
227
228 #define OP_LOAD_TWOWORD(o,index,type)                                \
229     do {                                                             \
230         INDEX_TWOWORD(index);                                        \
231         OP_LOCALINDEX(o,index);                                      \
232         LOCALTYPE_USED(index,type);                                  \
233     } while (0)
234
235 # define OP_STORE_ONEWORD(o,index,type)                              \
236     do {                                                             \
237         INDEX_ONEWORD(index);                                        \
238         OP_PREPARE_ZEROFLAGS(o);                                     \
239         iptr->dst.varindex = (index);                                \
240         LOCALTYPE_USED(index,type);                                  \
241         PINC;                                                        \
242     } while (0)
243
244 # define OP_STORE_TWOWORD(o,index,type)                              \
245     do {                                                             \
246         INDEX_TWOWORD(index);                                        \
247         OP_PREPARE_ZEROFLAGS(o);                                     \
248         iptr->dst.varindex = (index);                                \
249         LOCALTYPE_USED(index,type);                                  \
250         PINC;                                                        \
251     } while (0)
252
253 #define OP_BUILTIN_CHECK_EXCEPTION(bte)                              \
254     jd->isleafmethod         = false;                                \
255     OP_PREPARE_FLAGS(ICMD_BUILTIN, INS_FLAG_CHECK);                  \
256     iptr->sx.s23.s3.bte      = (bte);                                \
257     PINC
258
259 #define OP_BUILTIN_NO_EXCEPTION(bte)                                 \
260     jd->isleafmethod         = false;                                \
261     OP_PREPARE_ZEROFLAGS(ICMD_BUILTIN);                              \
262     iptr->sx.s23.s3.bte      = (bte);                                \
263     PINC
264
265 #define OP_BUILTIN_ARITHMETIC(opcode, bte)                           \
266     jd->isleafmethod         = false;                                \
267     OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);                        \
268     iptr->sx.s23.s3.bte      = (bte);                                \
269     PINC
270
271 /* CAUTION: You must set iptr->flags yourself when using this!                */
272 #define OP_FMIREF_PREPARE(o, fmiref)                                 \
273     OP_PREPARE(o);                                                   \
274     iptr->sx.s23.s3.fmiref   = (fmiref);
275
276
277 /* function prototypes ********************************************************/
278
279 bool parse(jitdata *jd);
280
281 #endif /* _PARSE_H */
282
283
284 /*
285  * These are local overrides for various environment variables in Emacs.
286  * Please do not remove this and leave it at the end of the file, where
287  * Emacs will automagically detect them.
288  * ---------------------------------------------------------------------
289  * Local variables:
290  * mode: c
291  * indent-tabs-mode: t
292  * c-basic-offset: 4
293  * tab-width: 4
294  * End:
295  * vim:noexpandtab:sw=4:ts=4:
296  */
297