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