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 3176 2005-09-14 08:51:23Z 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 #define gen_branch(_inst) { \
67 gen_##_inst(((Inst **)cd), 0); \
68 codegen_addreference(cd, (basicblock *) (iptr->target), cd->mcodeptr); \
72 /* functions used by cacao-gen.i */
74 /* vmgen-0.6.2 generates gen_... calls with Inst ** as first
75 parameter, but we need to pass in cd to make last_compiled
79 genarg_v(Inst **cd1, Cell v)
81 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
82 *((Cell *) *mcodepp) = v;
87 genarg_i(Inst **cd1, s4 i)
89 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
90 *((Cell *) *mcodepp) = i;
95 genarg_b(Inst ** cd1, s4 i)
101 genarg_f(Inst ** cd1, float f)
110 genarg_l(Inst ** cd1, s8 l)
112 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
113 vm_l2twoCell(l, ((Cell*)*mcodepp)[1], ((Cell*)*mcodepp)[0]);
118 genarg_aRef(Inst ** cd1, java_objectheader *a)
120 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
121 *((java_objectheader **) *mcodepp) = a;
126 genarg_aArray(Inst ** cd1, java_arrayheader *a)
128 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
129 *((java_arrayheader **) *mcodepp) = a;
134 genarg_aaTarget(Inst ** cd1, Inst **a)
136 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
137 *((Inst ***) *mcodepp) = a;
142 genarg_aClass(Inst ** cd1, classinfo *a)
144 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
145 *((classinfo **) *mcodepp) = a;
150 genarg_acr(Inst ** cd1, constant_classref *a)
152 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
153 *((constant_classref **) *mcodepp) = a;
158 genarg_addr(Inst ** cd1, u1 *a)
160 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
161 *((u1 **) *mcodepp) = a;
166 genarg_af(Inst ** cd1, functionptr a)
168 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
169 *((functionptr *) *mcodepp) = a;
174 genarg_am(Inst ** cd1, methodinfo *a)
176 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
177 *((methodinfo **) *mcodepp) = a;
182 genarg_acell(Inst ** cd1, Cell *a)
184 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
185 *((Cell **) *mcodepp) = a;
190 genarg_ainst(Inst ** cd1, Inst *a)
192 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
193 *((Inst **) *mcodepp) = a;
198 genarg_auf(Inst ** cd1, unresolved_field *a)
200 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
201 *((unresolved_field **) *mcodepp) = a;
206 genarg_aum(Inst ** cd1, unresolved_method *a)
208 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
209 *((unresolved_method **) *mcodepp) = a;
214 genarg_avftbl(Inst ** cd1, vftbl_t *a)
216 Inst **mcodepp = &(((codegendata *)cd1)->mcodeptr);
217 *((vftbl_t **) *mcodepp) = a;
222 /* include the interpreter generation functions *******************************/
224 #include "vm/jit/intrp/java-gen.i"
227 typedef void (*genfunctionptr) (Inst **);
229 typedef struct builtin_gen builtin_gen;
236 struct builtin_gen builtin_gen_table[] = {
237 {BUILTIN_new, gen_NEW, },
238 {BUILTIN_newarray, gen_NEWARRAY, },
239 {BUILTIN_newarray_boolean, gen_NEWARRAY_BOOLEAN,},
240 {BUILTIN_newarray_byte, gen_NEWARRAY_BYTE, },
241 {BUILTIN_newarray_char, gen_NEWARRAY_CHAR, },
242 {BUILTIN_newarray_short, gen_NEWARRAY_SHORT, },
243 {BUILTIN_newarray_int, gen_NEWARRAY_INT, },
244 {BUILTIN_newarray_long, gen_NEWARRAY_LONG, },
245 {BUILTIN_newarray_float, gen_NEWARRAY_FLOAT, },
246 {BUILTIN_newarray_double, gen_NEWARRAY_DOUBLE, },
247 {BUILTIN_arrayinstanceof, gen_ARRAYINSTANCEOF, },
248 #if defined(USE_THREADS)
249 {BUILTIN_monitorenter, gen_MONITORENTER, },
250 {BUILTIN_monitorexit, gen_MONITOREXIT, },
252 {BUILTIN_f2l, gen_F2L, },
253 {BUILTIN_d2l, gen_D2L, },
254 {BUILTIN_f2i, gen_F2I, },
255 {BUILTIN_d2i, gen_D2I, },
256 {BUILTIN_idiv, gen_IDIV, },
257 {BUILTIN_irem, gen_IREM, },
258 {BUILTIN_ldiv, gen_LDIV, },
259 {BUILTIN_lrem, gen_LREM, },
260 {BUILTIN_frem, gen_FREM, },
261 {BUILTIN_drem, gen_DREM, },
265 The following ones cannot use the BUILTIN mechanism, because they
266 need the class as immediate arguments of the patcher
268 PATCHER_builtin_new, gen_PATCHER_NEW,
269 PATCHER_builtin_newarray, gen_PATCHER_NEWARRAY,
270 PATCHER_builtin_arrayinstanceof, gen_PATCHER_ARRAYINSTANCEOF,
276 /* codegen *********************************************************************
278 Generates machine code.
280 *******************************************************************************/
282 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
284 s4 i, len, s1, s2, d;
290 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
291 unresolved_method *um;
292 builtintable_entry *bte;
295 /* prevent compiler warnings */
302 /* create method header */
304 (void) dseg_addaddress(cd, m); /* MethodPointer */
305 (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P); /* FrameSize */
307 #if defined(USE_THREADS)
308 if (checksync && (m->flags & ACC_SYNCHRONIZED))
309 (void) dseg_adds4(cd, 1); /* IsSync */
312 (void) dseg_adds4(cd, 0); /* IsSync */
314 (void) dseg_adds4(cd, 0); /* IsLeaf */
315 (void) dseg_adds4(cd, 0); /* IntSave */
316 (void) dseg_adds4(cd, 0); /* FltSave */
318 dseg_addlinenumbertablesize(cd);
320 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
322 /* create exception table */
324 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
325 dseg_addtarget(cd, ex->start);
326 dseg_addtarget(cd, ex->end);
327 dseg_addtarget(cd, ex->handler);
328 (void) dseg_addaddress(cd, ex->catchtype.cls);
331 /* initialize mcode variables */
333 cd->mcodeptr = cd->mcodebase;
334 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
338 #if defined(USE_THREADS)
339 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
340 if (m->flags & ACC_STATIC)
341 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
343 gen_ALOAD(((Inst **)cd), 0);
345 gen_MONITORENTER(((Inst **)cd));
350 gen_TRACECALL(((Inst **)cd));
352 /* walk through all basic blocks */
354 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
356 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
358 if (bptr->flags >= BBREACHED) {
360 /* walk through all instructions */
367 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
368 if (iptr->line != currentline) {
369 dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
370 currentline = iptr->line;
373 MCODECHECK(64); /* an instruction usually needs < 64 words */
376 case ICMD_INLINE_START:
377 case ICMD_INLINE_END:
380 case ICMD_NOP: /* ... ==> ... */
383 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
385 gen_CHECKNULL(((Inst **)cd));
388 /* constant operations ************************************************/
390 case ICMD_ICONST: /* ... ==> ..., constant */
391 /* op1 = 0, val.i = constant */
393 gen_ICONST(((Inst **)cd), iptr->val.i);
396 case ICMD_LCONST: /* ... ==> ..., constant */
397 /* op1 = 0, val.l = constant */
399 gen_LCONST(((Inst **)cd), iptr->val.l);
402 case ICMD_FCONST: /* ... ==> ..., constant */
403 /* op1 = 0, val.f = constant */
407 vm_f2Cell(iptr->val.f, fi);
408 gen_ICONST(((Inst **)cd), fi);
412 case ICMD_DCONST: /* ... ==> ..., constant */
413 /* op1 = 0, val.d = constant */
415 gen_LCONST(((Inst **)cd), *(s8 *)&(iptr->val.d));
418 case ICMD_ACONST: /* ... ==> ..., constant */
419 /* op1 = 0, val.a = constant */
421 gen_ACONST(((Inst **)cd), iptr->val.a);
425 /* load/store operations **********************************************/
427 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
428 /* op1 = local variable */
430 gen_ILOAD(((Inst **)cd), iptr->op1);
433 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
434 /* op1 = local variable */
436 gen_LLOAD(((Inst **)cd), iptr->op1);
439 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
440 /* op1 = local variable */
442 gen_ALOAD(((Inst **)cd), iptr->op1);
445 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
446 /* op1 = local variable */
448 gen_ILOAD(((Inst **)cd), iptr->op1);
451 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
452 /* op1 = local variable */
454 gen_LLOAD(((Inst **)cd), iptr->op1);
458 case ICMD_ISTORE: /* ..., value ==> ... */
459 /* op1 = local variable */
461 gen_ISTORE(((Inst **)cd), iptr->op1);
464 case ICMD_LSTORE: /* ..., value ==> ... */
465 /* op1 = local variable */
467 gen_LSTORE(((Inst **)cd), iptr->op1);
470 case ICMD_ASTORE: /* ..., value ==> ... */
471 /* op1 = local variable */
473 gen_ASTORE(((Inst **)cd), iptr->op1);
477 case ICMD_FSTORE: /* ..., value ==> ... */
478 /* op1 = local variable */
480 gen_ISTORE(((Inst **)cd), iptr->op1);
483 case ICMD_DSTORE: /* ..., value ==> ... */
484 /* op1 = local variable */
486 gen_LSTORE(((Inst **)cd), iptr->op1);
490 /* pop/dup/swap operations ********************************************/
492 /* attention: double and longs are only one entry in CACAO ICMDs */
494 /* stack.c changes stack manipulation operations to treat
495 longs/doubles as occupying a single slot. Here we are
496 undoing that (and only those things that stack.c did). */
498 case ICMD_POP: /* ..., value ==> ... */
500 if (IS_2_WORD_TYPE(src->type))
501 gen_POP2(((Inst **)cd));
503 gen_POP(((Inst **)cd));
506 case ICMD_POP2: /* ..., value, value ==> ... */
508 gen_POP2(((Inst **)cd));
511 case ICMD_DUP: /* ..., a ==> ..., a, a */
513 if (IS_2_WORD_TYPE(src->type))
514 gen_DUP2(((Inst **)cd));
516 gen_DUP(((Inst **)cd));
519 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
521 if (IS_2_WORD_TYPE(src->type)) {
522 if (IS_2_WORD_TYPE(src->prev->type)) {
523 gen_DUP2_X2(((Inst **)cd));
525 gen_DUP2_X1(((Inst **)cd));
528 if (IS_2_WORD_TYPE(src->prev->type)) {
529 gen_DUP_X2(((Inst **)cd));
531 gen_DUP_X1(((Inst **)cd));
536 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
538 if (IS_2_WORD_TYPE(src->type)) {
539 gen_DUP2_X2(((Inst **)cd));
541 gen_DUP_X2(((Inst **)cd));
544 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
546 gen_DUP2(((Inst **)cd));
549 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
551 if (IS_2_WORD_TYPE(src->prev->prev->type))
552 gen_DUP2_X2(((Inst **)cd));
554 gen_DUP2_X1(((Inst **)cd));
557 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
559 gen_DUP2_X2(((Inst **)cd));
562 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
564 gen_SWAP(((Inst **)cd));
568 /* integer operations *************************************************/
570 case ICMD_INEG: /* ..., value ==> ..., - value */
572 gen_INEG(((Inst **)cd));
575 case ICMD_LNEG: /* ..., value ==> ..., - value */
577 gen_LNEG(((Inst **)cd));
580 case ICMD_I2L: /* ..., value ==> ..., value */
582 gen_I2L(((Inst **)cd));
585 case ICMD_L2I: /* ..., value ==> ..., value */
587 gen_L2I(((Inst **)cd));
590 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
592 gen_INT2BYTE(((Inst **)cd));
595 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
597 gen_INT2CHAR(((Inst **)cd));
600 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
602 gen_INT2SHORT(((Inst **)cd));
606 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
608 gen_IADD(((Inst **)cd));
611 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
612 /* val.i = constant */
614 gen_ICONST(((Inst **)cd), iptr->val.i);
615 gen_IADD(((Inst **)cd));
618 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
620 gen_LADD(((Inst **)cd));
623 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
624 /* val.l = constant */
626 gen_LCONST(((Inst **)cd), iptr->val.l);
627 gen_LADD(((Inst **)cd));
630 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
632 gen_ISUB(((Inst **)cd));
635 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
636 /* val.i = constant */
638 gen_ICONST(((Inst **)cd), iptr->val.i);
639 gen_ISUB(((Inst **)cd));
642 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
644 gen_LSUB(((Inst **)cd));
647 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
648 /* val.l = constant */
650 gen_LCONST(((Inst **)cd), iptr->val.l);
651 gen_LSUB(((Inst **)cd));
654 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
656 gen_IMUL(((Inst **)cd));
659 case ICMD_IMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
661 gen_ICONST(((Inst **)cd), iptr->val.i);
662 gen_IMUL(((Inst **)cd));
665 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
667 gen_LMUL(((Inst **)cd));
670 case ICMD_LMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
672 gen_LCONST(((Inst **)cd), iptr->val.l);
673 gen_LMUL(((Inst **)cd));
676 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
678 gen_IDIV(((Inst **)cd));
681 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
683 gen_IREM(((Inst **)cd));
686 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
688 gen_LDIV(((Inst **)cd));
691 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
693 gen_LREM(((Inst **)cd));
696 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
697 /* val.i = constant */
699 gen_IDIVPOW2(((Inst **)cd), iptr->val.i);
702 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
703 /* val.i = constant */
705 gen_IREMPOW2(((Inst **)cd), iptr->val.i);
708 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
709 /* val.i = constant */
711 gen_LDIVPOW2(((Inst **)cd), iptr->val.i);
714 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
715 /* val.l = constant */
717 gen_LREMPOW2(((Inst **)cd), iptr->val.i);
720 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
722 gen_ISHL(((Inst **)cd));
725 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
726 /* val.i = constant */
728 gen_ICONST(((Inst **)cd), iptr->val.i);
729 gen_ISHL(((Inst **)cd));
732 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
734 gen_ISHR(((Inst **)cd));
737 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
738 /* val.i = constant */
740 gen_ICONST(((Inst **)cd), iptr->val.i);
741 gen_ISHR(((Inst **)cd));
744 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
746 gen_IUSHR(((Inst **)cd));
749 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
750 /* val.i = constant */
752 gen_ICONST(((Inst **)cd), iptr->val.i);
753 gen_IUSHR(((Inst **)cd));
756 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
758 gen_LSHL(((Inst **)cd));
761 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
762 /* val.i = constant */
764 gen_ICONST(((Inst **)cd), iptr->val.i);
765 gen_LSHL(((Inst **)cd));
768 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
770 gen_LSHR(((Inst **)cd));
773 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
774 /* val.i = constant */
776 gen_ICONST(((Inst **)cd), iptr->val.i);
777 gen_LSHR(((Inst **)cd));
780 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
782 gen_LUSHR(((Inst **)cd));
785 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
786 /* val.i = constant */
788 gen_ICONST(((Inst **)cd), iptr->val.i);
789 gen_LUSHR(((Inst **)cd));
792 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
794 gen_IAND(((Inst **)cd));
797 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
798 /* val.i = constant */
800 gen_ICONST(((Inst **)cd), iptr->val.i);
801 gen_IAND(((Inst **)cd));
804 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
806 gen_LAND(((Inst **)cd));
809 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
810 /* val.l = constant */
812 gen_LCONST(((Inst **)cd), iptr->val.l);
813 gen_LAND(((Inst **)cd));
816 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
818 gen_IOR(((Inst **)cd));
821 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
822 /* val.i = constant */
824 gen_ICONST(((Inst **)cd), iptr->val.i);
825 gen_IOR(((Inst **)cd));
828 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
830 gen_LOR(((Inst **)cd));
833 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
834 /* val.l = constant */
836 gen_LCONST(((Inst **)cd), iptr->val.l);
837 gen_LOR(((Inst **)cd));
840 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
842 gen_IXOR(((Inst **)cd));
845 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
846 /* val.i = constant */
848 gen_ICONST(((Inst **)cd), iptr->val.i);
849 gen_IXOR(((Inst **)cd));
852 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
854 gen_LXOR(((Inst **)cd));
857 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
858 /* val.l = constant */
860 gen_LCONST(((Inst **)cd), iptr->val.l);
861 gen_LXOR(((Inst **)cd));
865 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
867 gen_LCMP(((Inst **)cd));
871 case ICMD_IINC: /* ..., value ==> ..., value + constant */
872 /* op1 = variable, val.i = constant */
874 gen_IINC(((Inst **)cd), iptr->op1, iptr->val.i);
878 /* floating operations ************************************************/
880 case ICMD_FNEG: /* ..., value ==> ..., - value */
882 gen_FNEG(((Inst **)cd));
885 case ICMD_DNEG: /* ..., value ==> ..., - value */
887 gen_DNEG(((Inst **)cd));
890 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
892 gen_FADD(((Inst **)cd));
895 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
897 gen_DADD(((Inst **)cd));
900 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
902 gen_FSUB(((Inst **)cd));
905 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
907 gen_DSUB(((Inst **)cd));
910 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
912 gen_FMUL(((Inst **)cd));
915 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
917 gen_DMUL(((Inst **)cd));
920 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
922 gen_FDIV(((Inst **)cd));
925 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
927 gen_DDIV(((Inst **)cd));
930 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
932 gen_FREM(((Inst **)cd));
935 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
937 gen_DREM(((Inst **)cd));
940 case ICMD_I2F: /* ..., value ==> ..., (float) value */
942 gen_I2F(((Inst **)cd));
945 case ICMD_L2F: /* ..., value ==> ..., (float) value */
947 gen_L2F(((Inst **)cd));
950 case ICMD_I2D: /* ..., value ==> ..., (double) value */
952 gen_I2D(((Inst **)cd));
955 case ICMD_L2D: /* ..., value ==> ..., (double) value */
957 gen_L2D(((Inst **)cd));
960 case ICMD_F2I: /* ..., value ==> ..., (int) value */
962 gen_F2I(((Inst **)cd));
965 case ICMD_D2I: /* ..., value ==> ..., (int) value */
967 gen_D2I(((Inst **)cd));
970 case ICMD_F2L: /* ..., value ==> ..., (long) value */
972 gen_F2L(((Inst **)cd));
975 case ICMD_D2L: /* ..., value ==> ..., (long) value */
977 gen_D2L(((Inst **)cd));
980 case ICMD_F2D: /* ..., value ==> ..., (double) value */
982 gen_F2D(((Inst **)cd));
985 case ICMD_D2F: /* ..., value ==> ..., (float) value */
987 gen_D2F(((Inst **)cd));
990 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
992 gen_FCMPL(((Inst **)cd));
995 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
997 gen_DCMPL(((Inst **)cd));
1000 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1002 gen_FCMPG(((Inst **)cd));
1005 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1007 gen_DCMPG(((Inst **)cd));
1011 /* memory operations **************************************************/
1013 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1015 gen_ARRAYLENGTH(((Inst **)cd));
1018 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1020 gen_BALOAD(((Inst **)cd));
1023 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1025 gen_CALOAD(((Inst **)cd));
1028 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1030 gen_SALOAD(((Inst **)cd));
1033 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1034 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1036 gen_IALOAD(((Inst **)cd));
1039 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1040 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1042 gen_LALOAD(((Inst **)cd));
1045 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1047 gen_AALOAD(((Inst **)cd));
1051 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1053 gen_BASTORE(((Inst **)cd));
1056 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1057 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1059 gen_CASTORE(((Inst **)cd));
1062 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1063 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1065 gen_IASTORE(((Inst **)cd));
1068 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1069 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1071 gen_LASTORE(((Inst **)cd));
1074 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1076 gen_AASTORE(((Inst **)cd));
1080 case ICMD_GETSTATIC: /* ... ==> ..., value */
1081 /* op1 = type, val.a = field address */
1084 fieldinfo *fi = iptr->val.a;
1085 unresolved_field *uf = iptr->target;
1087 switch (iptr->op1) {
1090 if (fi == NULL || !fi->class->initialized) {
1091 gen_PATCHER_GETSTATIC_INT(((Inst **)cd), 0, uf);
1093 gen_GETSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1098 if (fi == NULL || !fi->class->initialized) {
1099 gen_PATCHER_GETSTATIC_LONG(((Inst **)cd), 0, uf);
1101 gen_GETSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1105 if (fi == NULL || !fi->class->initialized) {
1106 gen_PATCHER_GETSTATIC_CELL(((Inst **)cd), 0, uf);
1108 gen_GETSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1115 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1116 /* op1 = type, val.a = field address */
1119 fieldinfo *fi = iptr->val.a;
1120 unresolved_field *uf = iptr->target;
1122 switch (iptr->op1) {
1125 if (fi == NULL || !fi->class->initialized) {
1126 gen_PATCHER_PUTSTATIC_INT(((Inst **)cd), 0, uf);
1128 gen_PUTSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1133 if (fi == NULL || !fi->class->initialized) {
1134 gen_PATCHER_PUTSTATIC_LONG(((Inst **)cd), 0, uf);
1136 gen_PUTSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1140 if (fi == NULL || !fi->class->initialized) {
1141 gen_PATCHER_PUTSTATIC_CELL(((Inst **)cd), 0, uf);
1143 gen_PUTSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1150 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1151 /* val = value (in current instruction) */
1152 /* op1 = type, val.a = field address (in */
1153 /* following NOP) */
1156 fieldinfo *fi = iptr[1].val.a;
1157 unresolved_field *uf = iptr[1].target;
1159 switch (iptr->op1) {
1162 gen_ICONST(((Inst **)cd), iptr->val.i);
1163 if (fi == NULL || !fi->class->initialized) {
1164 gen_PATCHER_PUTSTATIC_INT(((Inst **)cd), 0, uf);
1166 gen_PUTSTATIC_INT(((Inst **)cd), (u1 *)&(fi->value.i), uf);
1171 gen_LCONST(((Inst **)cd), iptr->val.l);
1172 if (fi == NULL || !fi->class->initialized) {
1173 gen_PATCHER_PUTSTATIC_LONG(((Inst **)cd), 0, uf);
1175 gen_PUTSTATIC_LONG(((Inst **)cd), (u1 *)&(fi->value.l), uf);
1179 gen_ACONST(((Inst **)cd), iptr->val.a);
1180 if (fi == NULL || !fi->class->initialized) {
1181 gen_PATCHER_PUTSTATIC_CELL(((Inst **)cd), 0, uf);
1183 gen_PUTSTATIC_CELL(((Inst **)cd), (u1 *)&(fi->value.a), uf);
1191 case ICMD_GETFIELD: /* ... ==> ..., value */
1192 /* op1 = type, val.a = field address */
1195 fieldinfo *fi = iptr->val.a;
1196 unresolved_field *uf = iptr->target;
1198 switch (iptr->op1) {
1202 gen_PATCHER_GETFIELD_INT(((Inst **)cd), 0, uf);
1204 gen_GETFIELD_INT(((Inst **)cd), fi->offset, uf);
1210 gen_PATCHER_GETFIELD_LONG(((Inst **)cd), 0, uf);
1212 gen_GETFIELD_LONG(((Inst **)cd), fi->offset, uf);
1217 gen_PATCHER_GETFIELD_CELL(((Inst **)cd), 0, uf);
1219 gen_GETFIELD_CELL(((Inst **)cd), fi->offset, uf);
1226 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1227 /* op1 = type, val.a = field address */
1230 fieldinfo *fi = iptr->val.a;
1231 unresolved_field *uf = iptr->target;
1233 switch (iptr->op1) {
1237 gen_PATCHER_PUTFIELD_INT(((Inst **)cd), 0, uf);
1239 gen_PUTFIELD_INT(((Inst **)cd), fi->offset, uf);
1245 gen_PATCHER_PUTFIELD_LONG(((Inst **)cd), 0, uf);
1247 gen_PUTFIELD_LONG(((Inst **)cd), fi->offset, uf);
1252 gen_PATCHER_PUTFIELD_CELL(((Inst **)cd), 0, uf);
1254 gen_PUTFIELD_CELL(((Inst **)cd), fi->offset, uf);
1261 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1262 /* val = value (in current instruction) */
1263 /* op1 = type, val.a = field address (in */
1264 /* following NOP) */
1267 fieldinfo *fi = iptr[1].val.a;
1268 unresolved_field *uf = iptr[1].target;
1270 switch (iptr[1].op1) {
1273 gen_ICONST(((Inst **)cd), iptr->val.i);
1275 gen_PATCHER_PUTFIELD_INT(((Inst **)cd), 0, uf);
1277 gen_PUTFIELD_INT(((Inst **)cd), fi->offset, uf);
1282 gen_LCONST(((Inst **)cd), iptr->val.l);
1284 gen_PATCHER_PUTFIELD_LONG(((Inst **)cd), 0, uf);
1286 gen_PUTFIELD_LONG(((Inst **)cd), fi->offset, uf);
1290 gen_ACONST(((Inst **)cd), iptr->val.a);
1292 gen_PATCHER_PUTFIELD_CELL(((Inst **)cd), 0, uf);
1294 gen_PUTFIELD_CELL(((Inst **)cd), fi->offset, uf);
1302 /* branch operations **************************************************/
1304 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1306 gen_ATHROW(((Inst **)cd));
1309 case ICMD_GOTO: /* ... ==> ... */
1310 /* op1 = target JavaVM pc */
1314 case ICMD_JSR: /* ... ==> ... */
1315 /* op1 = target JavaVM pc */
1319 case ICMD_RET: /* ... ==> ... */
1320 /* op1 = local variable */
1322 gen_RET(((Inst **)cd), iptr->op1);
1325 case ICMD_IFNULL: /* ..., value ==> ... */
1326 /* op1 = target JavaVM pc */
1331 case ICMD_IFNONNULL: /* ..., value ==> ... */
1332 /* op1 = target JavaVM pc */
1334 gen_branch(IFNONNULL);
1337 case ICMD_IFEQ: /* ..., value ==> ... */
1338 /* op1 = target JavaVM pc, val.i = constant */
1340 if (iptr->val.i == 0) {
1343 gen_ICONST(((Inst **)cd), iptr->val.i);
1344 gen_branch(IF_ICMPEQ);
1348 case ICMD_IFLT: /* ..., value ==> ... */
1349 /* op1 = target JavaVM pc, val.i = constant */
1351 if (iptr->val.i == 0) {
1354 gen_ICONST(((Inst **)cd), iptr->val.i);
1355 gen_branch(IF_ICMPLT);
1359 case ICMD_IFLE: /* ..., value ==> ... */
1360 /* op1 = target JavaVM pc, val.i = constant */
1362 if (iptr->val.i == 0) {
1365 gen_ICONST(((Inst **)cd), iptr->val.i);
1366 gen_branch(IF_ICMPLE);
1370 case ICMD_IFNE: /* ..., value ==> ... */
1371 /* op1 = target JavaVM pc, val.i = constant */
1373 if (iptr->val.i == 0) {
1376 gen_ICONST(((Inst **)cd), iptr->val.i);
1377 gen_branch(IF_ICMPNE);
1381 case ICMD_IFGT: /* ..., value ==> ... */
1382 /* op1 = target JavaVM pc, val.i = constant */
1384 if (iptr->val.i == 0) {
1387 gen_ICONST(((Inst **)cd), iptr->val.i);
1388 gen_branch(IF_ICMPGT);
1392 case ICMD_IFGE: /* ..., value ==> ... */
1393 /* op1 = target JavaVM pc, val.i = constant */
1395 if (iptr->val.i == 0) {
1398 gen_ICONST(((Inst **)cd), iptr->val.i);
1399 gen_branch(IF_ICMPGE);
1403 case ICMD_IF_LEQ: /* ..., value ==> ... */
1404 /* op1 = target JavaVM pc, val.l = constant */
1406 gen_LCONST(((Inst **)cd), iptr->val.l);
1407 gen_branch(IF_LCMPEQ);
1410 case ICMD_IF_LLT: /* ..., value ==> ... */
1411 /* op1 = target JavaVM pc, val.l = constant */
1413 gen_LCONST(((Inst **)cd), iptr->val.l);
1414 gen_branch(IF_LCMPLT);
1417 case ICMD_IF_LLE: /* ..., value ==> ... */
1418 /* op1 = target JavaVM pc, val.l = constant */
1420 gen_LCONST(((Inst **)cd), iptr->val.l);
1421 gen_branch(IF_LCMPLE);
1424 case ICMD_IF_LNE: /* ..., value ==> ... */
1425 /* op1 = target JavaVM pc, val.l = constant */
1427 gen_LCONST(((Inst **)cd), iptr->val.l);
1428 gen_branch(IF_LCMPNE);
1431 case ICMD_IF_LGT: /* ..., value ==> ... */
1432 /* op1 = target JavaVM pc, val.l = constant */
1434 gen_LCONST(((Inst **)cd), iptr->val.l);
1435 gen_branch(IF_LCMPGT);
1438 case ICMD_IF_LGE: /* ..., value ==> ... */
1439 /* op1 = target JavaVM pc, val.l = constant */
1441 gen_LCONST(((Inst **)cd), iptr->val.l);
1442 gen_branch(IF_LCMPGE);
1445 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1446 /* op1 = target JavaVM pc */
1448 gen_branch(IF_ICMPEQ);
1451 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1452 /* op1 = target JavaVM pc */
1454 gen_branch(IF_LCMPEQ);
1457 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
1458 /* op1 = target JavaVM pc */
1460 gen_branch(IF_ACMPEQ);
1463 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
1464 /* op1 = target JavaVM pc */
1466 gen_branch(IF_ICMPNE);
1469 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1470 /* op1 = target JavaVM pc */
1472 gen_branch(IF_LCMPNE);
1475 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
1476 /* op1 = target JavaVM pc */
1478 gen_branch(IF_ACMPNE);
1481 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
1482 /* op1 = target JavaVM pc */
1484 gen_branch(IF_ICMPLT);
1487 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1488 /* op1 = target JavaVM pc */
1490 gen_branch(IF_LCMPLT);
1493 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
1494 /* op1 = target JavaVM pc */
1496 gen_branch(IF_ICMPGT);
1499 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1500 /* op1 = target JavaVM pc */
1502 gen_branch(IF_LCMPGT);
1505 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
1506 /* op1 = target JavaVM pc */
1508 gen_branch(IF_ICMPLE);
1511 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1512 /* op1 = target JavaVM pc */
1514 gen_branch(IF_LCMPLE);
1517 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
1518 /* op1 = target JavaVM pc */
1520 gen_branch(IF_ICMPGE);
1523 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1524 /* op1 = target JavaVM pc */
1526 gen_branch(IF_LCMPGE);
1530 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1531 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1532 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1534 #if defined(USE_THREADS)
1535 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1536 if (m->flags & ACC_STATIC) {
1537 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1539 gen_ALOAD(((Inst **)cd), 0);
1541 gen_MONITOREXIT(((Inst **)cd));
1545 gen_TRACERETURN(((Inst **)cd));
1547 gen_IRETURN(((Inst **)cd), cd->maxlocals);
1550 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1551 case ICMD_DRETURN: /* ..., retvalue ==> ... */
1553 #if defined(USE_THREADS)
1554 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1555 if (m->flags & ACC_STATIC) {
1556 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1558 gen_ALOAD(((Inst **)cd), 0);
1560 gen_MONITOREXIT(((Inst **)cd));
1564 gen_TRACELRETURN(((Inst **)cd));
1566 gen_LRETURN(((Inst **)cd), cd->maxlocals);
1569 case ICMD_RETURN: /* ... ==> ... */
1571 #if defined(USE_THREADS)
1572 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1573 if (m->flags & ACC_STATIC) {
1574 gen_ACONST(((Inst **)cd), (java_objectheader *) m->class);
1576 gen_ALOAD(((Inst **)cd), 0);
1578 gen_MONITOREXIT(((Inst **)cd));
1582 gen_TRACERETURN(((Inst **)cd));
1584 gen_RETURN(((Inst **)cd), cd->maxlocals);
1588 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1593 tptr = (void **) iptr->target;
1595 s4ptr = iptr->val.a;
1596 l = s4ptr[1]; /* low */
1597 i = s4ptr[2]; /* high */
1601 /* arguments: low, range, datasegment address, table offset in */
1602 /* datasegment, default target */
1603 gen_TABLESWITCH(((Inst **)cd), l, i, NULL, 0, NULL);
1604 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1605 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1607 /* build jump table top down and use address of lowest entry */
1612 dseg_addtarget(cd, (basicblock *) tptr[0]);
1617 /* length of dataseg after last dseg_addtarget is used by load */
1618 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1622 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
1627 tptr = (void **) iptr->target;
1629 s4ptr = iptr->val.a;
1631 /* s4ptr[0] is equal to tptr[0] */
1632 i = s4ptr[1]; /* count */
1634 /* arguments: count, datasegment address, table offset in */
1635 /* datasegment, default target */
1636 gen_LOOKUPSWITCH(((Inst **)cd), i, NULL, 0, NULL);
1637 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1638 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1640 /* build jump table top down and use address of lowest entry */
1646 dseg_addtarget(cd, (basicblock *) tptr[0]);
1647 dseg_addaddress(cd, s4ptr[0]);
1653 /* length of dataseg after last dseg_addtarget is used by load */
1654 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1658 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1659 /* op1 = arg count val.a = builtintable entry */
1661 if (bte->fp == PATCHER_builtin_new) {
1662 gen_PATCHER_NEW(((Inst **)cd), 0);
1663 } else if (bte->fp == PATCHER_builtin_newarray) {
1664 gen_PATCHER_NEWARRAY(((Inst **)cd), 0);
1665 } else if (bte->fp == PATCHER_builtin_arrayinstanceof) {
1666 gen_PATCHER_ARRAYINSTANCEOF(((Inst **)cd), 0);
1668 for (i = 0; i < sizeof(builtin_gen_table)/sizeof(builtin_gen); i++) {
1669 builtin_gen *bg = &builtin_gen_table[i];
1670 if (bg->builtin == bte->fp) {
1671 (bg->gen)(((Inst **)cd));
1672 goto gen_builtin_end;
1680 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1681 /* op1 = arg count, val.a = method pointer */
1687 md = um->methodref->parseddesc.md;
1688 gen_PATCHER_INVOKESTATIC(((Inst **)cd), 0, md->paramslots, um);
1691 md = lm->parseddesc;
1692 gen_INVOKESTATIC(((Inst **)cd), (Inst **)lm->stubroutine, md->paramslots, um);
1696 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1702 md = um->methodref->parseddesc.md;
1703 gen_PATCHER_INVOKESPECIAL(((Inst **)cd), 0, md->paramslots, um);
1706 md = lm->parseddesc;
1707 gen_INVOKESPECIAL(((Inst **)cd), (Inst **)lm->stubroutine, md->paramslots, um);
1711 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1717 md = um->methodref->parseddesc.md;
1718 gen_PATCHER_INVOKEVIRTUAL(((Inst **)cd), 0, md->paramslots, um);
1721 md = lm->parseddesc;
1723 s1 = OFFSET(vftbl_t, table[0]) +
1724 sizeof(methodptr) * lm->vftblindex;
1726 gen_INVOKEVIRTUAL(((Inst **)cd), s1, md->paramslots, um);
1730 case ICMD_INVOKEINTERFACE:/* op1 = arg count, val.a = method pointer */
1736 md = um->methodref->parseddesc.md;
1737 gen_PATCHER_INVOKEINTERFACE(((Inst **)cd), 0, 0, md->paramslots, um);
1740 md = lm->parseddesc;
1742 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1743 sizeof(methodptr*) * lm->class->index;
1745 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1747 gen_INVOKEINTERFACE(((Inst **)cd), s1, s2, md->paramslots, um);
1752 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1753 /* op1: 0 == array, 1 == class */
1754 /* val.a: (classinfo *) superclass */
1756 if (iptr->val.a == NULL) {
1757 gen_PATCHER_CHECKCAST(((Inst **)cd), 0, iptr->target);
1760 gen_CHECKCAST(((Inst **)cd), iptr->val.a, iptr->target);
1765 case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref */
1766 /* op1: 1... resolved, 0... not resolved */
1768 if (iptr->op1 == 0) {
1769 gen_PATCHER_ARRAYCHECKCAST(((Inst **)cd), 0, iptr->target);
1771 gen_ARRAYCHECKCAST(((Inst **)cd), iptr->target, 0);
1775 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1776 /* op1: 0 == array, 1 == class */
1777 /* val.a: (classinfo *) superclass */
1779 if (iptr->val.a == NULL) {
1780 gen_PATCHER_INSTANCEOF(((Inst **)cd), 0, iptr->target);
1782 gen_INSTANCEOF(((Inst **)cd), iptr->val.a, iptr->target);
1788 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
1790 /* XXX remove me! */
1793 case ICMD_CHECKEXCEPTION: /* ..., objectref ==> ..., objectref */
1795 gen_CHECKEXCEPTION(((Inst **)cd));
1798 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
1799 /* op1 = dimension, val.a = array descriptor */
1802 gen_PATCHER_MULTIANEWARRAY(((Inst **)cd), 0, iptr->op1, iptr->val.a);
1804 gen_MULTIANEWARRAY(((Inst **)cd), iptr->val.a, iptr->op1, 0);
1809 throw_cacao_exception_exit(string_java_lang_InternalError,
1810 "Unknown ICMD %d", iptr->opc);
1813 } /* for instruction */
1815 } /* if (bptr -> flags >= BBREACHED) */
1816 } /* for basic block */
1818 codegen_createlinenumbertable(cd);
1820 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1823 /* branch resolving (walk through all basic blocks) */
1825 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
1828 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
1829 gen_resolveanybranch(((u1*) m->entrypoint) + brefs->branchpos,
1830 ((u1 *)m->entrypoint) + bptr->mpc);
1836 /* a stub consists of
1848 codeptr points either to TRANSLATE or to the translated threaded code
1850 all methods are called indirectly through methodptr
1853 #define COMPILERSTUB_SIZE 4
1855 functionptr createcompilerstub (methodinfo *m)
1861 s = CNEW(Inst, COMPILERSTUB_SIZE);
1863 /* mark start of dump memory area */
1865 dumpsize = dump_size();
1867 cd = DNEW(codegendata);
1868 cd->mcodeptr = (u1 *) s;
1870 genarg_ainst((Inst **) cd, s + 2);
1872 if (m->flags & ACC_NATIVE) {
1873 genarg_i((Inst **) cd, m->parseddesc->paramslots);
1875 genarg_i((Inst **) cd, m->maxlocals);
1879 gen_TRANSLATE((Inst **) cd, m);
1881 #if defined(STATISTICS)
1883 count_cstub_len += COMPILERSTUB_SIZE;
1886 /* release dump area */
1888 dump_release(dumpsize);
1890 return (functionptr) s;
1903 where maxlocals==paramslots
1906 #define NATIVE_STUBSIZE 5
1908 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
1909 registerdata *rd, methoddesc *md)
1911 cd->mcodeptr = cd->mcodebase;
1912 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
1914 /* create method header */
1916 (void) dseg_addaddress(cd, m); /* MethodPointer */
1917 (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P); /* FrameSize */
1918 (void) dseg_adds4(cd, 0); /* IsSync */
1919 (void) dseg_adds4(cd, 0); /* IsLeaf */
1920 (void) dseg_adds4(cd, 0); /* IntSave */
1921 (void) dseg_adds4(cd, 0); /* FltSave */
1922 dseg_addlinenumbertablesize(cd);
1923 (void) dseg_adds4(cd, 0); /* ExTableSize */
1928 gen_TRACECALL(((Inst **)cd));
1931 gen_PATCHER_NATIVECALL(((Inst **)cd), m, f);
1934 gen_TRACENATIVECALL(((Inst **)cd), m, f);
1936 gen_NATIVECALL(((Inst **)cd), m, f);
1939 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1941 return m->entrypoint;
1945 functionptr createcalljavafunction(methodinfo *m)
1948 functionptr entrypoint;
1951 t_inlining_globals *id;
1955 /* mark dump memory */
1957 dumpsize = dump_size();
1959 tmpm = DNEW(methodinfo);
1960 cd = DNEW(codegendata);
1961 rd = DNEW(registerdata);
1962 id = DNEW(t_inlining_globals);
1964 /* setup code generation stuff */
1966 MSET(tmpm, 0, u1, sizeof(methodinfo));
1968 inlining_setup(tmpm, id);
1969 codegen_setup(tmpm, cd, id);
1973 cd->mcodeptr = cd->mcodebase;
1974 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
1976 /* create method header */
1978 (void) dseg_addaddress(cd, NULL); /* MethodPointer */
1979 (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P); /* FrameSize */
1980 (void) dseg_adds4(cd, 0); /* IsSync */
1981 (void) dseg_adds4(cd, 0); /* IsLeaf */
1982 (void) dseg_adds4(cd, 0); /* IntSave */
1983 (void) dseg_adds4(cd, 0); /* FltSave */
1984 dseg_addlinenumbertablesize(cd);
1985 (void) dseg_adds4(cd, 0); /* ExTableSize */
1991 gen_INVOKESTATIC(((Inst **)cd), (Inst **)m->stubroutine, md->paramslots, 0);
1992 gen_END(((Inst **)cd));
1994 codegen_finish(tmpm, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1996 entrypoint = tmpm->entrypoint;
1998 /* release memory */
2000 dump_release(dumpsize);
2007 * These are local overrides for various environment variables in Emacs.
2008 * Please do not remove this and leave it at the end of the file, where
2009 * Emacs will automagically detect them.
2010 * ---------------------------------------------------------------------
2013 * indent-tabs-mode: t