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