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 3731 2005-11-22 11:39:17Z twisti $
45 #include "vm/jit/intrp/codegen.h"
47 #include "cacao/cacao.h"
48 #include "native/native.h"
49 #include "vm/builtin.h"
50 #include "vm/global.h"
51 #include "vm/loader.h"
52 #include "vm/stringlocal.h"
53 #include "vm/tables.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/codegen.inc"
56 #include "vm/jit/jit.h"
58 #include "vm/jit/parse.h"
59 #include "vm/jit/patcher.h"
61 #include "vm/jit/intrp/intrp.h"
63 #include "libffi/include/ffi.h"
66 #define gen_branch(_inst) { \
67 gen_##_inst(((Inst **)cd), 0); \
68 codegen_addreference(cd, (basicblock *) (iptr->target), cd->mcodeptr); \
71 #define index2offset(_i) (-(_i) * SIZEOF_VOID_P)
73 /* functions used by cacao-gen.i */
75 /* vmgen-0.6.2 generates gen_... calls with Inst ** as first
76 parameter, but we need to pass in cd to make last_compiled
79 void genarg_v(Inst **cd1, Cell v)
81 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
82 *((Cell *) *mcodepp) = v;
86 void genarg_i(Inst **cd1, s4 i)
88 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
89 *((Cell *) *mcodepp) = i;
93 void genarg_b(Inst ** cd1, s4 i)
98 void genarg_f(Inst ** cd1, float f)
106 void genarg_l(Inst ** cd1, s8 l)
108 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
109 vm_l2twoCell(l, ((Cell *) *mcodepp)[1], ((Cell *) *mcodepp)[0]);
113 void genarg_aRef(Inst ** cd1, java_objectheader *a)
115 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
116 *((java_objectheader **) *mcodepp) = a;
120 void genarg_aArray(Inst ** cd1, java_arrayheader *a)
122 Inst **mcodepp = (Inst **) &(((codegendata *) cd1)->mcodeptr);
123 *((java_arrayheader **) *mcodepp) = a;
127 void genarg_aaTarget(Inst ** cd1, Inst **a)
129 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
130 *((Inst ***) *mcodepp) = a;
134 void genarg_aClass(Inst ** cd1, classinfo *a)
136 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
137 *((classinfo **) *mcodepp) = a;
141 void genarg_acr(Inst ** cd1, constant_classref *a)
143 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
144 *((constant_classref **) *mcodepp) = a;
148 void genarg_addr(Inst ** cd1, u1 *a)
150 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
151 *((u1 **) *mcodepp) = a;
155 void genarg_af(Inst ** cd1, functionptr a)
157 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
158 *((functionptr *) *mcodepp) = a;
162 void genarg_am(Inst ** cd1, methodinfo *a)
164 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
165 *((methodinfo **) *mcodepp) = a;
169 void genarg_acell(Inst ** cd1, Cell *a)
171 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
172 *((Cell **) *mcodepp) = a;
176 void genarg_ainst(Inst ** cd1, Inst *a)
178 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
179 *((Inst **) *mcodepp) = a;
183 void genarg_auf(Inst ** cd1, unresolved_field *a)
185 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
186 *((unresolved_field **) *mcodepp) = a;
190 void genarg_aum(Inst ** cd1, unresolved_method *a)
192 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
193 *((unresolved_method **) *mcodepp) = a;
197 void genarg_avftbl(Inst ** cd1, vftbl_t *a)
199 Inst **mcodepp = (Inst **) &(((codegendata *)cd1)->mcodeptr);
200 *((vftbl_t **) *mcodepp) = a;
205 /* include the interpreter generation functions *******************************/
207 #include "vm/jit/intrp/java-gen.i"
210 typedef void (*genfunctionptr) (Inst **);
212 typedef struct builtin_gen builtin_gen;
219 struct builtin_gen builtin_gen_table[] = {
220 {BUILTIN_new, gen_NEW, },
221 {BUILTIN_newarray, gen_NEWARRAY, },
222 {BUILTIN_newarray_boolean, gen_NEWARRAY_BOOLEAN,},
223 {BUILTIN_newarray_byte, gen_NEWARRAY_BYTE, },
224 {BUILTIN_newarray_char, gen_NEWARRAY_CHAR, },
225 {BUILTIN_newarray_short, gen_NEWARRAY_SHORT, },
226 {BUILTIN_newarray_int, gen_NEWARRAY_INT, },
227 {BUILTIN_newarray_long, gen_NEWARRAY_LONG, },
228 {BUILTIN_newarray_float, gen_NEWARRAY_FLOAT, },
229 {BUILTIN_newarray_double, gen_NEWARRAY_DOUBLE, },
230 {BUILTIN_arrayinstanceof, gen_ARRAYINSTANCEOF, },
231 #if defined(USE_THREADS)
232 {BUILTIN_monitorenter, gen_MONITORENTER, },
233 {BUILTIN_monitorexit, gen_MONITOREXIT, },
235 {BUILTIN_f2l, gen_F2L, },
236 {BUILTIN_d2l, gen_D2L, },
237 {BUILTIN_f2i, gen_F2I, },
238 {BUILTIN_d2i, gen_D2I, },
239 {BUILTIN_idiv, gen_IDIV, },
240 {BUILTIN_irem, gen_IREM, },
241 {BUILTIN_ldiv, gen_LDIV, },
242 {BUILTIN_lrem, gen_LREM, },
243 {BUILTIN_frem, gen_FREM, },
244 {BUILTIN_drem, gen_DREM, },
248 /* codegen *********************************************************************
250 Generates machine code.
252 *******************************************************************************/
254 bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
256 s4 i, len, s1, s2, d;
262 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
263 unresolved_method *um;
264 builtintable_entry *bte;
267 /* prevent compiler warnings */
274 /* create method header */
276 (void) dseg_addaddress(cd, m); /* MethodPointer */
277 (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P); /* FrameSize */
279 #if defined(USE_THREADS)
280 if (checksync && (m->flags & ACC_SYNCHRONIZED))
281 (void) dseg_adds4(cd, 1); /* IsSync */
284 (void) dseg_adds4(cd, 0); /* IsSync */
286 (void) dseg_adds4(cd, 0); /* IsLeaf */
287 (void) dseg_adds4(cd, 0); /* IntSave */
288 (void) dseg_adds4(cd, 0); /* FltSave */
290 dseg_addlinenumbertablesize(cd);
292 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
294 /* create exception table */
296 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
297 dseg_addtarget(cd, ex->start);
298 dseg_addtarget(cd, ex->end);
299 dseg_addtarget(cd, ex->handler);
300 (void) dseg_addaddress(cd, ex->catchtype.cls);
303 /* initialize mcode variables */
305 cd->mcodeptr = cd->mcodebase;
306 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
310 #if defined(USE_THREADS)
311 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
312 if (m->flags & ACC_STATIC)
313 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
315 gen_ALOAD(((Inst **)cd), 0);
317 gen_MONITORENTER(((Inst **)cd));
322 gen_TRACECALL(((Inst **)cd));
324 /* walk through all basic blocks */
326 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
328 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
330 if (bptr->flags >= BBREACHED) {
332 /* walk through all instructions */
339 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
340 if (iptr->line != currentline) {
341 dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
342 currentline = iptr->line;
345 MCODECHECK(64); /* an instruction usually needs < 64 words */
348 case ICMD_INLINE_START:
349 case ICMD_INLINE_END:
352 case ICMD_NOP: /* ... ==> ... */
355 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
357 gen_CHECKNULL(((Inst **)cd));
360 /* constant operations ************************************************/
362 case ICMD_ICONST: /* ... ==> ..., constant */
363 /* op1 = 0, val.i = constant */
365 gen_ICONST(((Inst **)cd), iptr->val.i);
368 case ICMD_LCONST: /* ... ==> ..., constant */
369 /* op1 = 0, val.l = constant */
371 gen_LCONST(((Inst **)cd), iptr->val.l);
374 case ICMD_FCONST: /* ... ==> ..., constant */
375 /* op1 = 0, val.f = constant */
379 vm_f2Cell(iptr->val.f, fi);
380 gen_ICONST(((Inst **)cd), fi);
384 case ICMD_DCONST: /* ... ==> ..., constant */
385 /* op1 = 0, val.d = constant */
387 gen_LCONST(((Inst **)cd), *(s8 *)&(iptr->val.d));
390 case ICMD_ACONST: /* ... ==> ..., constant */
391 /* op1 = 0, val.a = constant */
393 if ((iptr->target != NULL) && (iptr->val.a == NULL))
394 gen_PATCHER_ACONST(((Inst **) cd), NULL, iptr->target);
396 gen_ACONST(((Inst **) cd), iptr->val.a);
400 /* load/store operations **********************************************/
402 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
403 /* op1 = local variable */
405 gen_ILOAD(((Inst **)cd), index2offset(iptr->op1));
408 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
409 /* op1 = local variable */
411 gen_LLOAD(((Inst **)cd), index2offset(iptr->op1));
414 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
415 /* op1 = local variable */
417 gen_ALOAD(((Inst **)cd), index2offset(iptr->op1));
420 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
421 /* op1 = local variable */
423 gen_ILOAD(((Inst **)cd), index2offset(iptr->op1));
426 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
427 /* op1 = local variable */
429 gen_LLOAD(((Inst **)cd), index2offset(iptr->op1));
433 case ICMD_ISTORE: /* ..., value ==> ... */
434 /* op1 = local variable */
436 gen_ISTORE(((Inst **)cd), index2offset(iptr->op1));
439 case ICMD_LSTORE: /* ..., value ==> ... */
440 /* op1 = local variable */
442 gen_LSTORE(((Inst **)cd), index2offset(iptr->op1));
445 case ICMD_ASTORE: /* ..., value ==> ... */
446 /* op1 = local variable */
448 gen_ASTORE(((Inst **)cd), index2offset(iptr->op1));
452 case ICMD_FSTORE: /* ..., value ==> ... */
453 /* op1 = local variable */
455 gen_ISTORE(((Inst **)cd), index2offset(iptr->op1));
458 case ICMD_DSTORE: /* ..., value ==> ... */
459 /* op1 = local variable */
461 gen_LSTORE(((Inst **)cd), index2offset(iptr->op1));
465 /* pop/dup/swap operations ********************************************/
467 /* attention: double and longs are only one entry in CACAO ICMDs */
469 /* stack.c changes stack manipulation operations to treat
470 longs/doubles as occupying a single slot. Here we are
471 undoing that (and only those things that stack.c did). */
473 case ICMD_POP: /* ..., value ==> ... */
475 if (IS_2_WORD_TYPE(src->type))
476 gen_POP2(((Inst **)cd));
478 gen_POP(((Inst **)cd));
481 case ICMD_POP2: /* ..., value, value ==> ... */
483 gen_POP2(((Inst **)cd));
486 case ICMD_DUP: /* ..., a ==> ..., a, a */
488 if (IS_2_WORD_TYPE(src->type))
489 gen_DUP2(((Inst **)cd));
491 gen_DUP(((Inst **)cd));
494 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
496 if (IS_2_WORD_TYPE(src->type)) {
497 if (IS_2_WORD_TYPE(src->prev->type)) {
498 gen_DUP2_X2(((Inst **)cd));
500 gen_DUP2_X1(((Inst **)cd));
503 if (IS_2_WORD_TYPE(src->prev->type)) {
504 gen_DUP_X2(((Inst **)cd));
506 gen_DUP_X1(((Inst **)cd));
511 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
513 if (IS_2_WORD_TYPE(src->type)) {
514 gen_DUP2_X2(((Inst **)cd));
516 gen_DUP_X2(((Inst **)cd));
519 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
521 gen_DUP2(((Inst **)cd));
524 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
526 if (IS_2_WORD_TYPE(src->prev->prev->type))
527 gen_DUP2_X2(((Inst **)cd));
529 gen_DUP2_X1(((Inst **)cd));
532 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
534 gen_DUP2_X2(((Inst **)cd));
537 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
539 gen_SWAP(((Inst **)cd));
543 /* integer operations *************************************************/
545 case ICMD_INEG: /* ..., value ==> ..., - value */
547 gen_INEG(((Inst **)cd));
550 case ICMD_LNEG: /* ..., value ==> ..., - value */
552 gen_LNEG(((Inst **)cd));
555 case ICMD_I2L: /* ..., value ==> ..., value */
557 gen_I2L(((Inst **)cd));
560 case ICMD_L2I: /* ..., value ==> ..., value */
562 gen_L2I(((Inst **)cd));
565 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
567 gen_INT2BYTE(((Inst **)cd));
570 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
572 gen_INT2CHAR(((Inst **)cd));
575 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
577 gen_INT2SHORT(((Inst **)cd));
581 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
583 gen_IADD(((Inst **)cd));
586 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
587 /* val.i = constant */
589 gen_ICONST(((Inst **)cd), iptr->val.i);
590 gen_IADD(((Inst **)cd));
593 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
595 gen_LADD(((Inst **)cd));
598 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
599 /* val.l = constant */
601 gen_LCONST(((Inst **)cd), iptr->val.l);
602 gen_LADD(((Inst **)cd));
605 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
607 gen_ISUB(((Inst **)cd));
610 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
611 /* val.i = constant */
613 gen_ICONST(((Inst **)cd), iptr->val.i);
614 gen_ISUB(((Inst **)cd));
617 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
619 gen_LSUB(((Inst **)cd));
622 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
623 /* val.l = constant */
625 gen_LCONST(((Inst **)cd), iptr->val.l);
626 gen_LSUB(((Inst **)cd));
629 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
631 gen_IMUL(((Inst **)cd));
634 case ICMD_IMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
636 gen_ICONST(((Inst **)cd), iptr->val.i);
637 gen_IMUL(((Inst **)cd));
640 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
642 gen_LMUL(((Inst **)cd));
645 case ICMD_LMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
647 gen_LCONST(((Inst **)cd), iptr->val.l);
648 gen_LMUL(((Inst **)cd));
651 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
653 gen_IDIV(((Inst **)cd));
656 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
658 gen_IREM(((Inst **)cd));
661 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
663 gen_LDIV(((Inst **)cd));
666 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
668 gen_LREM(((Inst **)cd));
671 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
672 /* val.i = constant */
674 gen_IDIVPOW2(((Inst **)cd), iptr->val.i);
677 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
678 /* val.i = constant */
680 gen_IREMPOW2(((Inst **)cd), iptr->val.i);
683 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
684 /* val.i = constant */
686 gen_LDIVPOW2(((Inst **)cd), iptr->val.i);
689 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
690 /* val.l = constant */
692 gen_LREMPOW2(((Inst **)cd), iptr->val.i);
695 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
697 gen_ISHL(((Inst **)cd));
700 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
701 /* val.i = constant */
703 gen_ICONST(((Inst **)cd), iptr->val.i);
704 gen_ISHL(((Inst **)cd));
707 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
709 gen_ISHR(((Inst **)cd));
712 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
713 /* val.i = constant */
715 gen_ICONST(((Inst **)cd), iptr->val.i);
716 gen_ISHR(((Inst **)cd));
719 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
721 gen_IUSHR(((Inst **)cd));
724 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
725 /* val.i = constant */
727 gen_ICONST(((Inst **)cd), iptr->val.i);
728 gen_IUSHR(((Inst **)cd));
731 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
733 gen_LSHL(((Inst **)cd));
736 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
737 /* val.i = constant */
739 gen_ICONST(((Inst **)cd), iptr->val.i);
740 gen_LSHL(((Inst **)cd));
743 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
745 gen_LSHR(((Inst **)cd));
748 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
749 /* val.i = constant */
751 gen_ICONST(((Inst **)cd), iptr->val.i);
752 gen_LSHR(((Inst **)cd));
755 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
757 gen_LUSHR(((Inst **)cd));
760 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
761 /* val.i = constant */
763 gen_ICONST(((Inst **)cd), iptr->val.i);
764 gen_LUSHR(((Inst **)cd));
767 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
769 gen_IAND(((Inst **)cd));
772 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
773 /* val.i = constant */
775 gen_ICONST(((Inst **)cd), iptr->val.i);
776 gen_IAND(((Inst **)cd));
779 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
781 gen_LAND(((Inst **)cd));
784 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
785 /* val.l = constant */
787 gen_LCONST(((Inst **)cd), iptr->val.l);
788 gen_LAND(((Inst **)cd));
791 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
793 gen_IOR(((Inst **)cd));
796 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
797 /* val.i = constant */
799 gen_ICONST(((Inst **)cd), iptr->val.i);
800 gen_IOR(((Inst **)cd));
803 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
805 gen_LOR(((Inst **)cd));
808 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
809 /* val.l = constant */
811 gen_LCONST(((Inst **)cd), iptr->val.l);
812 gen_LOR(((Inst **)cd));
815 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
817 gen_IXOR(((Inst **)cd));
820 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
821 /* val.i = constant */
823 gen_ICONST(((Inst **)cd), iptr->val.i);
824 gen_IXOR(((Inst **)cd));
827 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
829 gen_LXOR(((Inst **)cd));
832 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
833 /* val.l = constant */
835 gen_LCONST(((Inst **)cd), iptr->val.l);
836 gen_LXOR(((Inst **)cd));
840 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
842 gen_LCMP(((Inst **)cd));
846 case ICMD_IINC: /* ..., value ==> ..., value + constant */
847 /* op1 = variable, val.i = constant */
849 gen_IINC(((Inst **)cd), index2offset(iptr->op1), iptr->val.i);
853 /* floating operations ************************************************/
855 case ICMD_FNEG: /* ..., value ==> ..., - value */
857 gen_FNEG(((Inst **)cd));
860 case ICMD_DNEG: /* ..., value ==> ..., - value */
862 gen_DNEG(((Inst **)cd));
865 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
867 gen_FADD(((Inst **)cd));
870 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
872 gen_DADD(((Inst **)cd));
875 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
877 gen_FSUB(((Inst **)cd));
880 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
882 gen_DSUB(((Inst **)cd));
885 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
887 gen_FMUL(((Inst **)cd));
890 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
892 gen_DMUL(((Inst **)cd));
895 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
897 gen_FDIV(((Inst **)cd));
900 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
902 gen_DDIV(((Inst **)cd));
905 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
907 gen_FREM(((Inst **)cd));
910 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
912 gen_DREM(((Inst **)cd));
915 case ICMD_I2F: /* ..., value ==> ..., (float) value */
917 gen_I2F(((Inst **)cd));
920 case ICMD_L2F: /* ..., value ==> ..., (float) value */
922 gen_L2F(((Inst **)cd));
925 case ICMD_I2D: /* ..., value ==> ..., (double) value */
927 gen_I2D(((Inst **)cd));
930 case ICMD_L2D: /* ..., value ==> ..., (double) value */
932 gen_L2D(((Inst **)cd));
935 case ICMD_F2I: /* ..., value ==> ..., (int) value */
937 gen_F2I(((Inst **)cd));
940 case ICMD_D2I: /* ..., value ==> ..., (int) value */
942 gen_D2I(((Inst **)cd));
945 case ICMD_F2L: /* ..., value ==> ..., (long) value */
947 gen_F2L(((Inst **)cd));
950 case ICMD_D2L: /* ..., value ==> ..., (long) value */
952 gen_D2L(((Inst **)cd));
955 case ICMD_F2D: /* ..., value ==> ..., (double) value */
957 gen_F2D(((Inst **)cd));
960 case ICMD_D2F: /* ..., value ==> ..., (float) value */
962 gen_D2F(((Inst **)cd));
965 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
967 gen_FCMPL(((Inst **)cd));
970 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
972 gen_DCMPL(((Inst **)cd));
975 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
977 gen_FCMPG(((Inst **)cd));
980 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
982 gen_DCMPG(((Inst **)cd));
986 /* memory operations **************************************************/
988 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
990 gen_ARRAYLENGTH(((Inst **)cd));
993 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
995 gen_BALOAD(((Inst **)cd));
998 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1000 gen_CALOAD(((Inst **)cd));
1003 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1005 gen_SALOAD(((Inst **)cd));
1008 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1009 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1011 gen_IALOAD(((Inst **)cd));
1014 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1015 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1017 gen_LALOAD(((Inst **)cd));
1020 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1022 gen_AALOAD(((Inst **)cd));
1026 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1028 gen_BASTORE(((Inst **)cd));
1031 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1032 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1034 gen_CASTORE(((Inst **)cd));
1037 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1038 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1040 gen_IASTORE(((Inst **)cd));
1043 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1044 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1046 gen_LASTORE(((Inst **)cd));
1049 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1051 gen_AASTORE(((Inst **)cd));
1055 case ICMD_GETSTATIC: /* ... ==> ..., value */
1056 /* op1 = type, val.a = field address */
1059 fieldinfo *fi = iptr->val.a;
1060 unresolved_field *uf = iptr->target;
1062 switch (iptr->op1) {
1065 if (fi == NULL || !fi->class->initialized) {
1066 gen_PATCHER_GETSTATIC_INT(((Inst **)cd), 0, uf);
1068 gen_GETSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1073 if (fi == NULL || !fi->class->initialized) {
1074 gen_PATCHER_GETSTATIC_LONG(((Inst **)cd), 0, uf);
1076 gen_GETSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1080 if (fi == NULL || !fi->class->initialized) {
1081 gen_PATCHER_GETSTATIC_CELL(((Inst **)cd), 0, uf);
1083 gen_GETSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1090 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1091 /* op1 = type, val.a = field address */
1094 fieldinfo *fi = iptr->val.a;
1095 unresolved_field *uf = iptr->target;
1097 switch (iptr->op1) {
1100 if (fi == NULL || !fi->class->initialized) {
1101 gen_PATCHER_PUTSTATIC_INT(((Inst **)cd), 0, uf);
1103 gen_PUTSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1108 if (fi == NULL || !fi->class->initialized) {
1109 gen_PATCHER_PUTSTATIC_LONG(((Inst **)cd), 0, uf);
1111 gen_PUTSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1115 if (fi == NULL || !fi->class->initialized) {
1116 gen_PATCHER_PUTSTATIC_CELL(((Inst **)cd), 0, uf);
1118 gen_PUTSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1125 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1126 /* val = value (in current instruction) */
1127 /* op1 = type, val.a = field address (in */
1128 /* following NOP) */
1131 fieldinfo *fi = iptr[1].val.a;
1132 unresolved_field *uf = iptr[1].target;
1134 switch (iptr->op1) {
1137 gen_ICONST(((Inst **)cd), iptr->val.i);
1138 if (fi == NULL || !fi->class->initialized) {
1139 gen_PATCHER_PUTSTATIC_INT(((Inst **)cd), 0, uf);
1141 gen_PUTSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1146 gen_LCONST(((Inst **)cd), iptr->val.l);
1147 if (fi == NULL || !fi->class->initialized) {
1148 gen_PATCHER_PUTSTATIC_LONG(((Inst **)cd), 0, uf);
1150 gen_PUTSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1154 gen_ACONST(((Inst **)cd), iptr->val.a);
1155 if (fi == NULL || !fi->class->initialized) {
1156 gen_PATCHER_PUTSTATIC_CELL(((Inst **)cd), 0, uf);
1158 gen_PUTSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1166 case ICMD_GETFIELD: /* ... ==> ..., value */
1167 /* op1 = type, val.a = field address */
1170 fieldinfo *fi = iptr->val.a;
1171 unresolved_field *uf = iptr->target;
1173 switch (iptr->op1) {
1177 gen_PATCHER_GETFIELD_INT(((Inst **)cd), 0, uf);
1179 gen_GETFIELD_INT(((Inst **)cd), fi->offset, uf);
1185 gen_PATCHER_GETFIELD_LONG(((Inst **)cd), 0, uf);
1187 gen_GETFIELD_LONG(((Inst **)cd), fi->offset, uf);
1192 gen_PATCHER_GETFIELD_CELL(((Inst **)cd), 0, uf);
1194 gen_GETFIELD_CELL(((Inst **)cd), fi->offset, uf);
1201 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1202 /* op1 = type, val.a = field address */
1205 fieldinfo *fi = iptr->val.a;
1206 unresolved_field *uf = iptr->target;
1208 switch (iptr->op1) {
1212 gen_PATCHER_PUTFIELD_INT(((Inst **)cd), 0, uf);
1214 gen_PUTFIELD_INT(((Inst **)cd), fi->offset, uf);
1220 gen_PATCHER_PUTFIELD_LONG(((Inst **)cd), 0, uf);
1222 gen_PUTFIELD_LONG(((Inst **)cd), fi->offset, uf);
1227 gen_PATCHER_PUTFIELD_CELL(((Inst **)cd), 0, uf);
1229 gen_PUTFIELD_CELL(((Inst **)cd), fi->offset, uf);
1236 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1237 /* val = value (in current instruction) */
1238 /* op1 = type, val.a = field address (in */
1239 /* following NOP) */
1242 fieldinfo *fi = iptr[1].val.a;
1243 unresolved_field *uf = iptr[1].target;
1245 switch (iptr[1].op1) {
1248 gen_ICONST(((Inst **)cd), iptr->val.i);
1250 gen_PATCHER_PUTFIELD_INT(((Inst **)cd), 0, uf);
1252 gen_PUTFIELD_INT(((Inst **)cd), fi->offset, uf);
1257 gen_LCONST(((Inst **)cd), iptr->val.l);
1259 gen_PATCHER_PUTFIELD_LONG(((Inst **)cd), 0, uf);
1261 gen_PUTFIELD_LONG(((Inst **)cd), fi->offset, uf);
1265 gen_ACONST(((Inst **)cd), iptr->val.a);
1267 gen_PATCHER_PUTFIELD_CELL(((Inst **)cd), 0, uf);
1269 gen_PUTFIELD_CELL(((Inst **)cd), fi->offset, uf);
1277 /* branch operations **************************************************/
1279 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1281 gen_ATHROW(((Inst **)cd));
1284 case ICMD_GOTO: /* ... ==> ... */
1285 /* op1 = target JavaVM pc */
1289 case ICMD_JSR: /* ... ==> ... */
1290 /* op1 = target JavaVM pc */
1294 case ICMD_RET: /* ... ==> ... */
1295 /* op1 = local variable */
1297 gen_RET(((Inst **)cd), index2offset(iptr->op1));
1300 case ICMD_IFNULL: /* ..., value ==> ... */
1301 /* op1 = target JavaVM pc */
1306 case ICMD_IFNONNULL: /* ..., value ==> ... */
1307 /* op1 = target JavaVM pc */
1309 gen_branch(IFNONNULL);
1312 case ICMD_IFEQ: /* ..., value ==> ... */
1313 /* op1 = target JavaVM pc, val.i = constant */
1315 if (iptr->val.i == 0) {
1318 gen_ICONST(((Inst **)cd), iptr->val.i);
1319 gen_branch(IF_ICMPEQ);
1323 case ICMD_IFLT: /* ..., value ==> ... */
1324 /* op1 = target JavaVM pc, val.i = constant */
1326 if (iptr->val.i == 0) {
1329 gen_ICONST(((Inst **)cd), iptr->val.i);
1330 gen_branch(IF_ICMPLT);
1334 case ICMD_IFLE: /* ..., value ==> ... */
1335 /* op1 = target JavaVM pc, val.i = constant */
1337 if (iptr->val.i == 0) {
1340 gen_ICONST(((Inst **)cd), iptr->val.i);
1341 gen_branch(IF_ICMPLE);
1345 case ICMD_IFNE: /* ..., value ==> ... */
1346 /* op1 = target JavaVM pc, val.i = constant */
1348 if (iptr->val.i == 0) {
1351 gen_ICONST(((Inst **)cd), iptr->val.i);
1352 gen_branch(IF_ICMPNE);
1356 case ICMD_IFGT: /* ..., value ==> ... */
1357 /* op1 = target JavaVM pc, val.i = constant */
1359 if (iptr->val.i == 0) {
1362 gen_ICONST(((Inst **)cd), iptr->val.i);
1363 gen_branch(IF_ICMPGT);
1367 case ICMD_IFGE: /* ..., value ==> ... */
1368 /* op1 = target JavaVM pc, val.i = constant */
1370 if (iptr->val.i == 0) {
1373 gen_ICONST(((Inst **)cd), iptr->val.i);
1374 gen_branch(IF_ICMPGE);
1378 case ICMD_IF_LEQ: /* ..., value ==> ... */
1379 /* op1 = target JavaVM pc, val.l = constant */
1381 gen_LCONST(((Inst **)cd), iptr->val.l);
1382 gen_branch(IF_LCMPEQ);
1385 case ICMD_IF_LLT: /* ..., value ==> ... */
1386 /* op1 = target JavaVM pc, val.l = constant */
1388 gen_LCONST(((Inst **)cd), iptr->val.l);
1389 gen_branch(IF_LCMPLT);
1392 case ICMD_IF_LLE: /* ..., value ==> ... */
1393 /* op1 = target JavaVM pc, val.l = constant */
1395 gen_LCONST(((Inst **)cd), iptr->val.l);
1396 gen_branch(IF_LCMPLE);
1399 case ICMD_IF_LNE: /* ..., value ==> ... */
1400 /* op1 = target JavaVM pc, val.l = constant */
1402 gen_LCONST(((Inst **)cd), iptr->val.l);
1403 gen_branch(IF_LCMPNE);
1406 case ICMD_IF_LGT: /* ..., value ==> ... */
1407 /* op1 = target JavaVM pc, val.l = constant */
1409 gen_LCONST(((Inst **)cd), iptr->val.l);
1410 gen_branch(IF_LCMPGT);
1413 case ICMD_IF_LGE: /* ..., value ==> ... */
1414 /* op1 = target JavaVM pc, val.l = constant */
1416 gen_LCONST(((Inst **)cd), iptr->val.l);
1417 gen_branch(IF_LCMPGE);
1420 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1421 /* op1 = target JavaVM pc */
1423 gen_branch(IF_ICMPEQ);
1426 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1427 /* op1 = target JavaVM pc */
1429 gen_branch(IF_LCMPEQ);
1432 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
1433 /* op1 = target JavaVM pc */
1435 gen_branch(IF_ACMPEQ);
1438 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
1439 /* op1 = target JavaVM pc */
1441 gen_branch(IF_ICMPNE);
1444 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1445 /* op1 = target JavaVM pc */
1447 gen_branch(IF_LCMPNE);
1450 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
1451 /* op1 = target JavaVM pc */
1453 gen_branch(IF_ACMPNE);
1456 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
1457 /* op1 = target JavaVM pc */
1459 gen_branch(IF_ICMPLT);
1462 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1463 /* op1 = target JavaVM pc */
1465 gen_branch(IF_LCMPLT);
1468 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
1469 /* op1 = target JavaVM pc */
1471 gen_branch(IF_ICMPGT);
1474 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1475 /* op1 = target JavaVM pc */
1477 gen_branch(IF_LCMPGT);
1480 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
1481 /* op1 = target JavaVM pc */
1483 gen_branch(IF_ICMPLE);
1486 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1487 /* op1 = target JavaVM pc */
1489 gen_branch(IF_LCMPLE);
1492 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
1493 /* op1 = target JavaVM pc */
1495 gen_branch(IF_ICMPGE);
1498 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1499 /* op1 = target JavaVM pc */
1501 gen_branch(IF_LCMPGE);
1505 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1506 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1507 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1509 #if defined(USE_THREADS)
1510 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1511 if (m->flags & ACC_STATIC) {
1512 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1514 gen_ALOAD(((Inst **)cd), 0);
1516 gen_MONITOREXIT(((Inst **)cd));
1520 gen_TRACERETURN(((Inst **)cd));
1522 gen_IRETURN(((Inst **)cd), index2offset(cd->maxlocals));
1525 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1526 case ICMD_DRETURN: /* ..., retvalue ==> ... */
1528 #if defined(USE_THREADS)
1529 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1530 if (m->flags & ACC_STATIC) {
1531 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1533 gen_ALOAD(((Inst **)cd), 0);
1535 gen_MONITOREXIT(((Inst **)cd));
1539 gen_TRACELRETURN(((Inst **)cd));
1541 gen_LRETURN(((Inst **)cd), index2offset(cd->maxlocals));
1544 case ICMD_RETURN: /* ... ==> ... */
1546 #if defined(USE_THREADS)
1547 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1548 if (m->flags & ACC_STATIC) {
1549 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1551 gen_ALOAD(((Inst **)cd), 0);
1553 gen_MONITOREXIT(((Inst **)cd));
1557 gen_TRACERETURN(((Inst **)cd));
1559 gen_RETURN(((Inst **)cd), index2offset(cd->maxlocals));
1563 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1568 tptr = (void **) iptr->target;
1570 s4ptr = iptr->val.a;
1571 l = s4ptr[1]; /* low */
1572 i = s4ptr[2]; /* high */
1576 /* arguments: low, range, datasegment address, table offset in */
1577 /* datasegment, default target */
1578 gen_TABLESWITCH(((Inst **)cd), l, i, NULL, 0, NULL);
1579 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1580 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1582 /* build jump table top down and use address of lowest entry */
1587 dseg_addtarget(cd, (basicblock *) tptr[0]);
1592 /* length of dataseg after last dseg_addtarget is used by load */
1593 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1597 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
1602 tptr = (void **) iptr->target;
1604 s4ptr = iptr->val.a;
1606 /* s4ptr[0] is equal to tptr[0] */
1607 i = s4ptr[1]; /* count */
1609 /* arguments: count, datasegment address, table offset in */
1610 /* datasegment, default target */
1611 gen_LOOKUPSWITCH(((Inst **)cd), i, NULL, 0, NULL);
1612 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1613 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1615 /* build jump table top down and use address of lowest entry */
1621 dseg_addtarget(cd, (basicblock *) tptr[0]);
1622 dseg_addaddress(cd, s4ptr[0]);
1628 /* length of dataseg after last dseg_addtarget is used by load */
1629 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1633 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1634 /* op1 = arg count val.a = builtintable entry */
1637 for (i = 0; i < sizeof(builtin_gen_table)/sizeof(builtin_gen); i++) {
1638 builtin_gen *bg = &builtin_gen_table[i];
1639 if (bg->builtin == bte->fp) {
1640 (bg->gen)(((Inst **)cd));
1641 goto gen_builtin_end;
1648 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1649 /* op1 = arg count, val.a = method pointer */
1655 md = um->methodref->parseddesc.md;
1656 gen_PATCHER_INVOKESTATIC(((Inst **)cd), 0, md->paramslots, um);
1659 md = lm->parseddesc;
1660 gen_INVOKESTATIC(((Inst **)cd), (Inst **)lm->stubroutine, md->paramslots, um);
1664 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1670 md = um->methodref->parseddesc.md;
1671 gen_PATCHER_INVOKESPECIAL(((Inst **)cd), 0, md->paramslots, um);
1674 md = lm->parseddesc;
1675 gen_INVOKESPECIAL(((Inst **)cd), (Inst **)lm->stubroutine, md->paramslots, um);
1679 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1685 md = um->methodref->parseddesc.md;
1686 gen_PATCHER_INVOKEVIRTUAL(((Inst **)cd), 0, md->paramslots, um);
1689 md = lm->parseddesc;
1691 s1 = OFFSET(vftbl_t, table[0]) +
1692 sizeof(methodptr) * lm->vftblindex;
1694 gen_INVOKEVIRTUAL(((Inst **)cd), s1, md->paramslots, um);
1698 case ICMD_INVOKEINTERFACE:/* op1 = arg count, val.a = method pointer */
1704 md = um->methodref->parseddesc.md;
1705 gen_PATCHER_INVOKEINTERFACE(((Inst **)cd), 0, 0, md->paramslots, um);
1708 md = lm->parseddesc;
1710 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1711 sizeof(methodptr*) * lm->class->index;
1713 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1715 gen_INVOKEINTERFACE(((Inst **)cd), s1, s2, md->paramslots, um);
1720 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1721 /* op1: 0 == array, 1 == class */
1722 /* val.a: (classinfo *) superclass */
1724 if (iptr->op1 == 1) {
1725 if (iptr->val.a == NULL)
1726 gen_PATCHER_CHECKCAST(((Inst **) cd), NULL, iptr->target);
1728 gen_CHECKCAST(((Inst **) cd), iptr->val.a, NULL);
1730 if (iptr->val.a == NULL)
1731 gen_PATCHER_ARRAYCHECKCAST(((Inst **) cd), NULL, iptr->target);
1733 gen_ARRAYCHECKCAST(((Inst **) cd), iptr->val.a, NULL);
1737 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1738 /* op1: 0 == array, 1 == class */
1739 /* val.a: (classinfo *) superclass */
1741 if (iptr->val.a == NULL)
1742 gen_PATCHER_INSTANCEOF(((Inst **) cd), 0, iptr->target);
1744 gen_INSTANCEOF(((Inst **) cd), iptr->val.a, iptr->target);
1747 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
1748 /* op1 = dimension, val.a = array descriptor */
1751 gen_PATCHER_MULTIANEWARRAY(((Inst **)cd), 0, iptr->op1, iptr->val.a);
1753 gen_MULTIANEWARRAY(((Inst **)cd), iptr->val.a, iptr->op1, 0);
1758 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
1762 } /* for instruction */
1764 } /* if (bptr -> flags >= BBREACHED) */
1765 } /* for basic block */
1767 codegen_createlinenumbertable(cd);
1769 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1772 vm_block_insert(m->mcode + m->mcodelength);
1775 /* branch resolving (walk through all basic blocks) */
1777 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
1780 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
1781 gen_resolveanybranch(((u1*) m->entrypoint) + brefs->branchpos,
1782 ((u1 *)m->entrypoint) + bptr->mpc);
1786 /* everything's ok */
1792 /* a stub consists of
1804 codeptr points either to TRANSLATE or to the translated threaded code
1806 all methods are called indirectly through methodptr
1809 #define COMPILERSTUB_SIZE 4
1811 functionptr createcompilerstub (methodinfo *m)
1817 s = CNEW(Inst, COMPILERSTUB_SIZE);
1819 /* mark start of dump memory area */
1821 dumpsize = dump_size();
1823 cd = DNEW(codegendata);
1824 cd->mcodeptr = (u1 *) s;
1826 genarg_ainst((Inst **) cd, s + 2);
1828 if (m->flags & ACC_NATIVE) {
1829 genarg_i((Inst **) cd, m->parseddesc->paramslots);
1831 genarg_i((Inst **) cd, m->maxlocals);
1835 gen_TRANSLATE((Inst **) cd, m);
1838 vm_block_insert(cd->mcodeptr);
1841 #if defined(STATISTICS)
1843 count_cstub_len += COMPILERSTUB_SIZE;
1846 /* release dump area */
1848 dump_release(dumpsize);
1850 return (functionptr) s;
1866 static ffi_cif *createnativecif(methodinfo *m, methoddesc *nmd)
1868 methoddesc *md = m->parseddesc;
1869 ffi_cif *pcif = NEW(ffi_cif);
1870 ffi_type **types = MNEW(ffi_type *, nmd->paramcount);
1871 ffi_type **ptypes = types;
1874 /* pass env pointer */
1876 *ptypes++ = &ffi_type_pointer;
1878 /* for static methods, pass class pointer */
1880 if (m->flags & ACC_STATIC)
1881 *ptypes++ = &ffi_type_pointer;
1883 /* pass parameter to native function */
1885 for (i = 0; i < md->paramcount; i++)
1886 *ptypes++ = cacaotype2ffitype(md->paramtypes[i].type);
1888 assert(ptypes - types == nmd->paramcount);
1890 if (ffi_prep_cif(pcif, FFI_DEFAULT_ABI, nmd->paramcount, cacaotype2ffitype(md->returntype.type), types) != FFI_OK)
1897 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
1898 registerdata *rd, methoddesc *nmd)
1902 cd->mcodeptr = cd->mcodebase;
1903 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
1905 /* create method header */
1907 (void) dseg_addaddress(cd, m); /* MethodPointer */
1908 (void) dseg_adds4(cd, nmd->paramslots * SIZEOF_VOID_P); /* FrameSize */
1909 (void) dseg_adds4(cd, 0); /* IsSync */
1910 (void) dseg_adds4(cd, 0); /* IsLeaf */
1911 (void) dseg_adds4(cd, 0); /* IntSave */
1912 (void) dseg_adds4(cd, 0); /* FltSave */
1913 dseg_addlinenumbertablesize(cd);
1914 (void) dseg_adds4(cd, 0); /* ExTableSize */
1916 /* prepare ffi cif structure */
1918 cif = createnativecif(m, nmd);
1923 gen_TRACECALL(((Inst **)cd));
1926 gen_PATCHER_NATIVECALL(((Inst **)cd), m, f, (u1 *)cif);
1929 gen_TRACENATIVECALL(((Inst **)cd), m, f, (u1 *)cif);
1931 gen_NATIVECALL(((Inst **)cd), m, f, (u1 *)cif);
1934 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1937 vm_block_insert(m->mcode + m->mcodelength);
1940 return m->entrypoint;
1944 functionptr createcalljavafunction(methodinfo *m)
1947 functionptr entrypoint;
1950 t_inlining_globals *id;
1954 /* mark dump memory */
1956 dumpsize = dump_size();
1958 tmpm = DNEW(methodinfo);
1959 cd = DNEW(codegendata);
1960 rd = DNEW(registerdata);
1961 id = DNEW(t_inlining_globals);
1963 /* setup code generation stuff */
1965 MSET(tmpm, 0, u1, sizeof(methodinfo));
1967 inlining_setup(tmpm, id);
1968 codegen_setup(tmpm, cd, id);
1972 cd->mcodeptr = cd->mcodebase;
1973 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
1975 /* create method header */
1977 (void) dseg_addaddress(cd, NULL); /* MethodPointer */
1978 (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P); /* FrameSize */
1979 (void) dseg_adds4(cd, 0); /* IsSync */
1980 (void) dseg_adds4(cd, 0); /* IsLeaf */
1981 (void) dseg_adds4(cd, 0); /* IntSave */
1982 (void) dseg_adds4(cd, 0); /* FltSave */
1983 dseg_addlinenumbertablesize(cd);
1984 (void) dseg_adds4(cd, 0); /* ExTableSize */
1990 gen_INVOKESTATIC(((Inst **)cd), (Inst **)m->stubroutine, md->paramslots, 0);
1991 gen_END(((Inst **)cd));
1993 codegen_finish(tmpm, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1996 vm_block_insert(tmpm->mcode + tmpm->mcodelength);
1998 entrypoint = tmpm->entrypoint;
2000 /* release memory */
2002 dump_release(dumpsize);
2009 * These are local overrides for various environment variables in Emacs.
2010 * Please do not remove this and leave it at the end of the file, where
2011 * Emacs will automagically detect them.
2012 * ---------------------------------------------------------------------
2015 * indent-tabs-mode: t