* src/vm/jit/intrp/codegen.c (createcalljavafunction): Create codeinfo with
[cacao.git] / src / vm / jit / intrp / codegen.c
1 /* src/vm/jit/intrp/codegen.c - code generator for Interpreter
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28             Anton Ertl
29                         Edwin Steiner
30
31    Changes:
32
33    $Id: codegen.c 4718 2006-04-01 21:03:40Z edwin $
34
35 */
36
37
38 #include "config.h"
39
40 #include <assert.h>
41 #include <stdio.h>
42
43 #if defined(WITH_FFI)
44 # include <ffi.h>
45 #elif defined(WITH_FFCALL)
46 # include <avcall.h>
47 #else
48 # error neither WITH_FFI nor WITH_FFCALL defined
49 #endif
50
51 #include "vm/types.h"
52
53 #include "arch.h"
54
55 #include "vm/jit/intrp/codegen.h"
56 #include "vm/jit/intrp/intrp.h"
57
58 #include "native/native.h"
59 #include "vm/builtin.h"
60 #include "vm/class.h"
61 #include "vm/exceptions.h"
62 #include "vm/global.h"
63 #include "vm/options.h"
64 #include "vm/stringlocal.h"
65 #include "vm/vm.h"
66 #include "vm/jit/asmpart.h"
67 #include "vm/jit/codegen-common.h"
68 #include "vm/jit/dseg.h"
69 #include "vm/jit/jit.h"
70 #include "vm/jit/parse.h"
71 #include "vm/jit/patcher.h"
72
73
74 #define gen_branch(_inst) { \
75   gen_##_inst(cd, 0); \
76   codegen_addreference(cd, (basicblock *) (iptr->target), cd->mcodeptr); \
77 }
78
79 #define index2offset(_i) (-(_i) * SIZEOF_VOID_P)
80
81 /* functions used by cacao-gen.i */
82
83 void genarg_v(codegendata *cd1, Cell v)
84 {
85         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
86         *((Cell *) *mcodepp) = v;
87         (*mcodepp)++;
88 }
89
90 void genarg_i(codegendata *cd1, s4 i)
91 {
92         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
93         *((Cell *) *mcodepp) = i;
94         (*mcodepp)++;
95 }
96
97 void genarg_b(codegendata *cd1, s4 i)
98 {
99   genarg_i(cd1, i);
100 }
101
102 void genarg_f(codegendata *cd1, float f)
103 {
104         s4 fi;
105
106         vm_f2Cell(f,fi);
107         genarg_i(cd1, fi);
108 }
109
110 void genarg_l(codegendata *cd1, s8 l)
111 {
112         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
113         vm_l2twoCell(l, ((Cell *) *mcodepp)[1], ((Cell *) *mcodepp)[0]);
114         (*mcodepp) +=2;
115 }
116
117 void genarg_aRef(codegendata *cd1, java_objectheader *a)
118 {
119         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
120         *((java_objectheader **) *mcodepp) = a;
121         (*mcodepp)++;
122 }
123
124 void genarg_aArray(codegendata *cd1, java_arrayheader *a)
125 {
126         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
127         *((java_arrayheader **) *mcodepp) = a;
128         (*mcodepp)++;
129 }
130
131 void genarg_aaTarget(codegendata *cd1, Inst **a)
132 {
133         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
134         *((Inst ***) *mcodepp) = a;
135         (*mcodepp)++;
136 }
137
138 void genarg_aClass(codegendata *cd1, classinfo *a)
139 {
140         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
141         *((classinfo **) *mcodepp) = a;
142         (*mcodepp)++;
143 }
144
145 void genarg_acr(codegendata *cd1, constant_classref *a)
146 {
147         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
148         *((constant_classref **) *mcodepp) = a;
149         (*mcodepp)++;
150 }
151
152 void genarg_addr(codegendata *cd1, u1 *a)
153 {
154         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
155         *((u1 **) *mcodepp) = a;
156         (*mcodepp)++;
157 }
158
159 void genarg_af(codegendata *cd1, functionptr a)
160 {
161         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
162         *((functionptr *) *mcodepp) = a;
163         (*mcodepp)++;
164 }
165
166 void genarg_am(codegendata *cd1, methodinfo *a)
167 {
168         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
169         *((methodinfo **) *mcodepp) = a;
170         (*mcodepp)++;
171 }
172
173 void genarg_acell(codegendata *cd1, Cell *a)
174 {
175         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
176         *((Cell **) *mcodepp) = a;
177         (*mcodepp)++;
178 }
179
180 void genarg_ainst(codegendata *cd1, Inst *a)
181 {
182         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
183         *((Inst **) *mcodepp) = a;
184         (*mcodepp)++;
185 }
186
187 void genarg_auf(codegendata *cd1, unresolved_field *a)
188 {
189         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
190         *((unresolved_field **) *mcodepp) = a;
191         (*mcodepp)++;
192 }
193
194 void genarg_aum(codegendata *cd1, unresolved_method *a)
195 {
196         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
197         *((unresolved_method **) *mcodepp) = a;
198         (*mcodepp)++;
199 }
200
201 void genarg_avftbl(codegendata *cd1, vftbl_t *a)
202 {
203         Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
204         *((vftbl_t **) *mcodepp) = a;
205         (*mcodepp)++;
206 }
207
208
209 /* include the interpreter generation functions *******************************/
210
211 #include "vm/jit/intrp/java-gen.i"
212
213
214 typedef void (*genfunctionptr) (codegendata *);
215
216 typedef struct builtin_gen builtin_gen;
217
218 struct builtin_gen {
219         functionptr builtin;
220         genfunctionptr gen;
221 };
222
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, },
235
236 #if defined(USE_THREADS)
237     {BUILTIN_monitorenter,            gen_MONITORENTER,    },
238     {BUILTIN_monitorexit,             gen_MONITOREXIT,     },
239 #endif
240
241 #if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L)
242     {BUILTIN_f2l,                     gen_F2L,             },
243 #endif
244
245 #if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L)
246     {BUILTIN_d2l,                                         gen_D2L,                         },
247 #endif
248
249 #if !(SUPPORT_FLOAT && SUPPORT_F2I)
250     {BUILTIN_f2i,                                         gen_F2I,                         },
251 #endif
252
253 #if !(SUPPORT_DOUBLE && SUPPORT_D2I)
254     {BUILTIN_d2i,                                         gen_D2I,                         },
255 #endif
256
257 #if !SUPPORT_DIVISION
258     {BUILTIN_idiv,                                        gen_IDIV,                        },
259     {BUILTIN_irem,                                        gen_IREM,                        },
260 #endif
261
262 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
263     {BUILTIN_ldiv,                                        gen_LDIV,                        },
264     {BUILTIN_lrem,                                        gen_LREM,                        },
265 #endif
266
267     {BUILTIN_frem,                                        gen_FREM,                        },
268     {BUILTIN_drem,                                        gen_DREM,            },
269 };
270
271
272 /* codegen *********************************************************************
273
274    Generates machine code.
275
276 *******************************************************************************/
277
278 bool intrp_codegen(jitdata *jd)
279 {
280         methodinfo         *m;
281         codegendata        *cd;
282         registerdata       *rd;
283         s4                  i, len, s1, s2, d;
284         stackptr            src;
285         basicblock         *bptr;
286         instruction        *iptr;
287         exceptiontable     *ex;
288         u2                  currentline;
289         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
290         unresolved_method  *um;
291         builtintable_entry *bte;
292         methoddesc         *md;
293
294         /* get required compiler data */
295
296         m  = jd->m;
297         cd = jd->cd;
298         rd = jd->rd;
299
300         /* prevent compiler warnings */
301
302         d = 0;
303         currentline = 0;
304         lm = NULL;
305         bte = NULL;
306
307         /* create method header */
308
309         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
310         (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P);    /* FrameSize      */
311
312 #if defined(USE_THREADS)
313         if (checksync && (m->flags & ACC_SYNCHRONIZED))
314                 (void) dseg_adds4(cd, 1);                           /* IsSync         */
315         else
316 #endif
317                 (void) dseg_adds4(cd, 0);                           /* IsSync         */
318                                                
319         (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
320         (void) dseg_adds4(cd, 0);                               /* IntSave        */
321         (void) dseg_adds4(cd, 0);                               /* FltSave        */
322
323         dseg_addlinenumbertablesize(cd);
324
325         (void) dseg_adds4(cd, cd->exceptiontablelength);        /* ExTableSize    */
326
327         /* create exception table */
328
329         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
330                 dseg_addtarget(cd, ex->start);
331                 dseg_addtarget(cd, ex->end);
332                 dseg_addtarget(cd, ex->handler);
333                 (void) dseg_addaddress(cd, ex->catchtype.cls);
334         }
335
336 #if 0   
337         /* initialize mcode variables */
338         
339         cd->mcodeptr = cd->mcodebase;
340         cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
341 #endif
342
343         gen_BBSTART;
344
345 #if defined(USE_THREADS)
346         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
347                 if (m->flags & ACC_STATIC)
348                         gen_ACONST(cd, (java_objectheader *) m->class);
349                 else
350                         gen_ALOAD(cd, 0);
351                 
352                 gen_MONITORENTER(cd);
353         }                       
354 #endif
355
356         if (opt_verbosecall)
357                 gen_TRACECALL(cd, m);
358
359         gen_BBEND;
360
361         /* walk through all basic blocks */
362
363         for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
364
365                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
366
367                 if (bptr->flags >= BBREACHED) {
368
369                 /* walk through all instructions */
370                 
371                 src = bptr->instack;
372                 len = bptr->icount;
373
374                 gen_BBSTART;
375
376                 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
377                         if (iptr->line != currentline) {
378                                 dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
379                                 currentline = iptr->line;
380                         }
381
382                 MCODECHECK(64);       /* an instruction usually needs < 64 words      */
383
384                 switch (iptr->opc) {
385
386                 case ICMD_INLINE_START:
387                 case ICMD_INLINE_END:
388                         break;
389
390                 case ICMD_NOP:        /* ...  ==> ...                                 */
391                         break;
392
393                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
394
395                         gen_CHECKNULL(cd);
396                         break;
397
398                 /* constant operations ************************************************/
399
400                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
401                                       /* op1 = 0, val.i = constant                    */
402
403                         gen_ICONST(cd, iptr->val.i);
404                         break;
405
406                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
407                                       /* op1 = 0, val.l = constant                    */
408
409                         gen_LCONST(cd, iptr->val.l);
410                         break;
411
412                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
413                                       /* op1 = 0, val.f = constant                    */
414                         {
415                                 ptrint fi;
416
417                                 vm_f2Cell(iptr->val.f, fi);
418                                 gen_ICONST(cd, fi);
419                         }
420                         break;
421                         
422                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
423                                       /* op1 = 0, val.d = constant                    */
424
425                         gen_LCONST(cd, *(s8 *)&(iptr->val.d));
426                         break;
427
428                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
429                                       /* op1 = 0, val.a = constant                    */
430
431                         if ((iptr->target != NULL) && (iptr->val.a == NULL))
432                                 gen_PATCHER_ACONST(cd, NULL, iptr->target);
433                         else
434                                 gen_ACONST(cd, iptr->val.a);
435                         break;
436
437
438                 /* load/store operations **********************************************/
439
440                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
441                                       /* op1 = local variable                         */
442
443                         gen_ILOAD(cd, index2offset(iptr->op1));
444                         break;
445
446                 case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
447                                       /* op1 = local variable                         */
448
449                         gen_LLOAD(cd, index2offset(iptr->op1));
450                         break;
451
452                 case ICMD_ALOAD:      /* ...  ==> ..., content of local variable      */
453                                       /* op1 = local variable                         */
454
455                         gen_ALOAD(cd, index2offset(iptr->op1));
456                         break;
457
458                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
459                                       /* op1 = local variable                         */
460
461                         gen_ILOAD(cd, index2offset(iptr->op1));
462                         break;
463
464                 case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
465                                       /* op1 = local variable                         */
466
467                         gen_LLOAD(cd, index2offset(iptr->op1));
468                         break;
469
470
471                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
472                                       /* op1 = local variable                         */
473
474                         gen_ISTORE(cd, index2offset(iptr->op1));
475                         break;
476
477                 case ICMD_LSTORE:     /* ..., value  ==> ...                          */
478                                       /* op1 = local variable                         */
479
480                         gen_LSTORE(cd, index2offset(iptr->op1));
481                         break;
482
483                 case ICMD_ASTORE:     /* ..., value  ==> ...                          */
484                                       /* op1 = local variable                         */
485
486                         gen_ASTORE(cd, index2offset(iptr->op1));
487                         break;
488
489
490                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
491                                       /* op1 = local variable                         */
492
493                         gen_ISTORE(cd, index2offset(iptr->op1));
494                         break;
495
496                 case ICMD_DSTORE:     /* ..., value  ==> ...                          */
497                                       /* op1 = local variable                         */
498
499                         gen_LSTORE(cd, index2offset(iptr->op1));
500                         break;
501
502
503                 /* pop/dup/swap operations ********************************************/
504
505                 /* attention: double and longs are only one entry in CACAO ICMDs      */
506
507                 /* stack.c changes stack manipulation operations to treat
508                    longs/doubles as occupying a single slot.  Here we are
509                    undoing that (and only those things that stack.c did). */
510
511                 case ICMD_POP:        /* ..., value  ==> ...                          */
512
513                         if (IS_2_WORD_TYPE(src->type))
514                                 gen_POP2(cd);
515                         else
516                                 gen_POP(cd);
517                         break;
518
519                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
520
521                         gen_POP2(cd);
522                         break;
523
524                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
525
526                         if (IS_2_WORD_TYPE(src->type))
527                                 gen_DUP2(cd);
528                         else
529                                 gen_DUP(cd);
530                         break;
531
532                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
533
534                         if (IS_2_WORD_TYPE(src->type)) {
535                                 if (IS_2_WORD_TYPE(src->prev->type)) {
536                                         gen_DUP2_X2(cd);
537                                 } else {
538                                         gen_DUP2_X1(cd);
539                                 }
540                         } else {
541                                 if (IS_2_WORD_TYPE(src->prev->type)) {
542                                         gen_DUP_X2(cd);
543                                 } else {
544                                         gen_DUP_X1(cd);
545                                 }
546                         }
547                         break;
548
549                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
550
551                         if (IS_2_WORD_TYPE(src->type)) {
552                                 gen_DUP2_X2(cd);
553                         } else
554                                 gen_DUP_X2(cd);
555                         break;
556
557                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
558
559                         gen_DUP2(cd);
560                         break;
561
562                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
563
564                         if (IS_2_WORD_TYPE(src->prev->prev->type))
565                                 gen_DUP2_X2(cd);
566                         else
567                                 gen_DUP2_X1(cd);
568                         break;
569
570                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
571
572                         gen_DUP2_X2(cd);
573                         break;
574
575                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
576
577                         gen_SWAP(cd);
578                         break;
579
580
581                 /* integer operations *************************************************/
582
583                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
584
585                         gen_INEG(cd);
586                         break;
587
588                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
589
590                         gen_LNEG(cd);
591                         break;
592
593                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
594
595                         gen_I2L(cd);
596                         break;
597
598                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
599
600                         gen_L2I(cd);
601                         break;
602
603                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
604
605                         gen_INT2BYTE(cd);
606                         break;
607
608                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
609
610                         gen_INT2CHAR(cd);
611                         break;
612
613                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
614
615                         gen_INT2SHORT(cd);
616                         break;
617
618
619                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
620
621                         gen_IADD(cd);
622                         break;
623
624                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
625                                       /* val.i = constant                             */
626
627                         gen_ICONST(cd, iptr->val.i);
628                         gen_IADD(cd);
629                         break;
630
631                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
632
633                         gen_LADD(cd);
634                         break;
635
636                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
637                                       /* val.l = constant                             */
638
639                         gen_LCONST(cd, iptr->val.l);
640                         gen_LADD(cd);
641                         break;
642
643                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
644
645                         gen_ISUB(cd);
646                         break;
647
648                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
649                                       /* val.i = constant                             */
650
651                         gen_ICONST(cd, iptr->val.i);
652                         gen_ISUB(cd);
653                         break;
654
655                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
656
657                         gen_LSUB(cd);
658                         break;
659
660                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
661                                       /* val.l = constant                             */
662
663                         gen_LCONST(cd, iptr->val.l);
664                         gen_LSUB(cd);
665                         break;
666
667                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
668
669                         gen_IMUL(cd);
670                         break;
671
672                 case ICMD_IMULCONST:  /* ..., val1, val2  ==> ..., val1 * val2        */
673
674                         gen_ICONST(cd, iptr->val.i);
675                         gen_IMUL(cd);
676                         break;
677
678                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
679
680                         gen_LMUL(cd);
681                         break;
682
683                 case ICMD_LMULCONST:  /* ..., val1, val2  ==> ..., val1 * val2        */
684
685                         gen_LCONST(cd, iptr->val.l);
686                         gen_LMUL(cd);
687                         break;
688
689                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
690
691                         gen_IDIV(cd);
692                         break;
693
694                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
695
696                         gen_IREM(cd);
697                         break;
698
699                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
700
701                         gen_LDIV(cd);
702                         break;
703
704                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
705
706                         gen_LREM(cd);
707                         break;
708
709                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
710                                       /* val.i = constant                             */
711                                       
712                         gen_IDIVPOW2(cd, iptr->val.i);
713                         break;
714
715                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
716                                       /* val.i = constant                             */
717
718                         gen_IREMPOW2(cd, iptr->val.i);
719                         break;
720
721                 case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value << constant       */
722                                       /* val.i = constant                             */
723                                       
724                         gen_LDIVPOW2(cd, iptr->val.i);
725                         break;
726
727                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
728                                       /* val.l = constant                             */
729
730                         gen_LREMPOW2(cd, iptr->val.i);
731                         break;
732
733                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
734
735                         gen_ISHL(cd);
736                         break;
737
738                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
739                                       /* val.i = constant                             */
740
741                         gen_ICONST(cd, iptr->val.i);
742                         gen_ISHL(cd);
743                         break;
744
745                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
746
747                         gen_ISHR(cd);
748                         break;
749
750                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
751                                       /* val.i = constant                             */
752
753                         gen_ICONST(cd, iptr->val.i);
754                         gen_ISHR(cd);
755                         break;
756
757                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
758
759                         gen_IUSHR(cd);
760                         break;
761
762                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
763                                       /* val.i = constant                             */
764
765                         gen_ICONST(cd, iptr->val.i);
766                         gen_IUSHR(cd);
767                         break;
768
769                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
770
771                         gen_LSHL(cd);
772                         break;
773
774                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
775                                       /* val.i = constant                             */
776
777                         gen_ICONST(cd, iptr->val.i);
778                         gen_LSHL(cd);
779                         break;
780
781                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
782
783                         gen_LSHR(cd);
784                         break;
785
786                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
787                                       /* val.i = constant                             */
788
789                         gen_ICONST(cd, iptr->val.i);
790                         gen_LSHR(cd);
791                         break;
792
793                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
794
795                         gen_LUSHR(cd);
796                         break;
797
798                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
799                                       /* val.i = constant                             */
800
801                         gen_ICONST(cd, iptr->val.i);
802                         gen_LUSHR(cd);
803                         break;
804
805                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
806
807                         gen_IAND(cd);
808                         break;
809
810                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
811                                       /* val.i = constant                             */
812
813                         gen_ICONST(cd, iptr->val.i);
814                         gen_IAND(cd);
815                         break;
816
817                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
818
819                         gen_LAND(cd);
820                         break;
821
822                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
823                                       /* val.l = constant                             */
824
825                         gen_LCONST(cd, iptr->val.l);
826                         gen_LAND(cd);
827                         break;
828
829                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
830
831                         gen_IOR(cd);
832                         break;
833
834                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
835                                       /* val.i = constant                             */
836
837                         gen_ICONST(cd, iptr->val.i);
838                         gen_IOR(cd);
839                         break;
840
841                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
842
843                         gen_LOR(cd);
844                         break;
845
846                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
847                                       /* val.l = constant                             */
848
849                         gen_LCONST(cd, iptr->val.l);
850                         gen_LOR(cd);
851                         break;
852
853                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
854
855                         gen_IXOR(cd);
856                         break;
857
858                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
859                                       /* val.i = constant                             */
860
861                         gen_ICONST(cd, iptr->val.i);
862                         gen_IXOR(cd);
863                         break;
864
865                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
866
867                         gen_LXOR(cd);
868                         break;
869
870                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
871                                       /* val.l = constant                             */
872
873                         gen_LCONST(cd, iptr->val.l);
874                         gen_LXOR(cd);
875                         break;
876
877
878                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
879
880                         gen_LCMP(cd);
881                         break;
882
883
884                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
885                                       /* op1 = variable, val.i = constant             */
886
887                         gen_IINC(cd, index2offset(iptr->op1), iptr->val.i);
888                         break;
889
890
891                 /* floating operations ************************************************/
892
893                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
894
895                         gen_FNEG(cd);
896                         break;
897
898                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
899
900                         gen_DNEG(cd);
901                         break;
902
903                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
904
905                         gen_FADD(cd);
906                         break;
907
908                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
909
910                         gen_DADD(cd);
911                         break;
912
913                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
914
915                         gen_FSUB(cd);
916                         break;
917
918                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
919
920                         gen_DSUB(cd);
921                         break;
922
923                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
924
925                         gen_FMUL(cd);
926                         break;
927
928                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2      */
929
930                         gen_DMUL(cd);
931                         break;
932
933                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
934
935                         gen_FDIV(cd);
936                         break;
937
938                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
939
940                         gen_DDIV(cd);
941                         break;
942                 
943                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
944
945                         gen_FREM(cd);
946                         break;
947
948                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
949
950                         gen_DREM(cd);
951                         break;
952                 
953                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
954
955                         gen_I2F(cd);
956                         break;
957
958                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
959
960                         gen_L2F(cd);
961                         break;
962
963                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
964
965                         gen_I2D(cd);
966                         break;
967                         
968                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
969
970                         gen_L2D(cd);
971                         break;
972                         
973                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
974
975                         gen_F2I(cd);
976                         break;
977                 
978                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
979
980                         gen_D2I(cd);
981                         break;
982                 
983                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
984
985                         gen_F2L(cd);
986                         break;
987
988                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
989
990                         gen_D2L(cd);
991                         break;
992
993                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
994
995                         gen_F2D(cd);
996                         break;
997                                         
998                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
999
1000                         gen_D2F(cd);
1001                         break;
1002                 
1003                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1004
1005                         gen_FCMPL(cd);
1006                         break;
1007                         
1008                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1009
1010                         gen_DCMPL(cd);
1011                         break;
1012                         
1013                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1014
1015                         gen_FCMPG(cd);
1016                         break;
1017
1018                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1019
1020                         gen_DCMPG(cd);
1021                         break;
1022
1023
1024                 /* memory operations **************************************************/
1025
1026                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1027
1028                         gen_ARRAYLENGTH(cd);
1029                         break;
1030
1031                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1032
1033                         gen_BALOAD(cd);
1034                         break;
1035
1036                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1037
1038                         gen_CALOAD(cd);
1039                         break;                  
1040
1041                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1042
1043                         gen_SALOAD(cd);
1044                         break;
1045
1046                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1047
1048                         gen_IALOAD(cd);
1049                         break;
1050
1051                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1052
1053                         gen_FALOAD(cd);
1054                         break;
1055
1056                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1057                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1058
1059                         gen_LALOAD(cd);
1060                         break;
1061
1062                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1063
1064                         gen_AALOAD(cd);
1065                         break;
1066
1067
1068                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1069
1070                         gen_BASTORE(cd);
1071                         break;
1072
1073                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1074                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1075
1076                         gen_CASTORE(cd);
1077                         break;
1078
1079                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1080
1081                         gen_IASTORE(cd);
1082                         break;
1083
1084                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1085
1086                         gen_FASTORE(cd);
1087                         break;
1088
1089                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1090                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1091
1092                         gen_LASTORE(cd);
1093                         break;
1094
1095                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1096
1097                         gen_AASTORE(cd);
1098                         break;
1099
1100
1101                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1102                                       /* op1 = type, val.a = field address            */
1103
1104                         {
1105                         fieldinfo *fi = iptr->val.a;
1106                         unresolved_field *uf = iptr->target;
1107
1108                         switch (iptr->op1) {
1109                         case TYPE_INT:
1110                                 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1111                                         gen_PATCHER_GETSTATIC_INT(cd, 0, uf);
1112                                 } else {
1113                                         gen_GETSTATIC_INT(cd, (u1 *)&(fi->value.i), uf);
1114                                 }
1115                                 break;
1116                         case TYPE_FLT:
1117                                 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1118                                         gen_PATCHER_GETSTATIC_FLOAT(cd, 0, uf);
1119                                 } else {
1120                                         gen_GETSTATIC_FLOAT(cd, (u1 *)&(fi->value.i), uf);
1121                                 }
1122                                 break;
1123                         case TYPE_LNG:
1124                         case TYPE_DBL:
1125                                 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1126                                         gen_PATCHER_GETSTATIC_LONG(cd, 0, uf);
1127                                 } else {
1128                                         gen_GETSTATIC_LONG(cd, (u1 *)&(fi->value.l), uf);
1129                                 }
1130                                 break;
1131                         case TYPE_ADR:
1132                                 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1133                                         gen_PATCHER_GETSTATIC_CELL(cd, 0, uf);
1134                                 } else {
1135                                         gen_GETSTATIC_CELL(cd, (u1 *)&(fi->value.a), uf);
1136                                 }
1137                                 break;
1138                         }
1139                         }
1140                         break;
1141
1142                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1143                                       /* op1 = type, val.a = field address            */
1144
1145                         {
1146                         fieldinfo *fi = iptr->val.a;
1147                         unresolved_field *uf = iptr->target;
1148
1149                         switch (iptr->op1) {
1150                         case TYPE_INT:
1151                                 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1152                                         gen_PATCHER_PUTSTATIC_INT(cd, 0, uf);
1153                                 } else {
1154                                         gen_PUTSTATIC_INT(cd, (u1 *)&(fi->value.i), uf);
1155                                 }
1156                                 break;
1157                         case TYPE_FLT:
1158                                 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1159                                         gen_PATCHER_PUTSTATIC_FLOAT(cd, 0, uf);
1160                                 } else {
1161                                         gen_PUTSTATIC_FLOAT(cd, (u1 *)&(fi->value.i), uf);
1162                                 }
1163                                 break;
1164                         case TYPE_LNG:
1165                         case TYPE_DBL:
1166                                 if ((fi == NULL) || !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1167                                         gen_PATCHER_PUTSTATIC_LONG(cd, 0, uf);
1168                                 } else {
1169                                         gen_PUTSTATIC_LONG(cd, (u1 *)&(fi->value.l), uf);
1170                                 }
1171                                 break;
1172                         case TYPE_ADR:
1173                                 if ((fi == NULL) ||     !CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1174                                         gen_PATCHER_PUTSTATIC_CELL(cd, 0, uf);
1175                                 } else {
1176                                         gen_PUTSTATIC_CELL(cd, (u1 *)&(fi->value.a), uf);
1177                                 }
1178                                 break;
1179                         }
1180                         }
1181                         break;
1182
1183
1184                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1185                                       /* op1 = type, val.a = field address            */
1186
1187                         {
1188                         fieldinfo *fi = iptr->val.a;
1189                         unresolved_field *uf = iptr->target;
1190
1191                         switch (iptr->op1) {
1192                         case TYPE_INT:
1193                                 if (fi == NULL) {
1194                                         gen_PATCHER_GETFIELD_INT(cd, 0, uf);
1195                                 } else {
1196                                         gen_GETFIELD_INT(cd, fi->offset, uf);
1197                                 }
1198                                 break;
1199                         case TYPE_FLT:
1200                                 if (fi == NULL) {
1201                                         gen_PATCHER_GETFIELD_FLOAT(cd, 0, uf);
1202                                 } else {
1203                                         gen_GETFIELD_FLOAT(cd, fi->offset, uf);
1204                                 }
1205                                 break;
1206                         case TYPE_LNG:
1207                         case TYPE_DBL:
1208                                 if (fi == NULL) {
1209                                         gen_PATCHER_GETFIELD_LONG(cd, 0, uf);
1210                                 } else {
1211                                         gen_GETFIELD_LONG(cd, fi->offset, uf);
1212                                 }
1213                                 break;
1214                         case TYPE_ADR:
1215                                 if (fi == NULL) {
1216                                         gen_PATCHER_GETFIELD_CELL(cd, 0, uf);
1217                                 } else {
1218                                         gen_GETFIELD_CELL(cd, fi->offset, uf);
1219                                 }
1220                                 break;
1221                         }
1222                         }
1223                         break;
1224
1225                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
1226                                       /* op1 = type, val.a = field address            */
1227
1228                         {
1229                         fieldinfo *fi = iptr->val.a;
1230                         unresolved_field *uf = iptr->target;
1231
1232                         switch (iptr->op1) {
1233                         case TYPE_INT:
1234                                 if (fi == NULL) {
1235                                         gen_PATCHER_PUTFIELD_INT(cd, 0, uf);
1236                                 } else {
1237                                         gen_PUTFIELD_INT(cd, fi->offset, uf);
1238                                 }
1239                                 break;
1240                         case TYPE_FLT:
1241                                 if (fi == NULL) {
1242                                         gen_PATCHER_PUTFIELD_FLOAT(cd, 0, uf);
1243                                 } else {
1244                                         gen_PUTFIELD_FLOAT(cd, fi->offset, uf);
1245                                 }
1246                                 break;
1247                         case TYPE_LNG:
1248                         case TYPE_DBL:
1249                                 if (fi == NULL) {
1250                                         gen_PATCHER_PUTFIELD_LONG(cd, 0, uf);
1251                                 } else {
1252                                         gen_PUTFIELD_LONG(cd, fi->offset, uf);
1253                                 }
1254                                 break;
1255                         case TYPE_ADR:
1256                                 if (fi == NULL) {
1257                                         gen_PATCHER_PUTFIELD_CELL(cd, 0, uf);
1258                                 } else {
1259                                         gen_PUTFIELD_CELL(cd, fi->offset, uf);
1260                                 }
1261                                 break;
1262                         }
1263                         }
1264                         break;
1265
1266
1267                 /* branch operations **************************************************/
1268
1269                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
1270
1271                         gen_ATHROW(cd);
1272                         break;
1273
1274                 case ICMD_GOTO:         /* ... ==> ...                                */
1275                                         /* op1 = target JavaVM pc                     */
1276                         gen_branch(GOTO);
1277                         break;
1278
1279                 case ICMD_JSR:          /* ... ==> ...                                */
1280                                         /* op1 = target JavaVM pc                     */
1281                         gen_branch(JSR);
1282                         break;
1283                         
1284                 case ICMD_RET:          /* ... ==> ...                                */
1285                                         /* op1 = local variable                       */
1286
1287                         gen_RET(cd, index2offset(iptr->op1));
1288                         break;
1289
1290                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1291                                         /* op1 = target JavaVM pc                     */
1292
1293                         gen_branch(IFNULL);
1294                         break;
1295
1296                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
1297                                         /* op1 = target JavaVM pc                     */
1298
1299                         gen_branch(IFNONNULL);
1300                         break;
1301
1302                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
1303                                         /* op1 = target JavaVM pc, val.i = constant   */
1304
1305                         if (iptr->val.i == 0) {
1306                                 gen_branch(IFEQ);
1307                         } else {
1308                                 gen_ICONST(cd, iptr->val.i);
1309                                 gen_branch(IF_ICMPEQ);
1310                         }
1311                         break;
1312
1313                 case ICMD_IFLT:         /* ..., value ==> ...                         */
1314                                         /* op1 = target JavaVM pc, val.i = constant   */
1315
1316                         if (iptr->val.i == 0) {
1317                                 gen_branch(IFLT);
1318                         } else {
1319                                 gen_ICONST(cd, iptr->val.i);
1320                                 gen_branch(IF_ICMPLT);
1321                         }
1322                         break;
1323
1324                 case ICMD_IFLE:         /* ..., value ==> ...                         */
1325                                         /* op1 = target JavaVM pc, val.i = constant   */
1326
1327                         if (iptr->val.i == 0) {
1328                                 gen_branch(IFLE);
1329                         } else {
1330                                 gen_ICONST(cd, iptr->val.i);
1331                                 gen_branch(IF_ICMPLE);
1332                         }
1333                         break;
1334
1335                 case ICMD_IFNE:         /* ..., value ==> ...                         */
1336                                         /* op1 = target JavaVM pc, val.i = constant   */
1337
1338                         if (iptr->val.i == 0) {
1339                                 gen_branch(IFNE);
1340                         } else {
1341                                 gen_ICONST(cd, iptr->val.i);
1342                                 gen_branch(IF_ICMPNE);
1343                         }
1344                         break;
1345
1346                 case ICMD_IFGT:         /* ..., value ==> ...                         */
1347                                         /* op1 = target JavaVM pc, val.i = constant   */
1348
1349                         if (iptr->val.i == 0) {
1350                                 gen_branch(IFGT);
1351                         } else {
1352                                 gen_ICONST(cd, iptr->val.i);
1353                                 gen_branch(IF_ICMPGT);
1354                         }
1355                         break;
1356
1357                 case ICMD_IFGE:         /* ..., value ==> ...                         */
1358                                         /* op1 = target JavaVM pc, val.i = constant   */
1359
1360                         if (iptr->val.i == 0) {
1361                                 gen_branch(IFGE);
1362                         } else {
1363                                 gen_ICONST(cd, iptr->val.i);
1364                                 gen_branch(IF_ICMPGE);
1365                         }
1366                         break;
1367
1368                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
1369                                         /* op1 = target JavaVM pc, val.l = constant   */
1370
1371                         gen_LCONST(cd, iptr->val.l);
1372                         gen_branch(IF_LCMPEQ);
1373                         break;
1374
1375                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
1376                                         /* op1 = target JavaVM pc, val.l = constant   */
1377
1378                         gen_LCONST(cd, iptr->val.l);
1379                         gen_branch(IF_LCMPLT);
1380                         break;
1381
1382                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
1383                                         /* op1 = target JavaVM pc, val.l = constant   */
1384
1385                         gen_LCONST(cd, iptr->val.l);
1386                         gen_branch(IF_LCMPLE);
1387                         break;
1388
1389                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
1390                                         /* op1 = target JavaVM pc, val.l = constant   */
1391
1392                         gen_LCONST(cd, iptr->val.l);
1393                         gen_branch(IF_LCMPNE);
1394                         break;
1395
1396                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
1397                                         /* op1 = target JavaVM pc, val.l = constant   */
1398
1399                         gen_LCONST(cd, iptr->val.l);
1400                         gen_branch(IF_LCMPGT);
1401                         break;
1402
1403                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
1404                                         /* op1 = target JavaVM pc, val.l = constant   */
1405
1406                         gen_LCONST(cd, iptr->val.l);
1407                         gen_branch(IF_LCMPGE);
1408                         break;
1409
1410                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
1411                                         /* op1 = target JavaVM pc                     */
1412
1413                         gen_branch(IF_ICMPEQ);
1414                         break;
1415
1416                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
1417                                         /* op1 = target JavaVM pc                     */
1418
1419                         gen_branch(IF_LCMPEQ);
1420                         break;
1421
1422                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
1423                                         /* op1 = target JavaVM pc                     */
1424
1425                         gen_branch(IF_ACMPEQ);
1426                         break;
1427
1428                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
1429                                         /* op1 = target JavaVM pc                     */
1430
1431                         gen_branch(IF_ICMPNE);
1432                         break;
1433
1434                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
1435                                         /* op1 = target JavaVM pc                     */
1436
1437                         gen_branch(IF_LCMPNE);
1438                         break;
1439
1440                 case ICMD_IF_ACMPNE:    /* ..., value, value ==> ...                  */
1441                                         /* op1 = target JavaVM pc                     */
1442
1443                         gen_branch(IF_ACMPNE);
1444                         break;
1445
1446                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
1447                                         /* op1 = target JavaVM pc                     */
1448
1449                         gen_branch(IF_ICMPLT);
1450                         break;
1451
1452                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
1453                                         /* op1 = target JavaVM pc                     */
1454
1455                         gen_branch(IF_LCMPLT);
1456                         break;
1457
1458                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
1459                                         /* op1 = target JavaVM pc                     */
1460
1461                         gen_branch(IF_ICMPGT);
1462                         break;
1463
1464                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
1465                                         /* op1 = target JavaVM pc                     */
1466
1467                         gen_branch(IF_LCMPGT);
1468                         break;
1469
1470                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
1471                                         /* op1 = target JavaVM pc                     */
1472
1473                         gen_branch(IF_ICMPLE);
1474                         break;
1475
1476                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
1477                                         /* op1 = target JavaVM pc                     */
1478
1479                         gen_branch(IF_LCMPLE);
1480                         break;
1481
1482                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
1483                                         /* op1 = target JavaVM pc                     */
1484
1485                         gen_branch(IF_ICMPGE);
1486                         break;
1487
1488                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
1489                                         /* op1 = target JavaVM pc                     */
1490
1491                         gen_branch(IF_LCMPGE);
1492                         break;
1493
1494
1495                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
1496                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
1497                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
1498
1499 #if defined(USE_THREADS)
1500                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1501                                 if (m->flags & ACC_STATIC) {
1502                                         gen_ACONST(cd, (java_objectheader *) m->class);
1503                                 } else {
1504                                         gen_ALOAD(cd, 0);
1505                                 }
1506                                 gen_MONITOREXIT(cd);
1507                         }
1508 #endif
1509                         if (opt_verbosecall)
1510                                 gen_TRACERETURN(cd, m);
1511
1512                         gen_IRETURN(cd, index2offset(cd->maxlocals));
1513                         break;
1514
1515                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
1516                 case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
1517
1518 #if defined(USE_THREADS)
1519                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1520                                 if (m->flags & ACC_STATIC) {
1521                                         gen_ACONST(cd, (java_objectheader *) m->class);
1522                                 } else {
1523                                         gen_ALOAD(cd, 0);
1524                                 }
1525                                 gen_MONITOREXIT(cd);
1526                         }
1527 #endif
1528                         if (opt_verbosecall)
1529                                 gen_TRACELRETURN(cd, m);
1530
1531                         gen_LRETURN(cd, index2offset(cd->maxlocals));
1532                         break;
1533
1534                 case ICMD_RETURN:       /* ...  ==> ...                               */
1535
1536 #if defined(USE_THREADS)
1537                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1538                                 if (m->flags & ACC_STATIC) {
1539                                         gen_ACONST(cd, (java_objectheader *) m->class);
1540                                 } else {
1541                                         gen_ALOAD(cd, 0);
1542                                 }
1543                                 gen_MONITOREXIT(cd);
1544                         }
1545 #endif
1546                         if (opt_verbosecall)
1547                                 gen_TRACERETURN(cd, m);
1548
1549                         gen_RETURN(cd, index2offset(cd->maxlocals));
1550                         break;
1551
1552
1553                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
1554                         {
1555                         s4 i, l, *s4ptr;
1556                         void **tptr;
1557
1558                         tptr = (void **) iptr->target;
1559
1560                         s4ptr = iptr->val.a;
1561                         l = s4ptr[1];                          /* low     */
1562                         i = s4ptr[2];                          /* high    */
1563                         
1564                         i = i - l + 1;
1565
1566                         /* arguments: low, range, datasegment address, table
1567                        offset in datasegment, default target */
1568
1569                         gen_TABLESWITCH(cd, l, i, NULL, 0, NULL);
1570
1571                         /* actually -3 cells offset */
1572
1573                         dseg_adddata(cd, (cd->mcodeptr - 2 * sizeof(Inst)));
1574                         codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1575
1576                         /* build jump table top down and use address of lowest entry */
1577
1578                         tptr += i;
1579
1580                         while (--i >= 0) {
1581                                 dseg_addtarget(cd, (basicblock *) tptr[0]); 
1582                                 --tptr;
1583                         }
1584                         }
1585
1586                         /* length of dataseg after last dseg_addtarget is used by load */
1587                         ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1588                         break;
1589
1590
1591                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
1592                         {
1593                         s4 i, *s4ptr;
1594                         void **tptr;
1595
1596                         tptr = (void **) iptr->target;
1597
1598                         s4ptr = iptr->val.a;
1599
1600                         /* s4ptr[0] is equal to tptr[0] */
1601                         i = s4ptr[1];                          /* count    */
1602                         
1603                         /* arguments: count, datasegment address, table offset in         */
1604                         /* datasegment, default target                                    */
1605                         gen_LOOKUPSWITCH(cd, i, NULL, 0, NULL);
1606                         dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1607                         codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1608
1609                         /* build jump table top down and use address of lowest entry */
1610
1611                         tptr += i;
1612                         s4ptr += i * 2;
1613
1614                         while (--i >= 0) {
1615                                 dseg_addtarget(cd, (basicblock *) tptr[0]); 
1616                                 dseg_addaddress(cd, s4ptr[0]);
1617                                 --tptr;
1618                                 s4ptr -= 2;
1619                         }
1620                         }
1621
1622                         /* length of dataseg after last dseg_addtarget is used by load */
1623                         ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1624                         break;
1625
1626
1627                 case ICMD_BUILTIN:      /* ..., arg1, arg2, arg3 ==> ...              */
1628                                         /* op1 = arg count val.a = builtintable entry */
1629                         bte = iptr->val.a;
1630
1631                         for (i = 0; i < sizeof(builtin_gen_table)/sizeof(builtin_gen); i++) {
1632                                 builtin_gen *bg = &builtin_gen_table[i];
1633                                 if (bg->builtin == bte->fp) {
1634                                         (bg->gen)(cd);
1635                                         goto gen_builtin_end;
1636                                 }
1637                         }
1638                         assert(0);
1639                 gen_builtin_end:
1640                         break;
1641
1642                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
1643                                         /* op1 = arg count, val.a = method pointer    */
1644
1645                         lm = iptr->val.a;
1646                         um = iptr->target;
1647
1648                         if (lm == NULL) {
1649                                 md = um->methodref->parseddesc.md;
1650                                 gen_PATCHER_INVOKESTATIC(cd, 0, md->paramslots, um);
1651
1652                         } else {
1653                                 md = lm->parseddesc;
1654                                 gen_INVOKESTATIC(cd, (Inst **)lm->stubroutine, md->paramslots, um);
1655                         }
1656                         break;
1657
1658                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1659
1660                         lm = iptr->val.a;
1661                         um = iptr->target;
1662
1663                         if (lm == NULL) {
1664                                 md = um->methodref->parseddesc.md;
1665                                 gen_PATCHER_INVOKESPECIAL(cd, 0, md->paramslots, um);
1666
1667                         } else {
1668                                 md = lm->parseddesc;
1669                                 gen_INVOKESPECIAL(cd, (Inst **)lm->stubroutine, md->paramslots, um);
1670                         }
1671                         break;
1672
1673                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
1674
1675                         lm = iptr->val.a;
1676                         um = iptr->target;
1677
1678                         if (lm == NULL) {
1679                                 md = um->methodref->parseddesc.md;
1680                                 gen_PATCHER_INVOKEVIRTUAL(cd, 0, md->paramslots, um);
1681
1682                         } else {
1683                                 md = lm->parseddesc;
1684
1685                                 s1 = OFFSET(vftbl_t, table[0]) +
1686                                         sizeof(methodptr) * lm->vftblindex;
1687
1688                                 gen_INVOKEVIRTUAL(cd, s1, md->paramslots, um);
1689                         }
1690                         break;
1691
1692                 case ICMD_INVOKEINTERFACE:/* op1 = arg count, val.a = method pointer  */
1693
1694                         lm = iptr->val.a;
1695                         um = iptr->target;
1696
1697                         if (lm == NULL) {
1698                                 md = um->methodref->parseddesc.md;
1699                                 gen_PATCHER_INVOKEINTERFACE(cd, 0, 0, md->paramslots, um);
1700
1701                         } else {
1702                                 md = lm->parseddesc;
1703
1704                                 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1705                                         sizeof(methodptr*) * lm->class->index;
1706
1707                                 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1708
1709                                 gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, um);
1710                         }
1711                         break;
1712
1713
1714                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
1715                                       /* op1:   0 == array, 1 == class                */
1716                                       /* val.a: (classinfo *) superclass              */
1717
1718                         if (iptr->op1 == 1) {
1719                                 if (iptr->val.a == NULL)
1720                                         gen_PATCHER_CHECKCAST(cd, NULL, iptr->target);
1721                                 else
1722                                         gen_CHECKCAST(cd, iptr->val.a, NULL);
1723                         } else {
1724                                 if (iptr->val.a == NULL)
1725                                         gen_PATCHER_ARRAYCHECKCAST(cd, NULL, iptr->target);
1726                                 else
1727                                         gen_ARRAYCHECKCAST(cd, iptr->val.a, NULL);
1728                         }
1729                         break;
1730
1731                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
1732                                       /* op1:   0 == array, 1 == class                */
1733                                       /* val.a: (classinfo *) superclass              */
1734
1735                         if (iptr->val.a == NULL)
1736                                 gen_PATCHER_INSTANCEOF(cd, NULL, iptr->target);
1737                         else
1738                                 gen_INSTANCEOF(cd, iptr->val.a, iptr->target);
1739                         break;
1740
1741                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
1742                                       /* op1 = dimension, val.a = class               */
1743
1744                         if (iptr->val.a == NULL) {
1745                                 gen_PATCHER_MULTIANEWARRAY(cd, NULL, iptr->op1, iptr->target);
1746                         } else {
1747                                 gen_MULTIANEWARRAY(cd, iptr->val.a, iptr->op1, NULL);
1748                         }
1749                         break;
1750
1751                 default:
1752                         *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
1753                         return false;
1754         } /* switch */
1755                 
1756         } /* for instruction */
1757
1758         gen_BBEND;
1759
1760         } /* if (bptr->flags >= BBREACHED) */
1761         } /* for basic block */
1762
1763         dseg_createlinenumbertable(cd);
1764
1765         codegen_finish(jd, (s4) (cd->mcodeptr - cd->mcodebase));
1766
1767 #ifdef VM_PROFILING
1768         vm_block_insert(jd->code->mcode + jd->code->mcodelength);
1769 #endif
1770
1771         /* branch resolving (walk through all basic blocks) */
1772
1773         for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
1774                 branchref *brefs;
1775
1776                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
1777                         gen_resolveanybranch(((u1*) jd->code->entrypoint) + brefs->branchpos,
1778                                              ((u1 *)jd->code->entrypoint) + bptr->mpc);
1779                 }
1780         }
1781
1782         /* everything's ok */
1783
1784         return true;
1785 }
1786
1787
1788 /* createcompilerstub **********************************************************
1789
1790    Creates a stub routine which calls the compiler.
1791
1792    A stub consists of:
1793
1794    +-------------+
1795    | methodinfo* |
1796    +-------------+ <-- stub
1797    | codeptr     |
1798    +-------------+
1799    | maxlocals   |
1800    +-------------+
1801    | TRANSLATE   |
1802    +-------------+
1803    | methodinfo  |
1804    +-------------+
1805
1806    codeptr points either to TRANSLATE or to the translated threaded code
1807
1808    all methods are called indirectly through methodptr
1809
1810 *******************************************************************************/
1811
1812 #define COMPILERSTUB_DATASIZE    1
1813 #define COMPILERSTUB_CODESIZE    4
1814
1815 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
1816
1817
1818 u1 *intrp_createcompilerstub(methodinfo *m)
1819 {
1820         Inst        *s;
1821         Inst        *d;
1822         codegendata *cd;
1823         s4           dumpsize;
1824
1825         s = CNEW(Inst, COMPILERSTUB_SIZE);
1826
1827         /* set data pointer and code pointer */
1828
1829         d = s;
1830         s = s + COMPILERSTUB_DATASIZE;
1831
1832         /* Store the methodinfo* in the same place as in the methodheader
1833            for compiled methods. */
1834
1835         d[0] = (Inst *) m;
1836
1837         /* mark start of dump memory area */
1838
1839         dumpsize = dump_size();
1840         
1841         cd = DNEW(codegendata);
1842     cd->mcodeptr = (u1 *) s;
1843         cd->lastinstwithoutdispatch = ~0;
1844         cd->superstarts = NULL;
1845
1846         genarg_ainst(cd, s + 2);
1847
1848         if (m->flags & ACC_NATIVE) {
1849                 genarg_i(cd, m->parseddesc->paramslots);
1850         } else {
1851                 genarg_i(cd, m->maxlocals);
1852         }
1853
1854         gen_BBSTART;
1855         gen_TRANSLATE(cd, m);
1856         gen_BBEND;
1857         
1858 #ifdef VM_PROFILING
1859         vm_block_insert(cd->mcodeptr);
1860 #endif
1861
1862 #if defined(ENABLE_STATISTICS)
1863         if (opt_stat)
1864                 count_cstub_len += COMPILERSTUB_SIZE;
1865 #endif
1866
1867         /* release dump area */
1868
1869         dump_release(dumpsize);
1870         
1871         return (u1 *) s;
1872 }
1873
1874
1875 #if defined(WITH_FFI)
1876 static ffi_type *cacaotype2ffitype(s4 cacaotype)
1877 {
1878         switch (cacaotype) {
1879         case TYPE_INT:
1880 #if SIZEOF_VOID_P == 8
1881                 return &ffi_type_sint64;
1882 #else
1883                 return &ffi_type_sint32;
1884 #endif
1885         case TYPE_LNG:
1886                 return &ffi_type_sint64;
1887         case TYPE_FLT:
1888                 return &ffi_type_float;
1889         case TYPE_DBL:
1890                 return &ffi_type_double;
1891         case TYPE_ADR:
1892                 return &ffi_type_pointer;
1893         case TYPE_VOID:
1894                 return &ffi_type_void;
1895         default:
1896                 assert(false);
1897         }
1898 }
1899 #endif
1900
1901
1902 /* native stub:
1903 +---------+
1904 |NATIVECALL|
1905 +---------+
1906 |methodinf|
1907 +---------+
1908 |function |
1909 +---------+
1910 |cif      |
1911 +---------+
1912 */
1913
1914 #if defined(WITH_FFI)
1915 static ffi_cif *createnativecif(methodinfo *m, methoddesc *nmd)
1916 {
1917         methoddesc  *md = m->parseddesc; 
1918         ffi_cif     *pcif = NEW(ffi_cif);
1919         ffi_type   **types = MNEW(ffi_type *, nmd->paramcount);
1920         ffi_type   **ptypes = types;
1921         s4           i;
1922
1923         /* pass env pointer */
1924
1925         *ptypes++ = &ffi_type_pointer;
1926
1927         /* for static methods, pass class pointer */
1928
1929         if (m->flags & ACC_STATIC)
1930                 *ptypes++ = &ffi_type_pointer;
1931
1932         /* pass parameter to native function */
1933
1934         for (i = 0; i < md->paramcount; i++)
1935                 *ptypes++ = cacaotype2ffitype(md->paramtypes[i].type);
1936
1937         assert(ptypes - types == nmd->paramcount);
1938
1939     if (ffi_prep_cif(pcif, FFI_DEFAULT_ABI, nmd->paramcount, cacaotype2ffitype(md->returntype.type), types) != FFI_OK)
1940                 assert(0);
1941
1942         return pcif;
1943 }
1944 #endif
1945
1946
1947 u1 *intrp_createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
1948 {
1949         methodinfo   *m;
1950         codegendata  *cd;
1951         registerdata *rd;
1952 #if defined(WITH_FFI)
1953         ffi_cif *cif;
1954 #else
1955         u1      *cif;
1956 #endif
1957
1958         /* get required compiler data */
1959
1960         m  = jd->m;
1961         cd = jd->cd;
1962         rd = jd->rd;
1963
1964         /* create method header */
1965
1966         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
1967         (void) dseg_adds4(cd, nmd->paramslots * SIZEOF_VOID_P); /* FrameSize      */
1968         (void) dseg_adds4(cd, 0);                               /* IsSync         */
1969         (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
1970         (void) dseg_adds4(cd, 0);                               /* IntSave        */
1971         (void) dseg_adds4(cd, 0);                               /* FltSave        */
1972         dseg_addlinenumbertablesize(cd);
1973         (void) dseg_adds4(cd, 0);                               /* ExTableSize    */
1974
1975 #if defined(WITH_FFI)
1976         /* prepare ffi cif structure */
1977
1978         cif = createnativecif(m, nmd);
1979 #else
1980         cif = NULL;
1981 #endif
1982
1983         gen_BBSTART;
1984
1985         if (opt_verbosecall)
1986                 gen_TRACECALL(cd, m);
1987
1988         if (f == NULL) {
1989                 gen_PATCHER_NATIVECALL(cd, m, f, (u1 *)cif);
1990         } else {
1991                 if (opt_verbosecall)
1992                         gen_TRACENATIVECALL(cd, m, f, (u1 *)cif);
1993                 else
1994                         gen_NATIVECALL(cd, m, f, (u1 *)cif);
1995         }
1996
1997         gen_BBEND;
1998
1999         codegen_finish(jd, (s4) (cd->mcodeptr - cd->mcodebase));
2000
2001 #ifdef VM_PROFILING
2002         vm_block_insert(jd->code->mcode + jd->code->mcodelength);
2003 #endif
2004
2005         return jd->code->entrypoint;
2006 }
2007
2008
2009 /* call jni function */
2010 Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1 *addrcif)
2011 {
2012 #if defined(WITH_FFCALL)
2013         av_alist alist;
2014         methoddesc *md;
2015         Cell *p;
2016         Cell *endsp;
2017         s4 i;
2018
2019         struct {
2020                 stackframeinfo sfi;
2021                 localref_table lrt;
2022         } s;
2023
2024         md = m->parseddesc;
2025
2026         switch (md->returntype.type) {
2027         case TYPE_INT:
2028                 endsp = sp - 1 + md->paramslots;
2029                 av_start_long(alist, f, endsp);
2030                 break;
2031         case TYPE_LNG:
2032                 endsp = sp - 2 + md->paramslots;
2033                 av_start_longlong(alist, f, endsp);
2034                 break;
2035         case TYPE_FLT:
2036                 endsp = sp - 1 + md->paramslots;
2037                 av_start_float(alist, f, endsp);
2038                 break;
2039         case TYPE_DBL:
2040                 endsp = sp - 2 + md->paramslots;
2041                 av_start_double(alist, f, endsp);
2042                 break;
2043         case TYPE_ADR:
2044                 endsp = sp - 1 + md->paramslots;
2045                 av_start_ptr(alist, f, void *, endsp);
2046                 break;
2047         case TYPE_VOID:
2048                 endsp = sp + md->paramslots;
2049                 av_start_void(alist, f);
2050                 break;
2051         default:
2052                 assert(false);
2053         }
2054
2055         av_ptr(alist, _Jv_JNIEnv *, _Jv_env);
2056
2057         if (m->flags & ACC_STATIC)
2058                 av_ptr(alist, classinfo *, m->class);
2059
2060         for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
2061                 switch (md->paramtypes[i].type) {
2062                 case TYPE_INT:
2063                         p -= 1;
2064                         av_long(alist, *p);
2065                         break;
2066                 case TYPE_LNG:
2067                         p -= 2;
2068                         av_longlong(alist, *(s8 *)p);
2069                         break;
2070                 case TYPE_FLT:
2071                         p -= 1;
2072                         av_float(alist, *((float *) p));
2073                         break;
2074                 case TYPE_DBL:
2075                         p -= 2;
2076                         av_double(alist, *(double *) p);
2077                         break;
2078                 case TYPE_ADR:
2079                         p -= 1;
2080                         av_ptr(alist, void *, *(void **) p);
2081                         break;
2082                 default:
2083                         assert(false);
2084                 }
2085         }
2086
2087         global_sp = sp;
2088
2089         /* create stackframe info structure */
2090
2091         codegen_start_native_call(((u1 *) &s) + sizeof(s), m->code->entrypoint,
2092                                                           (u1 *) fp, (u1 *) ra);
2093
2094         av_call(alist);
2095
2096         codegen_finish_native_call(((u1 *) &s) + sizeof(s));
2097
2098         CLEAR_global_sp;
2099
2100         return endsp;
2101 #elif defined(WITH_FFI)
2102         methoddesc  *md = m->parseddesc; 
2103         ffi_cif     *pcif;
2104         void        *values[md->paramcount + 2];
2105         void       **pvalues = values;
2106         Cell        *p;
2107         Cell        *endsp;
2108         s4           i;
2109         _Jv_JNIEnv  *penv;
2110
2111         struct {
2112                 stackframeinfo sfi;
2113                 localref_table lrt;
2114         } s;
2115
2116         pcif = (ffi_cif *) addrcif;
2117
2118         /* pass env pointer */
2119
2120         penv = (_Jv_JNIEnv *) _Jv_env;
2121         *pvalues++ = &penv;
2122
2123         /* for static methods, pass class pointer */
2124
2125         if (m->flags & ACC_STATIC)
2126                 *pvalues++ = &m->class;
2127
2128         /* pass parameter to native function */
2129
2130         for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
2131                 if (IS_2_WORD_TYPE(md->paramtypes[i].type))
2132                         p -= 2;
2133                 else
2134                         p--;
2135
2136                 *pvalues++ = p;
2137         }
2138
2139         /* calculate position of return value */
2140
2141         if (md->returntype.type == TYPE_VOID)
2142                 endsp = sp + md->paramslots;
2143         else
2144                 endsp = sp - (IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1) + md->paramslots;
2145
2146         global_sp = sp;
2147
2148         /* create stackframe info structure */
2149
2150         codegen_start_native_call(((u1 *) &s) + sizeof(s), m->code->entrypoint,
2151                                                           (u1 *) fp, (u1 *) ra);
2152
2153         ffi_call(pcif, FFI_FN(f), endsp, values);
2154
2155         codegen_finish_native_call(((u1 *) &s) + sizeof(s));
2156
2157         CLEAR_global_sp;
2158
2159         return endsp;
2160 #endif
2161 }
2162
2163
2164 u1 *createcalljavafunction(methodinfo *m)
2165 {
2166         methodinfo         *tmpm;
2167         u1                 *entrypoint;
2168         jitdata            *jd;
2169         codegendata        *cd;
2170         registerdata       *rd;
2171         s4                  dumpsize;
2172         methoddesc         *md;
2173
2174         /* mark dump memory */
2175
2176         dumpsize = dump_size();
2177
2178         /* allocate memory */
2179
2180         jd = DNEW(jitdata);
2181
2182         tmpm = DNEW(methodinfo);
2183         cd = DNEW(codegendata);
2184         rd = DNEW(registerdata);
2185
2186         jd->m = tmpm;
2187         jd->flags = 0;
2188         jd->cd = cd;
2189         jd->rd = rd;
2190
2191         /* Allocate codeinfo memory from the heap as we need to keep them. */
2192
2193         jd->code = code_codeinfo_new(tmpm); /* XXX check allocation */
2194
2195         /* setup code generation stuff */
2196
2197         MSET(tmpm, 0, u1, sizeof(methodinfo));
2198
2199         codegen_setup(jd);
2200
2201         md = m->parseddesc;
2202
2203         /* create method header */
2204
2205         (void) dseg_addaddress(cd, NULL);                       /* MethodPointer  */
2206         (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P);  /* FrameSize      */
2207         (void) dseg_adds4(cd, 0);                               /* IsSync         */
2208         (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
2209         (void) dseg_adds4(cd, 0);                               /* IntSave        */
2210         (void) dseg_adds4(cd, 0);                               /* FltSave        */
2211         dseg_addlinenumbertablesize(cd);
2212         (void) dseg_adds4(cd, 0);                               /* ExTableSize    */
2213
2214
2215         /* generate code */
2216         
2217         gen_BBSTART;
2218         gen_INVOKESTATIC(cd, (Inst **)m->stubroutine, md->paramslots, 0);
2219         gen_END(cd);
2220
2221         gen_BBEND;
2222
2223         codegen_finish(jd, (s4) (cd->mcodeptr - cd->mcodebase));
2224
2225 #ifdef VM_PROFILING
2226         vm_block_insert(jd->code->mcode + jd->code->mcodelength);
2227 #endif
2228         entrypoint = jd->code->entrypoint;
2229
2230         /* release memory */
2231
2232         dump_release(dumpsize);
2233
2234         return entrypoint;
2235 }
2236
2237
2238 /*
2239  * These are local overrides for various environment variables in Emacs.
2240  * Please do not remove this and leave it at the end of the file, where
2241  * Emacs will automagically detect them.
2242  * ---------------------------------------------------------------------
2243  * Local variables:
2244  * mode: c
2245  * indent-tabs-mode: t
2246  * c-basic-offset: 4
2247  * tab-width: 4
2248  * End:
2249  * vim:noexpandtab:sw=4:ts=4:
2250  */