1 /* src/vm/jit/intrp/codegen.c - code generator for Interpreter
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
30 Changes: Edwin Steiner
32 $Id: codegen.c 5632 2006-10-02 13:43:15Z edwin $
44 #elif defined(WITH_FFCALL)
47 # error neither WITH_FFI nor WITH_FFCALL defined
54 #include "vm/jit/intrp/codegen.h"
55 #include "vm/jit/intrp/intrp.h"
57 #include "native/native.h"
58 #include "vm/builtin.h"
60 #include "vm/exceptions.h"
61 #include "vm/global.h"
62 #include "vm/options.h"
63 #include "vm/stringlocal.h"
65 #include "vm/jit/asmpart.h"
66 #include "vm/jit/codegen-common.h"
67 #include "vm/jit/dseg.h"
68 #include "vm/jit/jit.h"
69 #include "vm/jit/parse.h"
70 #include "vm/jit/patcher.h"
73 #define gen_branch(_inst) { \
75 codegen_addreference(cd, (basicblock *) (iptr->target)); \
78 #define index2offset(_i) (-(_i) * SIZEOF_VOID_P)
80 /* functions used by cacao-gen.i */
82 void genarg_v(codegendata *cd1, Cell v)
84 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
85 *((Cell *) *mcodepp) = v;
89 void genarg_i(codegendata *cd1, s4 i)
91 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
92 *((Cell *) *mcodepp) = i;
96 void genarg_b(codegendata *cd1, s4 i)
101 void genarg_f(codegendata *cd1, float f)
109 void genarg_l(codegendata *cd1, s8 l)
111 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
112 vm_l2twoCell(l, ((Cell *) *mcodepp)[1], ((Cell *) *mcodepp)[0]);
116 void genarg_aRef(codegendata *cd1, java_objectheader *a)
118 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
119 *((java_objectheader **) *mcodepp) = a;
123 void genarg_aArray(codegendata *cd1, java_arrayheader *a)
125 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
126 *((java_arrayheader **) *mcodepp) = a;
130 void genarg_aaTarget(codegendata *cd1, Inst **a)
132 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
133 *((Inst ***) *mcodepp) = a;
137 void genarg_aClass(codegendata *cd1, classinfo *a)
139 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
140 *((classinfo **) *mcodepp) = a;
144 void genarg_acr(codegendata *cd1, constant_classref *a)
146 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
147 *((constant_classref **) *mcodepp) = a;
151 void genarg_addr(codegendata *cd1, u1 *a)
153 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
154 *((u1 **) *mcodepp) = a;
158 void genarg_af(codegendata *cd1, functionptr a)
160 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
161 *((functionptr *) *mcodepp) = a;
165 void genarg_afi(codegendata *cd1, fieldinfo *a)
167 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
168 *((fieldinfo **) *mcodepp) = a;
172 void genarg_am(codegendata *cd1, methodinfo *a)
174 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
175 *((methodinfo **) *mcodepp) = a;
179 void genarg_acell(codegendata *cd1, Cell *a)
181 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
182 *((Cell **) *mcodepp) = a;
186 void genarg_ainst(codegendata *cd1, Inst *a)
188 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
189 *((Inst **) *mcodepp) = a;
193 void genarg_auf(codegendata *cd1, unresolved_field *a)
195 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
196 *((unresolved_field **) *mcodepp) = a;
200 void genarg_aum(codegendata *cd1, unresolved_method *a)
202 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
203 *((unresolved_method **) *mcodepp) = a;
207 void genarg_avftbl(codegendata *cd1, vftbl_t *a)
209 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
210 *((vftbl_t **) *mcodepp) = a;
215 /* include the interpreter generation functions *******************************/
217 #include "vm/jit/intrp/java-gen.i"
220 typedef void (*genfunctionptr) (codegendata *);
222 typedef struct builtin_gen builtin_gen;
229 struct builtin_gen builtin_gen_table[] = {
230 {BUILTIN_new, gen_NEW, },
231 {BUILTIN_newarray, gen_NEWARRAY, },
232 {BUILTIN_newarray_boolean, gen_NEWARRAY_BOOLEAN,},
233 {BUILTIN_newarray_byte, gen_NEWARRAY_BYTE, },
234 {BUILTIN_newarray_char, gen_NEWARRAY_CHAR, },
235 {BUILTIN_newarray_short, gen_NEWARRAY_SHORT, },
236 {BUILTIN_newarray_int, gen_NEWARRAY_INT, },
237 {BUILTIN_newarray_long, gen_NEWARRAY_LONG, },
238 {BUILTIN_newarray_float, gen_NEWARRAY_FLOAT, },
239 {BUILTIN_newarray_double, gen_NEWARRAY_DOUBLE, },
240 {BUILTIN_arrayinstanceof, gen_ARRAYINSTANCEOF, },
242 #if defined(ENABLE_THREADS)
243 {BUILTIN_monitorenter, gen_MONITORENTER, },
244 {BUILTIN_monitorexit, gen_MONITOREXIT, },
247 #if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L)
248 {BUILTIN_f2l, gen_F2L, },
251 #if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L)
252 {BUILTIN_d2l, gen_D2L, },
255 #if !(SUPPORT_FLOAT && SUPPORT_F2I)
256 {BUILTIN_f2i, gen_F2I, },
259 #if !(SUPPORT_DOUBLE && SUPPORT_D2I)
260 {BUILTIN_d2i, gen_D2I, },
263 #if !SUPPORT_DIVISION
264 {BUILTIN_idiv, gen_IDIV, },
265 {BUILTIN_irem, gen_IREM, },
268 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
269 {BUILTIN_ldiv, gen_LDIV, },
270 {BUILTIN_lrem, gen_LREM, },
273 {BUILTIN_frem, gen_FREM, },
274 {BUILTIN_drem, gen_DREM, },
278 /* codegen *********************************************************************
280 Generates machine code.
282 *******************************************************************************/
284 bool intrp_codegen(jitdata *jd)
289 s4 i, len, s1, s2, d;
295 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
296 unresolved_method *um;
297 builtintable_entry *bte;
300 /* get required compiler data */
306 /* prevent compiler warnings */
313 /* create method header */
315 (void) dseg_addaddress(cd, jd->code); /* CodeinfoPointer */
316 (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P); /* FrameSize */
318 #if defined(ENABLE_THREADS)
319 if (checksync && (m->flags & ACC_SYNCHRONIZED))
320 (void) dseg_adds4(cd, 1); /* IsSync */
323 (void) dseg_adds4(cd, 0); /* IsSync */
325 (void) dseg_adds4(cd, 0); /* IsLeaf */
326 (void) dseg_adds4(cd, 0); /* IntSave */
327 (void) dseg_adds4(cd, 0); /* FltSave */
329 dseg_addlinenumbertablesize(cd);
331 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
333 /* create exception table */
335 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
336 dseg_addtarget(cd, ex->start);
337 dseg_addtarget(cd, ex->end);
338 dseg_addtarget(cd, ex->handler);
339 (void) dseg_addaddress(cd, ex->catchtype.any);
343 /* initialize mcode variables */
345 cd->mcodeptr = cd->mcodebase;
346 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
351 #if defined(ENABLE_THREADS)
352 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
353 if (m->flags & ACC_STATIC)
354 gen_ACONST(cd, (java_objectheader *) m->class);
358 gen_MONITORENTER(cd);
363 gen_TRACECALL(cd, m);
367 /* walk through all basic blocks */
369 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
371 bptr->mpc = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
373 if (bptr->flags >= BBREACHED) {
375 /* walk through all instructions */
382 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
383 if (iptr->line != currentline) {
384 dseg_addlinenumber(cd, iptr->line);
385 currentline = iptr->line;
388 MCODECHECK(64); /* an instruction usually needs < 64 words */
392 case ICMD_INLINE_START:
393 case ICMD_INLINE_END:
396 case ICMD_NOP: /* ... ==> ... */
399 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
404 /* constant operations ************************************************/
406 case ICMD_ICONST: /* ... ==> ..., constant */
407 /* op1 = 0, val.i = constant */
409 gen_ICONST(cd, iptr->val.i);
412 case ICMD_LCONST: /* ... ==> ..., constant */
413 /* op1 = 0, val.l = constant */
415 gen_LCONST(cd, iptr->val.l);
418 case ICMD_FCONST: /* ... ==> ..., constant */
419 /* op1 = 0, val.f = constant */
423 vm_f2Cell(iptr->val.f, fi);
428 case ICMD_DCONST: /* ... ==> ..., constant */
429 /* op1 = 0, val.d = constant */
431 gen_LCONST(cd, *(s8 *)&(iptr->val.d));
434 case ICMD_ACONST: /* ... ==> ..., constant */
435 /* op1 = 0, val.a = constant */
437 if (INSTRUCTION_IS_UNRESOLVED(iptr))
438 gen_PATCHER_ACONST(cd, NULL,
439 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr));
441 gen_ACONST(cd, iptr->val.a);
445 /* load/store operations **********************************************/
447 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
448 /* op1 = local variable */
450 gen_ILOAD(cd, index2offset(iptr->op1));
453 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
454 /* op1 = local variable */
456 gen_LLOAD(cd, index2offset(iptr->op1));
459 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
460 /* op1 = local variable */
462 gen_ALOAD(cd, index2offset(iptr->op1));
465 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
466 /* op1 = local variable */
468 gen_ILOAD(cd, index2offset(iptr->op1));
471 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
472 /* op1 = local variable */
474 gen_LLOAD(cd, index2offset(iptr->op1));
478 case ICMD_ISTORE: /* ..., value ==> ... */
479 /* op1 = local variable */
481 gen_ISTORE(cd, index2offset(iptr->op1));
484 case ICMD_LSTORE: /* ..., value ==> ... */
485 /* op1 = local variable */
487 gen_LSTORE(cd, index2offset(iptr->op1));
490 case ICMD_ASTORE: /* ..., value ==> ... */
491 /* op1 = local variable */
493 gen_ASTORE(cd, index2offset(iptr->op1));
497 case ICMD_FSTORE: /* ..., value ==> ... */
498 /* op1 = local variable */
500 gen_ISTORE(cd, index2offset(iptr->op1));
503 case ICMD_DSTORE: /* ..., value ==> ... */
504 /* op1 = local variable */
506 gen_LSTORE(cd, index2offset(iptr->op1));
510 /* pop/dup/swap operations ********************************************/
512 /* attention: double and longs are only one entry in CACAO ICMDs */
514 /* stack.c changes stack manipulation operations to treat
515 longs/doubles as occupying a single slot. Here we are
516 undoing that (and only those things that stack.c did). */
518 case ICMD_POP: /* ..., value ==> ... */
520 if (IS_2_WORD_TYPE(src->type))
526 case ICMD_POP2: /* ..., value, value ==> ... */
531 case ICMD_DUP: /* ..., a ==> ..., a, a */
533 if (IS_2_WORD_TYPE(src->type))
539 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
541 if (IS_2_WORD_TYPE(src->type)) {
542 if (IS_2_WORD_TYPE(src->prev->type)) {
548 if (IS_2_WORD_TYPE(src->prev->type)) {
556 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
558 if (IS_2_WORD_TYPE(src->type)) {
564 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
569 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
571 if (IS_2_WORD_TYPE(src->prev->prev->type))
577 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
582 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
588 /* integer operations *************************************************/
590 case ICMD_INEG: /* ..., value ==> ..., - value */
595 case ICMD_LNEG: /* ..., value ==> ..., - value */
600 case ICMD_I2L: /* ..., value ==> ..., value */
605 case ICMD_L2I: /* ..., value ==> ..., value */
610 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
615 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
620 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
626 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
631 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
632 /* val.i = constant */
634 gen_ICONST(cd, iptr->val.i);
638 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
643 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
644 /* val.l = constant */
646 gen_LCONST(cd, iptr->val.l);
650 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
655 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
656 /* val.i = constant */
658 gen_ICONST(cd, iptr->val.i);
662 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
667 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
668 /* val.l = constant */
670 gen_LCONST(cd, iptr->val.l);
674 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
679 case ICMD_IMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
681 gen_ICONST(cd, iptr->val.i);
685 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
690 case ICMD_LMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
692 gen_LCONST(cd, iptr->val.l);
696 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
701 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
706 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
711 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
716 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
717 /* val.i = constant */
719 gen_IDIVPOW2(cd, iptr->val.i);
722 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
723 /* val.i = constant */
725 gen_IREMPOW2(cd, iptr->val.i);
728 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
729 /* val.i = constant */
731 gen_LDIVPOW2(cd, iptr->val.i);
734 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
735 /* val.l = constant */
737 gen_LREMPOW2(cd, iptr->val.i);
740 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
745 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
746 /* val.i = constant */
748 gen_ICONST(cd, iptr->val.i);
752 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
757 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
758 /* val.i = constant */
760 gen_ICONST(cd, iptr->val.i);
764 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
769 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
770 /* val.i = constant */
772 gen_ICONST(cd, iptr->val.i);
776 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
781 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
782 /* val.i = constant */
784 gen_ICONST(cd, iptr->val.i);
788 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
793 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
794 /* val.i = constant */
796 gen_ICONST(cd, iptr->val.i);
800 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
805 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
806 /* val.i = constant */
808 gen_ICONST(cd, iptr->val.i);
812 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
817 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
818 /* val.i = constant */
820 gen_ICONST(cd, iptr->val.i);
824 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
829 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
830 /* val.l = constant */
832 gen_LCONST(cd, iptr->val.l);
836 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
841 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
842 /* val.i = constant */
844 gen_ICONST(cd, iptr->val.i);
848 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
853 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
854 /* val.l = constant */
856 gen_LCONST(cd, iptr->val.l);
860 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
865 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
866 /* val.i = constant */
868 gen_ICONST(cd, iptr->val.i);
872 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
877 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
878 /* val.l = constant */
880 gen_LCONST(cd, iptr->val.l);
885 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
891 case ICMD_IINC: /* ..., value ==> ..., value + constant */
892 /* op1 = variable, val.i = constant */
894 gen_IINC(cd, index2offset(iptr->op1), iptr->val.i);
898 /* floating operations ************************************************/
900 case ICMD_FNEG: /* ..., value ==> ..., - value */
905 case ICMD_DNEG: /* ..., value ==> ..., - value */
910 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
915 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
920 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
925 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
930 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
935 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
940 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
945 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
950 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
955 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
960 case ICMD_I2F: /* ..., value ==> ..., (float) value */
965 case ICMD_L2F: /* ..., value ==> ..., (float) value */
970 case ICMD_I2D: /* ..., value ==> ..., (double) value */
975 case ICMD_L2D: /* ..., value ==> ..., (double) value */
980 case ICMD_F2I: /* ..., value ==> ..., (int) value */
985 case ICMD_D2I: /* ..., value ==> ..., (int) value */
990 case ICMD_F2L: /* ..., value ==> ..., (long) value */
995 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1000 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1005 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1010 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1015 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1020 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1025 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1031 /* memory operations **************************************************/
1033 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1035 gen_ARRAYLENGTH(cd);
1038 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1043 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1048 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1053 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1058 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1063 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1064 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1069 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1075 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1080 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1081 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1086 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1091 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1096 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1097 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1102 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1108 case ICMD_GETSTATIC: /* ... ==> ..., value */
1109 /* op1 = type, val.a = field address */
1112 fieldinfo *fi = NULL;
1113 unresolved_field *uf = NULL;
1115 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1116 uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
1118 fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1120 switch (iptr->op1) {
1123 gen_PATCHER_GETSTATIC_INT(cd, 0, uf);
1124 } else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1125 gen_PATCHER_GETSTATIC_CLINIT_INT(cd, 0, fi);
1127 gen_GETSTATIC_INT(cd, (u1 *)&(fi->value.i), fi);
1132 gen_PATCHER_GETSTATIC_FLOAT(cd, 0, uf);
1133 } else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1134 gen_PATCHER_GETSTATIC_CLINIT_FLOAT(cd, 0, fi);
1136 gen_GETSTATIC_FLOAT(cd, (u1 *)&(fi->value.i), fi);
1142 gen_PATCHER_GETSTATIC_LONG(cd, 0, uf);
1143 } else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1144 gen_PATCHER_GETSTATIC_CLINIT_LONG(cd, 0, fi);
1146 gen_GETSTATIC_LONG(cd, (u1 *)&(fi->value.l), fi);
1151 gen_PATCHER_GETSTATIC_CELL(cd, 0, uf);
1152 } else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1153 gen_PATCHER_GETSTATIC_CLINIT_CELL(cd, 0, fi);
1155 gen_GETSTATIC_CELL(cd, (u1 *)&(fi->value.a), fi);
1162 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1163 /* op1 = type, val.a = field address */
1166 fieldinfo *fi = NULL;
1167 unresolved_field *uf = NULL;
1169 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1170 uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
1172 fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1174 switch (iptr->op1) {
1177 gen_PATCHER_PUTSTATIC_INT(cd, 0, uf);
1178 } else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1179 gen_PATCHER_PUTSTATIC_CLINIT_INT(cd, 0, fi);
1181 gen_PUTSTATIC_INT(cd, (u1 *)&(fi->value.i), fi);
1186 gen_PATCHER_PUTSTATIC_FLOAT(cd, 0, uf);
1187 } else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1188 gen_PATCHER_PUTSTATIC_CLINIT_FLOAT(cd, 0, fi);
1190 gen_PUTSTATIC_FLOAT(cd, (u1 *)&(fi->value.i), fi);
1196 gen_PATCHER_PUTSTATIC_LONG(cd, 0, uf);
1197 } else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1198 gen_PATCHER_PUTSTATIC_CLINIT_LONG(cd, 0, fi);
1200 gen_PUTSTATIC_LONG(cd, (u1 *)&(fi->value.l), fi);
1205 gen_PATCHER_PUTSTATIC_CELL(cd, 0, uf);
1206 } else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1207 gen_PATCHER_PUTSTATIC_CLINIT_CELL(cd, 0, fi);
1209 gen_PUTSTATIC_CELL(cd, (u1 *)&(fi->value.a), fi);
1217 case ICMD_GETFIELD: /* ... ==> ..., value */
1218 /* op1 = type, val.a = field address */
1221 fieldinfo *fi = NULL;
1222 unresolved_field *uf = NULL;
1224 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1225 uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
1227 fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1229 switch (iptr->op1) {
1232 gen_PATCHER_GETFIELD_INT(cd, 0, uf);
1234 gen_GETFIELD_INT(cd, fi->offset, fi);
1239 gen_PATCHER_GETFIELD_FLOAT(cd, 0, uf);
1241 gen_GETFIELD_FLOAT(cd, fi->offset, fi);
1247 gen_PATCHER_GETFIELD_LONG(cd, 0, uf);
1249 gen_GETFIELD_LONG(cd, fi->offset, fi);
1254 gen_PATCHER_GETFIELD_CELL(cd, 0, uf);
1256 gen_GETFIELD_CELL(cd, fi->offset, fi);
1263 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1264 /* op1 = type, val.a = field address */
1267 fieldinfo *fi = NULL;
1268 unresolved_field *uf = NULL;
1270 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1271 uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
1273 fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1275 switch (iptr->op1) {
1278 gen_PATCHER_PUTFIELD_INT(cd, 0, uf);
1280 gen_PUTFIELD_INT(cd, fi->offset, fi);
1285 gen_PATCHER_PUTFIELD_FLOAT(cd, 0, uf);
1287 gen_PUTFIELD_FLOAT(cd, fi->offset, fi);
1293 gen_PATCHER_PUTFIELD_LONG(cd, 0, uf);
1295 gen_PUTFIELD_LONG(cd, fi->offset, fi);
1300 gen_PATCHER_PUTFIELD_CELL(cd, 0, uf);
1302 gen_PUTFIELD_CELL(cd, fi->offset, fi);
1310 /* branch operations **************************************************/
1312 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1317 case ICMD_GOTO: /* ... ==> ... */
1318 case ICMD_RET: /* ... ==> ... */
1319 /* op1 = target JavaVM pc */
1323 case ICMD_JSR: /* ... ==> ... */
1324 /* op1 = target JavaVM pc */
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(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(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(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(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(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(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(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(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(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(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(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(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(ENABLE_THREADS)
1538 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1539 if (m->flags & ACC_STATIC) {
1540 gen_ACONST(cd, (java_objectheader *) m->class);
1544 gen_MONITOREXIT(cd);
1547 if (opt_verbosecall)
1548 gen_TRACERETURN(cd, m);
1550 gen_IRETURN(cd, index2offset(cd->maxlocals));
1553 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1554 case ICMD_DRETURN: /* ..., retvalue ==> ... */
1556 #if defined(ENABLE_THREADS)
1557 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1558 if (m->flags & ACC_STATIC) {
1559 gen_ACONST(cd, (java_objectheader *) m->class);
1563 gen_MONITOREXIT(cd);
1566 if (opt_verbosecall)
1567 gen_TRACELRETURN(cd, m);
1569 gen_LRETURN(cd, index2offset(cd->maxlocals));
1572 case ICMD_RETURN: /* ... ==> ... */
1574 #if defined(ENABLE_THREADS)
1575 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1576 if (m->flags & ACC_STATIC) {
1577 gen_ACONST(cd, (java_objectheader *) m->class);
1581 gen_MONITOREXIT(cd);
1584 if (opt_verbosecall)
1585 gen_TRACERETURN(cd, m);
1587 gen_RETURN(cd, index2offset(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
1605 offset in datasegment, default target */
1607 gen_TABLESWITCH(cd, l, i, NULL, 0, NULL);
1609 /* actually -3 cells offset */
1611 cd->mcodeptr = (u1 *) cd->mcodeptr - 2 * sizeof(Inst);
1613 cd->mcodeptr = (u1 *) cd->mcodeptr + 2 * sizeof(Inst);
1615 codegen_addreference(cd, (basicblock *) tptr[0]);
1617 /* build jump table top down and use address of lowest entry */
1622 dseg_addtarget(cd, (basicblock *) tptr[0]);
1627 /* length of dataseg after last dseg_addtarget is used by load */
1628 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1632 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
1637 tptr = (void **) iptr->target;
1639 s4ptr = iptr->val.a;
1641 /* s4ptr[0] is equal to tptr[0] */
1642 i = s4ptr[1]; /* count */
1644 /* arguments: count, datasegment address, table offset in */
1645 /* datasegment, default target */
1646 gen_LOOKUPSWITCH(cd, i, NULL, 0, NULL);
1648 /* actually -3 cells offset */
1650 cd->mcodeptr = (u1 *) cd->mcodeptr - 2 * sizeof(Inst);
1652 cd->mcodeptr = (u1 *) cd->mcodeptr + 2 * sizeof(Inst);
1654 codegen_addreference(cd, (basicblock *) tptr[0]);
1656 /* build jump table top down and use address of lowest entry */
1662 dseg_addtarget(cd, (basicblock *) tptr[0]);
1663 dseg_addaddress(cd, s4ptr[0]);
1669 /* length of dataseg after last dseg_addtarget is used by load */
1670 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1674 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1675 /* op1 = arg count val.a = builtintable entry */
1678 for (i = 0; i < sizeof(builtin_gen_table)/sizeof(builtin_gen); i++) {
1679 builtin_gen *bg = &builtin_gen_table[i];
1680 if (bg->builtin == bte->fp) {
1682 goto gen_builtin_end;
1689 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1690 /* op1 = arg count, val.a = method pointer */
1692 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1693 um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
1694 md = um->methodref->parseddesc.md;
1695 gen_PATCHER_INVOKESTATIC(cd, 0, md->paramslots, um);
1698 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
1699 md = lm->parseddesc;
1700 gen_INVOKESTATIC(cd, (Inst **)lm->stubroutine, md->paramslots, lm);
1704 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1706 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1707 um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
1708 md = um->methodref->parseddesc.md;
1709 gen_PATCHER_INVOKESPECIAL(cd, 0, md->paramslots, um);
1712 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
1713 md = lm->parseddesc;
1714 gen_INVOKESPECIAL(cd, (Inst **)lm->stubroutine, md->paramslots, lm);
1718 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1720 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1721 um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
1722 md = um->methodref->parseddesc.md;
1723 gen_PATCHER_INVOKEVIRTUAL(cd, 0, md->paramslots, um);
1726 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
1727 md = lm->parseddesc;
1729 s1 = OFFSET(vftbl_t, table[0]) +
1730 sizeof(methodptr) * lm->vftblindex;
1732 gen_INVOKEVIRTUAL(cd, s1, md->paramslots, lm);
1736 case ICMD_INVOKEINTERFACE:/* op1 = arg count, val.a = method pointer */
1738 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1739 um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
1740 md = um->methodref->parseddesc.md;
1741 gen_PATCHER_INVOKEINTERFACE(cd, 0, 0, md->paramslots, um);
1744 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
1745 md = lm->parseddesc;
1747 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1748 sizeof(methodptr*) * lm->class->index;
1750 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1752 gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, lm);
1757 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1758 /* op1: 0 == array, 1 == class */
1759 /* val.a: (classinfo *) superclass */
1761 if (iptr->op1 == 1) {
1762 if (iptr->val.a == NULL)
1763 gen_PATCHER_CHECKCAST(cd, NULL, iptr->target);
1765 gen_CHECKCAST(cd, iptr->val.a, NULL);
1767 if (iptr->val.a == NULL)
1768 gen_PATCHER_ARRAYCHECKCAST(cd, NULL, iptr->target);
1770 gen_ARRAYCHECKCAST(cd, iptr->val.a, NULL);
1774 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1775 /* op1: 0 == array, 1 == class */
1776 /* val.a: (classinfo *) superclass */
1778 if (iptr->val.a == NULL)
1779 gen_PATCHER_INSTANCEOF(cd, NULL, iptr->target);
1781 gen_INSTANCEOF(cd, iptr->val.a, iptr->target);
1784 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
1785 /* op1 = dimension, val.a = class */
1787 if (iptr->val.a == NULL) {
1788 gen_PATCHER_MULTIANEWARRAY(cd, NULL, iptr->op1, iptr->target);
1790 gen_MULTIANEWARRAY(cd, iptr->val.a, iptr->op1, NULL);
1795 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
1799 } /* for instruction */
1803 } /* if (bptr->flags >= BBREACHED) */
1804 } /* for basic block */
1806 dseg_createlinenumbertable(cd);
1811 vm_block_insert(jd->code->mcode + jd->code->mcodelength);
1814 /* branch resolving (walk through all basic blocks) */
1816 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
1819 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
1820 gen_resolveanybranch(((u1*) jd->code->entrypoint) + brefs->branchpos,
1821 ((u1 *)jd->code->entrypoint) + bptr->mpc);
1825 /* everything's ok */
1831 /* createcompilerstub **********************************************************
1833 Creates a stub routine which calls the compiler.
1839 +-------------+ <-- stub
1849 codeptr points either to TRANSLATE or to the translated threaded code
1851 all methods are called indirectly through methodptr
1853 *******************************************************************************/
1855 #define COMPILERSTUB_DATASIZE 1
1856 #define COMPILERSTUB_CODESIZE 4
1858 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
1861 u1 *intrp_createcompilerstub(methodinfo *m)
1869 s = CNEW(Inst, COMPILERSTUB_SIZE);
1871 /* set data pointer and code pointer */
1874 s = s + COMPILERSTUB_DATASIZE;
1876 /* Store the codeinfo pointer in the same place as in the
1877 methodheader for compiled methods. */
1879 code = code_codeinfo_new(m);
1880 d[0] = (Inst *) code;
1882 /* mark start of dump memory area */
1884 dumpsize = dump_size();
1886 cd = DNEW(codegendata);
1887 cd->mcodeptr = (u1 *) s;
1888 cd->lastinstwithoutdispatch = ~0;
1889 cd->superstarts = NULL;
1891 genarg_ainst(cd, s + 2);
1893 if (m->flags & ACC_NATIVE) {
1894 genarg_i(cd, m->parseddesc->paramslots);
1896 genarg_i(cd, m->maxlocals);
1900 gen_TRANSLATE(cd, m);
1904 vm_block_insert(cd->mcodeptr);
1907 #if defined(ENABLE_STATISTICS)
1909 count_cstub_len += COMPILERSTUB_SIZE;
1912 /* release dump area */
1914 dump_release(dumpsize);
1920 #if defined(WITH_FFI)
1921 static ffi_type *cacaotype2ffitype(s4 cacaotype)
1923 switch (cacaotype) {
1925 #if SIZEOF_VOID_P == 8
1926 return &ffi_type_sint64;
1928 return &ffi_type_sint32;
1931 return &ffi_type_sint64;
1933 return &ffi_type_float;
1935 return &ffi_type_double;
1937 return &ffi_type_pointer;
1939 return &ffi_type_void;
1959 #if defined(WITH_FFI)
1960 static ffi_cif *createnativecif(methodinfo *m, methoddesc *nmd)
1962 methoddesc *md = m->parseddesc;
1963 ffi_cif *pcif = NEW(ffi_cif);
1964 ffi_type **types = MNEW(ffi_type *, nmd->paramcount);
1965 ffi_type **ptypes = types;
1968 /* pass env pointer */
1970 *ptypes++ = &ffi_type_pointer;
1972 /* for static methods, pass class pointer */
1974 if (m->flags & ACC_STATIC)
1975 *ptypes++ = &ffi_type_pointer;
1977 /* pass parameter to native function */
1979 for (i = 0; i < md->paramcount; i++)
1980 *ptypes++ = cacaotype2ffitype(md->paramtypes[i].type);
1982 assert(ptypes - types == nmd->paramcount);
1984 if (ffi_prep_cif(pcif, FFI_DEFAULT_ABI, nmd->paramcount, cacaotype2ffitype(md->returntype.type), types) != FFI_OK)
1992 u1 *intrp_createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
1998 #if defined(WITH_FFI)
2004 /* get required compiler data */
2010 /* create method header */
2012 /* Store the codeinfo pointer in the same place as in the
2013 methodheader for compiled methods. */
2015 code = code_codeinfo_new(m);
2017 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
2018 (void) dseg_adds4(cd, nmd->paramslots * SIZEOF_VOID_P); /* FrameSize */
2019 (void) dseg_adds4(cd, 0); /* IsSync */
2020 (void) dseg_adds4(cd, 0); /* IsLeaf */
2021 (void) dseg_adds4(cd, 0); /* IntSave */
2022 (void) dseg_adds4(cd, 0); /* FltSave */
2023 dseg_addlinenumbertablesize(cd);
2024 (void) dseg_adds4(cd, 0); /* ExTableSize */
2026 #if defined(WITH_FFI)
2027 /* prepare ffi cif structure */
2029 cif = createnativecif(m, nmd);
2036 if (opt_verbosecall)
2037 gen_TRACECALL(cd, m);
2040 gen_PATCHER_NATIVECALL(cd, m, f, (u1 *)cif);
2042 if (opt_verbosecall)
2043 gen_TRACENATIVECALL(cd, m, f, (u1 *)cif);
2045 gen_NATIVECALL(cd, m, f, (u1 *)cif);
2053 vm_block_insert(jd->code->mcode + jd->code->mcodelength);
2056 return jd->code->entrypoint;
2060 /* call jni function */
2061 Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1 *addrcif)
2063 #if defined(WITH_FFCALL)
2077 switch (md->returntype.type) {
2079 endsp = sp - 1 + md->paramslots;
2080 av_start_long(alist, f, endsp);
2083 endsp = sp - 2 + md->paramslots;
2084 av_start_longlong(alist, f, endsp);
2087 endsp = sp - 1 + md->paramslots;
2088 av_start_float(alist, f, endsp);
2091 endsp = sp - 2 + md->paramslots;
2092 av_start_double(alist, f, endsp);
2095 endsp = sp - 1 + md->paramslots;
2096 av_start_ptr(alist, f, void *, endsp);
2099 endsp = sp + md->paramslots;
2100 av_start_void(alist, f);
2106 av_ptr(alist, _Jv_JNIEnv *, _Jv_env);
2108 if (m->flags & ACC_STATIC)
2109 av_ptr(alist, classinfo *, m->class);
2111 for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
2112 switch (md->paramtypes[i].type) {
2119 av_longlong(alist, *(s8 *)p);
2123 av_float(alist, *((float *) p));
2127 av_double(alist, *(double *) p);
2131 av_ptr(alist, void *, *(void **) p);
2140 /* create stackframe info structure */
2142 codegen_start_native_call(((u1 *) &s) + sizeof(s), m->code->entrypoint,
2143 (u1 *) fp, (u1 *) ra);
2147 codegen_finish_native_call(((u1 *) &s) + sizeof(s));
2152 #elif defined(WITH_FFI)
2153 methoddesc *md = m->parseddesc;
2155 void *values[md->paramcount + 2];
2156 void **pvalues = values;
2167 pcif = (ffi_cif *) addrcif;
2169 /* pass env pointer */
2171 penv = (_Jv_JNIEnv *) _Jv_env;
2174 /* for static methods, pass class pointer */
2176 if (m->flags & ACC_STATIC)
2177 *pvalues++ = &m->class;
2179 /* pass parameter to native function */
2181 for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
2182 if (IS_2_WORD_TYPE(md->paramtypes[i].type))
2190 /* calculate position of return value */
2192 if (md->returntype.type == TYPE_VOID)
2193 endsp = sp + md->paramslots;
2195 endsp = sp - (IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1) + md->paramslots;
2199 /* create stackframe info structure */
2201 codegen_start_native_call(((u1 *) &s) + sizeof(s), m->code->entrypoint,
2202 (u1 *) fp, (u1 *) ra);
2204 ffi_call(pcif, FFI_FN(f), endsp, values);
2206 codegen_finish_native_call(((u1 *) &s) + sizeof(s));
2215 u1 *createcalljavafunction(methodinfo *m)
2225 /* mark dump memory */
2227 dumpsize = dump_size();
2229 /* allocate memory */
2233 tmpm = DNEW(methodinfo);
2234 cd = DNEW(codegendata);
2235 rd = DNEW(registerdata);
2242 /* Allocate codeinfo memory from the heap as we need to keep them. */
2244 jd->code = code_codeinfo_new(tmpm); /* XXX check allocation */
2246 /* setup code generation stuff */
2248 MSET(tmpm, 0, u1, sizeof(methodinfo));
2254 /* create method header */
2256 (void) dseg_addaddress(cd, NULL); /* CodeinfoPointer */
2257 (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P); /* FrameSize */
2258 (void) dseg_adds4(cd, 0); /* IsSync */
2259 (void) dseg_adds4(cd, 0); /* IsLeaf */
2260 (void) dseg_adds4(cd, 0); /* IntSave */
2261 (void) dseg_adds4(cd, 0); /* FltSave */
2262 dseg_addlinenumbertablesize(cd);
2263 (void) dseg_adds4(cd, 0); /* ExTableSize */
2269 gen_INVOKESTATIC(cd, (Inst **)m->stubroutine, md->paramslots, 0);
2277 vm_block_insert(jd->code->mcode + jd->code->mcodelength);
2279 entrypoint = jd->code->entrypoint;
2281 /* release memory */
2283 dump_release(dumpsize);
2290 * These are local overrides for various environment variables in Emacs.
2291 * Please do not remove this and leave it at the end of the file, where
2292 * Emacs will automagically detect them.
2293 * ---------------------------------------------------------------------
2296 * indent-tabs-mode: t
2300 * vim:noexpandtab:sw=4:ts=4: