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