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 4185 2006-01-12 23:23:28Z twisti $
47 #include "vm/jit/intrp/codegen.h"
48 #include "vm/jit/intrp/intrp.h"
50 #include "cacao/cacao.h"
51 #include "native/native.h"
52 #include "vm/builtin.h"
54 #include "vm/exceptions.h"
55 #include "vm/global.h"
56 #include "vm/options.h"
57 #include "vm/stringlocal.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/codegen-common.h"
60 #include "vm/jit/dseg.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/parse.h"
63 #include "vm/jit/patcher.h"
67 #elif defined(WITH_FFCALL)
70 # error neither WITH_FFI nor WITH_FFCALL defined
74 #define gen_branch(_inst) { \
76 codegen_addreference(cd, (basicblock *) (iptr->target), cd->mcodeptr); \
79 #define index2offset(_i) (-(_i) * SIZEOF_VOID_P)
81 /* functions used by cacao-gen.i */
83 void genarg_v(codegendata *cd1, Cell v)
85 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
86 *((Cell *) *mcodepp) = v;
90 void genarg_i(codegendata *cd1, s4 i)
92 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
93 *((Cell *) *mcodepp) = i;
97 void genarg_b(codegendata *cd1, s4 i)
102 void genarg_f(codegendata *cd1, float f)
110 void genarg_l(codegendata *cd1, s8 l)
112 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
113 vm_l2twoCell(l, ((Cell *) *mcodepp)[1], ((Cell *) *mcodepp)[0]);
117 void genarg_aRef(codegendata *cd1, java_objectheader *a)
119 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
120 *((java_objectheader **) *mcodepp) = a;
124 void genarg_aArray(codegendata *cd1, java_arrayheader *a)
126 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
127 *((java_arrayheader **) *mcodepp) = a;
131 void genarg_aaTarget(codegendata *cd1, Inst **a)
133 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
134 *((Inst ***) *mcodepp) = a;
138 void genarg_aClass(codegendata *cd1, classinfo *a)
140 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
141 *((classinfo **) *mcodepp) = a;
145 void genarg_acr(codegendata *cd1, constant_classref *a)
147 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
148 *((constant_classref **) *mcodepp) = a;
152 void genarg_addr(codegendata *cd1, u1 *a)
154 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
155 *((u1 **) *mcodepp) = a;
159 void genarg_af(codegendata *cd1, functionptr a)
161 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
162 *((functionptr *) *mcodepp) = a;
166 void genarg_am(codegendata *cd1, methodinfo *a)
168 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
169 *((methodinfo **) *mcodepp) = a;
173 void genarg_acell(codegendata *cd1, Cell *a)
175 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
176 *((Cell **) *mcodepp) = a;
180 void genarg_ainst(codegendata *cd1, Inst *a)
182 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
183 *((Inst **) *mcodepp) = a;
187 void genarg_auf(codegendata *cd1, unresolved_field *a)
189 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
190 *((unresolved_field **) *mcodepp) = a;
194 void genarg_aum(codegendata *cd1, unresolved_method *a)
196 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
197 *((unresolved_method **) *mcodepp) = a;
201 void genarg_avftbl(codegendata *cd1, vftbl_t *a)
203 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
204 *((vftbl_t **) *mcodepp) = a;
209 /* include the interpreter generation functions *******************************/
211 #include "vm/jit/intrp/java-gen.i"
214 typedef void (*genfunctionptr) (codegendata *);
216 typedef struct builtin_gen builtin_gen;
223 struct builtin_gen builtin_gen_table[] = {
224 {BUILTIN_new, gen_NEW, },
225 {BUILTIN_newarray, gen_NEWARRAY, },
226 {BUILTIN_newarray_boolean, gen_NEWARRAY_BOOLEAN,},
227 {BUILTIN_newarray_byte, gen_NEWARRAY_BYTE, },
228 {BUILTIN_newarray_char, gen_NEWARRAY_CHAR, },
229 {BUILTIN_newarray_short, gen_NEWARRAY_SHORT, },
230 {BUILTIN_newarray_int, gen_NEWARRAY_INT, },
231 {BUILTIN_newarray_long, gen_NEWARRAY_LONG, },
232 {BUILTIN_newarray_float, gen_NEWARRAY_FLOAT, },
233 {BUILTIN_newarray_double, gen_NEWARRAY_DOUBLE, },
234 {BUILTIN_arrayinstanceof, gen_ARRAYINSTANCEOF, },
236 #if defined(USE_THREADS)
237 {BUILTIN_monitorenter, gen_MONITORENTER, },
238 {BUILTIN_monitorexit, gen_MONITOREXIT, },
241 #if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L)
242 {BUILTIN_f2l, gen_F2L, },
245 #if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L)
246 {BUILTIN_d2l, gen_D2L, },
249 #if !(SUPPORT_FLOAT && SUPPORT_F2I)
250 {BUILTIN_f2i, gen_F2I, },
253 #if !(SUPPORT_DOUBLE && SUPPORT_D2I)
254 {BUILTIN_d2i, gen_D2I, },
257 #if !SUPPORT_DIVISION
258 {BUILTIN_idiv, gen_IDIV, },
259 {BUILTIN_irem, gen_IREM, },
262 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
263 {BUILTIN_ldiv, gen_LDIV, },
264 {BUILTIN_lrem, gen_LREM, },
267 {BUILTIN_frem, gen_FREM, },
268 {BUILTIN_drem, gen_DREM, },
272 /* codegen *********************************************************************
274 Generates machine code.
276 *******************************************************************************/
278 bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd)
280 s4 i, len, s1, s2, d;
286 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
287 unresolved_method *um;
288 builtintable_entry *bte;
291 /* prevent compiler warnings */
298 /* create method header */
300 (void) dseg_addaddress(cd, m); /* MethodPointer */
301 (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P); /* FrameSize */
303 #if defined(USE_THREADS)
304 if (checksync && (m->flags & ACC_SYNCHRONIZED))
305 (void) dseg_adds4(cd, 1); /* IsSync */
308 (void) dseg_adds4(cd, 0); /* IsSync */
310 (void) dseg_adds4(cd, 0); /* IsLeaf */
311 (void) dseg_adds4(cd, 0); /* IntSave */
312 (void) dseg_adds4(cd, 0); /* FltSave */
314 dseg_addlinenumbertablesize(cd);
316 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
318 /* create exception table */
320 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
321 dseg_addtarget(cd, ex->start);
322 dseg_addtarget(cd, ex->end);
323 dseg_addtarget(cd, ex->handler);
324 (void) dseg_addaddress(cd, ex->catchtype.cls);
328 /* initialize mcode variables */
330 cd->mcodeptr = cd->mcodebase;
331 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
336 #if defined(USE_THREADS)
337 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
338 if (m->flags & ACC_STATIC)
339 gen_ACONST(cd, (java_objectheader *) m->class);
343 gen_MONITORENTER(cd);
348 gen_TRACECALL(cd, m);
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 */
377 case ICMD_INLINE_START:
378 case ICMD_INLINE_END:
381 case ICMD_NOP: /* ... ==> ... */
384 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
389 /* constant operations ************************************************/
391 case ICMD_ICONST: /* ... ==> ..., constant */
392 /* op1 = 0, val.i = constant */
394 gen_ICONST(cd, iptr->val.i);
397 case ICMD_LCONST: /* ... ==> ..., constant */
398 /* op1 = 0, val.l = constant */
400 gen_LCONST(cd, iptr->val.l);
403 case ICMD_FCONST: /* ... ==> ..., constant */
404 /* op1 = 0, val.f = constant */
408 vm_f2Cell(iptr->val.f, fi);
413 case ICMD_DCONST: /* ... ==> ..., constant */
414 /* op1 = 0, val.d = constant */
416 gen_LCONST(cd, *(s8 *)&(iptr->val.d));
419 case ICMD_ACONST: /* ... ==> ..., constant */
420 /* op1 = 0, val.a = constant */
422 if ((iptr->target != NULL) && (iptr->val.a == NULL))
423 gen_PATCHER_ACONST(cd, NULL, iptr->target);
425 gen_ACONST(cd, iptr->val.a);
429 /* load/store operations **********************************************/
431 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
432 /* op1 = local variable */
434 gen_ILOAD(cd, index2offset(iptr->op1));
437 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
438 /* op1 = local variable */
440 gen_LLOAD(cd, index2offset(iptr->op1));
443 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
444 /* op1 = local variable */
446 gen_ALOAD(cd, index2offset(iptr->op1));
449 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
450 /* op1 = local variable */
452 gen_ILOAD(cd, index2offset(iptr->op1));
455 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
456 /* op1 = local variable */
458 gen_LLOAD(cd, index2offset(iptr->op1));
462 case ICMD_ISTORE: /* ..., value ==> ... */
463 /* op1 = local variable */
465 gen_ISTORE(cd, index2offset(iptr->op1));
468 case ICMD_LSTORE: /* ..., value ==> ... */
469 /* op1 = local variable */
471 gen_LSTORE(cd, index2offset(iptr->op1));
474 case ICMD_ASTORE: /* ..., value ==> ... */
475 /* op1 = local variable */
477 gen_ASTORE(cd, index2offset(iptr->op1));
481 case ICMD_FSTORE: /* ..., value ==> ... */
482 /* op1 = local variable */
484 gen_ISTORE(cd, index2offset(iptr->op1));
487 case ICMD_DSTORE: /* ..., value ==> ... */
488 /* op1 = local variable */
490 gen_LSTORE(cd, index2offset(iptr->op1));
494 /* pop/dup/swap operations ********************************************/
496 /* attention: double and longs are only one entry in CACAO ICMDs */
498 /* stack.c changes stack manipulation operations to treat
499 longs/doubles as occupying a single slot. Here we are
500 undoing that (and only those things that stack.c did). */
502 case ICMD_POP: /* ..., value ==> ... */
504 if (IS_2_WORD_TYPE(src->type))
510 case ICMD_POP2: /* ..., value, value ==> ... */
515 case ICMD_DUP: /* ..., a ==> ..., a, a */
517 if (IS_2_WORD_TYPE(src->type))
523 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
525 if (IS_2_WORD_TYPE(src->type)) {
526 if (IS_2_WORD_TYPE(src->prev->type)) {
532 if (IS_2_WORD_TYPE(src->prev->type)) {
540 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
542 if (IS_2_WORD_TYPE(src->type)) {
548 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
553 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
555 if (IS_2_WORD_TYPE(src->prev->prev->type))
561 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
566 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
572 /* integer operations *************************************************/
574 case ICMD_INEG: /* ..., value ==> ..., - value */
579 case ICMD_LNEG: /* ..., value ==> ..., - value */
584 case ICMD_I2L: /* ..., value ==> ..., value */
589 case ICMD_L2I: /* ..., value ==> ..., value */
594 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
599 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
604 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
610 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
615 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
616 /* val.i = constant */
618 gen_ICONST(cd, iptr->val.i);
622 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
627 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
628 /* val.l = constant */
630 gen_LCONST(cd, iptr->val.l);
634 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
639 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
640 /* val.i = constant */
642 gen_ICONST(cd, iptr->val.i);
646 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
651 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
652 /* val.l = constant */
654 gen_LCONST(cd, iptr->val.l);
658 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
663 case ICMD_IMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
665 gen_ICONST(cd, iptr->val.i);
669 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
674 case ICMD_LMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
676 gen_LCONST(cd, iptr->val.l);
680 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
685 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
690 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
695 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
700 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
701 /* val.i = constant */
703 gen_IDIVPOW2(cd, iptr->val.i);
706 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
707 /* val.i = constant */
709 gen_IREMPOW2(cd, iptr->val.i);
712 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
713 /* val.i = constant */
715 gen_LDIVPOW2(cd, iptr->val.i);
718 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
719 /* val.l = constant */
721 gen_LREMPOW2(cd, iptr->val.i);
724 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
729 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
730 /* val.i = constant */
732 gen_ICONST(cd, iptr->val.i);
736 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
741 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
742 /* val.i = constant */
744 gen_ICONST(cd, iptr->val.i);
748 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
753 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
754 /* val.i = constant */
756 gen_ICONST(cd, iptr->val.i);
760 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
765 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
766 /* val.i = constant */
768 gen_ICONST(cd, iptr->val.i);
772 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
777 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
778 /* val.i = constant */
780 gen_ICONST(cd, iptr->val.i);
784 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
789 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
790 /* val.i = constant */
792 gen_ICONST(cd, iptr->val.i);
796 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
801 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
802 /* val.i = constant */
804 gen_ICONST(cd, iptr->val.i);
808 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
813 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
814 /* val.l = constant */
816 gen_LCONST(cd, iptr->val.l);
820 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
825 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
826 /* val.i = constant */
828 gen_ICONST(cd, iptr->val.i);
832 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
837 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
838 /* val.l = constant */
840 gen_LCONST(cd, iptr->val.l);
844 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
849 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
850 /* val.i = constant */
852 gen_ICONST(cd, iptr->val.i);
856 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
861 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
862 /* val.l = constant */
864 gen_LCONST(cd, iptr->val.l);
869 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
875 case ICMD_IINC: /* ..., value ==> ..., value + constant */
876 /* op1 = variable, val.i = constant */
878 gen_IINC(cd, index2offset(iptr->op1), iptr->val.i);
882 /* floating operations ************************************************/
884 case ICMD_FNEG: /* ..., value ==> ..., - value */
889 case ICMD_DNEG: /* ..., value ==> ..., - value */
894 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
899 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
904 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
909 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
914 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
919 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
924 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
929 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
934 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
939 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
944 case ICMD_I2F: /* ..., value ==> ..., (float) value */
949 case ICMD_L2F: /* ..., value ==> ..., (float) value */
954 case ICMD_I2D: /* ..., value ==> ..., (double) value */
959 case ICMD_L2D: /* ..., value ==> ..., (double) value */
964 case ICMD_F2I: /* ..., value ==> ..., (int) value */
969 case ICMD_D2I: /* ..., value ==> ..., (int) value */
974 case ICMD_F2L: /* ..., value ==> ..., (long) value */
979 case ICMD_D2L: /* ..., value ==> ..., (long) value */
984 case ICMD_F2D: /* ..., value ==> ..., (double) value */
989 case ICMD_D2F: /* ..., value ==> ..., (float) value */
994 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
999 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1004 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1009 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1015 /* memory operations **************************************************/
1017 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1019 gen_ARRAYLENGTH(cd);
1022 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1027 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1032 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1037 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1038 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1043 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1044 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1049 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1055 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1060 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1061 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1066 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1067 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1072 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1073 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1078 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1084 case ICMD_GETSTATIC: /* ... ==> ..., value */
1085 /* op1 = type, val.a = field address */
1088 fieldinfo *fi = iptr->val.a;
1089 unresolved_field *uf = iptr->target;
1091 switch (iptr->op1) {
1093 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1094 gen_PATCHER_GETSTATIC_INT(cd, 0, uf);
1096 gen_GETSTATIC_INT(cd, (u1 *)&(fi->value.i), uf);
1100 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1101 gen_PATCHER_GETSTATIC_FLOAT(cd, 0, uf);
1103 gen_GETSTATIC_FLOAT(cd, (u1 *)&(fi->value.i), uf);
1108 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1109 gen_PATCHER_GETSTATIC_LONG(cd, 0, uf);
1111 gen_GETSTATIC_LONG(cd, (u1 *)&(fi->value.l), uf);
1115 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1116 gen_PATCHER_GETSTATIC_CELL(cd, 0, uf);
1118 gen_GETSTATIC_CELL(cd, (u1 *)&(fi->value.a), uf);
1125 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1126 /* op1 = type, val.a = field address */
1129 fieldinfo *fi = iptr->val.a;
1130 unresolved_field *uf = iptr->target;
1132 switch (iptr->op1) {
1134 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1135 gen_PATCHER_PUTSTATIC_INT(cd, 0, uf);
1137 gen_PUTSTATIC_INT(cd, (u1 *)&(fi->value.i), uf);
1141 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1142 gen_PATCHER_PUTSTATIC_FLOAT(cd, 0, uf);
1144 gen_PUTSTATIC_FLOAT(cd, (u1 *)&(fi->value.i), uf);
1149 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1150 gen_PATCHER_PUTSTATIC_LONG(cd, 0, uf);
1152 gen_PUTSTATIC_LONG(cd, (u1 *)&(fi->value.l), uf);
1156 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1157 gen_PATCHER_PUTSTATIC_CELL(cd, 0, uf);
1159 gen_PUTSTATIC_CELL(cd, (u1 *)&(fi->value.a), uf);
1167 case ICMD_GETFIELD: /* ... ==> ..., value */
1168 /* op1 = type, val.a = field address */
1171 fieldinfo *fi = iptr->val.a;
1172 unresolved_field *uf = iptr->target;
1174 switch (iptr->op1) {
1177 gen_PATCHER_GETFIELD_INT(cd, 0, uf);
1179 gen_GETFIELD_INT(cd, fi->offset, uf);
1184 gen_PATCHER_GETFIELD_FLOAT(cd, 0, uf);
1186 gen_GETFIELD_FLOAT(cd, fi->offset, uf);
1192 gen_PATCHER_GETFIELD_LONG(cd, 0, uf);
1194 gen_GETFIELD_LONG(cd, fi->offset, uf);
1199 gen_PATCHER_GETFIELD_CELL(cd, 0, uf);
1201 gen_GETFIELD_CELL(cd, fi->offset, uf);
1208 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1209 /* op1 = type, val.a = field address */
1212 fieldinfo *fi = iptr->val.a;
1213 unresolved_field *uf = iptr->target;
1215 switch (iptr->op1) {
1218 gen_PATCHER_PUTFIELD_INT(cd, 0, uf);
1220 gen_PUTFIELD_INT(cd, fi->offset, uf);
1225 gen_PATCHER_PUTFIELD_FLOAT(cd, 0, uf);
1227 gen_PUTFIELD_FLOAT(cd, fi->offset, uf);
1233 gen_PATCHER_PUTFIELD_LONG(cd, 0, uf);
1235 gen_PUTFIELD_LONG(cd, fi->offset, uf);
1240 gen_PATCHER_PUTFIELD_CELL(cd, 0, uf);
1242 gen_PUTFIELD_CELL(cd, fi->offset, uf);
1250 /* branch operations **************************************************/
1252 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1257 case ICMD_GOTO: /* ... ==> ... */
1258 /* op1 = target JavaVM pc */
1262 case ICMD_JSR: /* ... ==> ... */
1263 /* op1 = target JavaVM pc */
1267 case ICMD_RET: /* ... ==> ... */
1268 /* op1 = local variable */
1270 gen_RET(cd, index2offset(iptr->op1));
1273 case ICMD_IFNULL: /* ..., value ==> ... */
1274 /* op1 = target JavaVM pc */
1279 case ICMD_IFNONNULL: /* ..., value ==> ... */
1280 /* op1 = target JavaVM pc */
1282 gen_branch(IFNONNULL);
1285 case ICMD_IFEQ: /* ..., value ==> ... */
1286 /* op1 = target JavaVM pc, val.i = constant */
1288 if (iptr->val.i == 0) {
1291 gen_ICONST(cd, iptr->val.i);
1292 gen_branch(IF_ICMPEQ);
1296 case ICMD_IFLT: /* ..., value ==> ... */
1297 /* op1 = target JavaVM pc, val.i = constant */
1299 if (iptr->val.i == 0) {
1302 gen_ICONST(cd, iptr->val.i);
1303 gen_branch(IF_ICMPLT);
1307 case ICMD_IFLE: /* ..., value ==> ... */
1308 /* op1 = target JavaVM pc, val.i = constant */
1310 if (iptr->val.i == 0) {
1313 gen_ICONST(cd, iptr->val.i);
1314 gen_branch(IF_ICMPLE);
1318 case ICMD_IFNE: /* ..., value ==> ... */
1319 /* op1 = target JavaVM pc, val.i = constant */
1321 if (iptr->val.i == 0) {
1324 gen_ICONST(cd, iptr->val.i);
1325 gen_branch(IF_ICMPNE);
1329 case ICMD_IFGT: /* ..., value ==> ... */
1330 /* op1 = target JavaVM pc, val.i = constant */
1332 if (iptr->val.i == 0) {
1335 gen_ICONST(cd, iptr->val.i);
1336 gen_branch(IF_ICMPGT);
1340 case ICMD_IFGE: /* ..., value ==> ... */
1341 /* op1 = target JavaVM pc, val.i = constant */
1343 if (iptr->val.i == 0) {
1346 gen_ICONST(cd, iptr->val.i);
1347 gen_branch(IF_ICMPGE);
1351 case ICMD_IF_LEQ: /* ..., value ==> ... */
1352 /* op1 = target JavaVM pc, val.l = constant */
1354 gen_LCONST(cd, iptr->val.l);
1355 gen_branch(IF_LCMPEQ);
1358 case ICMD_IF_LLT: /* ..., value ==> ... */
1359 /* op1 = target JavaVM pc, val.l = constant */
1361 gen_LCONST(cd, iptr->val.l);
1362 gen_branch(IF_LCMPLT);
1365 case ICMD_IF_LLE: /* ..., value ==> ... */
1366 /* op1 = target JavaVM pc, val.l = constant */
1368 gen_LCONST(cd, iptr->val.l);
1369 gen_branch(IF_LCMPLE);
1372 case ICMD_IF_LNE: /* ..., value ==> ... */
1373 /* op1 = target JavaVM pc, val.l = constant */
1375 gen_LCONST(cd, iptr->val.l);
1376 gen_branch(IF_LCMPNE);
1379 case ICMD_IF_LGT: /* ..., value ==> ... */
1380 /* op1 = target JavaVM pc, val.l = constant */
1382 gen_LCONST(cd, iptr->val.l);
1383 gen_branch(IF_LCMPGT);
1386 case ICMD_IF_LGE: /* ..., value ==> ... */
1387 /* op1 = target JavaVM pc, val.l = constant */
1389 gen_LCONST(cd, iptr->val.l);
1390 gen_branch(IF_LCMPGE);
1393 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1394 /* op1 = target JavaVM pc */
1396 gen_branch(IF_ICMPEQ);
1399 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1400 /* op1 = target JavaVM pc */
1402 gen_branch(IF_LCMPEQ);
1405 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
1406 /* op1 = target JavaVM pc */
1408 gen_branch(IF_ACMPEQ);
1411 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
1412 /* op1 = target JavaVM pc */
1414 gen_branch(IF_ICMPNE);
1417 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1418 /* op1 = target JavaVM pc */
1420 gen_branch(IF_LCMPNE);
1423 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
1424 /* op1 = target JavaVM pc */
1426 gen_branch(IF_ACMPNE);
1429 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
1430 /* op1 = target JavaVM pc */
1432 gen_branch(IF_ICMPLT);
1435 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1436 /* op1 = target JavaVM pc */
1438 gen_branch(IF_LCMPLT);
1441 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
1442 /* op1 = target JavaVM pc */
1444 gen_branch(IF_ICMPGT);
1447 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1448 /* op1 = target JavaVM pc */
1450 gen_branch(IF_LCMPGT);
1453 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
1454 /* op1 = target JavaVM pc */
1456 gen_branch(IF_ICMPLE);
1459 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1460 /* op1 = target JavaVM pc */
1462 gen_branch(IF_LCMPLE);
1465 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
1466 /* op1 = target JavaVM pc */
1468 gen_branch(IF_ICMPGE);
1471 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1472 /* op1 = target JavaVM pc */
1474 gen_branch(IF_LCMPGE);
1478 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1479 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1480 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1482 #if defined(USE_THREADS)
1483 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1484 if (m->flags & ACC_STATIC) {
1485 gen_ACONST(cd, (java_objectheader *) m->class);
1489 gen_MONITOREXIT(cd);
1493 gen_TRACERETURN(cd, m);
1495 gen_IRETURN(cd, index2offset(cd->maxlocals));
1498 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1499 case ICMD_DRETURN: /* ..., retvalue ==> ... */
1501 #if defined(USE_THREADS)
1502 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1503 if (m->flags & ACC_STATIC) {
1504 gen_ACONST(cd, (java_objectheader *) m->class);
1508 gen_MONITOREXIT(cd);
1512 gen_TRACELRETURN(cd, m);
1514 gen_LRETURN(cd, index2offset(cd->maxlocals));
1517 case ICMD_RETURN: /* ... ==> ... */
1519 #if defined(USE_THREADS)
1520 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1521 if (m->flags & ACC_STATIC) {
1522 gen_ACONST(cd, (java_objectheader *) m->class);
1526 gen_MONITOREXIT(cd);
1530 gen_TRACERETURN(cd, m);
1532 gen_RETURN(cd, index2offset(cd->maxlocals));
1536 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1541 tptr = (void **) iptr->target;
1543 s4ptr = iptr->val.a;
1544 l = s4ptr[1]; /* low */
1545 i = s4ptr[2]; /* high */
1549 /* arguments: low, range, datasegment address, table offset in */
1550 /* datasegment, default target */
1551 gen_TABLESWITCH(cd, l, i, NULL, 0, NULL);
1552 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1553 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1555 /* build jump table top down and use address of lowest entry */
1560 dseg_addtarget(cd, (basicblock *) tptr[0]);
1565 /* length of dataseg after last dseg_addtarget is used by load */
1566 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1570 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
1575 tptr = (void **) iptr->target;
1577 s4ptr = iptr->val.a;
1579 /* s4ptr[0] is equal to tptr[0] */
1580 i = s4ptr[1]; /* count */
1582 /* arguments: count, datasegment address, table offset in */
1583 /* datasegment, default target */
1584 gen_LOOKUPSWITCH(cd, i, NULL, 0, NULL);
1585 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1586 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1588 /* build jump table top down and use address of lowest entry */
1594 dseg_addtarget(cd, (basicblock *) tptr[0]);
1595 dseg_addaddress(cd, s4ptr[0]);
1601 /* length of dataseg after last dseg_addtarget is used by load */
1602 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1606 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1607 /* op1 = arg count val.a = builtintable entry */
1610 for (i = 0; i < sizeof(builtin_gen_table)/sizeof(builtin_gen); i++) {
1611 builtin_gen *bg = &builtin_gen_table[i];
1612 if (bg->builtin == bte->fp) {
1614 goto gen_builtin_end;
1621 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1622 /* op1 = arg count, val.a = method pointer */
1628 md = um->methodref->parseddesc.md;
1629 gen_PATCHER_INVOKESTATIC(cd, 0, md->paramslots, um);
1632 md = lm->parseddesc;
1633 gen_INVOKESTATIC(cd, (Inst **)lm->stubroutine, md->paramslots, um);
1637 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1643 md = um->methodref->parseddesc.md;
1644 gen_PATCHER_INVOKESPECIAL(cd, 0, md->paramslots, um);
1647 md = lm->parseddesc;
1648 gen_INVOKESPECIAL(cd, (Inst **)lm->stubroutine, md->paramslots, um);
1652 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1658 md = um->methodref->parseddesc.md;
1659 gen_PATCHER_INVOKEVIRTUAL(cd, 0, md->paramslots, um);
1662 md = lm->parseddesc;
1664 s1 = OFFSET(vftbl_t, table[0]) +
1665 sizeof(methodptr) * lm->vftblindex;
1667 gen_INVOKEVIRTUAL(cd, s1, md->paramslots, um);
1671 case ICMD_INVOKEINTERFACE:/* op1 = arg count, val.a = method pointer */
1677 md = um->methodref->parseddesc.md;
1678 gen_PATCHER_INVOKEINTERFACE(cd, 0, 0, md->paramslots, um);
1681 md = lm->parseddesc;
1683 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1684 sizeof(methodptr*) * lm->class->index;
1686 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1688 gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, um);
1693 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1694 /* op1: 0 == array, 1 == class */
1695 /* val.a: (classinfo *) superclass */
1697 if (iptr->op1 == 1) {
1698 if (iptr->val.a == NULL)
1699 gen_PATCHER_CHECKCAST(cd, NULL, iptr->target);
1701 gen_CHECKCAST(cd, iptr->val.a, NULL);
1703 if (iptr->val.a == NULL)
1704 gen_PATCHER_ARRAYCHECKCAST(cd, NULL, iptr->target);
1706 gen_ARRAYCHECKCAST(cd, iptr->val.a, NULL);
1710 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1711 /* op1: 0 == array, 1 == class */
1712 /* val.a: (classinfo *) superclass */
1714 if (iptr->val.a == NULL)
1715 gen_PATCHER_INSTANCEOF(cd, NULL, iptr->target);
1717 gen_INSTANCEOF(cd, iptr->val.a, iptr->target);
1720 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
1721 /* op1 = dimension, val.a = class */
1723 if (iptr->val.a == NULL) {
1724 gen_PATCHER_MULTIANEWARRAY(cd, NULL, iptr->op1, iptr->target);
1726 gen_MULTIANEWARRAY(cd, iptr->val.a, iptr->op1, NULL);
1731 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
1735 } /* for instruction */
1739 } /* if (bptr->flags >= BBREACHED) */
1740 } /* for basic block */
1742 dseg_createlinenumbertable(cd);
1744 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1747 vm_block_insert(m->mcode + m->mcodelength);
1750 /* branch resolving (walk through all basic blocks) */
1752 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
1755 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
1756 gen_resolveanybranch(((u1*) m->entrypoint) + brefs->branchpos,
1757 ((u1 *)m->entrypoint) + bptr->mpc);
1761 /* everything's ok */
1767 /* a stub consists of
1779 codeptr points either to TRANSLATE or to the translated threaded code
1781 all methods are called indirectly through methodptr
1784 #define COMPILERSTUB_SIZE 4
1786 u1 *intrp_createcompilerstub(methodinfo *m)
1792 s = CNEW(Inst, COMPILERSTUB_SIZE);
1794 /* mark start of dump memory area */
1796 dumpsize = dump_size();
1798 cd = DNEW(codegendata);
1799 cd->mcodeptr = (u1 *) s;
1800 cd->lastinstwithoutdispatch = ~0;
1801 cd->superstarts = NULL;
1803 genarg_ainst(cd, s + 2);
1805 if (m->flags & ACC_NATIVE) {
1806 genarg_i(cd, m->parseddesc->paramslots);
1808 genarg_i(cd, m->maxlocals);
1812 gen_TRANSLATE(cd, m);
1816 vm_block_insert(cd->mcodeptr);
1819 #if defined(ENABLE_STATISTICS)
1821 count_cstub_len += COMPILERSTUB_SIZE;
1824 /* release dump area */
1826 dump_release(dumpsize);
1844 #if defined(WITH_FFI)
1845 static ffi_cif *createnativecif(methodinfo *m, methoddesc *nmd)
1847 methoddesc *md = m->parseddesc;
1848 ffi_cif *pcif = NEW(ffi_cif);
1849 ffi_type **types = MNEW(ffi_type *, nmd->paramcount);
1850 ffi_type **ptypes = types;
1853 /* pass env pointer */
1855 *ptypes++ = &ffi_type_pointer;
1857 /* for static methods, pass class pointer */
1859 if (m->flags & ACC_STATIC)
1860 *ptypes++ = &ffi_type_pointer;
1862 /* pass parameter to native function */
1864 for (i = 0; i < md->paramcount; i++)
1865 *ptypes++ = cacaotype2ffitype(md->paramtypes[i].type);
1867 assert(ptypes - types == nmd->paramcount);
1869 if (ffi_prep_cif(pcif, FFI_DEFAULT_ABI, nmd->paramcount, cacaotype2ffitype(md->returntype.type), types) != FFI_OK)
1877 u1 *intrp_createnativestub(functionptr f, methodinfo *m, codegendata *cd,
1878 registerdata *rd, methoddesc *nmd)
1880 #if defined(WITH_FFI)
1886 /* create method header */
1888 (void) dseg_addaddress(cd, m); /* MethodPointer */
1889 (void) dseg_adds4(cd, nmd->paramslots * SIZEOF_VOID_P); /* FrameSize */
1890 (void) dseg_adds4(cd, 0); /* IsSync */
1891 (void) dseg_adds4(cd, 0); /* IsLeaf */
1892 (void) dseg_adds4(cd, 0); /* IntSave */
1893 (void) dseg_adds4(cd, 0); /* FltSave */
1894 dseg_addlinenumbertablesize(cd);
1895 (void) dseg_adds4(cd, 0); /* ExTableSize */
1897 #if defined(WITH_FFI)
1898 /* prepare ffi cif structure */
1900 cif = createnativecif(m, nmd);
1908 gen_TRACECALL(cd, m);
1911 gen_PATCHER_NATIVECALL(cd, m, f, (u1 *)cif);
1914 gen_TRACENATIVECALL(cd, m, f, (u1 *)cif);
1916 gen_NATIVECALL(cd, m, f, (u1 *)cif);
1921 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1924 vm_block_insert(m->mcode + m->mcodelength);
1927 return m->entrypoint;
1931 #if defined(WITH_FFI)
1932 ffi_type *cacaotype2ffitype(s4 cacaotype)
1934 switch (cacaotype) {
1936 return &ffi_type_slong;
1938 return &ffi_type_sint64;
1940 return &ffi_type_float;
1942 return &ffi_type_double;
1944 return &ffi_type_pointer;
1946 return &ffi_type_void;
1954 /* call jni function */
1955 Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1 *addrcif)
1957 #if defined(WITH_FFCALL)
1971 switch (md->returntype.type) {
1973 endsp = sp - 1 + md->paramslots;
1974 av_start_long(alist, f, endsp);
1977 endsp = sp - 2 + md->paramslots;
1978 av_start_longlong(alist, f, endsp);
1981 endsp = sp - 1 + md->paramslots;
1982 #if WORDS_BIGENDIAN == 1 && SIZEOF_VOID_P == 8 && 0
1983 av_start_float(alist, f, ((float *) endsp) + 1);
1985 av_start_float(alist, f, endsp);
1989 endsp = sp - 2 + md->paramslots;
1990 av_start_double(alist, f, endsp);
1993 endsp = sp - 1 + md->paramslots;
1994 av_start_ptr(alist, f, void *, endsp);
1997 endsp = sp + md->paramslots;
1998 av_start_void(alist, f);
2004 av_ptr(alist, JNIEnv *, &env);
2006 if (m->flags & ACC_STATIC)
2007 av_ptr(alist, classinfo *, m->class);
2009 for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
2010 switch (md->paramtypes[i].type) {
2017 av_longlong(alist, *(s8 *)p);
2021 #if WORDS_BIGENDIAN == 1 && SIZEOF_VOID_P == 8 && 0
2022 av_float(alist, *(((float *) p) + 1));
2024 av_float(alist, *((float *) p));
2029 av_double(alist, *(double *) p);
2033 av_ptr(alist, void *, *(void **) p);
2042 /* create stackframe info structure */
2044 codegen_start_native_call((u1 *) (&s + sizeof(s)), m->entrypoint,
2045 (u1 *) fp, (u1 *) ra);
2049 codegen_finish_native_call((u1 *) (&s + sizeof(s)));
2054 #elif defined(WITH_FFI)
2055 methoddesc *md = m->parseddesc;
2057 void *values[md->paramcount + 2];
2058 void **pvalues = values;
2069 pcif = (ffi_cif *) addrcif;
2071 /* pass env pointer */
2073 penv = (JNIEnv *) &env;
2076 /* for static methods, pass class pointer */
2078 if (m->flags & ACC_STATIC) {
2079 *pvalues++ = &m->class;
2082 /* pass parameter to native function */
2084 for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
2085 if (IS_2_WORD_TYPE(md->paramtypes[i].type))
2090 #if WORDS_BIGENDIAN == 1 && SIZEOF_VOID_P == 8 && 0
2091 if (md->paramtypes[i].type == TYPE_FLT)
2092 *pvalues++ = (void *)(((float *)p)+1);
2098 /* calculate position of return value */
2100 if (md->returntype.type == TYPE_VOID)
2101 endsp = sp + md->paramslots;
2103 endsp = sp - (IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1) + md->paramslots;
2107 /* create stackframe info structure */
2109 codegen_start_native_call((u1 *) (&s + sizeof(s)), m->entrypoint,
2110 (u1 *) fp, (u1 *) ra);
2112 #if WORDS_BIGENDIAN == 1 && SIZEOF_VOID_P == 8 && 0
2113 if (md->returntype.type == TYPE_FLT)
2114 ffi_call(pcif, FFI_FN(f), ((float *) endsp) + 1, values);
2117 ffi_call(pcif, FFI_FN(f), endsp, values);
2119 codegen_finish_native_call((u1 *) (&s + sizeof(s)));
2128 u1 *createcalljavafunction(methodinfo *m)
2134 t_inlining_globals *id;
2138 /* mark dump memory */
2140 dumpsize = dump_size();
2142 tmpm = DNEW(methodinfo);
2143 cd = DNEW(codegendata);
2144 rd = DNEW(registerdata);
2145 id = DNEW(t_inlining_globals);
2147 /* setup code generation stuff */
2149 MSET(tmpm, 0, u1, sizeof(methodinfo));
2151 inlining_setup(tmpm, id);
2152 codegen_setup(tmpm, cd, id);
2156 /* create method header */
2158 (void) dseg_addaddress(cd, NULL); /* MethodPointer */
2159 (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P); /* FrameSize */
2160 (void) dseg_adds4(cd, 0); /* IsSync */
2161 (void) dseg_adds4(cd, 0); /* IsLeaf */
2162 (void) dseg_adds4(cd, 0); /* IntSave */
2163 (void) dseg_adds4(cd, 0); /* FltSave */
2164 dseg_addlinenumbertablesize(cd);
2165 (void) dseg_adds4(cd, 0); /* ExTableSize */
2171 gen_INVOKESTATIC(cd, (Inst **)m->stubroutine, md->paramslots, 0);
2176 codegen_finish(tmpm, cd, (s4) (cd->mcodeptr - cd->mcodebase));
2179 vm_block_insert(tmpm->mcode + tmpm->mcodelength);
2181 entrypoint = tmpm->entrypoint;
2183 /* release memory */
2185 dump_release(dumpsize);
2192 * These are local overrides for various environment variables in Emacs.
2193 * Please do not remove this and leave it at the end of the file, where
2194 * Emacs will automagically detect them.
2195 * ---------------------------------------------------------------------
2198 * indent-tabs-mode: t