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 3180 2005-09-15 15:53:56Z twisti $
44 #include "machine-instr.h"
46 #include "vm/jit/intrp/arch.h"
47 #include "vm/jit/intrp/codegen.h"
48 #include "vm/jit/intrp/types.h"
50 #include "cacao/cacao.h"
51 #include "native/native.h"
52 #include "vm/builtin.h"
53 #include "vm/global.h"
54 #include "vm/loader.h"
55 #include "vm/stringlocal.h"
56 #include "vm/tables.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen.inc"
59 #include "vm/jit/jit.h"
61 #include "vm/jit/parse.h"
62 #include "vm/jit/patcher.h"
64 #include "vm/jit/intrp/intrp.h"
66 #include "libffi/include/ffi.h"
69 #define gen_branch(_inst) { \
70 gen_##_inst(((Inst **)cd), 0); \
71 codegen_addreference(cd, (basicblock *) (iptr->target), cd->mcodeptr); \
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
82 genarg_v(Inst **cd1, Cell v)
84 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
85 *((Cell *) *mcodepp) = v;
90 genarg_i(Inst **cd1, s4 i)
92 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
93 *((Cell *) *mcodepp) = i;
98 genarg_b(Inst ** cd1, s4 i)
104 genarg_f(Inst ** cd1, float f)
113 genarg_l(Inst ** cd1, s8 l)
115 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
116 vm_l2twoCell(l, ((Cell*)*mcodepp)[1], ((Cell*)*mcodepp)[0]);
121 genarg_aRef(Inst ** cd1, java_objectheader *a)
123 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
124 *((java_objectheader **) *mcodepp) = a;
129 genarg_aArray(Inst ** cd1, java_arrayheader *a)
131 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
132 *((java_arrayheader **) *mcodepp) = a;
137 genarg_aaTarget(Inst ** cd1, Inst **a)
139 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
140 *((Inst ***) *mcodepp) = a;
145 genarg_aClass(Inst ** cd1, classinfo *a)
147 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
148 *((classinfo **) *mcodepp) = a;
153 genarg_acr(Inst ** cd1, constant_classref *a)
155 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
156 *((constant_classref **) *mcodepp) = a;
161 genarg_addr(Inst ** cd1, u1 *a)
163 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
164 *((u1 **) *mcodepp) = a;
169 genarg_af(Inst ** cd1, functionptr a)
171 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
172 *((functionptr *) *mcodepp) = a;
177 genarg_am(Inst ** cd1, methodinfo *a)
179 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
180 *((methodinfo **) *mcodepp) = a;
185 genarg_acell(Inst ** cd1, Cell *a)
187 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
188 *((Cell **) *mcodepp) = a;
193 genarg_ainst(Inst ** cd1, Inst *a)
195 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
196 *((Inst **) *mcodepp) = a;
201 genarg_auf(Inst ** cd1, unresolved_field *a)
203 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
204 *((unresolved_field **) *mcodepp) = a;
209 genarg_aum(Inst ** cd1, unresolved_method *a)
211 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
212 *((unresolved_method **) *mcodepp) = a;
217 genarg_avftbl(Inst ** cd1, vftbl_t *a)
219 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
220 *((vftbl_t **) *mcodepp) = a;
225 /* include the interpreter generation functions *******************************/
227 #include "vm/jit/intrp/java-gen.i"
230 typedef void (*genfunctionptr) (Inst **);
232 typedef struct builtin_gen builtin_gen;
239 struct builtin_gen builtin_gen_table[] = {
240 {BUILTIN_new, gen_NEW, },
241 {BUILTIN_newarray, gen_NEWARRAY, },
242 {BUILTIN_newarray_boolean, gen_NEWARRAY_BOOLEAN,},
243 {BUILTIN_newarray_byte, gen_NEWARRAY_BYTE, },
244 {BUILTIN_newarray_char, gen_NEWARRAY_CHAR, },
245 {BUILTIN_newarray_short, gen_NEWARRAY_SHORT, },
246 {BUILTIN_newarray_int, gen_NEWARRAY_INT, },
247 {BUILTIN_newarray_long, gen_NEWARRAY_LONG, },
248 {BUILTIN_newarray_float, gen_NEWARRAY_FLOAT, },
249 {BUILTIN_newarray_double, gen_NEWARRAY_DOUBLE, },
250 {BUILTIN_arrayinstanceof, gen_ARRAYINSTANCEOF, },
251 #if defined(USE_THREADS)
252 {BUILTIN_monitorenter, gen_MONITORENTER, },
253 {BUILTIN_monitorexit, gen_MONITOREXIT, },
255 {BUILTIN_f2l, gen_F2L, },
256 {BUILTIN_d2l, gen_D2L, },
257 {BUILTIN_f2i, gen_F2I, },
258 {BUILTIN_d2i, gen_D2I, },
259 {BUILTIN_idiv, gen_IDIV, },
260 {BUILTIN_irem, gen_IREM, },
261 {BUILTIN_ldiv, gen_LDIV, },
262 {BUILTIN_lrem, gen_LREM, },
263 {BUILTIN_frem, gen_FREM, },
264 {BUILTIN_drem, gen_DREM, },
268 The following ones cannot use the BUILTIN mechanism, because they
269 need the class as immediate arguments of the patcher
271 PATCHER_builtin_new, gen_PATCHER_NEW,
272 PATCHER_builtin_newarray, gen_PATCHER_NEWARRAY,
273 PATCHER_builtin_arrayinstanceof, gen_PATCHER_ARRAYINSTANCEOF,
279 /* codegen *********************************************************************
281 Generates machine code.
283 *******************************************************************************/
285 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
287 s4 i, len, s1, s2, d;
293 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
294 unresolved_method *um;
295 builtintable_entry *bte;
298 /* prevent compiler warnings */
305 /* create method header */
307 (void) dseg_addaddress(cd, m); /* MethodPointer */
308 (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P); /* FrameSize */
310 #if defined(USE_THREADS)
311 if (checksync && (m->flags & ACC_SYNCHRONIZED))
312 (void) dseg_adds4(cd, 1); /* IsSync */
315 (void) dseg_adds4(cd, 0); /* IsSync */
317 (void) dseg_adds4(cd, 0); /* IsLeaf */
318 (void) dseg_adds4(cd, 0); /* IntSave */
319 (void) dseg_adds4(cd, 0); /* FltSave */
321 dseg_addlinenumbertablesize(cd);
323 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
325 /* create exception table */
327 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
328 dseg_addtarget(cd, ex->start);
329 dseg_addtarget(cd, ex->end);
330 dseg_addtarget(cd, ex->handler);
331 (void) dseg_addaddress(cd, ex->catchtype.cls);
334 /* initialize mcode variables */
336 cd->mcodeptr = cd->mcodebase;
337 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
341 #if defined(USE_THREADS)
342 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
343 if (m->flags & ACC_STATIC)
344 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
346 gen_ALOAD(((Inst **)cd), 0);
348 gen_MONITORENTER(((Inst **)cd));
353 gen_TRACECALL(((Inst **)cd));
355 /* walk through all basic blocks */
357 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
359 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
361 if (bptr->flags >= BBREACHED) {
363 /* walk through all instructions */
370 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
371 if (iptr->line != currentline) {
372 dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
373 currentline = iptr->line;
376 MCODECHECK(64); /* an instruction usually needs < 64 words */
379 case ICMD_INLINE_START:
380 case ICMD_INLINE_END:
383 case ICMD_NOP: /* ... ==> ... */
386 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
388 gen_CHECKNULL(((Inst **)cd));
391 /* constant operations ************************************************/
393 case ICMD_ICONST: /* ... ==> ..., constant */
394 /* op1 = 0, val.i = constant */
396 gen_ICONST(((Inst **)cd), iptr->val.i);
399 case ICMD_LCONST: /* ... ==> ..., constant */
400 /* op1 = 0, val.l = constant */
402 gen_LCONST(((Inst **)cd), iptr->val.l);
405 case ICMD_FCONST: /* ... ==> ..., constant */
406 /* op1 = 0, val.f = constant */
410 vm_f2Cell(iptr->val.f, fi);
411 gen_ICONST(((Inst **)cd), fi);
415 case ICMD_DCONST: /* ... ==> ..., constant */
416 /* op1 = 0, val.d = constant */
418 gen_LCONST(((Inst **)cd), *(s8 *)&(iptr->val.d));
421 case ICMD_ACONST: /* ... ==> ..., constant */
422 /* op1 = 0, val.a = constant */
424 gen_ACONST(((Inst **)cd), iptr->val.a);
428 /* load/store operations **********************************************/
430 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
431 /* op1 = local variable */
433 gen_ILOAD(((Inst **)cd), iptr->op1);
436 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
437 /* op1 = local variable */
439 gen_LLOAD(((Inst **)cd), iptr->op1);
442 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
443 /* op1 = local variable */
445 gen_ALOAD(((Inst **)cd), iptr->op1);
448 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
449 /* op1 = local variable */
451 gen_ILOAD(((Inst **)cd), iptr->op1);
454 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
455 /* op1 = local variable */
457 gen_LLOAD(((Inst **)cd), iptr->op1);
461 case ICMD_ISTORE: /* ..., value ==> ... */
462 /* op1 = local variable */
464 gen_ISTORE(((Inst **)cd), iptr->op1);
467 case ICMD_LSTORE: /* ..., value ==> ... */
468 /* op1 = local variable */
470 gen_LSTORE(((Inst **)cd), iptr->op1);
473 case ICMD_ASTORE: /* ..., value ==> ... */
474 /* op1 = local variable */
476 gen_ASTORE(((Inst **)cd), iptr->op1);
480 case ICMD_FSTORE: /* ..., value ==> ... */
481 /* op1 = local variable */
483 gen_ISTORE(((Inst **)cd), iptr->op1);
486 case ICMD_DSTORE: /* ..., value ==> ... */
487 /* op1 = local variable */
489 gen_LSTORE(((Inst **)cd), iptr->op1);
493 /* pop/dup/swap operations ********************************************/
495 /* attention: double and longs are only one entry in CACAO ICMDs */
497 /* stack.c changes stack manipulation operations to treat
498 longs/doubles as occupying a single slot. Here we are
499 undoing that (and only those things that stack.c did). */
501 case ICMD_POP: /* ..., value ==> ... */
503 if (IS_2_WORD_TYPE(src->type))
504 gen_POP2(((Inst **)cd));
506 gen_POP(((Inst **)cd));
509 case ICMD_POP2: /* ..., value, value ==> ... */
511 gen_POP2(((Inst **)cd));
514 case ICMD_DUP: /* ..., a ==> ..., a, a */
516 if (IS_2_WORD_TYPE(src->type))
517 gen_DUP2(((Inst **)cd));
519 gen_DUP(((Inst **)cd));
522 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
524 if (IS_2_WORD_TYPE(src->type)) {
525 if (IS_2_WORD_TYPE(src->prev->type)) {
526 gen_DUP2_X2(((Inst **)cd));
528 gen_DUP2_X1(((Inst **)cd));
531 if (IS_2_WORD_TYPE(src->prev->type)) {
532 gen_DUP_X2(((Inst **)cd));
534 gen_DUP_X1(((Inst **)cd));
539 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
541 if (IS_2_WORD_TYPE(src->type)) {
542 gen_DUP2_X2(((Inst **)cd));
544 gen_DUP_X2(((Inst **)cd));
547 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
549 gen_DUP2(((Inst **)cd));
552 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
554 if (IS_2_WORD_TYPE(src->prev->prev->type))
555 gen_DUP2_X2(((Inst **)cd));
557 gen_DUP2_X1(((Inst **)cd));
560 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
562 gen_DUP2_X2(((Inst **)cd));
565 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
567 gen_SWAP(((Inst **)cd));
571 /* integer operations *************************************************/
573 case ICMD_INEG: /* ..., value ==> ..., - value */
575 gen_INEG(((Inst **)cd));
578 case ICMD_LNEG: /* ..., value ==> ..., - value */
580 gen_LNEG(((Inst **)cd));
583 case ICMD_I2L: /* ..., value ==> ..., value */
585 gen_I2L(((Inst **)cd));
588 case ICMD_L2I: /* ..., value ==> ..., value */
590 gen_L2I(((Inst **)cd));
593 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
595 gen_INT2BYTE(((Inst **)cd));
598 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
600 gen_INT2CHAR(((Inst **)cd));
603 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
605 gen_INT2SHORT(((Inst **)cd));
609 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
611 gen_IADD(((Inst **)cd));
614 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
615 /* val.i = constant */
617 gen_ICONST(((Inst **)cd), iptr->val.i);
618 gen_IADD(((Inst **)cd));
621 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
623 gen_LADD(((Inst **)cd));
626 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
627 /* val.l = constant */
629 gen_LCONST(((Inst **)cd), iptr->val.l);
630 gen_LADD(((Inst **)cd));
633 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
635 gen_ISUB(((Inst **)cd));
638 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
639 /* val.i = constant */
641 gen_ICONST(((Inst **)cd), iptr->val.i);
642 gen_ISUB(((Inst **)cd));
645 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
647 gen_LSUB(((Inst **)cd));
650 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
651 /* val.l = constant */
653 gen_LCONST(((Inst **)cd), iptr->val.l);
654 gen_LSUB(((Inst **)cd));
657 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
659 gen_IMUL(((Inst **)cd));
662 case ICMD_IMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
664 gen_ICONST(((Inst **)cd), iptr->val.i);
665 gen_IMUL(((Inst **)cd));
668 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
670 gen_LMUL(((Inst **)cd));
673 case ICMD_LMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
675 gen_LCONST(((Inst **)cd), iptr->val.l);
676 gen_LMUL(((Inst **)cd));
679 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
681 gen_IDIV(((Inst **)cd));
684 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
686 gen_IREM(((Inst **)cd));
689 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
691 gen_LDIV(((Inst **)cd));
694 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
696 gen_LREM(((Inst **)cd));
699 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
700 /* val.i = constant */
702 gen_IDIVPOW2(((Inst **)cd), iptr->val.i);
705 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
706 /* val.i = constant */
708 gen_IREMPOW2(((Inst **)cd), iptr->val.i);
711 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
712 /* val.i = constant */
714 gen_LDIVPOW2(((Inst **)cd), iptr->val.i);
717 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
718 /* val.l = constant */
720 gen_LREMPOW2(((Inst **)cd), iptr->val.i);
723 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
725 gen_ISHL(((Inst **)cd));
728 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
729 /* val.i = constant */
731 gen_ICONST(((Inst **)cd), iptr->val.i);
732 gen_ISHL(((Inst **)cd));
735 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
737 gen_ISHR(((Inst **)cd));
740 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
741 /* val.i = constant */
743 gen_ICONST(((Inst **)cd), iptr->val.i);
744 gen_ISHR(((Inst **)cd));
747 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
749 gen_IUSHR(((Inst **)cd));
752 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
753 /* val.i = constant */
755 gen_ICONST(((Inst **)cd), iptr->val.i);
756 gen_IUSHR(((Inst **)cd));
759 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
761 gen_LSHL(((Inst **)cd));
764 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
765 /* val.i = constant */
767 gen_ICONST(((Inst **)cd), iptr->val.i);
768 gen_LSHL(((Inst **)cd));
771 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
773 gen_LSHR(((Inst **)cd));
776 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
777 /* val.i = constant */
779 gen_ICONST(((Inst **)cd), iptr->val.i);
780 gen_LSHR(((Inst **)cd));
783 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
785 gen_LUSHR(((Inst **)cd));
788 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
789 /* val.i = constant */
791 gen_ICONST(((Inst **)cd), iptr->val.i);
792 gen_LUSHR(((Inst **)cd));
795 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
797 gen_IAND(((Inst **)cd));
800 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
801 /* val.i = constant */
803 gen_ICONST(((Inst **)cd), iptr->val.i);
804 gen_IAND(((Inst **)cd));
807 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
809 gen_LAND(((Inst **)cd));
812 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
813 /* val.l = constant */
815 gen_LCONST(((Inst **)cd), iptr->val.l);
816 gen_LAND(((Inst **)cd));
819 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
821 gen_IOR(((Inst **)cd));
824 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
825 /* val.i = constant */
827 gen_ICONST(((Inst **)cd), iptr->val.i);
828 gen_IOR(((Inst **)cd));
831 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
833 gen_LOR(((Inst **)cd));
836 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
837 /* val.l = constant */
839 gen_LCONST(((Inst **)cd), iptr->val.l);
840 gen_LOR(((Inst **)cd));
843 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
845 gen_IXOR(((Inst **)cd));
848 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
849 /* val.i = constant */
851 gen_ICONST(((Inst **)cd), iptr->val.i);
852 gen_IXOR(((Inst **)cd));
855 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
857 gen_LXOR(((Inst **)cd));
860 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
861 /* val.l = constant */
863 gen_LCONST(((Inst **)cd), iptr->val.l);
864 gen_LXOR(((Inst **)cd));
868 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
870 gen_LCMP(((Inst **)cd));
874 case ICMD_IINC: /* ..., value ==> ..., value + constant */
875 /* op1 = variable, val.i = constant */
877 gen_IINC(((Inst **)cd), iptr->op1, iptr->val.i);
881 /* floating operations ************************************************/
883 case ICMD_FNEG: /* ..., value ==> ..., - value */
885 gen_FNEG(((Inst **)cd));
888 case ICMD_DNEG: /* ..., value ==> ..., - value */
890 gen_DNEG(((Inst **)cd));
893 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
895 gen_FADD(((Inst **)cd));
898 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
900 gen_DADD(((Inst **)cd));
903 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
905 gen_FSUB(((Inst **)cd));
908 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
910 gen_DSUB(((Inst **)cd));
913 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
915 gen_FMUL(((Inst **)cd));
918 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
920 gen_DMUL(((Inst **)cd));
923 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
925 gen_FDIV(((Inst **)cd));
928 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
930 gen_DDIV(((Inst **)cd));
933 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
935 gen_FREM(((Inst **)cd));
938 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
940 gen_DREM(((Inst **)cd));
943 case ICMD_I2F: /* ..., value ==> ..., (float) value */
945 gen_I2F(((Inst **)cd));
948 case ICMD_L2F: /* ..., value ==> ..., (float) value */
950 gen_L2F(((Inst **)cd));
953 case ICMD_I2D: /* ..., value ==> ..., (double) value */
955 gen_I2D(((Inst **)cd));
958 case ICMD_L2D: /* ..., value ==> ..., (double) value */
960 gen_L2D(((Inst **)cd));
963 case ICMD_F2I: /* ..., value ==> ..., (int) value */
965 gen_F2I(((Inst **)cd));
968 case ICMD_D2I: /* ..., value ==> ..., (int) value */
970 gen_D2I(((Inst **)cd));
973 case ICMD_F2L: /* ..., value ==> ..., (long) value */
975 gen_F2L(((Inst **)cd));
978 case ICMD_D2L: /* ..., value ==> ..., (long) value */
980 gen_D2L(((Inst **)cd));
983 case ICMD_F2D: /* ..., value ==> ..., (double) value */
985 gen_F2D(((Inst **)cd));
988 case ICMD_D2F: /* ..., value ==> ..., (float) value */
990 gen_D2F(((Inst **)cd));
993 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
995 gen_FCMPL(((Inst **)cd));
998 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1000 gen_DCMPL(((Inst **)cd));
1003 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1005 gen_FCMPG(((Inst **)cd));
1008 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1010 gen_DCMPG(((Inst **)cd));
1014 /* memory operations **************************************************/
1016 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1018 gen_ARRAYLENGTH(((Inst **)cd));
1021 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1023 gen_BALOAD(((Inst **)cd));
1026 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1028 gen_CALOAD(((Inst **)cd));
1031 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1033 gen_SALOAD(((Inst **)cd));
1036 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1037 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1039 gen_IALOAD(((Inst **)cd));
1042 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1043 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1045 gen_LALOAD(((Inst **)cd));
1048 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1050 gen_AALOAD(((Inst **)cd));
1054 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1056 gen_BASTORE(((Inst **)cd));
1059 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1060 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1062 gen_CASTORE(((Inst **)cd));
1065 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1066 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1068 gen_IASTORE(((Inst **)cd));
1071 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1072 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1074 gen_LASTORE(((Inst **)cd));
1077 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1079 gen_AASTORE(((Inst **)cd));
1083 case ICMD_GETSTATIC: /* ... ==> ..., value */
1084 /* op1 = type, val.a = field address */
1087 fieldinfo *fi = iptr->val.a;
1088 unresolved_field *uf = iptr->target;
1090 switch (iptr->op1) {
1093 if (fi == NULL || !fi->class->initialized) {
1094 gen_PATCHER_GETSTATIC_INT(((Inst **)cd), 0, uf);
1096 gen_GETSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1101 if (fi == NULL || !fi->class->initialized) {
1102 gen_PATCHER_GETSTATIC_LONG(((Inst **)cd), 0, uf);
1104 gen_GETSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1108 if (fi == NULL || !fi->class->initialized) {
1109 gen_PATCHER_GETSTATIC_CELL(((Inst **)cd), 0, uf);
1111 gen_GETSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1118 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1119 /* op1 = type, val.a = field address */
1122 fieldinfo *fi = iptr->val.a;
1123 unresolved_field *uf = iptr->target;
1125 switch (iptr->op1) {
1128 if (fi == NULL || !fi->class->initialized) {
1129 gen_PATCHER_PUTSTATIC_INT(((Inst **)cd), 0, uf);
1131 gen_PUTSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1136 if (fi == NULL || !fi->class->initialized) {
1137 gen_PATCHER_PUTSTATIC_LONG(((Inst **)cd), 0, uf);
1139 gen_PUTSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1143 if (fi == NULL || !fi->class->initialized) {
1144 gen_PATCHER_PUTSTATIC_CELL(((Inst **)cd), 0, uf);
1146 gen_PUTSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1153 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1154 /* val = value (in current instruction) */
1155 /* op1 = type, val.a = field address (in */
1156 /* following NOP) */
1159 fieldinfo *fi = iptr[1].val.a;
1160 unresolved_field *uf = iptr[1].target;
1162 switch (iptr->op1) {
1165 gen_ICONST(((Inst **)cd), iptr->val.i);
1166 if (fi == NULL || !fi->class->initialized) {
1167 gen_PATCHER_PUTSTATIC_INT(((Inst **)cd), 0, uf);
1169 gen_PUTSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1174 gen_LCONST(((Inst **)cd), iptr->val.l);
1175 if (fi == NULL || !fi->class->initialized) {
1176 gen_PATCHER_PUTSTATIC_LONG(((Inst **)cd), 0, uf);
1178 gen_PUTSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1182 gen_ACONST(((Inst **)cd), iptr->val.a);
1183 if (fi == NULL || !fi->class->initialized) {
1184 gen_PATCHER_PUTSTATIC_CELL(((Inst **)cd), 0, uf);
1186 gen_PUTSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1194 case ICMD_GETFIELD: /* ... ==> ..., value */
1195 /* op1 = type, val.a = field address */
1198 fieldinfo *fi = iptr->val.a;
1199 unresolved_field *uf = iptr->target;
1201 switch (iptr->op1) {
1205 gen_PATCHER_GETFIELD_INT(((Inst **)cd), 0, uf);
1207 gen_GETFIELD_INT(((Inst **)cd), fi->offset, uf);
1213 gen_PATCHER_GETFIELD_LONG(((Inst **)cd), 0, uf);
1215 gen_GETFIELD_LONG(((Inst **)cd), fi->offset, uf);
1220 gen_PATCHER_GETFIELD_CELL(((Inst **)cd), 0, uf);
1222 gen_GETFIELD_CELL(((Inst **)cd), fi->offset, uf);
1229 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1230 /* op1 = type, val.a = field address */
1233 fieldinfo *fi = iptr->val.a;
1234 unresolved_field *uf = iptr->target;
1236 switch (iptr->op1) {
1240 gen_PATCHER_PUTFIELD_INT(((Inst **)cd), 0, uf);
1242 gen_PUTFIELD_INT(((Inst **)cd), fi->offset, uf);
1248 gen_PATCHER_PUTFIELD_LONG(((Inst **)cd), 0, uf);
1250 gen_PUTFIELD_LONG(((Inst **)cd), fi->offset, uf);
1255 gen_PATCHER_PUTFIELD_CELL(((Inst **)cd), 0, uf);
1257 gen_PUTFIELD_CELL(((Inst **)cd), fi->offset, uf);
1264 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1265 /* val = value (in current instruction) */
1266 /* op1 = type, val.a = field address (in */
1267 /* following NOP) */
1270 fieldinfo *fi = iptr[1].val.a;
1271 unresolved_field *uf = iptr[1].target;
1273 switch (iptr[1].op1) {
1276 gen_ICONST(((Inst **)cd), iptr->val.i);
1278 gen_PATCHER_PUTFIELD_INT(((Inst **)cd), 0, uf);
1280 gen_PUTFIELD_INT(((Inst **)cd), fi->offset, uf);
1285 gen_LCONST(((Inst **)cd), iptr->val.l);
1287 gen_PATCHER_PUTFIELD_LONG(((Inst **)cd), 0, uf);
1289 gen_PUTFIELD_LONG(((Inst **)cd), fi->offset, uf);
1293 gen_ACONST(((Inst **)cd), iptr->val.a);
1295 gen_PATCHER_PUTFIELD_CELL(((Inst **)cd), 0, uf);
1297 gen_PUTFIELD_CELL(((Inst **)cd), fi->offset, uf);
1305 /* branch operations **************************************************/
1307 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1309 gen_ATHROW(((Inst **)cd));
1312 case ICMD_GOTO: /* ... ==> ... */
1313 /* op1 = target JavaVM pc */
1317 case ICMD_JSR: /* ... ==> ... */
1318 /* op1 = target JavaVM pc */
1322 case ICMD_RET: /* ... ==> ... */
1323 /* op1 = local variable */
1325 gen_RET(((Inst **)cd), iptr->op1);
1328 case ICMD_IFNULL: /* ..., value ==> ... */
1329 /* op1 = target JavaVM pc */
1334 case ICMD_IFNONNULL: /* ..., value ==> ... */
1335 /* op1 = target JavaVM pc */
1337 gen_branch(IFNONNULL);
1340 case ICMD_IFEQ: /* ..., value ==> ... */
1341 /* op1 = target JavaVM pc, val.i = constant */
1343 if (iptr->val.i == 0) {
1346 gen_ICONST(((Inst **)cd), iptr->val.i);
1347 gen_branch(IF_ICMPEQ);
1351 case ICMD_IFLT: /* ..., value ==> ... */
1352 /* op1 = target JavaVM pc, val.i = constant */
1354 if (iptr->val.i == 0) {
1357 gen_ICONST(((Inst **)cd), iptr->val.i);
1358 gen_branch(IF_ICMPLT);
1362 case ICMD_IFLE: /* ..., value ==> ... */
1363 /* op1 = target JavaVM pc, val.i = constant */
1365 if (iptr->val.i == 0) {
1368 gen_ICONST(((Inst **)cd), iptr->val.i);
1369 gen_branch(IF_ICMPLE);
1373 case ICMD_IFNE: /* ..., value ==> ... */
1374 /* op1 = target JavaVM pc, val.i = constant */
1376 if (iptr->val.i == 0) {
1379 gen_ICONST(((Inst **)cd), iptr->val.i);
1380 gen_branch(IF_ICMPNE);
1384 case ICMD_IFGT: /* ..., value ==> ... */
1385 /* op1 = target JavaVM pc, val.i = constant */
1387 if (iptr->val.i == 0) {
1390 gen_ICONST(((Inst **)cd), iptr->val.i);
1391 gen_branch(IF_ICMPGT);
1395 case ICMD_IFGE: /* ..., value ==> ... */
1396 /* op1 = target JavaVM pc, val.i = constant */
1398 if (iptr->val.i == 0) {
1401 gen_ICONST(((Inst **)cd), iptr->val.i);
1402 gen_branch(IF_ICMPGE);
1406 case ICMD_IF_LEQ: /* ..., value ==> ... */
1407 /* op1 = target JavaVM pc, val.l = constant */
1409 gen_LCONST(((Inst **)cd), iptr->val.l);
1410 gen_branch(IF_LCMPEQ);
1413 case ICMD_IF_LLT: /* ..., value ==> ... */
1414 /* op1 = target JavaVM pc, val.l = constant */
1416 gen_LCONST(((Inst **)cd), iptr->val.l);
1417 gen_branch(IF_LCMPLT);
1420 case ICMD_IF_LLE: /* ..., value ==> ... */
1421 /* op1 = target JavaVM pc, val.l = constant */
1423 gen_LCONST(((Inst **)cd), iptr->val.l);
1424 gen_branch(IF_LCMPLE);
1427 case ICMD_IF_LNE: /* ..., value ==> ... */
1428 /* op1 = target JavaVM pc, val.l = constant */
1430 gen_LCONST(((Inst **)cd), iptr->val.l);
1431 gen_branch(IF_LCMPNE);
1434 case ICMD_IF_LGT: /* ..., value ==> ... */
1435 /* op1 = target JavaVM pc, val.l = constant */
1437 gen_LCONST(((Inst **)cd), iptr->val.l);
1438 gen_branch(IF_LCMPGT);
1441 case ICMD_IF_LGE: /* ..., value ==> ... */
1442 /* op1 = target JavaVM pc, val.l = constant */
1444 gen_LCONST(((Inst **)cd), iptr->val.l);
1445 gen_branch(IF_LCMPGE);
1448 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1449 /* op1 = target JavaVM pc */
1451 gen_branch(IF_ICMPEQ);
1454 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1455 /* op1 = target JavaVM pc */
1457 gen_branch(IF_LCMPEQ);
1460 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
1461 /* op1 = target JavaVM pc */
1463 gen_branch(IF_ACMPEQ);
1466 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
1467 /* op1 = target JavaVM pc */
1469 gen_branch(IF_ICMPNE);
1472 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1473 /* op1 = target JavaVM pc */
1475 gen_branch(IF_LCMPNE);
1478 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
1479 /* op1 = target JavaVM pc */
1481 gen_branch(IF_ACMPNE);
1484 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
1485 /* op1 = target JavaVM pc */
1487 gen_branch(IF_ICMPLT);
1490 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1491 /* op1 = target JavaVM pc */
1493 gen_branch(IF_LCMPLT);
1496 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
1497 /* op1 = target JavaVM pc */
1499 gen_branch(IF_ICMPGT);
1502 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1503 /* op1 = target JavaVM pc */
1505 gen_branch(IF_LCMPGT);
1508 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
1509 /* op1 = target JavaVM pc */
1511 gen_branch(IF_ICMPLE);
1514 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1515 /* op1 = target JavaVM pc */
1517 gen_branch(IF_LCMPLE);
1520 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
1521 /* op1 = target JavaVM pc */
1523 gen_branch(IF_ICMPGE);
1526 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1527 /* op1 = target JavaVM pc */
1529 gen_branch(IF_LCMPGE);
1533 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1534 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1535 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1537 #if defined(USE_THREADS)
1538 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1539 if (m->flags & ACC_STATIC) {
1540 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1542 gen_ALOAD(((Inst **)cd), 0);
1544 gen_MONITOREXIT(((Inst **)cd));
1548 gen_TRACERETURN(((Inst **)cd));
1550 gen_IRETURN(((Inst **)cd), cd->maxlocals);
1553 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1554 case ICMD_DRETURN: /* ..., retvalue ==> ... */
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_TRACELRETURN(((Inst **)cd));
1569 gen_LRETURN(((Inst **)cd), cd->maxlocals);
1572 case ICMD_RETURN: /* ... ==> ... */
1574 #if defined(USE_THREADS)
1575 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1576 if (m->flags & ACC_STATIC) {
1577 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1579 gen_ALOAD(((Inst **)cd), 0);
1581 gen_MONITOREXIT(((Inst **)cd));
1585 gen_TRACERETURN(((Inst **)cd));
1587 gen_RETURN(((Inst **)cd), cd->maxlocals);
1591 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1596 tptr = (void **) iptr->target;
1598 s4ptr = iptr->val.a;
1599 l = s4ptr[1]; /* low */
1600 i = s4ptr[2]; /* high */
1604 /* arguments: low, range, datasegment address, table offset in */
1605 /* datasegment, default target */
1606 gen_TABLESWITCH(((Inst **)cd), l, i, NULL, 0, NULL);
1607 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1608 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1610 /* build jump table top down and use address of lowest entry */
1615 dseg_addtarget(cd, (basicblock *) tptr[0]);
1620 /* length of dataseg after last dseg_addtarget is used by load */
1621 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1625 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
1630 tptr = (void **) iptr->target;
1632 s4ptr = iptr->val.a;
1634 /* s4ptr[0] is equal to tptr[0] */
1635 i = s4ptr[1]; /* count */
1637 /* arguments: count, datasegment address, table offset in */
1638 /* datasegment, default target */
1639 gen_LOOKUPSWITCH(((Inst **)cd), i, NULL, 0, NULL);
1640 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1641 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1643 /* build jump table top down and use address of lowest entry */
1649 dseg_addtarget(cd, (basicblock *) tptr[0]);
1650 dseg_addaddress(cd, s4ptr[0]);
1656 /* length of dataseg after last dseg_addtarget is used by load */
1657 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1661 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1662 /* op1 = arg count val.a = builtintable entry */
1664 if (bte->fp == PATCHER_builtin_new) {
1665 gen_PATCHER_NEW(((Inst **)cd), 0);
1666 } else if (bte->fp == PATCHER_builtin_newarray) {
1667 gen_PATCHER_NEWARRAY(((Inst **)cd), 0);
1668 } else if (bte->fp == PATCHER_builtin_arrayinstanceof) {
1669 gen_PATCHER_ARRAYINSTANCEOF(((Inst **)cd), 0);
1671 for (i = 0; i < sizeof(builtin_gen_table)/sizeof(builtin_gen); i++) {
1672 builtin_gen *bg = &builtin_gen_table[i];
1673 if (bg->builtin == bte->fp) {
1674 (bg->gen)(((Inst **)cd));
1675 goto gen_builtin_end;
1683 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1684 /* op1 = arg count, val.a = method pointer */
1690 md = um->methodref->parseddesc.md;
1691 gen_PATCHER_INVOKESTATIC(((Inst **)cd), 0, md->paramslots, um);
1694 md = lm->parseddesc;
1695 gen_INVOKESTATIC(((Inst **)cd), (Inst **)lm->stubroutine, md->paramslots, um);
1699 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1705 md = um->methodref->parseddesc.md;
1706 gen_PATCHER_INVOKESPECIAL(((Inst **)cd), 0, md->paramslots, um);
1709 md = lm->parseddesc;
1710 gen_INVOKESPECIAL(((Inst **)cd), (Inst **)lm->stubroutine, md->paramslots, um);
1714 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1720 md = um->methodref->parseddesc.md;
1721 gen_PATCHER_INVOKEVIRTUAL(((Inst **)cd), 0, md->paramslots, um);
1724 md = lm->parseddesc;
1726 s1 = OFFSET(vftbl_t, table[0]) +
1727 sizeof(methodptr) * lm->vftblindex;
1729 gen_INVOKEVIRTUAL(((Inst **)cd), s1, md->paramslots, um);
1733 case ICMD_INVOKEINTERFACE:/* op1 = arg count, val.a = method pointer */
1739 md = um->methodref->parseddesc.md;
1740 gen_PATCHER_INVOKEINTERFACE(((Inst **)cd), 0, 0, md->paramslots, um);
1743 md = lm->parseddesc;
1745 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1746 sizeof(methodptr*) * lm->class->index;
1748 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1750 gen_INVOKEINTERFACE(((Inst **)cd), s1, s2, md->paramslots, um);
1755 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1756 /* op1: 0 == array, 1 == class */
1757 /* val.a: (classinfo *) superclass */
1759 if (iptr->val.a == NULL) {
1760 gen_PATCHER_CHECKCAST(((Inst **)cd), 0, iptr->target);
1763 gen_CHECKCAST(((Inst **)cd), iptr->val.a, iptr->target);
1768 case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref */
1769 /* op1: 1... resolved, 0... not resolved */
1771 if (iptr->op1 == 0) {
1772 gen_PATCHER_ARRAYCHECKCAST(((Inst **)cd), 0, iptr->target);
1774 gen_ARRAYCHECKCAST(((Inst **)cd), iptr->target, 0);
1778 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1779 /* op1: 0 == array, 1 == class */
1780 /* val.a: (classinfo *) superclass */
1782 if (iptr->val.a == NULL) {
1783 gen_PATCHER_INSTANCEOF(((Inst **)cd), 0, iptr->target);
1785 gen_INSTANCEOF(((Inst **)cd), iptr->val.a, iptr->target);
1791 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
1793 /* XXX remove me! */
1796 case ICMD_CHECKEXCEPTION: /* ..., objectref ==> ..., objectref */
1798 gen_CHECKEXCEPTION(((Inst **)cd));
1801 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
1802 /* op1 = dimension, val.a = array descriptor */
1805 gen_PATCHER_MULTIANEWARRAY(((Inst **)cd), 0, iptr->op1, iptr->val.a);
1807 gen_MULTIANEWARRAY(((Inst **)cd), iptr->val.a, iptr->op1, 0);
1812 throw_cacao_exception_exit(string_java_lang_InternalError,
1813 "Unknown ICMD %d", iptr->opc);
1816 } /* for instruction */
1818 } /* if (bptr -> flags >= BBREACHED) */
1819 } /* for basic block */
1821 codegen_createlinenumbertable(cd);
1823 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1826 vm_block_insert(m->mcode + m->mcodelength);
1829 /* branch resolving (walk through all basic blocks) */
1831 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
1834 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
1835 gen_resolveanybranch(((u1*) m->entrypoint) + brefs->branchpos,
1836 ((u1 *)m->entrypoint) + bptr->mpc);
1842 /* a stub consists of
1854 codeptr points either to TRANSLATE or to the translated threaded code
1856 all methods are called indirectly through methodptr
1859 #define COMPILERSTUB_SIZE 4
1861 functionptr createcompilerstub (methodinfo *m)
1867 s = CNEW(Inst, COMPILERSTUB_SIZE);
1869 /* mark start of dump memory area */
1871 dumpsize = dump_size();
1873 cd = DNEW(codegendata);
1874 cd->mcodeptr = (u1 *) s;
1876 genarg_ainst((Inst **) cd, s + 2);
1878 if (m->flags & ACC_NATIVE) {
1879 genarg_i((Inst **) cd, m->parseddesc->paramslots);
1881 genarg_i((Inst **) cd, m->maxlocals);
1885 gen_TRANSLATE((Inst **) cd, m);
1888 vm_block_insert(cd->mcodeptr);
1891 #if defined(STATISTICS)
1893 count_cstub_len += COMPILERSTUB_SIZE;
1896 /* release dump area */
1898 dump_release(dumpsize);
1900 return (functionptr) s;
1916 static ffi_cif *createnativecif(methodinfo *m, methoddesc *nmd)
1919 methoddesc *md = m->parseddesc;
1920 ffi_cif *pcif = NEW(ffi_cif);
1921 ffi_type **types = MNEW(ffi_type *, nmd->paramcount);
1922 ffi_type **ptypes = types;
1925 /* pass env pointer */
1927 *ptypes++ = &ffi_type_pointer;
1929 /* for static methods, pass class pointer */
1931 if (m->flags & ACC_STATIC) {
1932 *ptypes++ = &ffi_type_pointer;
1935 /* pass parameter to native function */
1937 for (i = 0; i < md->paramcount; i++) {
1938 *ptypes++ = cacaotype2ffitype(md->paramtypes[i].type);
1941 assert(ptypes-types == nmd->paramcount);
1942 if (ffi_prep_cif(pcif, FFI_DEFAULT_ABI, nmd->paramcount, cacaotype2ffitype(md->returntype.type), types) != FFI_OK)
1952 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
1953 registerdata *rd, methoddesc *nmd)
1957 cd->mcodeptr = cd->mcodebase;
1958 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
1960 /* create method header */
1962 (void) dseg_addaddress(cd, m); /* MethodPointer */
1963 (void) dseg_adds4(cd, nmd->paramslots * SIZEOF_VOID_P); /* FrameSize */
1964 (void) dseg_adds4(cd, 0); /* IsSync */
1965 (void) dseg_adds4(cd, 0); /* IsLeaf */
1966 (void) dseg_adds4(cd, 0); /* IntSave */
1967 (void) dseg_adds4(cd, 0); /* FltSave */
1968 dseg_addlinenumbertablesize(cd);
1969 (void) dseg_adds4(cd, 0); /* ExTableSize */
1971 /* prepare ffi cif structure */
1973 cif = createnativecif(m, nmd);
1978 gen_TRACECALL(((Inst **)cd));
1981 gen_PATCHER_NATIVECALL(((Inst **)cd), m, f, (u1 *)cif);
1984 gen_TRACENATIVECALL(((Inst **)cd), m, f, (u1 *)cif);
1986 gen_NATIVECALL(((Inst **)cd), m, f, (u1 *)cif);
1989 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1992 vm_block_insert(m->mcode + m->mcodelength);
1995 return m->entrypoint;
1999 functionptr createcalljavafunction(methodinfo *m)
2002 functionptr entrypoint;
2005 t_inlining_globals *id;
2009 /* mark dump memory */
2011 dumpsize = dump_size();
2013 tmpm = DNEW(methodinfo);
2014 cd = DNEW(codegendata);
2015 rd = DNEW(registerdata);
2016 id = DNEW(t_inlining_globals);
2018 /* setup code generation stuff */
2020 MSET(tmpm, 0, u1, sizeof(methodinfo));
2022 inlining_setup(tmpm, id);
2023 codegen_setup(tmpm, cd, id);
2027 cd->mcodeptr = cd->mcodebase;
2028 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
2030 /* create method header */
2032 (void) dseg_addaddress(cd, NULL); /* MethodPointer */
2033 (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P); /* FrameSize */
2034 (void) dseg_adds4(cd, 0); /* IsSync */
2035 (void) dseg_adds4(cd, 0); /* IsLeaf */
2036 (void) dseg_adds4(cd, 0); /* IntSave */
2037 (void) dseg_adds4(cd, 0); /* FltSave */
2038 dseg_addlinenumbertablesize(cd);
2039 (void) dseg_adds4(cd, 0); /* ExTableSize */
2045 gen_INVOKESTATIC(((Inst **)cd), (Inst **)m->stubroutine, md->paramslots, 0);
2046 gen_END(((Inst **)cd));
2048 codegen_finish(tmpm, cd, (s4) (cd->mcodeptr - cd->mcodebase));
2051 vm_block_insert(tmpm->mcode + tmpm->mcodelength);
2053 entrypoint = tmpm->entrypoint;
2055 /* release memory */
2057 dump_release(dumpsize);
2064 * These are local overrides for various environment variables in Emacs.
2065 * Please do not remove this and leave it at the end of the file, where
2066 * Emacs will automagically detect them.
2067 * ---------------------------------------------------------------------
2070 * indent-tabs-mode: t