* Dynamic superinstructions added.
[cacao.git] / src / vm / jit / intrp / engine.c
1 /* src/vm/jit/intrp/engine.c - #included by engine1.c and engine2.c
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Christian Thalinger
28             Anton Ertl
29
30    Changes:
31
32    $Id: engine.c 3895 2005-12-07 16:03:37Z anton $
33 */
34
35 #include <assert.h>
36
37 /* #define VM_DEBUG */
38 #define USE_spTOS
39
40 #include "arch.h"
41 #include "vm/jit/intrp/intrp.h"
42
43 #include "md-abi.h"                           /* required for TRACE_ARGS_NUM */
44
45 #include "cacao/cacao.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/jit/codegen.inc.h"
51 #include "vm/jit/methodheader.h"
52 #include "vm/jit/patcher.h"
53
54 #define FFCALL 0
55
56 #if FFCALL
57 # include "ffcall/avcall/avcall.h"
58 #else
59 # include "libffi/include/ffi.h"
60 #endif
61
62 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
63 # ifndef USE_MD_THREAD_STUFF
64 #  include "machine-instr.h"
65 # else
66 #  include "threads/native/generic-primitives.h"
67 # endif
68 #endif
69
70 #if !defined(STORE_ORDER_BARRIER) && !defined(USE_THREADS)
71 #define STORE_ORDER_BARRIER() /* nothing */
72 #endif
73
74
75 /* threading macros */
76 #define GCC_PR15242_WORKAROUND
77 #ifdef GCC_PR15242_WORKAROUND
78 #define DO_GOTO goto before_goto
79 #else
80 #define DO_GOTO goto *ca
81 #endif
82
83 #  define NEXT_P0
84 #  define IP            (ip)
85 #  define SET_IP(p)     do {ip=(p); NEXT_P0;} while (0)
86 #  define NEXT_INST     (*IP)
87 #  define INC_IP(const_inc)     do { ip+=(const_inc);} while (0)
88 #  define DEF_CA
89 #  define NEXT_P1       (ip++)
90 #  define NEXT_P1_5     do {ca=ip[-1];} while(0)
91 #  define NEXT_P2   do {NEXT_P1_5; DO_GOTO;} while(0)
92
93 #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})
94 #define IPTOS NEXT_INST
95
96 #if defined(USE_spTOS)
97 #define IF_spTOS(x) x
98 #else
99 #define IF_spTOS(x)
100 #define spTOS (sp[0])
101 #endif
102
103 /* conversion on fetch */
104
105 #ifdef VM_PROFILING
106 #define SUPER_END  vm_count_block(IP)
107 #else
108 #define SUPER_END
109 #define vm_uncount_block(_ip)   /* nothing */
110 #endif
111
112
113 #define THROW0       goto throw
114 #define THROW(_ball) do { \
115                        __asm__(""); /* work around gcc PR 25285 */ \
116                        goto *throw_##_ball; \
117                      } while (0)
118
119 #define THROWCODE(_ball) \
120     throw_##_ball##1: \
121         global_sp = sp; \
122         *exceptionptr = (stacktrace_inline_##_ball(NULL, (u1 *) fp, (functionptr) IP, (functionptr) IP)); \
123         CLEAR_global_sp; \
124         THROW0;
125
126 #define CHECK_NULL_PTR(ptr) \
127     { \
128         if ((ptr) == NULL) { \
129             THROW(nullpointerexception); \
130             } \
131         }
132
133 #define CHECK_OUT_OF_BOUNDS(_array, _idx)              \
134         {                                            \
135           if (length_array(_array) <= (u4) (_idx)) { \
136                 arrayindexoutofbounds_index = (_idx); \
137                                 THROW(arrayindexoutofboundsexception); \
138           } \
139         }
140
141 #define CHECK_ZERO_DIVISOR(_divisor) \
142   { if (_divisor == 0) \
143       THROW(arithmeticexception); \
144   } 
145
146 #if 0
147 /* !! alignment bug */
148 #define access_local_long(_offset) \
149         ( *(s8 *)(((u1 *)fp) + (_offset)) )
150 #endif
151
152 #define length_array(array)                          \
153         ( ((java_arrayheader*)(array))->size )
154
155 #define access_array_int(array, index)               \
156         ((((java_intarray*)(array))->data)[index])
157
158 #define access_array_long(array, index)               \
159         ((((java_longarray*)(array))->data)[index])
160
161 #define access_array_char(array, index)               \
162         ((((java_chararray*)(array))->data)[index])
163
164 #define access_array_short(array, index)               \
165         ((((java_shortarray*)(array))->data)[index])
166
167 #define access_array_byte(array, index)               \
168         ((((java_bytearray*)(array))->data)[index])
169
170 #define access_array_addr(array, index)               \
171         ((((java_objectarray*)(array))->data)[index])
172
173 #define MAXLOCALS(stub) (((Cell *)stub)[1])
174
175 #if 0
176 #define CLEARSTACK(_start, _end) \
177          do {Cell *__start=(_start); MSET(__start,0,u1,(_end)-__start); } while (0)
178 #else
179 #define CLEARSTACK(_start, _end)
180 #endif
181
182
183 #ifdef VM_DEBUG
184 #define NAME(_x) if (vm_debug) {fprintf(vm_out, "%lx: %-20s, ", (long)(ip-1), _x); fprintf(vm_out,"fp=%p, sp=%p", fp, sp);}
185 #else
186 #define NAME(_x)
187 #endif
188
189 #define LABEL2(name) J_##name: __asm__("");
190 #define LABEL3(name) K_##name: __asm__("");
191
192
193 java_objectheader *
194 engine(Inst *ip0, Cell * sp, Cell * fp)
195 {
196   Inst *ip;
197   Inst ca; /* code address; this is the next dispatched instruction */
198   IF_spTOS(Cell   spTOS);
199   static Inst   labels[] = {
200 #define INST_ADDR(_inst) (&&I_##_inst)
201 #include "java-labels.i"
202 #undef INST_ADDR
203           NULL,
204 #define INST_ADDR(_inst) (&&J_##_inst)
205 #include "java-labels.i"
206 #undef INST_ADDR
207 #define INST_ADDR(_inst) (&&K_##_inst)
208 #include "java-labels.i"
209 #undef INST_ADDR
210     (Label)&&after_last,
211     (Label)&&before_goto,
212     (Label)&&after_goto,
213 #define INST_ADDR(_inst) (&&H_##_inst)
214 #include "java-labels.i"
215 #undef INST_ADDR
216   };
217   /* local variables for the various throw codes; this helps make
218          potentially throwing instructions relocatable (instead of a
219          non-relocatable direct jump, they perform an indirect jump) */
220   Label throw_arithmeticexception            = &&throw_arithmeticexception1;
221   Label throw_arrayindexoutofboundsexception = &&throw_arrayindexoutofboundsexception1;
222   Label throw_classcastexception                         = &&throw_classcastexception1;  
223   Label throw_nullpointerexception                   = &&throw_nullpointerexception1;
224   Label throw_arraystoreexception            = &&throw_arraystoreexception1;
225   s4 arrayindexoutofbounds_index; /* pass the index to the throw code */
226
227   if (vm_debug)
228       fprintf(vm_out,"entering engine(%p,%p,%p)\n",ip0,sp,fp);
229   if (ip0 == NULL) {
230     return (java_objectheader *)labels;
231   }
232
233   if (0) {
234   before_goto:
235           goto *ca;
236   after_goto:
237           /* ensure that gcc does not constant-propagate the contents of
238                  these variables and thus undo our relocatability work */
239           throw_arithmeticexception = 0;
240           throw_arrayindexoutofboundsexception = 0;
241           throw_classcastexception = 0;
242           throw_nullpointerexception = 0;
243           throw_arraystoreexception = 0;
244
245       /* the actual codes jumped to through the ...exception variables */
246           THROWCODE(arithmeticexception);
247           THROWCODE(classcastexception);
248           THROWCODE(nullpointerexception);
249           THROWCODE(arraystoreexception);
250
251   throw_arrayindexoutofboundsexception1:
252           global_sp = sp;
253           *exceptionptr = stacktrace_inline_arrayindexoutofboundsexception(NULL, (u1 *) fp, (functionptr) IP, (functionptr) IP, arrayindexoutofbounds_index);
254           CLEAR_global_sp;
255           THROW0;
256   }
257
258   /* I don't have a clue where these things come from,
259      but I've put them in macros.h for the moment */
260   IF_spTOS(spTOS = sp[0]);
261
262   SET_IP(ip0);
263   NEXT;
264
265 #define INST_ADDR(_inst) (&&I_##_inst)
266 #include "java-vm.i"
267 #undef NAME
268  after_last: return NULL;
269 }
270
271
272 /*
273  * These are local overrides for various environment variables in Emacs.
274  * Please do not remove this and leave it at the end of the file, where
275  * Emacs will automagically detect them.
276  * ---------------------------------------------------------------------
277  * Local variables:
278  * mode: c
279  * indent-tabs-mode: t
280  * c-basic-offset: 4
281  * tab-width: 4
282  * End:
283  */