* src/vm/jit/emit-common.c (codegen.h): Added.
[cacao.git] / src / vm / jit / emit-common.c
1 /* src/vm/jit/emit-common.c - common code emitter functions
2
3    Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28             Edwin Steiner
29
30    $Id: emitfuncs.c 4398 2006-01-31 23:43:08Z twisti $
31
32 */
33
34
35 #include "config.h"
36
37 #include <assert.h>
38
39 #include "vm/types.h"
40
41 #include "codegen.h"
42
43 #include "vm/options.h"
44
45 #if defined(ENABLE_STATISTICS)
46 # include "vm/statistics.h"
47 #endif
48
49 #include "vm/jit/emit-common.h"
50 #include "vm/jit/jit.h"
51
52
53 /* emit_load_s1 ****************************************************************
54
55    Emits a possible load of the first source operand.
56
57 *******************************************************************************/
58
59 s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
60 {
61         varinfo *src;
62         s4       reg;
63
64         src = VAROP(iptr->s1);
65
66         reg = emit_load(jd, iptr, src, tempreg);
67
68         return reg;
69 }
70
71
72 /* emit_load_s2 ****************************************************************
73
74    Emits a possible load of the second source operand.
75
76 *******************************************************************************/
77
78 s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
79 {
80         varinfo *src;
81         s4       reg;
82
83         src = VAROP(iptr->sx.s23.s2);
84
85         reg = emit_load(jd, iptr, src, tempreg);
86
87         return reg;
88 }
89
90
91 /* emit_load_s3 ****************************************************************
92
93    Emits a possible load of the third source operand.
94
95 *******************************************************************************/
96
97 s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
98 {
99         varinfo *src;
100         s4       reg;
101
102         src = VAROP(iptr->sx.s23.s3);
103
104         reg = emit_load(jd, iptr, src, tempreg);
105
106         return reg;
107 }
108
109
110 /* emit_load_s1_low ************************************************************
111
112    Emits a possible load of the low 32-bits of the first long source
113    operand.
114
115 *******************************************************************************/
116
117 #if SIZEOF_VOID_P == 4
118 s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg)
119 {
120         varinfo *src;
121         s4       reg;
122
123         src = VAROP(iptr->s1);
124
125         reg = emit_load_low(jd, iptr, src, tempreg);
126
127         return reg;
128 }
129 #endif
130
131
132 /* emit_load_s2_low ************************************************************
133
134    Emits a possible load of the low 32-bits of the second long source
135    operand.
136
137 *******************************************************************************/
138
139 #if SIZEOF_VOID_P == 4
140 s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg)
141 {
142         varinfo *src;
143         s4       reg;
144
145         src = VAROP(iptr->sx.s23.s2);
146
147         reg = emit_load_low(jd, iptr, src, tempreg);
148
149         return reg;
150 }
151 #endif
152
153
154 /* emit_load_s3_low ************************************************************
155
156    Emits a possible load of the low 32-bits of the third long source
157    operand.
158
159 *******************************************************************************/
160
161 #if SIZEOF_VOID_P == 4
162 s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg)
163 {
164         varinfo *src;
165         s4       reg;
166
167         src = VAROP(iptr->sx.s23.s3);
168
169         reg = emit_load_low(jd, iptr, src, tempreg);
170
171         return reg;
172 }
173 #endif
174
175
176 /* emit_load_s1_high ***********************************************************
177
178    Emits a possible load of the high 32-bits of the first long source
179    operand.
180
181 *******************************************************************************/
182
183 #if SIZEOF_VOID_P == 4
184 s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg)
185 {
186         varinfo *src;
187         s4       reg;
188
189         src = VAROP(iptr->s1);
190
191         reg = emit_load_high(jd, iptr, src, tempreg);
192
193         return reg;
194 }
195 #endif
196
197
198 /* emit_load_s2_high ***********************************************************
199
200    Emits a possible load of the high 32-bits of the second long source
201    operand.
202
203 *******************************************************************************/
204
205 #if SIZEOF_VOID_P == 4
206 s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg)
207 {
208         varinfo *src;
209         s4       reg;
210
211         src = VAROP(iptr->sx.s23.s2);
212
213         reg = emit_load_high(jd, iptr, src, tempreg);
214
215         return reg;
216 }
217 #endif
218
219
220 /* emit_load_s3_high ***********************************************************
221
222    Emits a possible load of the high 32-bits of the third long source
223    operand.
224
225 *******************************************************************************/
226
227 #if SIZEOF_VOID_P == 4
228 s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg)
229 {
230         varinfo *src;
231         s4       reg;
232
233         src = VAROP(iptr->sx.s23.s3);
234
235         reg = emit_load_high(jd, iptr, src, tempreg);
236
237         return reg;
238 }
239 #endif
240
241
242 /* emit_store_dst **************************************************************
243
244    This function generates the code to store the result of an
245    operation back into a spilled pseudo-variable.  If the
246    pseudo-variable has not been spilled in the first place, this
247    function will generate nothing.
248     
249 *******************************************************************************/
250
251 void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
252 {
253         emit_store(jd, iptr, VAROP(iptr->dst), d);
254 }
255
256
257 /* emit_bxx ********************************************************************
258
259    Wrappers for conditional branch instructions.
260
261 *******************************************************************************/
262
263 void emit_bc(codegendata *cd, basicblock *target, s4 condition)
264 {
265         s4 branchmpc;
266         s4 disp;
267
268         /* Target basic block already has an PC, so we can generate the
269            branch immediately. */
270
271         if ((target->mpc >= 0)) {
272                 STATISTICS(count_branches_resolved++);
273
274                 /* calculate the mpc of the branch instruction */
275
276                 branchmpc = cd->mcodeptr - cd->mcodebase;
277                 disp      = target->mpc - branchmpc;
278
279                 emit_branch(cd, disp, condition);
280         }
281         else {
282                 /* current mcodeptr is the correct position,
283                    afterwards emit the NOPs */
284
285                 codegen_add_branch_ref(cd, target, condition);
286
287                 /* generate NOPs as placeholder for branch code */
288                 /* XXX if recompile-with-long-branches */
289
290                 BRANCH_NOPS;
291         }
292 }
293
294
295 void emit_br(codegendata *cd, basicblock *target)
296 {
297         emit_bc(cd, target, BRANCH_UNCONDITIONAL);
298 }
299
300
301 void emit_beq(codegendata *cd, basicblock *target)
302 {
303         emit_bc(cd, target, BRANCH_EQ);
304 }
305
306
307 void emit_bne(codegendata *cd, basicblock *target)
308 {
309         emit_bc(cd, target, BRANCH_NE);
310 }
311
312
313 void emit_blt(codegendata *cd, basicblock *target)
314 {
315         emit_bc(cd, target, BRANCH_LT);
316 }
317
318
319 void emit_bge(codegendata *cd, basicblock *target)
320 {
321         emit_bc(cd, target, BRANCH_GE);
322 }
323
324
325 void emit_bgt(codegendata *cd, basicblock *target)
326 {
327         emit_bc(cd, target, BRANCH_GT);
328 }
329
330
331 void emit_ble(codegendata *cd, basicblock *target)
332 {
333         emit_bc(cd, target, BRANCH_LE);
334 }
335
336
337 void emit_bnan(codegendata *cd, basicblock *target)
338 {
339         emit_bc(cd, target, BRANCH_NAN);
340 }
341
342
343 /* emit_array_checks ***********************************************************
344
345    Emit exception checks for array accesses, if they need to be
346    emitted.
347
348 *******************************************************************************/
349
350 #if defined(__ALPHA__) || defined(__POWERPC__)
351 void emit_array_checks(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
352 {
353         if (INSTRUCTION_MUST_CHECK(iptr)) {
354                 emit_nullpointer_check(cd, s1);
355                 emit_arrayindexoutofbounds_check(cd, s1, s2);
356         }
357 }
358 #endif
359
360
361 /*
362  * These are local overrides for various environment variables in Emacs.
363  * Please do not remove this and leave it at the end of the file, where
364  * Emacs will automagically detect them.
365  * ---------------------------------------------------------------------
366  * Local variables:
367  * mode: c
368  * indent-tabs-mode: t
369  * c-basic-offset: 4
370  * tab-width: 4
371  * End:
372  * vim:noexpandtab:sw=4:ts=4:
373  */