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