1 /* src/vm/jit/intrp/codegen.c - code generator for Interpreter
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
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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 Changes: Christian Thalinger
33 $Id: codegen.c 3247 2005-09-21 14:59:57Z twisti $
47 #include "vm/jit/intrp/codegen.h"
49 #include "cacao/cacao.h"
50 #include "native/native.h"
51 #include "vm/builtin.h"
52 #include "vm/global.h"
53 #include "vm/loader.h"
54 #include "vm/stringlocal.h"
55 #include "vm/tables.h"
56 #include "vm/jit/asmpart.h"
57 #include "vm/jit/codegen.inc"
58 #include "vm/jit/jit.h"
60 #include "vm/jit/parse.h"
61 #include "vm/jit/patcher.h"
63 #include "vm/jit/intrp/intrp.h"
65 #include "libffi/include/ffi.h"
68 #define gen_branch(_inst) { \
69 gen_##_inst(((Inst **)cd), 0); \
70 codegen_addreference(cd, (basicblock *) (iptr->target), cd->mcodeptr); \
73 #define index2offset(_i) (-(_i) * SIZEOF_VOID_P)
75 /* functions used by cacao-gen.i */
77 /* vmgen-0.6.2 generates gen_... calls with Inst ** as first
78 parameter, but we need to pass in cd to make last_compiled
81 void genarg_v(Inst **cd1, Cell v)
83 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
84 *((Cell *) *mcodepp) = v;
88 void genarg_i(Inst **cd1, s4 i)
90 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
91 *((Cell *) *mcodepp) = i;
95 void genarg_b(Inst ** cd1, s4 i)
100 void genarg_f(Inst ** cd1, float f)
108 void genarg_l(Inst ** cd1, s8 l)
110 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
111 vm_l2twoCell(l, ((Cell *) *mcodepp)[1], ((Cell *) *mcodepp)[0]);
115 void genarg_aRef(Inst ** cd1, java_objectheader *a)
117 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
118 *((java_objectheader **) *mcodepp) = a;
122 void genarg_aArray(Inst ** cd1, java_arrayheader *a)
124 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
125 *((java_arrayheader **) *mcodepp) = a;
129 void genarg_aaTarget(Inst ** cd1, Inst **a)
131 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
132 *((Inst ***) *mcodepp) = a;
136 void genarg_aClass(Inst ** cd1, classinfo *a)
138 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
139 *((classinfo **) *mcodepp) = a;
143 void genarg_acr(Inst ** cd1, constant_classref *a)
145 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
146 *((constant_classref **) *mcodepp) = a;
150 void genarg_addr(Inst ** cd1, u1 *a)
152 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
153 *((u1 **) *mcodepp) = a;
157 void genarg_af(Inst ** cd1, functionptr a)
159 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
160 *((functionptr *) *mcodepp) = a;
164 void genarg_am(Inst ** cd1, methodinfo *a)
166 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
167 *((methodinfo **) *mcodepp) = a;
171 void genarg_acell(Inst ** cd1, Cell *a)
173 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
174 *((Cell **) *mcodepp) = a;
178 void genarg_ainst(Inst ** cd1, Inst *a)
180 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
181 *((Inst **) *mcodepp) = a;
185 void genarg_auf(Inst ** cd1, unresolved_field *a)
187 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
188 *((unresolved_field **) *mcodepp) = a;
192 void genarg_aum(Inst ** cd1, unresolved_method *a)
194 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
195 *((unresolved_method **) *mcodepp) = a;
199 void genarg_avftbl(Inst ** cd1, vftbl_t *a)
201 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
202 *((vftbl_t **) *mcodepp) = a;
207 /* include the interpreter generation functions *******************************/
209 #include "vm/jit/intrp/java-gen.i"
212 typedef void (*genfunctionptr) (Inst **);
214 typedef struct builtin_gen builtin_gen;
221 struct builtin_gen builtin_gen_table[] = {
222 {BUILTIN_new, gen_NEW, },
223 {BUILTIN_newarray, gen_NEWARRAY, },
224 {BUILTIN_newarray_boolean, gen_NEWARRAY_BOOLEAN,},
225 {BUILTIN_newarray_byte, gen_NEWARRAY_BYTE, },
226 {BUILTIN_newarray_char, gen_NEWARRAY_CHAR, },
227 {BUILTIN_newarray_short, gen_NEWARRAY_SHORT, },
228 {BUILTIN_newarray_int, gen_NEWARRAY_INT, },
229 {BUILTIN_newarray_long, gen_NEWARRAY_LONG, },
230 {BUILTIN_newarray_float, gen_NEWARRAY_FLOAT, },
231 {BUILTIN_newarray_double, gen_NEWARRAY_DOUBLE, },
232 {BUILTIN_arrayinstanceof, gen_ARRAYINSTANCEOF, },
233 #if defined(USE_THREADS)
234 {BUILTIN_monitorenter, gen_MONITORENTER, },
235 {BUILTIN_monitorexit, gen_MONITOREXIT, },
237 {BUILTIN_f2l, gen_F2L, },
238 {BUILTIN_d2l, gen_D2L, },
239 {BUILTIN_f2i, gen_F2I, },
240 {BUILTIN_d2i, gen_D2I, },
241 {BUILTIN_idiv, gen_IDIV, },
242 {BUILTIN_irem, gen_IREM, },
243 {BUILTIN_ldiv, gen_LDIV, },
244 {BUILTIN_lrem, gen_LREM, },
245 {BUILTIN_frem, gen_FREM, },
246 {BUILTIN_drem, gen_DREM, },
250 The following ones cannot use the BUILTIN mechanism, because they
251 need the class as immediate arguments of the patcher
253 PATCHER_builtin_new, gen_PATCHER_NEW,
254 PATCHER_builtin_newarray, gen_PATCHER_NEWARRAY,
255 PATCHER_builtin_arrayinstanceof, gen_PATCHER_ARRAYINSTANCEOF,
261 /* codegen *********************************************************************
263 Generates machine code.
265 *******************************************************************************/
267 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
269 s4 i, len, s1, s2, d;
275 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
276 unresolved_method *um;
277 builtintable_entry *bte;
280 /* prevent compiler warnings */
287 /* create method header */
289 (void) dseg_addaddress(cd, m); /* MethodPointer */
290 (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P); /* FrameSize */
292 #if defined(USE_THREADS)
293 if (checksync && (m->flags & ACC_SYNCHRONIZED))
294 (void) dseg_adds4(cd, 1); /* IsSync */
297 (void) dseg_adds4(cd, 0); /* IsSync */
299 (void) dseg_adds4(cd, 0); /* IsLeaf */
300 (void) dseg_adds4(cd, 0); /* IntSave */
301 (void) dseg_adds4(cd, 0); /* FltSave */
303 dseg_addlinenumbertablesize(cd);
305 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
307 /* create exception table */
309 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
310 dseg_addtarget(cd, ex->start);
311 dseg_addtarget(cd, ex->end);
312 dseg_addtarget(cd, ex->handler);
313 (void) dseg_addaddress(cd, ex->catchtype.cls);
316 /* initialize mcode variables */
318 cd->mcodeptr = cd->mcodebase;
319 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
323 #if defined(USE_THREADS)
324 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
325 if (m->flags & ACC_STATIC)
326 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
328 gen_ALOAD(((Inst **)cd), 0);
330 gen_MONITORENTER(((Inst **)cd));
335 gen_TRACECALL(((Inst **)cd));
337 /* walk through all basic blocks */
339 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
341 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
343 if (bptr->flags >= BBREACHED) {
345 /* walk through all instructions */
352 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
353 if (iptr->line != currentline) {
354 dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
355 currentline = iptr->line;
358 MCODECHECK(64); /* an instruction usually needs < 64 words */
361 case ICMD_INLINE_START:
362 case ICMD_INLINE_END:
365 case ICMD_NOP: /* ... ==> ... */
368 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
370 gen_CHECKNULL(((Inst **)cd));
373 /* constant operations ************************************************/
375 case ICMD_ICONST: /* ... ==> ..., constant */
376 /* op1 = 0, val.i = constant */
378 gen_ICONST(((Inst **)cd), iptr->val.i);
381 case ICMD_LCONST: /* ... ==> ..., constant */
382 /* op1 = 0, val.l = constant */
384 gen_LCONST(((Inst **)cd), iptr->val.l);
387 case ICMD_FCONST: /* ... ==> ..., constant */
388 /* op1 = 0, val.f = constant */
392 vm_f2Cell(iptr->val.f, fi);
393 gen_ICONST(((Inst **)cd), fi);
397 case ICMD_DCONST: /* ... ==> ..., constant */
398 /* op1 = 0, val.d = constant */
400 gen_LCONST(((Inst **)cd), *(s8 *)&(iptr->val.d));
403 case ICMD_ACONST: /* ... ==> ..., constant */
404 /* op1 = 0, val.a = constant */
406 gen_ACONST(((Inst **)cd), iptr->val.a);
410 /* load/store operations **********************************************/
412 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
413 /* op1 = local variable */
415 gen_ILOAD(((Inst **)cd), index2offset(iptr->op1));
418 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
419 /* op1 = local variable */
421 gen_LLOAD(((Inst **)cd), index2offset(iptr->op1));
424 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
425 /* op1 = local variable */
427 gen_ALOAD(((Inst **)cd), index2offset(iptr->op1));
430 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
431 /* op1 = local variable */
433 gen_ILOAD(((Inst **)cd), index2offset(iptr->op1));
436 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
437 /* op1 = local variable */
439 gen_LLOAD(((Inst **)cd), index2offset(iptr->op1));
443 case ICMD_ISTORE: /* ..., value ==> ... */
444 /* op1 = local variable */
446 gen_ISTORE(((Inst **)cd), index2offset(iptr->op1));
449 case ICMD_LSTORE: /* ..., value ==> ... */
450 /* op1 = local variable */
452 gen_LSTORE(((Inst **)cd), index2offset(iptr->op1));
455 case ICMD_ASTORE: /* ..., value ==> ... */
456 /* op1 = local variable */
458 gen_ASTORE(((Inst **)cd), index2offset(iptr->op1));
462 case ICMD_FSTORE: /* ..., value ==> ... */
463 /* op1 = local variable */
465 gen_ISTORE(((Inst **)cd), index2offset(iptr->op1));
468 case ICMD_DSTORE: /* ..., value ==> ... */
469 /* op1 = local variable */
471 gen_LSTORE(((Inst **)cd), index2offset(iptr->op1));
475 /* pop/dup/swap operations ********************************************/
477 /* attention: double and longs are only one entry in CACAO ICMDs */
479 /* stack.c changes stack manipulation operations to treat
480 longs/doubles as occupying a single slot. Here we are
481 undoing that (and only those things that stack.c did). */
483 case ICMD_POP: /* ..., value ==> ... */
485 if (IS_2_WORD_TYPE(src->type))
486 gen_POP2(((Inst **)cd));
488 gen_POP(((Inst **)cd));
491 case ICMD_POP2: /* ..., value, value ==> ... */
493 gen_POP2(((Inst **)cd));
496 case ICMD_DUP: /* ..., a ==> ..., a, a */
498 if (IS_2_WORD_TYPE(src->type))
499 gen_DUP2(((Inst **)cd));
501 gen_DUP(((Inst **)cd));
504 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
506 if (IS_2_WORD_TYPE(src->type)) {
507 if (IS_2_WORD_TYPE(src->prev->type)) {
508 gen_DUP2_X2(((Inst **)cd));
510 gen_DUP2_X1(((Inst **)cd));
513 if (IS_2_WORD_TYPE(src->prev->type)) {
514 gen_DUP_X2(((Inst **)cd));
516 gen_DUP_X1(((Inst **)cd));
521 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
523 if (IS_2_WORD_TYPE(src->type)) {
524 gen_DUP2_X2(((Inst **)cd));
526 gen_DUP_X2(((Inst **)cd));
529 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
531 gen_DUP2(((Inst **)cd));
534 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
536 if (IS_2_WORD_TYPE(src->prev->prev->type))
537 gen_DUP2_X2(((Inst **)cd));
539 gen_DUP2_X1(((Inst **)cd));
542 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
544 gen_DUP2_X2(((Inst **)cd));
547 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
549 gen_SWAP(((Inst **)cd));
553 /* integer operations *************************************************/
555 case ICMD_INEG: /* ..., value ==> ..., - value */
557 gen_INEG(((Inst **)cd));
560 case ICMD_LNEG: /* ..., value ==> ..., - value */
562 gen_LNEG(((Inst **)cd));
565 case ICMD_I2L: /* ..., value ==> ..., value */
567 gen_I2L(((Inst **)cd));
570 case ICMD_L2I: /* ..., value ==> ..., value */
572 gen_L2I(((Inst **)cd));
575 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
577 gen_INT2BYTE(((Inst **)cd));
580 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
582 gen_INT2CHAR(((Inst **)cd));
585 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
587 gen_INT2SHORT(((Inst **)cd));
591 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
593 gen_IADD(((Inst **)cd));
596 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
597 /* val.i = constant */
599 gen_ICONST(((Inst **)cd), iptr->val.i);
600 gen_IADD(((Inst **)cd));
603 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
605 gen_LADD(((Inst **)cd));
608 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
609 /* val.l = constant */
611 gen_LCONST(((Inst **)cd), iptr->val.l);
612 gen_LADD(((Inst **)cd));
615 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
617 gen_ISUB(((Inst **)cd));
620 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
621 /* val.i = constant */
623 gen_ICONST(((Inst **)cd), iptr->val.i);
624 gen_ISUB(((Inst **)cd));
627 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
629 gen_LSUB(((Inst **)cd));
632 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
633 /* val.l = constant */
635 gen_LCONST(((Inst **)cd), iptr->val.l);
636 gen_LSUB(((Inst **)cd));
639 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
641 gen_IMUL(((Inst **)cd));
644 case ICMD_IMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
646 gen_ICONST(((Inst **)cd), iptr->val.i);
647 gen_IMUL(((Inst **)cd));
650 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
652 gen_LMUL(((Inst **)cd));
655 case ICMD_LMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
657 gen_LCONST(((Inst **)cd), iptr->val.l);
658 gen_LMUL(((Inst **)cd));
661 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
663 gen_IDIV(((Inst **)cd));
666 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
668 gen_IREM(((Inst **)cd));
671 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
673 gen_LDIV(((Inst **)cd));
676 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
678 gen_LREM(((Inst **)cd));
681 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
682 /* val.i = constant */
684 gen_IDIVPOW2(((Inst **)cd), iptr->val.i);
687 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
688 /* val.i = constant */
690 gen_IREMPOW2(((Inst **)cd), iptr->val.i);
693 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
694 /* val.i = constant */
696 gen_LDIVPOW2(((Inst **)cd), iptr->val.i);
699 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
700 /* val.l = constant */
702 gen_LREMPOW2(((Inst **)cd), iptr->val.i);
705 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
707 gen_ISHL(((Inst **)cd));
710 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
711 /* val.i = constant */
713 gen_ICONST(((Inst **)cd), iptr->val.i);
714 gen_ISHL(((Inst **)cd));
717 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
719 gen_ISHR(((Inst **)cd));
722 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
723 /* val.i = constant */
725 gen_ICONST(((Inst **)cd), iptr->val.i);
726 gen_ISHR(((Inst **)cd));
729 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
731 gen_IUSHR(((Inst **)cd));
734 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
735 /* val.i = constant */
737 gen_ICONST(((Inst **)cd), iptr->val.i);
738 gen_IUSHR(((Inst **)cd));
741 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
743 gen_LSHL(((Inst **)cd));
746 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
747 /* val.i = constant */
749 gen_ICONST(((Inst **)cd), iptr->val.i);
750 gen_LSHL(((Inst **)cd));
753 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
755 gen_LSHR(((Inst **)cd));
758 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
759 /* val.i = constant */
761 gen_ICONST(((Inst **)cd), iptr->val.i);
762 gen_LSHR(((Inst **)cd));
765 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
767 gen_LUSHR(((Inst **)cd));
770 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
771 /* val.i = constant */
773 gen_ICONST(((Inst **)cd), iptr->val.i);
774 gen_LUSHR(((Inst **)cd));
777 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
779 gen_IAND(((Inst **)cd));
782 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
783 /* val.i = constant */
785 gen_ICONST(((Inst **)cd), iptr->val.i);
786 gen_IAND(((Inst **)cd));
789 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
791 gen_LAND(((Inst **)cd));
794 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
795 /* val.l = constant */
797 gen_LCONST(((Inst **)cd), iptr->val.l);
798 gen_LAND(((Inst **)cd));
801 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
803 gen_IOR(((Inst **)cd));
806 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
807 /* val.i = constant */
809 gen_ICONST(((Inst **)cd), iptr->val.i);
810 gen_IOR(((Inst **)cd));
813 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
815 gen_LOR(((Inst **)cd));
818 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
819 /* val.l = constant */
821 gen_LCONST(((Inst **)cd), iptr->val.l);
822 gen_LOR(((Inst **)cd));
825 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
827 gen_IXOR(((Inst **)cd));
830 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
831 /* val.i = constant */
833 gen_ICONST(((Inst **)cd), iptr->val.i);
834 gen_IXOR(((Inst **)cd));
837 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
839 gen_LXOR(((Inst **)cd));
842 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
843 /* val.l = constant */
845 gen_LCONST(((Inst **)cd), iptr->val.l);
846 gen_LXOR(((Inst **)cd));
850 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
852 gen_LCMP(((Inst **)cd));
856 case ICMD_IINC: /* ..., value ==> ..., value + constant */
857 /* op1 = variable, val.i = constant */
859 gen_IINC(((Inst **)cd), index2offset(iptr->op1), iptr->val.i);
863 /* floating operations ************************************************/
865 case ICMD_FNEG: /* ..., value ==> ..., - value */
867 gen_FNEG(((Inst **)cd));
870 case ICMD_DNEG: /* ..., value ==> ..., - value */
872 gen_DNEG(((Inst **)cd));
875 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
877 gen_FADD(((Inst **)cd));
880 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
882 gen_DADD(((Inst **)cd));
885 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
887 gen_FSUB(((Inst **)cd));
890 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
892 gen_DSUB(((Inst **)cd));
895 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
897 gen_FMUL(((Inst **)cd));
900 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
902 gen_DMUL(((Inst **)cd));
905 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
907 gen_FDIV(((Inst **)cd));
910 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
912 gen_DDIV(((Inst **)cd));
915 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
917 gen_FREM(((Inst **)cd));
920 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
922 gen_DREM(((Inst **)cd));
925 case ICMD_I2F: /* ..., value ==> ..., (float) value */
927 gen_I2F(((Inst **)cd));
930 case ICMD_L2F: /* ..., value ==> ..., (float) value */
932 gen_L2F(((Inst **)cd));
935 case ICMD_I2D: /* ..., value ==> ..., (double) value */
937 gen_I2D(((Inst **)cd));
940 case ICMD_L2D: /* ..., value ==> ..., (double) value */
942 gen_L2D(((Inst **)cd));
945 case ICMD_F2I: /* ..., value ==> ..., (int) value */
947 gen_F2I(((Inst **)cd));
950 case ICMD_D2I: /* ..., value ==> ..., (int) value */
952 gen_D2I(((Inst **)cd));
955 case ICMD_F2L: /* ..., value ==> ..., (long) value */
957 gen_F2L(((Inst **)cd));
960 case ICMD_D2L: /* ..., value ==> ..., (long) value */
962 gen_D2L(((Inst **)cd));
965 case ICMD_F2D: /* ..., value ==> ..., (double) value */
967 gen_F2D(((Inst **)cd));
970 case ICMD_D2F: /* ..., value ==> ..., (float) value */
972 gen_D2F(((Inst **)cd));
975 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
977 gen_FCMPL(((Inst **)cd));
980 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
982 gen_DCMPL(((Inst **)cd));
985 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
987 gen_FCMPG(((Inst **)cd));
990 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
992 gen_DCMPG(((Inst **)cd));
996 /* memory operations **************************************************/
998 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1000 gen_ARRAYLENGTH(((Inst **)cd));
1003 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1005 gen_BALOAD(((Inst **)cd));
1008 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1010 gen_CALOAD(((Inst **)cd));
1013 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1015 gen_SALOAD(((Inst **)cd));
1018 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1019 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1021 gen_IALOAD(((Inst **)cd));
1024 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1025 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1027 gen_LALOAD(((Inst **)cd));
1030 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1032 gen_AALOAD(((Inst **)cd));
1036 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1038 gen_BASTORE(((Inst **)cd));
1041 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1042 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1044 gen_CASTORE(((Inst **)cd));
1047 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1048 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1050 gen_IASTORE(((Inst **)cd));
1053 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1054 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1056 gen_LASTORE(((Inst **)cd));
1059 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1061 gen_AASTORE(((Inst **)cd));
1065 case ICMD_GETSTATIC: /* ... ==> ..., value */
1066 /* op1 = type, val.a = field address */
1069 fieldinfo *fi = iptr->val.a;
1070 unresolved_field *uf = iptr->target;
1072 switch (iptr->op1) {
1075 if (fi == NULL || !fi->class->initialized) {
1076 gen_PATCHER_GETSTATIC_INT(((Inst **)cd), 0, uf);
1078 gen_GETSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1083 if (fi == NULL || !fi->class->initialized) {
1084 gen_PATCHER_GETSTATIC_LONG(((Inst **)cd), 0, uf);
1086 gen_GETSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1090 if (fi == NULL || !fi->class->initialized) {
1091 gen_PATCHER_GETSTATIC_CELL(((Inst **)cd), 0, uf);
1093 gen_GETSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1100 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1101 /* op1 = type, val.a = field address */
1104 fieldinfo *fi = iptr->val.a;
1105 unresolved_field *uf = iptr->target;
1107 switch (iptr->op1) {
1110 if (fi == NULL || !fi->class->initialized) {
1111 gen_PATCHER_PUTSTATIC_INT(((Inst **)cd), 0, uf);
1113 gen_PUTSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1118 if (fi == NULL || !fi->class->initialized) {
1119 gen_PATCHER_PUTSTATIC_LONG(((Inst **)cd), 0, uf);
1121 gen_PUTSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1125 if (fi == NULL || !fi->class->initialized) {
1126 gen_PATCHER_PUTSTATIC_CELL(((Inst **)cd), 0, uf);
1128 gen_PUTSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1135 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1136 /* val = value (in current instruction) */
1137 /* op1 = type, val.a = field address (in */
1138 /* following NOP) */
1141 fieldinfo *fi = iptr[1].val.a;
1142 unresolved_field *uf = iptr[1].target;
1144 switch (iptr->op1) {
1147 gen_ICONST(((Inst **)cd), iptr->val.i);
1148 if (fi == NULL || !fi->class->initialized) {
1149 gen_PATCHER_PUTSTATIC_INT(((Inst **)cd), 0, uf);
1151 gen_PUTSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1156 gen_LCONST(((Inst **)cd), iptr->val.l);
1157 if (fi == NULL || !fi->class->initialized) {
1158 gen_PATCHER_PUTSTATIC_LONG(((Inst **)cd), 0, uf);
1160 gen_PUTSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1164 gen_ACONST(((Inst **)cd), iptr->val.a);
1165 if (fi == NULL || !fi->class->initialized) {
1166 gen_PATCHER_PUTSTATIC_CELL(((Inst **)cd), 0, uf);
1168 gen_PUTSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1176 case ICMD_GETFIELD: /* ... ==> ..., value */
1177 /* op1 = type, val.a = field address */
1180 fieldinfo *fi = iptr->val.a;
1181 unresolved_field *uf = iptr->target;
1183 switch (iptr->op1) {
1187 gen_PATCHER_GETFIELD_INT(((Inst **)cd), 0, uf);
1189 gen_GETFIELD_INT(((Inst **)cd), fi->offset, uf);
1195 gen_PATCHER_GETFIELD_LONG(((Inst **)cd), 0, uf);
1197 gen_GETFIELD_LONG(((Inst **)cd), fi->offset, uf);
1202 gen_PATCHER_GETFIELD_CELL(((Inst **)cd), 0, uf);
1204 gen_GETFIELD_CELL(((Inst **)cd), fi->offset, uf);
1211 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1212 /* op1 = type, val.a = field address */
1215 fieldinfo *fi = iptr->val.a;
1216 unresolved_field *uf = iptr->target;
1218 switch (iptr->op1) {
1222 gen_PATCHER_PUTFIELD_INT(((Inst **)cd), 0, uf);
1224 gen_PUTFIELD_INT(((Inst **)cd), fi->offset, uf);
1230 gen_PATCHER_PUTFIELD_LONG(((Inst **)cd), 0, uf);
1232 gen_PUTFIELD_LONG(((Inst **)cd), fi->offset, uf);
1237 gen_PATCHER_PUTFIELD_CELL(((Inst **)cd), 0, uf);
1239 gen_PUTFIELD_CELL(((Inst **)cd), fi->offset, uf);
1246 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1247 /* val = value (in current instruction) */
1248 /* op1 = type, val.a = field address (in */
1249 /* following NOP) */
1252 fieldinfo *fi = iptr[1].val.a;
1253 unresolved_field *uf = iptr[1].target;
1255 switch (iptr[1].op1) {
1258 gen_ICONST(((Inst **)cd), iptr->val.i);
1260 gen_PATCHER_PUTFIELD_INT(((Inst **)cd), 0, uf);
1262 gen_PUTFIELD_INT(((Inst **)cd), fi->offset, uf);
1267 gen_LCONST(((Inst **)cd), iptr->val.l);
1269 gen_PATCHER_PUTFIELD_LONG(((Inst **)cd), 0, uf);
1271 gen_PUTFIELD_LONG(((Inst **)cd), fi->offset, uf);
1275 gen_ACONST(((Inst **)cd), iptr->val.a);
1277 gen_PATCHER_PUTFIELD_CELL(((Inst **)cd), 0, uf);
1279 gen_PUTFIELD_CELL(((Inst **)cd), fi->offset, uf);
1287 /* branch operations **************************************************/
1289 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1291 gen_ATHROW(((Inst **)cd));
1294 case ICMD_GOTO: /* ... ==> ... */
1295 /* op1 = target JavaVM pc */
1299 case ICMD_JSR: /* ... ==> ... */
1300 /* op1 = target JavaVM pc */
1304 case ICMD_RET: /* ... ==> ... */
1305 /* op1 = local variable */
1307 gen_RET(((Inst **)cd), index2offset(iptr->op1));
1310 case ICMD_IFNULL: /* ..., value ==> ... */
1311 /* op1 = target JavaVM pc */
1316 case ICMD_IFNONNULL: /* ..., value ==> ... */
1317 /* op1 = target JavaVM pc */
1319 gen_branch(IFNONNULL);
1322 case ICMD_IFEQ: /* ..., value ==> ... */
1323 /* op1 = target JavaVM pc, val.i = constant */
1325 if (iptr->val.i == 0) {
1328 gen_ICONST(((Inst **)cd), iptr->val.i);
1329 gen_branch(IF_ICMPEQ);
1333 case ICMD_IFLT: /* ..., value ==> ... */
1334 /* op1 = target JavaVM pc, val.i = constant */
1336 if (iptr->val.i == 0) {
1339 gen_ICONST(((Inst **)cd), iptr->val.i);
1340 gen_branch(IF_ICMPLT);
1344 case ICMD_IFLE: /* ..., value ==> ... */
1345 /* op1 = target JavaVM pc, val.i = constant */
1347 if (iptr->val.i == 0) {
1350 gen_ICONST(((Inst **)cd), iptr->val.i);
1351 gen_branch(IF_ICMPLE);
1355 case ICMD_IFNE: /* ..., value ==> ... */
1356 /* op1 = target JavaVM pc, val.i = constant */
1358 if (iptr->val.i == 0) {
1361 gen_ICONST(((Inst **)cd), iptr->val.i);
1362 gen_branch(IF_ICMPNE);
1366 case ICMD_IFGT: /* ..., value ==> ... */
1367 /* op1 = target JavaVM pc, val.i = constant */
1369 if (iptr->val.i == 0) {
1372 gen_ICONST(((Inst **)cd), iptr->val.i);
1373 gen_branch(IF_ICMPGT);
1377 case ICMD_IFGE: /* ..., value ==> ... */
1378 /* op1 = target JavaVM pc, val.i = constant */
1380 if (iptr->val.i == 0) {
1383 gen_ICONST(((Inst **)cd), iptr->val.i);
1384 gen_branch(IF_ICMPGE);
1388 case ICMD_IF_LEQ: /* ..., value ==> ... */
1389 /* op1 = target JavaVM pc, val.l = constant */
1391 gen_LCONST(((Inst **)cd), iptr->val.l);
1392 gen_branch(IF_LCMPEQ);
1395 case ICMD_IF_LLT: /* ..., value ==> ... */
1396 /* op1 = target JavaVM pc, val.l = constant */
1398 gen_LCONST(((Inst **)cd), iptr->val.l);
1399 gen_branch(IF_LCMPLT);
1402 case ICMD_IF_LLE: /* ..., value ==> ... */
1403 /* op1 = target JavaVM pc, val.l = constant */
1405 gen_LCONST(((Inst **)cd), iptr->val.l);
1406 gen_branch(IF_LCMPLE);
1409 case ICMD_IF_LNE: /* ..., value ==> ... */
1410 /* op1 = target JavaVM pc, val.l = constant */
1412 gen_LCONST(((Inst **)cd), iptr->val.l);
1413 gen_branch(IF_LCMPNE);
1416 case ICMD_IF_LGT: /* ..., value ==> ... */
1417 /* op1 = target JavaVM pc, val.l = constant */
1419 gen_LCONST(((Inst **)cd), iptr->val.l);
1420 gen_branch(IF_LCMPGT);
1423 case ICMD_IF_LGE: /* ..., value ==> ... */
1424 /* op1 = target JavaVM pc, val.l = constant */
1426 gen_LCONST(((Inst **)cd), iptr->val.l);
1427 gen_branch(IF_LCMPGE);
1430 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1431 /* op1 = target JavaVM pc */
1433 gen_branch(IF_ICMPEQ);
1436 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1437 /* op1 = target JavaVM pc */
1439 gen_branch(IF_LCMPEQ);
1442 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
1443 /* op1 = target JavaVM pc */
1445 gen_branch(IF_ACMPEQ);
1448 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
1449 /* op1 = target JavaVM pc */
1451 gen_branch(IF_ICMPNE);
1454 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1455 /* op1 = target JavaVM pc */
1457 gen_branch(IF_LCMPNE);
1460 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
1461 /* op1 = target JavaVM pc */
1463 gen_branch(IF_ACMPNE);
1466 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
1467 /* op1 = target JavaVM pc */
1469 gen_branch(IF_ICMPLT);
1472 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1473 /* op1 = target JavaVM pc */
1475 gen_branch(IF_LCMPLT);
1478 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
1479 /* op1 = target JavaVM pc */
1481 gen_branch(IF_ICMPGT);
1484 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1485 /* op1 = target JavaVM pc */
1487 gen_branch(IF_LCMPGT);
1490 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
1491 /* op1 = target JavaVM pc */
1493 gen_branch(IF_ICMPLE);
1496 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1497 /* op1 = target JavaVM pc */
1499 gen_branch(IF_LCMPLE);
1502 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
1503 /* op1 = target JavaVM pc */
1505 gen_branch(IF_ICMPGE);
1508 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1509 /* op1 = target JavaVM pc */
1511 gen_branch(IF_LCMPGE);
1515 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1516 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1517 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1519 #if defined(USE_THREADS)
1520 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1521 if (m->flags & ACC_STATIC) {
1522 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1524 gen_ALOAD(((Inst **)cd), 0);
1526 gen_MONITOREXIT(((Inst **)cd));
1530 gen_TRACERETURN(((Inst **)cd));
1532 gen_IRETURN(((Inst **)cd), index2offset(cd->maxlocals));
1535 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1536 case ICMD_DRETURN: /* ..., retvalue ==> ... */
1538 #if defined(USE_THREADS)
1539 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1540 if (m->flags & ACC_STATIC) {
1541 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1543 gen_ALOAD(((Inst **)cd), 0);
1545 gen_MONITOREXIT(((Inst **)cd));
1549 gen_TRACELRETURN(((Inst **)cd));
1551 gen_LRETURN(((Inst **)cd), index2offset(cd->maxlocals));
1554 case ICMD_RETURN: /* ... ==> ... */
1556 #if defined(USE_THREADS)
1557 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1558 if (m->flags & ACC_STATIC) {
1559 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1561 gen_ALOAD(((Inst **)cd), 0);
1563 gen_MONITOREXIT(((Inst **)cd));
1567 gen_TRACERETURN(((Inst **)cd));
1569 gen_RETURN(((Inst **)cd), index2offset(cd->maxlocals));
1573 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1578 tptr = (void **) iptr->target;
1580 s4ptr = iptr->val.a;
1581 l = s4ptr[1]; /* low */
1582 i = s4ptr[2]; /* high */
1586 /* arguments: low, range, datasegment address, table offset in */
1587 /* datasegment, default target */
1588 gen_TABLESWITCH(((Inst **)cd), l, i, NULL, 0, NULL);
1589 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1590 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1592 /* build jump table top down and use address of lowest entry */
1597 dseg_addtarget(cd, (basicblock *) tptr[0]);
1602 /* length of dataseg after last dseg_addtarget is used by load */
1603 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1607 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
1612 tptr = (void **) iptr->target;
1614 s4ptr = iptr->val.a;
1616 /* s4ptr[0] is equal to tptr[0] */
1617 i = s4ptr[1]; /* count */
1619 /* arguments: count, datasegment address, table offset in */
1620 /* datasegment, default target */
1621 gen_LOOKUPSWITCH(((Inst **)cd), i, NULL, 0, NULL);
1622 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1623 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1625 /* build jump table top down and use address of lowest entry */
1631 dseg_addtarget(cd, (basicblock *) tptr[0]);
1632 dseg_addaddress(cd, s4ptr[0]);
1638 /* length of dataseg after last dseg_addtarget is used by load */
1639 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1643 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1644 /* op1 = arg count val.a = builtintable entry */
1646 if (bte->fp == PATCHER_builtin_new) {
1647 gen_PATCHER_NEW(((Inst **)cd), 0);
1648 } else if (bte->fp == PATCHER_builtin_newarray) {
1649 gen_PATCHER_NEWARRAY(((Inst **)cd), 0);
1650 } else if (bte->fp == PATCHER_builtin_arrayinstanceof) {
1651 gen_PATCHER_ARRAYINSTANCEOF(((Inst **)cd), 0);
1653 for (i = 0; i < sizeof(builtin_gen_table)/sizeof(builtin_gen); i++) {
1654 builtin_gen *bg = &builtin_gen_table[i];
1655 if (bg->builtin == bte->fp) {
1656 (bg->gen)(((Inst **)cd));
1657 goto gen_builtin_end;
1665 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1666 /* op1 = arg count, val.a = method pointer */
1672 md = um->methodref->parseddesc.md;
1673 gen_PATCHER_INVOKESTATIC(((Inst **)cd), 0, md->paramslots, um);
1676 md = lm->parseddesc;
1677 gen_INVOKESTATIC(((Inst **)cd), (Inst **)lm->stubroutine, md->paramslots, um);
1681 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1687 md = um->methodref->parseddesc.md;
1688 gen_PATCHER_INVOKESPECIAL(((Inst **)cd), 0, md->paramslots, um);
1691 md = lm->parseddesc;
1692 gen_INVOKESPECIAL(((Inst **)cd), (Inst **)lm->stubroutine, md->paramslots, um);
1696 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1702 md = um->methodref->parseddesc.md;
1703 gen_PATCHER_INVOKEVIRTUAL(((Inst **)cd), 0, md->paramslots, um);
1706 md = lm->parseddesc;
1708 s1 = OFFSET(vftbl_t, table[0]) +
1709 sizeof(methodptr) * lm->vftblindex;
1711 gen_INVOKEVIRTUAL(((Inst **)cd), s1, md->paramslots, um);
1715 case ICMD_INVOKEINTERFACE:/* op1 = arg count, val.a = method pointer */
1721 md = um->methodref->parseddesc.md;
1722 gen_PATCHER_INVOKEINTERFACE(((Inst **)cd), 0, 0, md->paramslots, um);
1725 md = lm->parseddesc;
1727 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1728 sizeof(methodptr*) * lm->class->index;
1730 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1732 gen_INVOKEINTERFACE(((Inst **)cd), s1, s2, md->paramslots, um);
1737 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1738 /* op1: 0 == array, 1 == class */
1739 /* val.a: (classinfo *) superclass */
1741 if (iptr->val.a == NULL) {
1742 gen_PATCHER_CHECKCAST(((Inst **)cd), 0, iptr->target);
1745 gen_CHECKCAST(((Inst **)cd), iptr->val.a, iptr->target);
1750 case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref */
1751 /* op1: 1... resolved, 0... not resolved */
1753 if (iptr->op1 == 0) {
1754 gen_PATCHER_ARRAYCHECKCAST(((Inst **)cd), 0, iptr->target);
1756 gen_ARRAYCHECKCAST(((Inst **)cd), iptr->target, 0);
1760 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1761 /* op1: 0 == array, 1 == class */
1762 /* val.a: (classinfo *) superclass */
1764 if (iptr->val.a == NULL) {
1765 gen_PATCHER_INSTANCEOF(((Inst **)cd), 0, iptr->target);
1767 gen_INSTANCEOF(((Inst **)cd), iptr->val.a, iptr->target);
1773 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
1775 /* XXX remove me! */
1778 case ICMD_CHECKEXCEPTION: /* ..., objectref ==> ..., objectref */
1780 gen_CHECKEXCEPTION(((Inst **)cd));
1783 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
1784 /* op1 = dimension, val.a = array descriptor */
1787 gen_PATCHER_MULTIANEWARRAY(((Inst **)cd), 0, iptr->op1, iptr->val.a);
1789 gen_MULTIANEWARRAY(((Inst **)cd), iptr->val.a, iptr->op1, 0);
1794 throw_cacao_exception_exit(string_java_lang_InternalError,
1795 "Unknown ICMD %d", iptr->opc);
1798 } /* for instruction */
1800 } /* if (bptr -> flags >= BBREACHED) */
1801 } /* for basic block */
1803 codegen_createlinenumbertable(cd);
1805 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1808 vm_block_insert(m->mcode + m->mcodelength);
1811 /* branch resolving (walk through all basic blocks) */
1813 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
1816 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
1817 gen_resolveanybranch(((u1*) m->entrypoint) + brefs->branchpos,
1818 ((u1 *)m->entrypoint) + bptr->mpc);
1824 /* a stub consists of
1836 codeptr points either to TRANSLATE or to the translated threaded code
1838 all methods are called indirectly through methodptr
1841 #define COMPILERSTUB_SIZE 4
1843 functionptr createcompilerstub (methodinfo *m)
1849 s = CNEW(Inst, COMPILERSTUB_SIZE);
1851 /* mark start of dump memory area */
1853 dumpsize = dump_size();
1855 cd = DNEW(codegendata);
1856 cd->mcodeptr = (u1 *) s;
1858 genarg_ainst((Inst **) cd, s + 2);
1860 if (m->flags & ACC_NATIVE) {
1861 genarg_i((Inst **) cd, m->parseddesc->paramslots);
1863 genarg_i((Inst **) cd, m->maxlocals);
1867 gen_TRANSLATE((Inst **) cd, m);
1870 vm_block_insert(cd->mcodeptr);
1873 #if defined(STATISTICS)
1875 count_cstub_len += COMPILERSTUB_SIZE;
1878 /* release dump area */
1880 dump_release(dumpsize);
1882 return (functionptr) s;
1898 static ffi_cif *createnativecif(methodinfo *m, methoddesc *nmd)
1900 methoddesc *md = m->parseddesc;
1901 ffi_cif *pcif = NEW(ffi_cif);
1902 ffi_type **types = MNEW(ffi_type *, nmd->paramcount);
1903 ffi_type **ptypes = types;
1906 /* pass env pointer */
1908 *ptypes++ = &ffi_type_pointer;
1910 /* for static methods, pass class pointer */
1912 if (m->flags & ACC_STATIC)
1913 *ptypes++ = &ffi_type_pointer;
1915 /* pass parameter to native function */
1917 for (i = 0; i < md->paramcount; i++)
1918 *ptypes++ = cacaotype2ffitype(md->paramtypes[i].type);
1920 assert(ptypes - types == nmd->paramcount);
1922 if (ffi_prep_cif(pcif, FFI_DEFAULT_ABI, nmd->paramcount, cacaotype2ffitype(md->returntype.type), types) != FFI_OK)
1929 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
1930 registerdata *rd, methoddesc *nmd)
1934 cd->mcodeptr = cd->mcodebase;
1935 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
1937 /* create method header */
1939 (void) dseg_addaddress(cd, m); /* MethodPointer */
1940 (void) dseg_adds4(cd, nmd->paramslots * SIZEOF_VOID_P); /* FrameSize */
1941 (void) dseg_adds4(cd, 0); /* IsSync */
1942 (void) dseg_adds4(cd, 0); /* IsLeaf */
1943 (void) dseg_adds4(cd, 0); /* IntSave */
1944 (void) dseg_adds4(cd, 0); /* FltSave */
1945 dseg_addlinenumbertablesize(cd);
1946 (void) dseg_adds4(cd, 0); /* ExTableSize */
1948 /* prepare ffi cif structure */
1950 cif = createnativecif(m, nmd);
1955 gen_TRACECALL(((Inst **)cd));
1958 gen_PATCHER_NATIVECALL(((Inst **)cd), m, f, (u1 *)cif);
1961 gen_TRACENATIVECALL(((Inst **)cd), m, f, (u1 *)cif);
1963 gen_NATIVECALL(((Inst **)cd), m, f, (u1 *)cif);
1966 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1969 vm_block_insert(m->mcode + m->mcodelength);
1972 return m->entrypoint;
1976 functionptr createcalljavafunction(methodinfo *m)
1979 functionptr entrypoint;
1982 t_inlining_globals *id;
1986 /* mark dump memory */
1988 dumpsize = dump_size();
1990 tmpm = DNEW(methodinfo);
1991 cd = DNEW(codegendata);
1992 rd = DNEW(registerdata);
1993 id = DNEW(t_inlining_globals);
1995 /* setup code generation stuff */
1997 MSET(tmpm, 0, u1, sizeof(methodinfo));
1999 inlining_setup(tmpm, id);
2000 codegen_setup(tmpm, cd, id);
2004 cd->mcodeptr = cd->mcodebase;
2005 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
2007 /* create method header */
2009 (void) dseg_addaddress(cd, NULL); /* MethodPointer */
2010 (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P); /* FrameSize */
2011 (void) dseg_adds4(cd, 0); /* IsSync */
2012 (void) dseg_adds4(cd, 0); /* IsLeaf */
2013 (void) dseg_adds4(cd, 0); /* IntSave */
2014 (void) dseg_adds4(cd, 0); /* FltSave */
2015 dseg_addlinenumbertablesize(cd);
2016 (void) dseg_adds4(cd, 0); /* ExTableSize */
2022 gen_INVOKESTATIC(((Inst **)cd), (Inst **)m->stubroutine, md->paramslots, 0);
2023 gen_END(((Inst **)cd));
2025 codegen_finish(tmpm, cd, (s4) (cd->mcodeptr - cd->mcodebase));
2028 vm_block_insert(tmpm->mcode + tmpm->mcodelength);
2030 entrypoint = tmpm->entrypoint;
2032 /* release memory */
2034 dump_release(dumpsize);
2041 * These are local overrides for various environment variables in Emacs.
2042 * Please do not remove this and leave it at the end of the file, where
2043 * Emacs will automagically detect them.
2044 * ---------------------------------------------------------------------
2047 * indent-tabs-mode: t