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