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