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