* vm/class.h: Added.
[cacao.git] / src / vm / jit / mips / codegen.c
1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
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             Christian Ullrich
32             Edwin Steiner
33
34    Contains the codegenerator for an MIPS (R4000 or higher) processor.
35    This module generates MIPS machine code for a sequence of
36    intermediate code commands (ICMDs).
37
38    $Id: codegen.c 3879 2005-12-05 19:36:57Z twisti $
39
40 */
41
42
43 #include <assert.h>
44 #include <stdio.h>
45
46 #include "config.h"
47 #include "vm/types.h"
48
49 #include "md.h"
50 #include "md-abi.h"
51 #include "md-abi.inc"
52
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
55
56 #include "cacao/cacao.h"
57 #include "native/native.h"
58 #include "vm/builtin.h"
59 #include "vm/class.h"
60 #include "vm/stringlocal.h"
61 #include "vm/jit/asmpart.h"
62 #include "vm/jit/codegen.inc"
63 #include "vm/jit/jit.h"
64
65 #if defined(LSRA)
66 # include "vm/jit/lsra.h"
67 # include "vm/jit/lsra.inc"
68 #endif
69
70 #include "vm/jit/patcher.h"
71 #include "vm/jit/reg.h"
72 #include "vm/jit/reg.inc"
73
74
75 /* codegen *********************************************************************
76
77    Generates machine code.
78
79 *******************************************************************************/
80
81 bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
82 {
83         s4                  len, s1, s2, s3, d, disp;
84         ptrint              a;
85         s4                  parentargs_base;
86         s4                 *mcodeptr;
87         stackptr            src;
88         varinfo            *var;
89         basicblock         *bptr;
90         instruction        *iptr;
91         exceptiontable     *ex;
92         u2                  currentline;
93         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
94         builtintable_entry *bte;
95         methoddesc         *md;
96
97         {
98         s4 i, p, t, l;
99         s4 savedregs_num;
100
101         savedregs_num = (m->isleafmethod) ? 0 : 1;        /* space to save the RA */
102
103         /* space to save used callee saved registers */
104
105         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
106         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
107
108         parentargs_base = rd->memuse + savedregs_num;
109
110 #if defined(USE_THREADS)           /* space to save argument of monitor_enter */
111         if (checksync && (m->flags & ACC_SYNCHRONIZED))
112                 parentargs_base++;
113 #endif
114
115         /* adjust frame size for 16 byte alignment */
116
117         if (parentargs_base & 1)
118                 parentargs_base++;
119
120         /* create method header */
121
122 #if SIZEOF_VOID_P == 4
123         (void) dseg_addaddress(cd, m);                          /* Filler         */
124 #endif
125         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
126         (void) dseg_adds4(cd, parentargs_base * 8);             /* FrameSize      */
127
128 #if defined(USE_THREADS)
129         /* IsSync contains the offset relative to the stack pointer for the
130            argument of monitor_exit used in the exception handler. Since the
131            offset could be zero and give a wrong meaning of the flag it is
132            offset by one.
133         */
134
135         if (checksync && (m->flags & ACC_SYNCHRONIZED))
136                 (void) dseg_adds4(cd, (rd->memuse + 1) * 8);        /* IsSync         */
137         else
138 #endif
139                 (void) dseg_adds4(cd, 0);                           /* IsSync         */
140                                                
141         (void) dseg_adds4(cd, m->isleafmethod);                 /* IsLeaf         */
142         (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);  /* IntSave        */
143         (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);  /* FltSave        */
144         dseg_addlinenumbertablesize(cd);
145         (void) dseg_adds4(cd, cd->exceptiontablelength);        /* ExTableSize    */
146
147         /* create exception table */
148
149         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
150                 dseg_addtarget(cd, ex->start);
151                 dseg_addtarget(cd, ex->end);
152                 dseg_addtarget(cd, ex->handler);
153                 (void) dseg_addaddress(cd, ex->catchtype.cls);
154         }
155         
156         /* initialize mcode variables */
157         
158         mcodeptr = (s4 *) cd->mcodebase;
159         cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
160         MCODECHECK(128 + m->paramcount);
161
162         /* initialize the last patcher pointer */
163
164         cd->lastmcodeptr = (u1 *) mcodeptr;
165
166         /* create stack frame (if necessary) */
167
168         if (parentargs_base)
169                 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
170
171         /* save return address and used callee saved registers */
172
173         p = parentargs_base;
174         if (!m->isleafmethod) {
175                 p--; M_AST(REG_RA, REG_SP, p * 8);
176         }
177         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
178                 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
179         }
180         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
181                 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
182         }
183
184         /* take arguments out of register or stack frame */
185
186         md = m->parseddesc;
187
188         for (p = 0, l = 0; p < md->paramcount; p++) {
189                 t = md->paramtypes[p].type;
190                 var = &(rd->locals[l][t]);
191                 l++;
192                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
193                         l++;
194                 if (var->type < 0)
195                         continue;
196                 s1 = md->params[p].regoff;
197                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
198                         if (!md->params[p].inmemory) {           /* register arguments    */
199                                 s2 = rd->argintregs[s1];
200                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
201                                         M_INTMOVE(s2, var->regoff);
202                                 } else {                             /* reg arg -> spilled    */
203                                         M_LST(s2, REG_SP, var->regoff * 8);
204                                 }
205
206                         } else {                                 /* stack arguments       */
207                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
208                                         M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
209                                 } else {                             /* stack arg -> spilled  */
210                                         var->regoff = parentargs_base + s1;
211                                 }
212                         }
213
214                 } else {                                     /* floating args         */
215                         if (!md->params[p].inmemory) {           /* register arguments    */
216                                 s2 = rd->argfltregs[s1];
217                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
218                                         M_TFLTMOVE(var->type, s2, var->regoff);
219                                 } else {                                         /* reg arg -> spilled    */
220                                         M_DST(s2, REG_SP, var->regoff * 8);
221                                 }
222
223                         } else {                                 /* stack arguments       */
224                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
225                                         M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
226                                 } else {                             /* stack-arg -> spilled  */
227                                         var->regoff = parentargs_base + s1;
228                                 }
229                         }
230                 }
231         } /* end for */
232
233         /* call monitorenter function */
234
235 #if defined(USE_THREADS)
236         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
237                 /* stack offset for monitor argument */
238
239                 s1 = rd->memuse;
240
241                 if (runverbose) {
242                         M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
243
244                         for (p = 0; p < INT_ARG_CNT; p++)
245                                 M_LST(rd->argintregs[p], REG_SP, p * 8);
246
247                         for (p = 0; p < FLT_ARG_CNT; p++)
248                                 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
249
250                         s1 += INT_ARG_CNT + FLT_ARG_CNT;
251                 }
252
253                 /* decide which monitor enter function to call */
254
255                 if (m->flags & ACC_STATIC) {
256                         p = dseg_addaddress(cd, m->class);
257                         M_ALD(REG_ITMP1, REG_PV, p);
258                         M_AST(REG_ITMP1, REG_SP, s1 * 8);
259                         p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
260                         M_ALD(REG_ITMP3, REG_PV, p);
261                         M_JSR(REG_RA, REG_ITMP3);
262                         M_INTMOVE(REG_ITMP1, rd->argintregs[0]); /* branch delay */
263
264                 } else {
265                         M_BEQZ(rd->argintregs[0], 0);
266                         codegen_addxnullrefs(cd, mcodeptr);
267                         p = dseg_addaddress(cd, BUILTIN_monitorenter);
268                         M_ALD(REG_ITMP3, REG_PV, p);
269                         M_JSR(REG_RA, REG_ITMP3);
270                         M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* br delay */
271                 }
272
273                 if (runverbose) {
274                         for (p = 0; p < INT_ARG_CNT; p++)
275                                 M_LLD(rd->argintregs[p], REG_SP, p * 8);
276
277                         for (p = 0; p < FLT_ARG_CNT; p++)
278                                 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
279
280
281                         M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
282                 }
283         }
284 #endif
285
286         /* copy argument registers to stack and call trace function */
287
288         if (runverbose) {
289                 M_LDA(REG_SP, REG_SP, -(2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
290                 M_AST(REG_RA, REG_SP, 1 * 8);
291
292                 /* save integer argument registers */
293
294                 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
295                         M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
296
297                 /* save and copy float arguments into integer registers */
298
299                 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
300                         t = md->paramtypes[p].type;
301
302                         if (IS_FLT_DBL_TYPE(t)) {
303                                 if (IS_2_WORD_TYPE(t)) {
304                                         M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
305                                         M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
306
307                                 } else {
308                                         M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
309                                         M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
310                                 }
311
312                         } else {
313                                 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
314                         }
315                 }
316
317                 /* save temporary registers for leaf methods */
318
319                 if (m->isleafmethod) {
320                         for (p = 0; p < INT_TMP_CNT; p++)
321                                 M_LST(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
322
323                         for (p = 0; p < FLT_TMP_CNT; p++)
324                                 M_DST(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
325                 }
326
327                 p = dseg_addaddress(cd, m);
328                 M_ALD(REG_ITMP1, REG_PV, p);
329                 M_AST(REG_ITMP1, REG_SP, 0 * 8);
330                 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
331                 M_ALD(REG_ITMP3, REG_PV, disp);
332                 M_JSR(REG_RA, REG_ITMP3);
333                 M_NOP;
334
335                 M_ALD(REG_RA, REG_SP, 1 * 8);
336
337                 /* restore integer argument registers */
338
339                 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
340                         M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
341
342                 /* restore float argument registers */
343
344                 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
345                         t = md->paramtypes[p].type;
346
347                         if (IS_FLT_DBL_TYPE(t)) {
348                                 if (IS_2_WORD_TYPE(t)) {
349                                         M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
350
351                                 } else {
352                                         M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
353                                 }
354
355                         } else {
356                                 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
357                         }
358                 }
359
360                 /* restore temporary registers for leaf methods */
361
362                 if (m->isleafmethod) {
363                         for (p = 0; p < INT_TMP_CNT; p++)
364                                 M_LLD(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
365
366                         for (p = 0; p < FLT_TMP_CNT; p++)
367                                 M_DLD(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
368                 }
369
370                 M_LDA(REG_SP, REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
371         }
372
373         }
374
375         /* end of header generation */
376
377         /* walk through all basic blocks */
378
379         for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
380
381                 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
382
383                 if (bptr->flags >= BBREACHED) {
384
385                         /* branch resolving */
386                         {
387                                 branchref *bref;
388                                 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
389                                         gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, 
390                                                                           bref->branchpos,
391                                                                           bptr->mpc);
392                                 }
393                         }
394
395                 /* copy interface registers to their destination */
396
397                 src = bptr->instack;
398                 len = bptr->indepth;
399                 MCODECHECK(64+len);
400 #ifdef LSRA
401                 if (opt_lsra) {
402                 while (src != NULL) {
403                         len--;
404                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
405                                         /*                              d = reg_of_var(m, src, REG_ITMP1); */
406                                         if (!(src->flags & INMEMORY))
407                                                 d= src->regoff;
408                                         else
409                                                 d=REG_ITMP1;
410                                         M_INTMOVE(REG_ITMP1, d);
411                                         store_reg_to_var_int(src, d);
412                                 }
413                                 src = src->prev;
414                         }
415                 } else {
416 #endif
417                 while (src != NULL) {
418                         len--;
419                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
420                                 d = reg_of_var(rd, src, REG_ITMP1);
421                                 M_INTMOVE(REG_ITMP1, d);
422                                 store_reg_to_var_int(src, d);
423
424                         } else {
425                                 d = reg_of_var(rd, src, REG_IFTMP);
426                                 if ((src->varkind != STACKVAR)) {
427                                         s2 = src->type;
428                                         if (IS_FLT_DBL_TYPE(s2)) {
429                                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
430                                                         s1 = rd->interfaces[len][s2].regoff;
431                                                         M_TFLTMOVE(s2, s1, d);
432
433                                                 } else {
434                                                         M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
435                                                 }
436                                                 store_reg_to_var_flt(src, d);
437
438                                         } else {
439                                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
440                                                         s1 = rd->interfaces[len][s2].regoff;
441                                                         M_INTMOVE(s1,d);
442
443                                                 } else {
444                                                         M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
445                                                 }
446                                                 store_reg_to_var_int(src, d);
447                                         }
448                                 }
449                         }
450                         src = src->prev;
451                 }
452 #ifdef LSRA
453                 }
454 #endif
455                 /* walk through all instructions */
456                 
457                 src = bptr->instack;
458                 len = bptr->icount;
459                 currentline = 0;
460
461                 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
462                         if (iptr->line != currentline) {
463                                 dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr);
464                                 currentline = iptr->line;
465                         }
466
467                         MCODECHECK(64);   /* an instruction usually needs < 64 words      */
468
469                         switch (iptr->opc) {
470
471                 case ICMD_NOP:        /* ...  ==> ...                                 */
472                         break;
473
474                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
475
476                         var_to_reg_int(s1, src, REG_ITMP1);
477                         M_BEQZ(s1, 0);
478                         codegen_addxnullrefs(cd, mcodeptr);
479                         M_NOP;
480                         break;
481
482                 /* constant operations ************************************************/
483
484                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
485                                       /* op1 = 0, val.i = constant                    */
486
487                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
488                         ICONST(d, iptr->val.i);
489                         store_reg_to_var_int(iptr->dst, d);
490                         break;
491
492                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
493                                       /* op1 = 0, val.l = constant                    */
494
495                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
496                         LCONST(d, iptr->val.l);
497                         store_reg_to_var_int(iptr->dst, d);
498                         break;
499
500                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
501                                       /* op1 = 0, val.f = constant                    */
502
503                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
504                         disp = dseg_addfloat(cd, iptr->val.f);
505                         M_FLD(d, REG_PV, disp);
506                         store_reg_to_var_flt(iptr->dst, d);
507                         break;
508                         
509                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
510                                       /* op1 = 0, val.d = constant                    */
511
512                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
513                         disp = dseg_adddouble(cd, iptr->val.d);
514                         M_DLD(d, REG_PV, disp);
515                         store_reg_to_var_flt (iptr->dst, d);
516                         break;
517
518                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
519                                       /* op1 = 0, val.a = constant                    */
520
521                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
522
523                         if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
524                                 disp = dseg_addaddress(cd, iptr->val.a);
525
526                                 codegen_addpatchref(cd, mcodeptr,
527                                                                         PATCHER_aconst,
528                                                                         (unresolved_class *) iptr->target, disp);
529
530                                 if (opt_showdisassemble) {
531                                         M_NOP; M_NOP;
532                                 }
533
534                                 M_ALD(d, REG_PV, disp);
535
536                         } else {
537                                 if (iptr->val.a == NULL) {
538                                         M_INTMOVE(REG_ZERO, d);
539                                 } else {
540                                         disp = dseg_addaddress(cd, iptr->val.a);
541                                         M_ALD(d, REG_PV, disp);
542                                 }
543                         }
544                         store_reg_to_var_int(iptr->dst, d);
545                         break;
546
547
548                 /* load/store operations **********************************************/
549
550                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
551                 case ICMD_LLOAD:      /* op1 = local variable                         */
552                 case ICMD_ALOAD:
553
554                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
555                         if ((iptr->dst->varkind == LOCALVAR) &&
556                             (iptr->dst->varnum == iptr->op1))
557                                 break;
558                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
559                         if (var->flags & INMEMORY) {
560                                 M_LLD(d, REG_SP, 8 * var->regoff);
561                         } else {
562                                 M_INTMOVE(var->regoff,d);
563                         }
564                         store_reg_to_var_int(iptr->dst, d);
565                         break;
566
567                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
568                 case ICMD_DLOAD:      /* op1 = local variable                         */
569
570                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
571                         if ((iptr->dst->varkind == LOCALVAR) &&
572                             (iptr->dst->varnum == iptr->op1))
573                                 break;
574                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
575                         {
576                                 int t2 = ((iptr->opc == ICMD_FLOAD) ? TYPE_FLT : TYPE_DBL);
577                                 if (var->flags & INMEMORY) {
578                                         M_CCFLD(var->type, t2, d, REG_SP, 8 * var->regoff);
579                                 } else {
580                                         M_CCFLTMOVE(var->type, t2, var->regoff, d);
581                                 }
582                         }
583                         store_reg_to_var_flt(iptr->dst, d);
584                         break;
585
586
587                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
588                 case ICMD_LSTORE:     /* op1 = local variable                         */
589                 case ICMD_ASTORE:
590
591                         if ((src->varkind == LOCALVAR) &&
592                             (src->varnum == iptr->op1))
593                                 break;
594                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
595                         if (var->flags & INMEMORY) {
596                                 var_to_reg_int(s1, src, REG_ITMP1);
597                                 M_LST(s1, REG_SP, 8 * var->regoff);
598
599                         } else {
600                                 var_to_reg_int(s1, src, var->regoff);
601                                 M_INTMOVE(s1, var->regoff);
602                         }
603                         break;
604
605                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
606                 case ICMD_DSTORE:     /* op1 = local variable                         */
607
608                         if ((src->varkind == LOCALVAR) &&
609                             (src->varnum == iptr->op1))
610                                 break;
611                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
612                         {
613                                 int t1 = ((iptr->opc == ICMD_FSTORE) ? TYPE_FLT : TYPE_DBL);
614                                 if (var->flags & INMEMORY) {
615                                         var_to_reg_flt(s1, src, REG_FTMP1);
616                                         M_CCFST(t1, var->type, s1, REG_SP, 8 * var->regoff);
617
618                                 } else {
619                                         var_to_reg_flt(s1, src, var->regoff);
620                                         M_CCFLTMOVE(t1, var->type, s1, var->regoff);
621                                 }
622                         }
623                         break;
624
625
626                 /* pop/dup/swap operations ********************************************/
627
628                 /* attention: double and longs are only one entry in CACAO ICMDs      */
629
630                 case ICMD_POP:        /* ..., value  ==> ...                          */
631                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
632                         break;
633
634                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
635                         M_COPY(src, iptr->dst);
636                         break;
637
638                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
639
640                         M_COPY(src,       iptr->dst);
641                         M_COPY(src->prev, iptr->dst->prev);
642                         M_COPY(iptr->dst, iptr->dst->prev->prev);
643                         break;
644
645                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
646
647                         M_COPY(src,             iptr->dst);
648                         M_COPY(src->prev,       iptr->dst->prev);
649                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
650                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
651                         break;
652
653                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
654
655                         M_COPY(src,       iptr->dst);
656                         M_COPY(src->prev, iptr->dst->prev);
657                         break;
658
659                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
660
661                         M_COPY(src,             iptr->dst);
662                         M_COPY(src->prev,       iptr->dst->prev);
663                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
664                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
665                         M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
666                         break;
667
668                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
669
670                         M_COPY(src,                   iptr->dst);
671                         M_COPY(src->prev,             iptr->dst->prev);
672                         M_COPY(src->prev->prev,       iptr->dst->prev->prev);
673                         M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
674                         M_COPY(iptr->dst,             iptr->dst->prev->prev->prev->prev);
675                         M_COPY(iptr->dst->prev,       iptr->dst->prev->prev->prev->prev->prev);
676                         break;
677
678                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
679
680                         M_COPY(src,       iptr->dst->prev);
681                         M_COPY(src->prev, iptr->dst);
682                         break;
683
684
685                 /* integer operations *************************************************/
686
687                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
688
689                         var_to_reg_int(s1, src, REG_ITMP1); 
690                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
691                         M_ISUB(REG_ZERO, s1, d);
692                         store_reg_to_var_int(iptr->dst, d);
693                         break;
694
695                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
696
697                         var_to_reg_int(s1, src, REG_ITMP1);
698                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
699                         M_LSUB(REG_ZERO, s1, d);
700                         store_reg_to_var_int(iptr->dst, d);
701                         break;
702
703                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
704
705                         var_to_reg_int(s1, src, REG_ITMP1);
706                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
707                         M_INTMOVE(s1, d);
708                         store_reg_to_var_int(iptr->dst, d);
709                         break;
710
711                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
712
713                         var_to_reg_int(s1, src, REG_ITMP1);
714                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
715                         M_ISLL_IMM(s1, 0, d );
716                         store_reg_to_var_int(iptr->dst, d);
717                         break;
718
719                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
720
721                         var_to_reg_int(s1, src, REG_ITMP1);
722                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
723                         M_LSLL_IMM(s1, 56, d);
724                         M_LSRA_IMM( d, 56, d);
725                         store_reg_to_var_int(iptr->dst, d);
726                         break;
727
728                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
729
730                         var_to_reg_int(s1, src, REG_ITMP1);
731                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
732             M_CZEXT(s1, d);
733                         store_reg_to_var_int(iptr->dst, d);
734                         break;
735
736                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
737
738                         var_to_reg_int(s1, src, REG_ITMP1);
739                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
740                         M_LSLL_IMM(s1, 48, d);
741                         M_LSRA_IMM( d, 48, d);
742                         store_reg_to_var_int(iptr->dst, d);
743                         break;
744
745
746                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
747
748                         var_to_reg_int(s1, src->prev, REG_ITMP1);
749                         var_to_reg_int(s2, src, REG_ITMP2);
750                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
751                         M_IADD(s1, s2, d);
752                         store_reg_to_var_int(iptr->dst, d);
753                         break;
754
755                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
756                                       /* val.i = constant                             */
757
758                         var_to_reg_int(s1, src, REG_ITMP1);
759                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
760                         if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
761                                 M_IADD_IMM(s1, iptr->val.i, d);
762                         } else {
763                                 ICONST(REG_ITMP2, iptr->val.i);
764                                 M_IADD(s1, REG_ITMP2, d);
765                         }
766                         store_reg_to_var_int(iptr->dst, d);
767                         break;
768
769                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
770
771                         var_to_reg_int(s1, src->prev, REG_ITMP1);
772                         var_to_reg_int(s2, src, REG_ITMP2);
773                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
774                         M_LADD(s1, s2, d);
775                         store_reg_to_var_int(iptr->dst, d);
776                         break;
777
778                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
779                                       /* val.l = constant                             */
780
781                         var_to_reg_int(s1, src, REG_ITMP1);
782                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
783                         if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
784                                 M_LADD_IMM(s1, iptr->val.l, d);
785                         } else {
786                                 LCONST(REG_ITMP2, iptr->val.l);
787                                 M_LADD(s1, REG_ITMP2, d);
788                         }
789                         store_reg_to_var_int(iptr->dst, d);
790                         break;
791
792                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
793
794                         var_to_reg_int(s1, src->prev, REG_ITMP1);
795                         var_to_reg_int(s2, src, REG_ITMP2);
796                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
797                         M_ISUB(s1, s2, d);
798                         store_reg_to_var_int(iptr->dst, d);
799                         break;
800
801                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
802                                       /* val.i = constant                             */
803
804                         var_to_reg_int(s1, src, REG_ITMP1);
805                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
806                         if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
807                                 M_IADD_IMM(s1, -iptr->val.i, d);
808                         } else {
809                                 ICONST(REG_ITMP2, iptr->val.i);
810                                 M_ISUB(s1, REG_ITMP2, d);
811                         }
812                         store_reg_to_var_int(iptr->dst, d);
813                         break;
814
815                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
816
817                         var_to_reg_int(s1, src->prev, REG_ITMP1);
818                         var_to_reg_int(s2, src, REG_ITMP2);
819                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
820                         M_LSUB(s1, s2, d);
821                         store_reg_to_var_int(iptr->dst, d);
822                         break;
823
824                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
825                                       /* val.l = constant                             */
826
827                         var_to_reg_int(s1, src, REG_ITMP1);
828                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
829                         if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
830                                 M_LADD_IMM(s1, -iptr->val.l, d);
831                         } else {
832                                 LCONST(REG_ITMP2, iptr->val.l);
833                                 M_LSUB(s1, REG_ITMP2, d);
834                         }
835                         store_reg_to_var_int(iptr->dst, d);
836                         break;
837
838                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
839
840                         var_to_reg_int(s1, src->prev, REG_ITMP1);
841                         var_to_reg_int(s2, src, REG_ITMP2);
842                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
843                         M_IMUL(s1, s2);
844                         M_MFLO(d);
845                         M_NOP;
846                         M_NOP;
847                         store_reg_to_var_int(iptr->dst, d);
848                         break;
849
850                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
851                                       /* val.i = constant                             */
852
853                         var_to_reg_int(s1, src, REG_ITMP1);
854                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
855                         ICONST(REG_ITMP2, iptr->val.i);
856                         M_IMUL(s1, REG_ITMP2);
857                         M_MFLO(d);
858                         M_NOP;
859                         M_NOP;
860                         store_reg_to_var_int(iptr->dst, d);
861                         break;
862
863                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
864
865                         var_to_reg_int(s1, src->prev, REG_ITMP1);
866                         var_to_reg_int(s2, src, REG_ITMP2);
867                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
868                         M_LMUL(s1, s2);
869                         M_MFLO(d);
870                         M_NOP;
871                         M_NOP;
872                         store_reg_to_var_int(iptr->dst, d);
873                         break;
874
875                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
876                                       /* val.l = constant                             */
877
878                         var_to_reg_int(s1, src, REG_ITMP1);
879                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
880                         LCONST(REG_ITMP2, iptr->val.l);
881                         M_LMUL(s1, REG_ITMP2);
882                         M_MFLO(d);
883                         M_NOP;
884                         M_NOP;
885                         store_reg_to_var_int(iptr->dst, d);
886                         break;
887
888                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
889
890                         var_to_reg_int(s1, src->prev, REG_ITMP1);
891                         var_to_reg_int(s2, src, REG_ITMP2);
892                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
893                         gen_div_check(s2);
894                         M_IDIV(s1, s2);
895                         M_MFLO(d);
896                         M_NOP;
897                         M_NOP;
898                         store_reg_to_var_int(iptr->dst, d);
899                         break;
900
901                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
902
903                         var_to_reg_int(s1, src->prev, REG_ITMP1);
904                         var_to_reg_int(s2, src, REG_ITMP2);
905                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
906                         gen_div_check(s2);
907                         M_LDIV(s1, s2);
908                         M_MFLO(d);
909                         M_NOP;
910                         M_NOP;
911                         store_reg_to_var_int(iptr->dst, d);
912                         break;
913
914                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
915
916                         var_to_reg_int(s1, src->prev, REG_ITMP1);
917                         var_to_reg_int(s2, src, REG_ITMP2);
918                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
919                         gen_div_check(s2);
920                         M_IDIV(s1, s2);
921                         M_MFHI(d);
922                         M_NOP;
923                         M_NOP;
924                         store_reg_to_var_int(iptr->dst, d);
925                         break;
926
927                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
928
929                         var_to_reg_int(s1, src->prev, REG_ITMP1);
930                         var_to_reg_int(s2, src, REG_ITMP2);
931                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
932                         gen_div_check(s2);
933                         M_LDIV(s1, s2);
934                         M_MFHI(d);
935                         M_NOP;
936                         M_NOP;
937                         store_reg_to_var_int(iptr->dst, d);
938                         break;
939
940                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
941                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
942                                       
943                         var_to_reg_int(s1, src, REG_ITMP1);
944                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
945                         M_LSRA_IMM(s1, 63, REG_ITMP2);
946                         M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
947                         M_LADD(s1, REG_ITMP2, REG_ITMP2);
948                         M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
949                         store_reg_to_var_int(iptr->dst, d);
950                         break;
951
952                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
953
954                         var_to_reg_int(s1, src->prev, REG_ITMP1);
955                         var_to_reg_int(s2, src, REG_ITMP2);
956                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
957                         M_ISLL(s1, s2, d);
958                         store_reg_to_var_int(iptr->dst, d);
959                         break;
960
961                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
962                                       /* val.i = constant                             */
963
964                         var_to_reg_int(s1, src, REG_ITMP1);
965                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
966                         M_ISLL_IMM(s1, iptr->val.i, d);
967                         store_reg_to_var_int(iptr->dst, d);
968                         break;
969
970                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
971
972                         var_to_reg_int(s1, src->prev, REG_ITMP1);
973                         var_to_reg_int(s2, src, REG_ITMP2);
974                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
975                         M_ISRA(s1, s2, d);
976                         store_reg_to_var_int(iptr->dst, d);
977                         break;
978
979                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
980                                       /* val.i = constant                             */
981
982                         var_to_reg_int(s1, src, REG_ITMP1);
983                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
984                         M_ISRA_IMM(s1, iptr->val.i, d);
985                         store_reg_to_var_int(iptr->dst, d);
986                         break;
987
988                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
989
990                         var_to_reg_int(s1, src->prev, REG_ITMP1);
991                         var_to_reg_int(s2, src, REG_ITMP2);
992                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
993                         M_ISRL(s1, s2, d);
994                         store_reg_to_var_int(iptr->dst, d);
995                         break;
996
997                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
998                                       /* val.i = constant                             */
999
1000                         var_to_reg_int(s1, src, REG_ITMP1);
1001                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1002                         M_ISRL_IMM(s1, iptr->val.i, d);
1003                         store_reg_to_var_int(iptr->dst, d);
1004                         break;
1005
1006                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1007
1008                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1009                         var_to_reg_int(s2, src, REG_ITMP2);
1010                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1011                         M_LSLL(s1, s2, d);
1012                         store_reg_to_var_int(iptr->dst, d);
1013                         break;
1014
1015                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1016                                       /* val.i = constant                             */
1017
1018                         var_to_reg_int(s1, src, REG_ITMP1);
1019                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1020                         M_LSLL_IMM(s1, iptr->val.i, d);
1021                         store_reg_to_var_int(iptr->dst, d);
1022                         break;
1023
1024                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1025
1026                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1027                         var_to_reg_int(s2, src, REG_ITMP2);
1028                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1029                         M_LSRA(s1, s2, d);
1030                         store_reg_to_var_int(iptr->dst, d);
1031                         break;
1032
1033                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1034                                       /* val.i = constant                             */
1035
1036                         var_to_reg_int(s1, src, REG_ITMP1);
1037                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1038                         M_LSRA_IMM(s1, iptr->val.i, d);
1039                         store_reg_to_var_int(iptr->dst, d);
1040                         break;
1041
1042                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1043
1044                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1045                         var_to_reg_int(s2, src, REG_ITMP2);
1046                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1047                         M_LSRL(s1, s2, d);
1048                         store_reg_to_var_int(iptr->dst, d);
1049                         break;
1050
1051                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1052                                       /* val.i = constant                             */
1053
1054                         var_to_reg_int(s1, src, REG_ITMP1);
1055                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1056                         M_LSRL_IMM(s1, iptr->val.i, d);
1057                         store_reg_to_var_int(iptr->dst, d);
1058                         break;
1059
1060                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1061                 case ICMD_LAND:
1062
1063                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1064                         var_to_reg_int(s2, src, REG_ITMP2);
1065                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1066                         M_AND(s1, s2, d);
1067                         store_reg_to_var_int(iptr->dst, d);
1068                         break;
1069
1070                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1071                                       /* val.i = constant                             */
1072
1073                         var_to_reg_int(s1, src, REG_ITMP1);
1074                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1075                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1076                                 M_AND_IMM(s1, iptr->val.i, d);
1077                         } else {
1078                                 ICONST(REG_ITMP2, iptr->val.i);
1079                                 M_AND(s1, REG_ITMP2, d);
1080                         }
1081                         store_reg_to_var_int(iptr->dst, d);
1082                         break;
1083
1084                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1085                                       /* val.i = constant                             */
1086
1087                         var_to_reg_int(s1, src, REG_ITMP1);
1088                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1089                         if (s1 == d) {
1090                                 M_MOV(s1, REG_ITMP1);
1091                                 s1 = REG_ITMP1;
1092                         }
1093                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1094                                 M_AND_IMM(s1, iptr->val.i, d);
1095                                 M_BGEZ(s1, 4);
1096                                 M_NOP;
1097                                 M_ISUB(REG_ZERO, s1, d);
1098                                 M_AND_IMM(d, iptr->val.i, d);
1099                         } else {
1100                                 ICONST(REG_ITMP2, iptr->val.i);
1101                                 M_AND(s1, REG_ITMP2, d);
1102                                 M_BGEZ(s1, 4);
1103                                 M_NOP;
1104                                 M_ISUB(REG_ZERO, s1, d);
1105                                 M_AND(d, REG_ITMP2, d);
1106                         }
1107                         M_ISUB(REG_ZERO, d, d);
1108                         store_reg_to_var_int(iptr->dst, d);
1109                         break;
1110
1111                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1112                                       /* val.l = constant                             */
1113
1114                         var_to_reg_int(s1, src, REG_ITMP1);
1115                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1116                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1117                                 M_AND_IMM(s1, iptr->val.l, d);
1118                         } else {
1119                                 LCONST(REG_ITMP2, iptr->val.l);
1120                                 M_AND(s1, REG_ITMP2, d);
1121                         }
1122                         store_reg_to_var_int(iptr->dst, d);
1123                         break;
1124
1125                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1126                                       /* val.l = constant                             */
1127
1128                         var_to_reg_int(s1, src, REG_ITMP1);
1129                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1130                         if (s1 == d) {
1131                                 M_MOV(s1, REG_ITMP1);
1132                                 s1 = REG_ITMP1;
1133                         }
1134                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1135                                 M_AND_IMM(s1, iptr->val.l, d);
1136                                 M_BGEZ(s1, 4);
1137                                 M_NOP;
1138                                 M_LSUB(REG_ZERO, s1, d);
1139                                 M_AND_IMM(d, iptr->val.l, d);
1140                         } else {
1141                                 LCONST(REG_ITMP2, iptr->val.l);
1142                                 M_AND(s1, REG_ITMP2, d);
1143                                 M_BGEZ(s1, 4);
1144                                 M_NOP;
1145                                 M_LSUB(REG_ZERO, s1, d);
1146                                 M_AND(d, REG_ITMP2, d);
1147                         }
1148                         M_LSUB(REG_ZERO, d, d);
1149                         store_reg_to_var_int(iptr->dst, d);
1150                         break;
1151
1152                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1153                 case ICMD_LOR:
1154
1155                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1156                         var_to_reg_int(s2, src, REG_ITMP2);
1157                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1158                         M_OR(s1,s2, d);
1159                         store_reg_to_var_int(iptr->dst, d);
1160                         break;
1161
1162                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1163                                       /* val.i = constant                             */
1164
1165                         var_to_reg_int(s1, src, REG_ITMP1);
1166                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1167                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1168                                 M_OR_IMM(s1, iptr->val.i, d);
1169                         } else {
1170                                 ICONST(REG_ITMP2, iptr->val.i);
1171                                 M_OR(s1, REG_ITMP2, d);
1172                         }
1173                         store_reg_to_var_int(iptr->dst, d);
1174                         break;
1175
1176                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1177                                       /* val.l = constant                             */
1178
1179                         var_to_reg_int(s1, src, REG_ITMP1);
1180                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1181                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1182                                 M_OR_IMM(s1, iptr->val.l, d);
1183                         } else {
1184                                 LCONST(REG_ITMP2, iptr->val.l);
1185                                 M_OR(s1, REG_ITMP2, d);
1186                         }
1187                         store_reg_to_var_int(iptr->dst, d);
1188                         break;
1189
1190                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1191                 case ICMD_LXOR:
1192
1193                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1194                         var_to_reg_int(s2, src, REG_ITMP2);
1195                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1196                         M_XOR(s1, s2, d);
1197                         store_reg_to_var_int(iptr->dst, d);
1198                         break;
1199
1200                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1201                                       /* val.i = constant                             */
1202
1203                         var_to_reg_int(s1, src, REG_ITMP1);
1204                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1205                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1206                                 M_XOR_IMM(s1, iptr->val.i, d);
1207                         } else {
1208                                 ICONST(REG_ITMP2, iptr->val.i);
1209                                 M_XOR(s1, REG_ITMP2, d);
1210                         }
1211                         store_reg_to_var_int(iptr->dst, d);
1212                         break;
1213
1214                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1215                                       /* val.l = constant                             */
1216
1217                         var_to_reg_int(s1, src, REG_ITMP1);
1218                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1219                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1220                                 M_XOR_IMM(s1, iptr->val.l, d);
1221                         } else {
1222                                 LCONST(REG_ITMP2, iptr->val.l);
1223                                 M_XOR(s1, REG_ITMP2, d);
1224                         }
1225                         store_reg_to_var_int(iptr->dst, d);
1226                         break;
1227
1228
1229                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1230
1231                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1232                         var_to_reg_int(s2, src, REG_ITMP2);
1233                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1234                         M_CMPLT(s1, s2, REG_ITMP3);
1235                         M_CMPLT(s2, s1, REG_ITMP1);
1236                         M_LSUB(REG_ITMP1, REG_ITMP3, d);
1237                         store_reg_to_var_int(iptr->dst, d);
1238                         break;
1239
1240
1241                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
1242                                       /* op1 = variable, val.i = constant             */
1243
1244                         var = &(rd->locals[iptr->op1][TYPE_INT]);
1245                         if (var->flags & INMEMORY) {
1246                                 s1 = REG_ITMP1;
1247                                 M_LLD(s1, REG_SP, var->regoff * 8);
1248                         } else
1249                                 s1 = var->regoff;
1250                         M_IADD_IMM(s1, iptr->val.i, s1);
1251                         if (var->flags & INMEMORY)
1252                                 M_LST(s1, REG_SP, var->regoff * 8);
1253                         break;
1254
1255
1256                 /* floating operations ************************************************/
1257
1258                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1259
1260                         var_to_reg_flt(s1, src, REG_FTMP1);
1261                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1262                         M_FNEG(s1, d);
1263                         store_reg_to_var_flt(iptr->dst, d);
1264                         break;
1265
1266                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1267
1268                         var_to_reg_flt(s1, src, REG_FTMP1);
1269                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1270                         M_DNEG(s1, d);
1271                         store_reg_to_var_flt(iptr->dst, d);
1272                         break;
1273
1274                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1275
1276                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1277                         var_to_reg_flt(s2, src, REG_FTMP2);
1278                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1279                         M_FADD(s1, s2, d);
1280                         store_reg_to_var_flt(iptr->dst, d);
1281                         break;
1282
1283                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1284
1285                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1286                         var_to_reg_flt(s2, src, REG_FTMP2);
1287                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1288                         M_DADD(s1, s2, d);
1289                         store_reg_to_var_flt(iptr->dst, d);
1290                         break;
1291
1292                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1293
1294                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1295                         var_to_reg_flt(s2, src, REG_FTMP2);
1296                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1297                         M_FSUB(s1, s2, d);
1298                         store_reg_to_var_flt(iptr->dst, d);
1299                         break;
1300
1301                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1302
1303                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1304                         var_to_reg_flt(s2, src, REG_FTMP2);
1305                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1306                         M_DSUB(s1, s2, d);
1307                         store_reg_to_var_flt(iptr->dst, d);
1308                         break;
1309
1310                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1311
1312                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1313                         var_to_reg_flt(s2, src, REG_FTMP2);
1314                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1315                         M_FMUL(s1, s2, d);
1316                         store_reg_to_var_flt(iptr->dst, d);
1317                         break;
1318
1319                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2      */
1320
1321                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1322                         var_to_reg_flt(s2, src, REG_FTMP2);
1323                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1324                         M_DMUL(s1, s2, d);
1325                         store_reg_to_var_flt(iptr->dst, d);
1326                         break;
1327
1328                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1329
1330                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1331                         var_to_reg_flt(s2, src, REG_FTMP2);
1332                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1333                         M_FDIV(s1, s2, d);
1334                         store_reg_to_var_flt(iptr->dst, d);
1335                         break;
1336
1337                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1338
1339                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1340                         var_to_reg_flt(s2, src, REG_FTMP2);
1341                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1342                         M_DDIV(s1, s2, d);
1343                         store_reg_to_var_flt(iptr->dst, d);
1344                         break;
1345
1346 #if 0           
1347                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1348
1349                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1350                         var_to_reg_flt(s2, src, REG_FTMP2);
1351                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1352                         M_FDIV(s1,s2, REG_FTMP3);
1353                         M_FLOORFL(REG_FTMP3, REG_FTMP3);
1354                         M_CVTLF(REG_FTMP3, REG_FTMP3);
1355                         M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1356                         M_FSUB(s1, REG_FTMP3, d);
1357                         store_reg_to_var_flt(iptr->dst, d);
1358                     break;
1359
1360                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1361
1362                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1363                         var_to_reg_flt(s2, src, REG_FTMP2);
1364                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1365                         M_DDIV(s1,s2, REG_FTMP3);
1366                         M_FLOORDL(REG_FTMP3, REG_FTMP3);
1367                         M_CVTLD(REG_FTMP3, REG_FTMP3);
1368                         M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1369                         M_DSUB(s1, REG_FTMP3, d);
1370                         store_reg_to_var_flt(iptr->dst, d);
1371                     break;
1372 #endif
1373
1374                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1375                 case ICMD_L2F:
1376                         var_to_reg_int(s1, src, REG_ITMP1);
1377                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1378                         M_MOVLD(s1, d);
1379                         M_CVTLF(d, d);
1380                         store_reg_to_var_flt(iptr->dst, d);
1381                         break;
1382
1383                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1384                 case ICMD_L2D:
1385                         var_to_reg_int(s1, src, REG_ITMP1);
1386                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1387                         M_MOVLD(s1, d);
1388                         M_CVTLD(d, d);
1389                         store_reg_to_var_flt(iptr->dst, d);
1390                         break;
1391                         
1392                 case ICMD_F2I:       /* ..., (float) value  ==> ..., (int) value      */
1393
1394                         var_to_reg_flt(s1, src, REG_FTMP1);
1395                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1396                         M_TRUNCFI(s1, REG_FTMP1);
1397                         M_MOVDI(REG_FTMP1, d);
1398                         M_NOP;
1399                         store_reg_to_var_int(iptr->dst, d);
1400                         break;
1401                 
1402                 case ICMD_D2I:       /* ..., (double) value  ==> ..., (int) value     */
1403
1404                         var_to_reg_flt(s1, src, REG_FTMP1);
1405                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1406                         M_TRUNCDI(s1, REG_FTMP1);
1407                         M_MOVDI(REG_FTMP1, d);
1408                         M_NOP;
1409                         store_reg_to_var_int(iptr->dst, d);
1410                         break;
1411                 
1412                 case ICMD_F2L:       /* ..., (float) value  ==> ..., (long) value     */
1413
1414                         var_to_reg_flt(s1, src, REG_FTMP1);
1415                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1416                         M_TRUNCFL(s1, REG_FTMP1);
1417                         M_MOVDL(REG_FTMP1, d);
1418                         M_NOP;
1419                         store_reg_to_var_int(iptr->dst, d);
1420                         break;
1421
1422                 case ICMD_D2L:       /* ..., (double) value  ==> ..., (long) value    */
1423
1424                         var_to_reg_flt(s1, src, REG_FTMP1);
1425                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1426                         M_TRUNCDL(s1, REG_FTMP1);
1427                         M_MOVDL(REG_FTMP1, d);
1428                         M_NOP;
1429                         store_reg_to_var_int(iptr->dst, d);
1430                         break;
1431
1432                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1433
1434                         var_to_reg_flt(s1, src, REG_FTMP1);
1435                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1436                         M_CVTFD(s1, d);
1437                         store_reg_to_var_flt(iptr->dst, d);
1438                         break;
1439                                         
1440                 case ICMD_D2F:       /* ..., value  ==> ..., (double) value           */
1441
1442                         var_to_reg_flt(s1, src, REG_FTMP1);
1443                         d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1444                         M_CVTDF(s1, d);
1445                         store_reg_to_var_flt(iptr->dst, d);
1446                         break;
1447                 
1448                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1449
1450                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1451                         var_to_reg_flt(s2, src, REG_FTMP2);
1452                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1453                         M_FCMPULEF(s1, s2);
1454                         M_FBT(3);
1455                         M_LADD_IMM(REG_ZERO, 1, d);
1456                         M_BR(4);
1457                         M_NOP;
1458                         M_FCMPEQF(s1, s2);
1459                         M_LSUB_IMM(REG_ZERO, 1, d);
1460                         M_CMOVT(REG_ZERO, d);
1461                         store_reg_to_var_int(iptr->dst, d);
1462                         break;
1463
1464                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1465
1466                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1467                         var_to_reg_flt(s2, src, REG_FTMP2);
1468                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1469                         M_FCMPULED(s1, s2);
1470                         M_FBT(3);
1471                         M_LADD_IMM(REG_ZERO, 1, d);
1472                         M_BR(4);
1473                         M_NOP;
1474                         M_FCMPEQD(s1, s2);
1475                         M_LSUB_IMM(REG_ZERO, 1, d);
1476                         M_CMOVT(REG_ZERO, d);
1477                         store_reg_to_var_int(iptr->dst, d);
1478                         break;
1479                         
1480                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1481
1482                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1483                         var_to_reg_flt(s2, src, REG_FTMP2);
1484                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1485                         M_FCMPOLTF(s1, s2);
1486                         M_FBF(3);
1487                         M_LSUB_IMM(REG_ZERO, 1, d);
1488                         M_BR(4);
1489                         M_NOP;
1490                         M_FCMPEQF(s1, s2);
1491                         M_LADD_IMM(REG_ZERO, 1, d);
1492                         M_CMOVT(REG_ZERO, d);
1493                         store_reg_to_var_int(iptr->dst, d);
1494                         break;
1495
1496                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1497
1498                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
1499                         var_to_reg_flt(s2, src, REG_FTMP2);
1500                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1501                         M_FCMPOLTD(s1, s2);
1502                         M_FBF(3);
1503                         M_LSUB_IMM(REG_ZERO, 1, d);
1504                         M_BR(4);
1505                         M_NOP;
1506                         M_FCMPEQD(s1, s2);
1507                         M_LADD_IMM(REG_ZERO, 1, d);
1508                         M_CMOVT(REG_ZERO, d);
1509                         store_reg_to_var_int(iptr->dst, d);
1510                         break;
1511
1512
1513                 /* memory operations **************************************************/
1514
1515                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1516
1517                         var_to_reg_int(s1, src, REG_ITMP1);
1518                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1519                         gen_nullptr_check(s1);
1520                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1521                         store_reg_to_var_int(iptr->dst, d);
1522                         break;
1523
1524                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1525
1526                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1527                         var_to_reg_int(s2, src, REG_ITMP2);
1528                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1529                         if (iptr->op1 == 0) {
1530                                 gen_nullptr_check(s1);
1531                                 gen_bound_check;
1532                         }
1533                         M_AADD(s2, s1, REG_ITMP3);
1534                         M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1535                         store_reg_to_var_int(iptr->dst, d);
1536                         break;
1537
1538                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1539
1540                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1541                         var_to_reg_int(s2, src, REG_ITMP2);
1542                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1543                         if (iptr->op1 == 0) {
1544                                 gen_nullptr_check(s1);
1545                                 gen_bound_check;
1546                         }
1547                         M_AADD(s2, s1, REG_ITMP3);
1548                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1549                         M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1550                         store_reg_to_var_int(iptr->dst, d);
1551                         break;                  
1552
1553                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1554
1555                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1556                         var_to_reg_int(s2, src, REG_ITMP2);
1557                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1558                         if (iptr->op1 == 0) {
1559                                 gen_nullptr_check(s1);
1560                                 gen_bound_check;
1561                         }
1562                         M_AADD(s2, s1, REG_ITMP3);
1563                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1564                         M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1565                         store_reg_to_var_int(iptr->dst, d);
1566                         break;
1567
1568                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1569
1570                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1571                         var_to_reg_int(s2, src, REG_ITMP2);
1572                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1573                         if (iptr->op1 == 0) {
1574                                 gen_nullptr_check(s1);
1575                                 gen_bound_check;
1576                         }
1577                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1578                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1579                         M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1580                         store_reg_to_var_int(iptr->dst, d);
1581                         break;
1582
1583                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1584
1585                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1586                         var_to_reg_int(s2, src, REG_ITMP2);
1587                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1588                         if (iptr->op1 == 0) {
1589                                 gen_nullptr_check(s1);
1590                                 gen_bound_check;
1591                         }
1592                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1593                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1594                         M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1595                         store_reg_to_var_int(iptr->dst, d);
1596                         break;
1597
1598                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1599
1600                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1601                         var_to_reg_int(s2, src, REG_ITMP2);
1602                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1603                         if (iptr->op1 == 0) {
1604                                 gen_nullptr_check(s1);
1605                                 gen_bound_check;
1606                         }
1607                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1608                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1609                         M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1610                         store_reg_to_var_flt(iptr->dst, d);
1611                         break;
1612
1613                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1614
1615                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1616                         var_to_reg_int(s2, src, REG_ITMP2);
1617                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1618                         if (iptr->op1 == 0) {
1619                                 gen_nullptr_check(s1);
1620                                 gen_bound_check;
1621                         }
1622                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1623                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1624                         M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1625                         store_reg_to_var_flt(iptr->dst, d);
1626                         break;
1627
1628                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1629
1630                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1631                         var_to_reg_int(s2, src, REG_ITMP2);
1632                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1633                         if (iptr->op1 == 0) {
1634                                 gen_nullptr_check(s1);
1635                                 gen_bound_check;
1636                         }
1637                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1638                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1639                         M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1640                         store_reg_to_var_int(iptr->dst, d);
1641                         break;
1642
1643
1644                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1645
1646                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1647                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1648                         if (iptr->op1 == 0) {
1649                                 gen_nullptr_check(s1);
1650                                 gen_bound_check;
1651                         }
1652                         M_AADD(s2, s1, REG_ITMP1);
1653                         var_to_reg_int(s3, src, REG_ITMP3);
1654                         M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1655                         break;
1656
1657                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1658                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1659
1660                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1661                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1662                         if (iptr->op1 == 0) {
1663                                 gen_nullptr_check(s1);
1664                                 gen_bound_check;
1665                         }
1666                         M_AADD(s2, s1, REG_ITMP1);
1667                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1668                         var_to_reg_int(s3, src, REG_ITMP3);
1669                         M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1670                         break;
1671
1672                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1673
1674                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1675                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1676                         if (iptr->op1 == 0) {
1677                                 gen_nullptr_check(s1);
1678                                 gen_bound_check;
1679                         }
1680                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1681                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1682                         var_to_reg_int(s3, src, REG_ITMP3);
1683                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1684                         break;
1685
1686                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1687
1688                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1689                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1690                         if (iptr->op1 == 0) {
1691                                 gen_nullptr_check(s1);
1692                                 gen_bound_check;
1693                         }
1694                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1695                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1696                         var_to_reg_int(s3, src, REG_ITMP3);
1697                         M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1698                         break;
1699
1700                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1701
1702                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1703                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1704                         if (iptr->op1 == 0) {
1705                                 gen_nullptr_check(s1);
1706                                 gen_bound_check;
1707                         }
1708                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1709                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1710                         var_to_reg_flt(s3, src, REG_FTMP1);
1711                         M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1712                         break;
1713
1714                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1715
1716                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1717                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1718                         if (iptr->op1 == 0) {
1719                                 gen_nullptr_check(s1);
1720                                 gen_bound_check;
1721                         }
1722                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1723                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1724                         var_to_reg_flt(s3, src, REG_FTMP1);
1725                         M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1726                         break;
1727
1728
1729                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1730
1731                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1732                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1733                         if (iptr->op1 == 0) {
1734                                 gen_nullptr_check(s1);
1735                                 gen_bound_check;
1736                         }
1737                         var_to_reg_int(s3, src, REG_ITMP3);
1738
1739                         M_MOV(s1, rd->argintregs[0]);
1740                         M_MOV(s3, rd->argintregs[1]);
1741                         disp = dseg_addaddress(cd, BUILTIN_canstore);
1742                         M_ALD(REG_ITMP3, REG_PV, disp);
1743                         M_JSR(REG_RA, REG_ITMP3);
1744                         M_NOP;
1745
1746                         M_BEQZ(REG_RESULT, 0);
1747                         codegen_addxstorerefs(cd, mcodeptr);
1748                         M_NOP;
1749
1750                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1751                         var_to_reg_int(s2, src->prev, REG_ITMP2);
1752                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1753                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1754                         var_to_reg_int(s3, src, REG_ITMP3);
1755                         M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1756                         break;
1757
1758
1759                 case ICMD_BASTORECONST:   /* ..., arrayref, index  ==> ...            */
1760
1761                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1762                         var_to_reg_int(s2, src, REG_ITMP2);
1763                         if (iptr->op1 == 0) {
1764                                 gen_nullptr_check(s1);
1765                                 gen_bound_check;
1766                         }
1767                         M_AADD(s2, s1, REG_ITMP1);
1768                         M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1769                         break;
1770
1771                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1772                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1773
1774                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1775                         var_to_reg_int(s2, src, REG_ITMP2);
1776                         if (iptr->op1 == 0) {
1777                                 gen_nullptr_check(s1);
1778                                 gen_bound_check;
1779                         }
1780                         M_AADD(s2, s1, REG_ITMP1);
1781                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1782                         M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1783                         break;
1784
1785                 case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
1786
1787                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1788                         var_to_reg_int(s2, src, REG_ITMP2);
1789                         if (iptr->op1 == 0) {
1790                                 gen_nullptr_check(s1);
1791                                 gen_bound_check;
1792                         }
1793                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1794                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1795                         M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1796                         break;
1797
1798                 case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
1799
1800                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1801                         var_to_reg_int(s2, src, REG_ITMP2);
1802                         if (iptr->op1 == 0) {
1803                                 gen_nullptr_check(s1);
1804                                 gen_bound_check;
1805                         }
1806                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1807                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1808                         M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1809                         break;
1810
1811                 case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
1812
1813                         var_to_reg_int(s1, src->prev, REG_ITMP1);
1814                         var_to_reg_int(s2, src, REG_ITMP2);
1815                         if (iptr->op1 == 0) {
1816                                 gen_nullptr_check(s1);
1817                                 gen_bound_check;
1818                         }
1819                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1820                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1821                         M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1822                         break;
1823
1824
1825                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1826                                       /* op1 = type, val.a = field address            */
1827
1828                         if (!iptr->val.a) {
1829                                 disp = dseg_addaddress(cd, NULL);
1830
1831                                 codegen_addpatchref(cd, mcodeptr,
1832                                                                         PATCHER_get_putstatic,
1833                                                                         (unresolved_field *) iptr->target, disp);
1834
1835                                 if (opt_showdisassemble) {
1836                                         M_NOP; M_NOP;
1837                                 }
1838
1839                         } else {
1840                                 fieldinfo *fi = iptr->val.a;
1841
1842                                 disp = dseg_addaddress(cd, &(fi->value));
1843
1844                                 if (!(fi->class->state & CLASS_INITIALIZED)) {
1845                                         codegen_addpatchref(cd, mcodeptr,
1846                                                                                 PATCHER_clinit, fi->class, 0);
1847
1848                                         if (opt_showdisassemble) {
1849                                                 M_NOP; M_NOP;
1850                                         }
1851                                 }
1852                         }
1853
1854                         M_ALD(REG_ITMP1, REG_PV, disp);
1855                         switch (iptr->op1) {
1856                         case TYPE_INT:
1857                                 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1858                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1859                                 store_reg_to_var_int(iptr->dst, d);
1860                                 break;
1861                         case TYPE_LNG:
1862                                 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1863                                 M_LLD_INTERN(d, REG_ITMP1, 0);
1864                                 store_reg_to_var_int(iptr->dst, d);
1865                                 break;
1866                         case TYPE_ADR:
1867                                 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1868                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1869                                 store_reg_to_var_int(iptr->dst, d);
1870                                 break;
1871                         case TYPE_FLT:
1872                                 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1873                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1874                                 store_reg_to_var_flt(iptr->dst, d);
1875                                 break;
1876                         case TYPE_DBL:                          
1877                                 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
1878                                 M_DLD_INTERN(d, REG_ITMP1, 0);
1879                                 store_reg_to_var_flt(iptr->dst, d);
1880                                 break;
1881                         }
1882                         break;
1883
1884                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1885                                       /* op1 = type, val.a = field address            */
1886
1887                         if (!iptr->val.a) {
1888                                 disp = dseg_addaddress(cd, NULL);
1889
1890                                 codegen_addpatchref(cd, mcodeptr,
1891                                                                         PATCHER_get_putstatic,
1892                                                                         (unresolved_field *) iptr->target, disp);
1893
1894                                 if (opt_showdisassemble) {
1895                                         M_NOP; M_NOP;
1896                                 }
1897
1898                         } else {
1899                                 fieldinfo *fi = iptr->val.a;
1900
1901                                 disp = dseg_addaddress(cd, &(fi->value));
1902
1903                                 if (!(fi->class->state & CLASS_INITIALIZED)) {
1904                                         codegen_addpatchref(cd, mcodeptr,
1905                                                                                 PATCHER_clinit, fi->class, 0);
1906
1907                                         if (opt_showdisassemble) {
1908                                                 M_NOP; M_NOP;
1909                                         }
1910                                 }
1911                         }
1912
1913                         M_ALD(REG_ITMP1, REG_PV, disp);
1914                         switch (iptr->op1) {
1915                         case TYPE_INT:
1916                                 var_to_reg_int(s2, src, REG_ITMP2);
1917                                 M_IST_INTERN(s2, REG_ITMP1, 0);
1918                                 break;
1919                         case TYPE_LNG:
1920                                 var_to_reg_int(s2, src, REG_ITMP2);
1921                                 M_LST_INTERN(s2, REG_ITMP1, 0);
1922                                 break;
1923                         case TYPE_ADR:
1924                                 var_to_reg_int(s2, src, REG_ITMP2);
1925                                 M_AST_INTERN(s2, REG_ITMP1, 0);
1926                                 break;
1927                         case TYPE_FLT:
1928                                 var_to_reg_flt(s2, src, REG_FTMP2);
1929                                 M_FST_INTERN(s2, REG_ITMP1, 0);
1930                                 break;
1931                         case TYPE_DBL:
1932                                 var_to_reg_flt(s2, src, REG_FTMP2);
1933                                 M_DST_INTERN(s2, REG_ITMP1, 0);
1934                                 break;
1935                         }
1936                         break;
1937
1938                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
1939                                           /* val = value (in current instruction)     */
1940                                           /* op1 = type, val.a = field address (in    */
1941                                           /* following NOP)                           */
1942
1943                         if (!iptr[1].val.a) {
1944                                 disp = dseg_addaddress(cd, NULL);
1945
1946                                 codegen_addpatchref(cd, mcodeptr,
1947                                                                         PATCHER_get_putstatic,
1948                                                                         (unresolved_field *) iptr[1].target, disp);
1949
1950                                 if (opt_showdisassemble) {
1951                                         M_NOP; M_NOP;
1952                                 }
1953
1954                         } else {
1955                                 fieldinfo *fi = iptr[1].val.a;
1956
1957                                 disp = dseg_addaddress(cd, &(fi->value));
1958
1959                                 if (!(fi->class->state & CLASS_INITIALIZED)) {
1960                                         codegen_addpatchref(cd, mcodeptr,
1961                                                                                 PATCHER_clinit, fi->class, 0);
1962
1963                                         if (opt_showdisassemble) {
1964                                                 M_NOP; M_NOP;
1965                                         }
1966                                 }
1967                         }
1968
1969                         M_ALD(REG_ITMP1, REG_PV, disp);
1970                         switch (iptr->op1) {
1971                         case TYPE_INT:
1972                                 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1973                                 break;
1974                         case TYPE_LNG:
1975                                 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
1976                                 break;
1977                         case TYPE_ADR:
1978                                 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1979                                 break;
1980                         case TYPE_FLT:
1981                                 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1982                                 break;
1983                         case TYPE_DBL:
1984                                 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1985                                 break;
1986                         }
1987                         break;
1988
1989
1990                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1991                                       /* op1 = type, val.i = field offset             */
1992
1993                         var_to_reg_int(s1, src, REG_ITMP1);
1994                         gen_nullptr_check(s1);
1995
1996                         if (!iptr->val.a) {
1997                                 codegen_addpatchref(cd, mcodeptr,
1998                                                                         PATCHER_get_putfield,
1999                                                                         (unresolved_field *) iptr->target, 0);
2000
2001                                 if (opt_showdisassemble) {
2002                                         M_NOP; M_NOP;
2003                                 }
2004
2005                                 a = 0;
2006
2007                         } else {
2008                                 a = ((fieldinfo *) (iptr->val.a))->offset;
2009                         }
2010
2011                         switch (iptr->op1) {
2012                         case TYPE_INT:
2013                                 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2014                                 M_ILD(d, s1, a);
2015                                 store_reg_to_var_int(iptr->dst, d);
2016                                 break;
2017                         case TYPE_LNG:
2018                                 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2019                                 M_LLD(d, s1, a);
2020                                 store_reg_to_var_int(iptr->dst, d);
2021                                 break;
2022                         case TYPE_ADR:
2023                                 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2024                                 M_ALD(d, s1, a);
2025                                 store_reg_to_var_int(iptr->dst, d);
2026                                 break;
2027                         case TYPE_FLT:
2028                                 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2029                                 M_FLD(d, s1, a);
2030                                 store_reg_to_var_flt(iptr->dst, d);
2031                                 break;
2032                         case TYPE_DBL:                          
2033                                 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2034                                 M_DLD(d, s1, a);
2035                                 store_reg_to_var_flt(iptr->dst, d);
2036                                 break;
2037                         }
2038                         break;
2039
2040                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2041                                       /* op1 = type, val.a = field address            */
2042
2043                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2044                         gen_nullptr_check(s1);
2045
2046                         if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2047                                 var_to_reg_int(s2, src, REG_ITMP2);
2048                         } else {
2049                                 var_to_reg_flt(s2, src, REG_FTMP2);
2050                         }
2051
2052                         if (!iptr->val.a) {
2053                                 codegen_addpatchref(cd, mcodeptr,
2054                                                                         PATCHER_get_putfield,
2055                                                                         (unresolved_field *) iptr->target, 0);
2056
2057                                 if (opt_showdisassemble) {
2058                                         M_NOP; M_NOP;
2059                                 }
2060
2061                                 a = 0;
2062
2063                         } else {
2064                                 a = ((fieldinfo *) (iptr->val.a))->offset;
2065                         }
2066
2067                         switch (iptr->op1) {
2068                         case TYPE_INT:
2069                                 M_IST(s2, s1, a);
2070                                 break;
2071                         case TYPE_LNG:
2072                                 M_LST(s2, s1, a);
2073                                 break;
2074                         case TYPE_ADR:
2075                                 M_AST(s2, s1, a);
2076                                 break;
2077                         case TYPE_FLT:
2078                                 M_FST(s2, s1, a);
2079                                 break;
2080                         case TYPE_DBL:
2081                                 M_DST(s2, s1, a);
2082                                 break;
2083                         }
2084                         break;
2085
2086                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2087                                           /* val = value (in current instruction)     */
2088                                           /* op1 = type, val.a = field address (in    */
2089                                           /* following NOP)                           */
2090
2091                         var_to_reg_int(s1, src, REG_ITMP1);
2092                         gen_nullptr_check(s1);
2093
2094                         if (!iptr[1].val.a) {
2095                                 codegen_addpatchref(cd, mcodeptr,
2096                                                                         PATCHER_get_putfield,
2097                                                                         (unresolved_field *) iptr[1].target, 0);
2098
2099                                 if (opt_showdisassemble) {
2100                                         M_NOP; M_NOP;
2101                                 }
2102
2103                                 a = 0;
2104
2105                         } else {
2106                                 a = ((fieldinfo *) (iptr[1].val.a))->offset;
2107                         }
2108
2109                         switch (iptr[1].op1) {
2110                         case TYPE_INT:
2111                                 M_IST(REG_ZERO, s1, a);
2112                                 break;
2113                         case TYPE_LNG:
2114                                 M_LST(REG_ZERO, s1, a);
2115                                 break;
2116                         case TYPE_ADR:
2117                                 M_AST(REG_ZERO, s1, a);
2118                                 break;
2119                         case TYPE_FLT:
2120                                 M_FST(REG_ZERO, s1, a);
2121                                 break;
2122                         case TYPE_DBL:
2123                                 M_DST(REG_ZERO, s1, a);
2124                                 break;
2125                         }
2126                         break;
2127
2128
2129                 /* branch operations **************************************************/
2130
2131                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2132
2133                         var_to_reg_int(s1, src, REG_ITMP1);
2134                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2135                         
2136 #ifdef ENABLE_VERIFIER
2137                         if (iptr->val.a) {
2138                                 codegen_addpatchref(cd, mcodeptr,
2139                                                                         PATCHER_athrow_areturn,
2140                                                                         (unresolved_class *) iptr->val.a, 0);
2141
2142                                 if (opt_showdisassemble) {
2143                                         M_NOP; M_NOP;
2144                                 }
2145                         }
2146 #endif /* ENABLE_VERIFIER */
2147
2148                         disp = dseg_addaddress(cd, asm_handle_exception);
2149                         M_ALD(REG_ITMP2, REG_PV, disp);
2150                         M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2151                         M_NOP;
2152                         M_NOP;              /* nop ensures that XPC is less than the end */
2153                                             /* of basic block                            */
2154                         ALIGNCODENOP;
2155                         break;
2156
2157                 case ICMD_GOTO:         /* ... ==> ...                                */
2158                                         /* op1 = target JavaVM pc                     */
2159                         M_BR(0);
2160                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2161                         M_NOP;
2162                         ALIGNCODENOP;
2163                         break;
2164
2165                 case ICMD_JSR:          /* ... ==> ...                                */
2166                                         /* op1 = target JavaVM pc                     */
2167
2168                         dseg_addtarget(cd, (basicblock *) iptr->target);
2169                         M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2170                         M_JSR(REG_ITMP1, REG_ITMP1);        /* REG_ITMP1 = return address */
2171                         M_NOP;
2172                         break;
2173                         
2174                 case ICMD_RET:          /* ... ==> ...                                */
2175                                         /* op1 = local variable                       */
2176                         var = &(rd->locals[iptr->op1][TYPE_ADR]);
2177                         if (var->flags & INMEMORY) {
2178                                 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2179                                 M_RET(REG_ITMP1);
2180                         } else
2181                                 M_RET(var->regoff);
2182                         M_NOP;
2183                         ALIGNCODENOP;
2184                         break;
2185
2186                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2187                                         /* op1 = target JavaVM pc                     */
2188
2189                         var_to_reg_int(s1, src, REG_ITMP1);
2190                         M_BEQZ(s1, 0);
2191                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2192                         M_NOP;
2193                         break;
2194
2195                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2196                                         /* op1 = target JavaVM pc                     */
2197
2198                         var_to_reg_int(s1, src, REG_ITMP1);
2199                         M_BNEZ(s1, 0);
2200                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2201                         M_NOP;
2202                         break;
2203
2204                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2205                                         /* op1 = target JavaVM pc, val.i = constant   */
2206
2207                         var_to_reg_int(s1, src, REG_ITMP1);
2208                         if (iptr->val.i == 0) {
2209                                 M_BEQZ(s1, 0);
2210                         } else {
2211                                 ICONST(REG_ITMP2, iptr->val.i);
2212                                 M_BEQ(s1, REG_ITMP2, 0);
2213                         }
2214                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2215                         M_NOP;
2216                         break;
2217
2218                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2219                                         /* op1 = target JavaVM pc, val.i = constant   */
2220
2221                         var_to_reg_int(s1, src, REG_ITMP1);
2222                         if (iptr->val.i == 0) {
2223                                 M_BLTZ(s1, 0);
2224                         } else {
2225                                 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2226                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2227                                 } else {
2228                                         ICONST(REG_ITMP2, iptr->val.i);
2229                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2230                                 }
2231                                 M_BNEZ(REG_ITMP1, 0);
2232                         }
2233                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2234                         M_NOP;
2235                         break;
2236
2237                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2238                                         /* op1 = target JavaVM pc, val.i = constant   */
2239
2240                         var_to_reg_int(s1, src, REG_ITMP1);
2241                         if (iptr->val.i == 0) {
2242                                 M_BLEZ(s1, 0);
2243                                 }
2244                         else {
2245                                 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2246                                         M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2247                                         M_BNEZ(REG_ITMP1, 0);
2248                                         }
2249                                 else {
2250                                         ICONST(REG_ITMP2, iptr->val.i);
2251                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2252                                         M_BEQZ(REG_ITMP1, 0);
2253                                         }
2254                                 }
2255                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2256                         M_NOP;
2257                         break;
2258
2259                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2260                                         /* op1 = target JavaVM pc, val.i = constant   */
2261
2262                         var_to_reg_int(s1, src, REG_ITMP1);
2263                         if (iptr->val.i == 0) {
2264                                 M_BNEZ(s1, 0);
2265                                 }
2266                         else {
2267                                 ICONST(REG_ITMP2, iptr->val.i);
2268                                 M_BNE(s1, REG_ITMP2, 0);
2269                                 }
2270                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2271                         M_NOP;
2272                         break;
2273
2274                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2275                                         /* op1 = target JavaVM pc, val.i = constant   */
2276
2277                         var_to_reg_int(s1, src, REG_ITMP1);
2278                         if (iptr->val.i == 0) {
2279                                 M_BGTZ(s1, 0);
2280                                 }
2281                         else {
2282                                 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2283                                         M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2284                                         M_BEQZ(REG_ITMP1, 0);
2285                                         }
2286                                 else {
2287                                         ICONST(REG_ITMP2, iptr->val.i);
2288                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2289                                         M_BNEZ(REG_ITMP1, 0);
2290                                         }
2291                                 }
2292                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2293                         M_NOP;
2294                         break;
2295
2296                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2297                                         /* op1 = target JavaVM pc, val.i = constant   */
2298
2299                         var_to_reg_int(s1, src, REG_ITMP1);
2300                         if (iptr->val.i == 0) {
2301                                 M_BGEZ(s1, 0);
2302                                 }
2303                         else {
2304                                 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2305                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2306                                         }
2307                                 else {
2308                                         ICONST(REG_ITMP2, iptr->val.i);
2309                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2310                                         }
2311                                 M_BEQZ(REG_ITMP1, 0);
2312                                 }
2313                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2314                         M_NOP;
2315                         break;
2316
2317                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2318                                         /* op1 = target JavaVM pc, val.l = constant   */
2319
2320                         var_to_reg_int(s1, src, REG_ITMP1);
2321                         if (iptr->val.l == 0) {
2322                                 M_BEQZ(s1, 0);
2323                                 }
2324                         else {
2325                                 LCONST(REG_ITMP2, iptr->val.l);
2326                                 M_BEQ(s1, REG_ITMP2, 0);
2327                                 }
2328                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2329                         M_NOP;
2330                         break;
2331
2332                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2333                                         /* op1 = target JavaVM pc, val.l = constant   */
2334
2335                         var_to_reg_int(s1, src, REG_ITMP1);
2336                         if (iptr->val.l == 0) {
2337                                 M_BLTZ(s1, 0);
2338                                 }
2339                         else {
2340                                 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2341                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2342                                         }
2343                                 else {
2344                                         LCONST(REG_ITMP2, iptr->val.l);
2345                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2346                                         }
2347                                 M_BNEZ(REG_ITMP1, 0);
2348                                 }
2349                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2350                         M_NOP;
2351                         break;
2352
2353                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2354                                         /* op1 = target JavaVM pc, val.l = constant   */
2355
2356                         var_to_reg_int(s1, src, REG_ITMP1);
2357                         if (iptr->val.l == 0) {
2358                                 M_BLEZ(s1, 0);
2359                                 }
2360                         else {
2361                                 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2362                                         M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2363                                         M_BNEZ(REG_ITMP1, 0);
2364                                         }
2365                                 else {
2366                                         LCONST(REG_ITMP2, iptr->val.l);
2367                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2368                                         M_BEQZ(REG_ITMP1, 0);
2369                                         }
2370                                 }
2371                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2372                         M_NOP;
2373                         break;
2374
2375                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2376                                         /* op1 = target JavaVM pc, val.l = constant   */
2377
2378                         var_to_reg_int(s1, src, REG_ITMP1);
2379                         if (iptr->val.l == 0) {
2380                                 M_BNEZ(s1, 0);
2381                                 }
2382                         else {
2383                                 LCONST(REG_ITMP2, iptr->val.l);
2384                                 M_BNE(s1, REG_ITMP2, 0);
2385                                 }
2386                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2387                         M_NOP;
2388                         break;
2389
2390                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2391                                         /* op1 = target JavaVM pc, val.l = constant   */
2392
2393                         var_to_reg_int(s1, src, REG_ITMP1);
2394                         if (iptr->val.l == 0) {
2395                                 M_BGTZ(s1, 0);
2396                                 }
2397                         else {
2398                                 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2399                                         M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2400                                         M_BEQZ(REG_ITMP1, 0);
2401                                         }
2402                                 else {
2403                                         LCONST(REG_ITMP2, iptr->val.l);
2404                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2405                                         M_BNEZ(REG_ITMP1, 0);
2406                                         }
2407                                 }
2408                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2409                         M_NOP;
2410                         break;
2411
2412                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2413                                         /* op1 = target JavaVM pc, val.l = constant   */
2414
2415                         var_to_reg_int(s1, src, REG_ITMP1);
2416                         if (iptr->val.l == 0) {
2417                                 M_BGEZ(s1, 0);
2418                                 }
2419                         else {
2420                                 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2421                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2422                                         }
2423                                 else {
2424                                         LCONST(REG_ITMP2, iptr->val.l);
2425                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2426                                         }
2427                                 M_BEQZ(REG_ITMP1, 0);
2428                                 }
2429                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2430                         M_NOP;
2431                         break;
2432
2433                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2434                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2435                 case ICMD_IF_ACMPEQ:
2436
2437                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2438                         var_to_reg_int(s2, src, REG_ITMP2);
2439                         M_BEQ(s1, s2, 0);
2440                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2441                         M_NOP;
2442                         break;
2443
2444                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2445                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2446                 case ICMD_IF_ACMPNE:
2447
2448                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2449                         var_to_reg_int(s2, src, REG_ITMP2);
2450                         M_BNE(s1, s2, 0);
2451                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2452                         M_NOP;
2453                         break;
2454
2455                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2456                 case ICMD_IF_LCMPLT:    /* op1 = target JavaVM pc                     */
2457
2458                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2459                         var_to_reg_int(s2, src, REG_ITMP2);
2460                         M_CMPLT(s1, s2, REG_ITMP1);
2461                         M_BNEZ(REG_ITMP1, 0);
2462                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2463                         M_NOP;
2464                         break;
2465
2466                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2467                 case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
2468
2469                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2470                         var_to_reg_int(s2, src, REG_ITMP2);
2471                         M_CMPGT(s1, s2, REG_ITMP1);
2472                         M_BNEZ(REG_ITMP1, 0);
2473                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2474                         M_NOP;
2475                         break;
2476
2477                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2478                 case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
2479
2480                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2481                         var_to_reg_int(s2, src, REG_ITMP2);
2482                         M_CMPGT(s1, s2, REG_ITMP1);
2483                         M_BEQZ(REG_ITMP1, 0);
2484                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2485                         M_NOP;
2486                         break;
2487
2488                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2489                 case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
2490
2491                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2492                         var_to_reg_int(s2, src, REG_ITMP2);
2493                         M_CMPLT(s1, s2, REG_ITMP1);
2494                         M_BEQZ(REG_ITMP1, 0);
2495                         codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2496                         M_NOP;
2497                         break;
2498
2499 #ifdef CONDITIONAL_LOADCONST
2500                 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST                           */
2501
2502                 case ICMD_ELSE_ICONST:  /* handled by IFxx_ICONST                     */
2503                         break;
2504
2505                 case ICMD_IFEQ_ICONST:  /* ..., value ==> ..., constant               */
2506                                         /* val.i = constant                           */
2507
2508                         var_to_reg_int(s1, src, REG_ITMP1);
2509                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2510                         s3 = iptr->val.i;
2511                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2512                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2513                                         M_CMPEQ(s1, REG_ZERO, d);
2514                                         store_reg_to_var_int(iptr->dst, d);
2515                                         break;
2516                                 }
2517                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2518                                         M_CMPEQ(s1, REG_ZERO, d);
2519                                         M_XOR_IMM(d, 1, d);
2520                                         store_reg_to_var_int(iptr->dst, d);
2521                                         break;
2522                                 }
2523                                 if (s1 == d) {
2524                                         M_MOV(s1, REG_ITMP1);
2525                                         s1 = REG_ITMP1;
2526                                 }
2527                                 ICONST(d, iptr[1].val.i);
2528                         }
2529                         if ((s3 >= 0) && (s3 <= 255)) {
2530                                 M_CMOVEQ_IMM(s1, s3, d);
2531                         } else {
2532                                 ICONST(REG_ITMP3, s3);
2533                                 M_CMOVEQ(s1, REG_ITMP3, d);
2534                         }
2535                         store_reg_to_var_int(iptr->dst, d);
2536                         break;
2537
2538                 case ICMD_IFNE_ICONST:  /* ..., value ==> ..., constant               */
2539                                         /* val.i = constant                           */
2540
2541                         var_to_reg_int(s1, src, REG_ITMP1);
2542                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2543                         s3 = iptr->val.i;
2544                         if (iptr[1].opc == ICMD_ELSE_ICONST) {
2545                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2546                                         M_CMPEQ(s1, REG_ZERO, d);
2547                                         store_reg_to_var_int(iptr->dst, d);
2548                                         break;
2549                                 }
2550                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2551                                         M_CMPEQ(s1, REG_ZERO, d);
2552                                         M_XOR_IMM(d, 1, d);
2553                                         store_reg_to_var_int(iptr->dst, d);
2554                                         break;
2555                                 }
2556                                 if (s1 == d) {
2557                                         M_MOV(s1, REG_ITMP1);
2558                                         s1 = REG_ITMP1;
2559                                 }
2560                                 ICONST(d, iptr[1].val.i);
2561                         }
2562                         if ((s3 >= 0) && (s3 <= 255)) {
2563                                 M_CMOVNE_IMM(s1, s3, d);
2564                         } else {
2565                                 ICONST(REG_ITMP3, s3);
2566                                 M_CMOVNE(s1, REG_ITMP3, d);
2567                         }
2568                         store_reg_to_var_int(iptr->dst, d);
2569                         break;
2570
2571                 case ICMD_IFLT_ICONST:  /* ..., value ==> ..., constant               */
2572                                         /* val.i = constant                           */
2573
2574                         var_to_reg_int(s1, src, REG_ITMP1);
2575                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2576                         s3 = iptr->val.i;
2577                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2578                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2579                                         M_CMPLT(s1, REG_ZERO, d);
2580                                         store_reg_to_var_int(iptr->dst, d);
2581                                         break;
2582                                 }
2583                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2584                                         M_CMPLE(REG_ZERO, s1, d);
2585                                         store_reg_to_var_int(iptr->dst, d);
2586                                         break;
2587                                 }
2588                                 if (s1 == d) {
2589                                         M_MOV(s1, REG_ITMP1);
2590                                         s1 = REG_ITMP1;
2591                                 }
2592                                 ICONST(d, iptr[1].val.i);
2593                         }
2594                         if ((s3 >= 0) && (s3 <= 255)) {
2595                                 M_CMOVLT_IMM(s1, s3, d);
2596                         } else {
2597                                 ICONST(REG_ITMP3, s3);
2598                                 M_CMOVLT(s1, REG_ITMP3, d);
2599                         }
2600                         store_reg_to_var_int(iptr->dst, d);
2601                         break;
2602
2603                 case ICMD_IFGE_ICONST:  /* ..., value ==> ..., constant               */
2604                                         /* val.i = constant                           */
2605
2606                         var_to_reg_int(s1, src, REG_ITMP1);
2607                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2608                         s3 = iptr->val.i;
2609                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2610                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2611                                         M_CMPLE(REG_ZERO, s1, d);
2612                                         store_reg_to_var_int(iptr->dst, d);
2613                                         break;
2614                                 }
2615                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2616                                         M_CMPLT(s1, REG_ZERO, d);
2617                                         store_reg_to_var_int(iptr->dst, d);
2618                                         break;
2619                                 }
2620                                 if (s1 == d) {
2621                                         M_MOV(s1, REG_ITMP1);
2622                                         s1 = REG_ITMP1;
2623                                 }
2624                                 ICONST(d, iptr[1].val.i);
2625                         }
2626                         if ((s3 >= 0) && (s3 <= 255)) {
2627                                 M_CMOVGE_IMM(s1, s3, d);
2628                         } else {
2629                                 ICONST(REG_ITMP3, s3);
2630                                 M_CMOVGE(s1, REG_ITMP3, d);
2631                         }
2632                         store_reg_to_var_int(iptr->dst, d);
2633                         break;
2634
2635                 case ICMD_IFGT_ICONST:  /* ..., value ==> ..., constant               */
2636                                         /* val.i = constant                           */
2637
2638                         var_to_reg_int(s1, src, REG_ITMP1);
2639                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2640                         s3 = iptr->val.i;
2641                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2642                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2643                                         M_CMPLT(REG_ZERO, s1, d);
2644                                         store_reg_to_var_int(iptr->dst, d);
2645                                         break;
2646                                 }
2647                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2648                                         M_CMPLE(s1, REG_ZERO, d);
2649                                         store_reg_to_var_int(iptr->dst, d);
2650                                         break;
2651                                 }
2652                                 if (s1 == d) {
2653                                         M_MOV(s1, REG_ITMP1);
2654                                         s1 = REG_ITMP1;
2655                                 }
2656                                 ICONST(d, iptr[1].val.i);
2657                         }
2658                         if ((s3 >= 0) && (s3 <= 255)) {
2659                                 M_CMOVGT_IMM(s1, s3, d);
2660                         } else {
2661                                 ICONST(REG_ITMP3, s3);
2662                                 M_CMOVGT(s1, REG_ITMP3, d);
2663                         }
2664                         store_reg_to_var_int(iptr->dst, d);
2665                         break;
2666
2667                 case ICMD_IFLE_ICONST:  /* ..., value ==> ..., constant               */
2668                                         /* val.i = constant                           */
2669
2670                         var_to_reg_int(s1, src, REG_ITMP1);
2671                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2672                         s3 = iptr->val.i;
2673                         if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2674                                 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2675                                         M_CMPLE(s1, REG_ZERO, d);
2676                                         store_reg_to_var_int(iptr->dst, d);
2677                                         break;
2678                                 }
2679                                 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2680                                         M_CMPLT(REG_ZERO, s1, d);
2681                                         store_reg_to_var_int(iptr->dst, d);
2682                                         break;
2683                                 }
2684                                 if (s1 == d) {
2685                                         M_MOV(s1, REG_ITMP1);
2686                                         s1 = REG_ITMP1;
2687                                 }
2688                                 ICONST(d, iptr[1].val.i);
2689                         }
2690                         if ((s3 >= 0) && (s3 <= 255)) {
2691                                 M_CMOVLE_IMM(s1, s3, d);
2692                         } else {
2693                                 ICONST(REG_ITMP3, s3);
2694                                 M_CMOVLE(s1, REG_ITMP3, d);
2695                         }
2696                         store_reg_to_var_int(iptr->dst, d);
2697                         break;
2698 #endif
2699
2700
2701                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2702                 case ICMD_LRETURN:
2703
2704                         var_to_reg_int(s1, src, REG_RESULT);
2705                         M_INTMOVE(s1, REG_RESULT);
2706                         goto nowperformreturn;
2707
2708                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2709
2710                         var_to_reg_int(s1, src, REG_RESULT);
2711                         M_INTMOVE(s1, REG_RESULT);
2712
2713 #ifdef ENABLE_VERIFIER
2714                         if (iptr->val.a) {
2715                                 codegen_addpatchref(cd, mcodeptr,
2716                                                                         PATCHER_athrow_areturn,
2717                                                                         (unresolved_class *) iptr->val.a, 0);
2718
2719                                 if (opt_showdisassemble) {
2720                                         M_NOP; M_NOP;
2721                                 }
2722                         }
2723 #endif /* ENABLE_VERIFIER */
2724                         goto nowperformreturn;
2725
2726             case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2727             case ICMD_DRETURN:
2728                         var_to_reg_flt(s1, src, REG_FRESULT);
2729                         {
2730                                 int t = ((iptr->opc == ICMD_FRETURN) ? TYPE_FLT : TYPE_DBL);
2731                                 M_TFLTMOVE(t, s1, REG_FRESULT);
2732                         }
2733                         goto nowperformreturn;
2734
2735                 case ICMD_RETURN:      /* ...  ==> ...                                */
2736
2737 nowperformreturn:
2738                         {
2739                         s4 i, p;
2740                         
2741                         p = parentargs_base;
2742                         
2743                         /* call trace function */
2744
2745                         if (runverbose) {
2746                                 M_LDA(REG_SP, REG_SP, -3 * 8);
2747                                 M_LST(REG_RA, REG_SP, 0 * 8);
2748                                 M_LST(REG_RESULT, REG_SP, 1 * 8);
2749                                 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2750
2751                                 disp = dseg_addaddress(cd, m);
2752                                 M_ALD(rd->argintregs[0], REG_PV, disp);
2753                                 M_MOV(REG_RESULT, rd->argintregs[1]);
2754                                 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2755                                 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2756
2757                                 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2758                                 M_ALD(REG_ITMP3, REG_PV, disp);
2759                                 M_JSR(REG_RA, REG_ITMP3);
2760                                 M_NOP;
2761
2762                                 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2763                                 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2764                                 M_LLD(REG_RA, REG_SP, 0 * 8);
2765                                 M_LDA(REG_SP, REG_SP, 3 * 8);
2766                         }
2767
2768 #if defined(USE_THREADS)
2769                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2770                                 disp = dseg_addaddress(cd, (void *) builtin_monitorexit);
2771                                 M_ALD(REG_ITMP3, REG_PV, disp);
2772
2773                                 /* we need to save the proper return value */
2774
2775                                 switch (iptr->opc) {
2776                                 case ICMD_IRETURN:
2777                                 case ICMD_ARETURN:
2778                                 case ICMD_LRETURN:
2779                                         M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2780                                         M_JSR(REG_RA, REG_ITMP3);
2781                                         M_LST(REG_RESULT, REG_SP, rd->memuse * 8);  /* delay slot */
2782                                         break;
2783                                 case ICMD_FRETURN:
2784                                 case ICMD_DRETURN:
2785                                         M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2786                                         M_JSR(REG_RA, REG_ITMP3);
2787                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2788                                         break;
2789                                 case ICMD_RETURN:
2790                                         M_JSR(REG_RA, REG_ITMP3);
2791                                         M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2792                                         break;
2793                                 }
2794
2795                                 /* and now restore the proper return value */
2796
2797                                 switch (iptr->opc) {
2798                                 case ICMD_IRETURN:
2799                                 case ICMD_ARETURN:
2800                                 case ICMD_LRETURN:
2801                                         M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2802                                         break;
2803                                 case ICMD_FRETURN:
2804                                 case ICMD_DRETURN:
2805                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2806                                         break;
2807                                 }
2808                         }
2809 #endif
2810
2811                         /* restore return address                                         */
2812
2813                         if (!m->isleafmethod) {
2814                                 p--; M_ALD(REG_RA, REG_SP, p * 8);
2815                         }
2816
2817                         /* restore saved registers                                        */
2818
2819                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2820                                 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2821                         }
2822                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2823                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2824                         }
2825
2826                         /* deallocate stack and return                                    */
2827
2828                         if (parentargs_base) {
2829                                 s4 lo, hi;
2830
2831                                 disp = parentargs_base * 8;
2832                                 lo = (short) (disp);
2833                                 hi = (short) (((disp) - lo) >> 16);
2834
2835                                 if (hi == 0) {
2836                                         M_RET(REG_RA);
2837                                         M_LADD_IMM(REG_SP, lo, REG_SP);             /* delay slot */
2838                                 } else {
2839                                         M_LUI(REG_ITMP3,hi);
2840                                         M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2841                                         M_RET(REG_RA);
2842                                         M_LADD(REG_ITMP3,REG_SP,REG_SP);            /* delay slot */
2843                                 }
2844
2845                         } else {
2846                                 M_RET(REG_RA);
2847                                 M_NOP;
2848                         }
2849
2850                         ALIGNCODENOP;
2851                         }
2852                         break;
2853
2854
2855                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2856                         {
2857                         s4 i, l, *s4ptr;
2858                         void **tptr;
2859
2860                         tptr = (void **) iptr->target;
2861
2862                         s4ptr = iptr->val.a;
2863                         l = s4ptr[1];                          /* low     */
2864                         i = s4ptr[2];                          /* high    */
2865                         
2866                         var_to_reg_int(s1, src, REG_ITMP1);
2867                         if (l == 0)
2868                                 {M_INTMOVE(s1, REG_ITMP1);}
2869                         else if (l <= 32768) {
2870                                 M_IADD_IMM(s1, -l, REG_ITMP1);
2871                                 }
2872                         else {
2873                                 ICONST(REG_ITMP2, l);
2874                                 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2875                                 }
2876                         i = i - l + 1;
2877
2878                         /* range check */
2879
2880                         M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2881                         M_BEQZ(REG_ITMP2, 0);
2882                         codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2883                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
2884
2885                         /* build jump table top down and use address of lowest entry */
2886
2887                         /* s4ptr += 3 + i; */
2888                         tptr += i;
2889
2890                         while (--i >= 0) {
2891                                 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
2892                                 dseg_addtarget(cd, (basicblock *) tptr[0]); 
2893                                 --tptr;
2894                                 }
2895                         }
2896
2897                         /* length of dataseg after last dseg_addtarget is used by load */
2898
2899                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2900                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2901                         M_JMP(REG_ITMP2);
2902                         M_NOP;
2903                         ALIGNCODENOP;
2904                         break;
2905
2906
2907                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2908                         {
2909                         s4 i, /*l, */val, *s4ptr;
2910                         void **tptr;
2911
2912                         tptr = (void **) iptr->target;
2913
2914                         s4ptr = iptr->val.a;
2915                         /*l = s4ptr[0];*/                          /* default  */
2916                         i = s4ptr[1];                          /* count    */
2917                         
2918                         MCODECHECK((i<<2)+8);
2919                         var_to_reg_int(s1, src, REG_ITMP1);
2920                         while (--i >= 0) {
2921                                 s4ptr += 2;
2922                                 ++tptr;
2923
2924                                 val = s4ptr[0];
2925                                 ICONST(REG_ITMP2, val);
2926                                 M_BEQ(s1, REG_ITMP2, 0);
2927                                 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr); 
2928                                 M_NOP;
2929                                 }
2930
2931                         M_BR(0);
2932                         tptr = (void **) iptr->target;
2933                         codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2934                         M_NOP;
2935                         ALIGNCODENOP;
2936                         break;
2937                         }
2938
2939
2940                 case ICMD_BUILTIN:      /* ..., arg1 ==> ...                          */
2941                                         /* op1 = arg count val.a = builtintable entry */
2942
2943                         bte = iptr->val.a;
2944                         md = bte->md;
2945                         goto gen_method;
2946
2947                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2948                                         /* op1 = arg count, val.a = method pointer    */
2949
2950                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2951                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2952                 case ICMD_INVOKEINTERFACE:
2953
2954                         lm = iptr->val.a;
2955
2956                         if (lm == NULL) {
2957                                 unresolved_method *um = iptr->target;
2958                                 md = um->methodref->parseddesc.md;
2959                         } else {
2960                                 md = lm->parseddesc;
2961                         }
2962
2963 gen_method:
2964                         s3 = md->paramcount;
2965
2966                         MCODECHECK((s3 << 1) + 64);
2967
2968                         /* copy arguments to registers or stack location                  */
2969
2970                         for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
2971                                 if (src->varkind == ARGVAR)
2972                                         continue;
2973                                 if (IS_INT_LNG_TYPE(src->type)) {
2974                                         if (!md->params[s3].inmemory) {
2975                                                 s1 = rd->argintregs[md->params[s3].regoff];
2976                                                 var_to_reg_int(d, src, s1);
2977                                                 M_INTMOVE(d, s1);
2978                                         } else  {
2979                                                 var_to_reg_int(d, src, REG_ITMP1);
2980                                                 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2981                                         }
2982
2983                                 } else {
2984                                         if (!md->params[s3].inmemory) {
2985                                                 s1 = rd->argfltregs[md->params[s3].regoff];
2986                                                 var_to_reg_flt(d, src, s1);
2987                                                 M_TFLTMOVE(src->type, d, s1);
2988                                         } else {
2989                                                 var_to_reg_flt(d, src, REG_FTMP1);
2990                                                 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2991                                         }
2992                                 }
2993                         }
2994
2995                         switch (iptr->opc) {
2996                         case ICMD_BUILTIN:
2997                                 disp = dseg_addaddress(cd, bte->fp);
2998                                 d = md->returntype.type;
2999
3000                                 M_ALD(REG_ITMP3, REG_PV, disp);  /* built-in-function pointer */
3001                                 M_JSR(REG_RA, REG_ITMP3);
3002                                 M_NOP;
3003                                 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3004                                 M_LDA(REG_PV, REG_RA, -disp);
3005
3006                                 /* if op1 == true, we need to check for an exception */
3007
3008                                 if (iptr->op1 == true) {
3009                                         M_BEQZ(REG_RESULT, 0);
3010                                         codegen_addxexceptionrefs(cd, mcodeptr);
3011                                         M_NOP;
3012                                 }
3013                                 break;
3014
3015                         case ICMD_INVOKESPECIAL:
3016                                 M_BEQZ(rd->argintregs[0], 0);
3017                                 codegen_addxnullrefs(cd, mcodeptr);
3018                                 M_NOP;
3019                                 /* fall through */
3020
3021                         case ICMD_INVOKESTATIC:
3022                                 if (lm == NULL) {
3023                                         unresolved_method *um = iptr->target;
3024
3025                                         disp = dseg_addaddress(cd, NULL);
3026
3027                                         codegen_addpatchref(cd, mcodeptr,
3028                                                                                 PATCHER_invokestatic_special, um, disp);
3029
3030                                         if (opt_showdisassemble) {
3031                                                 M_NOP; M_NOP;
3032                                         }
3033
3034                                         d = um->methodref->parseddesc.md->returntype.type;
3035
3036                                 } else {
3037                                         disp = dseg_addaddress(cd, lm->stubroutine);
3038                                         d = lm->parseddesc->returntype.type;
3039                                 }
3040
3041                                 M_ALD(REG_PV, REG_PV, disp);          /* method pointer in pv */
3042                                 M_JSR(REG_RA, REG_PV);
3043                                 M_NOP;
3044                                 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3045                                 M_LDA(REG_PV, REG_RA, -disp);
3046                                 break;
3047
3048                         case ICMD_INVOKEVIRTUAL:
3049                                 gen_nullptr_check(rd->argintregs[0]);
3050
3051                                 if (lm == NULL) {
3052                                         unresolved_method *um = iptr->target;
3053
3054                                         codegen_addpatchref(cd, mcodeptr,
3055                                                                                 PATCHER_invokevirtual, um, 0);
3056
3057                                         if (opt_showdisassemble) {
3058                                                 M_NOP; M_NOP;
3059                                         }
3060
3061                                         s1 = 0;
3062                                         d = um->methodref->parseddesc.md->returntype.type;
3063
3064                                 } else {
3065                                         s1 = OFFSET(vftbl_t, table[0]) +
3066                                                 sizeof(methodptr) * lm->vftblindex;
3067                                         d = lm->parseddesc->returntype.type;
3068                                 }
3069
3070                                 M_ALD(REG_METHODPTR, rd->argintregs[0],
3071                                           OFFSET(java_objectheader, vftbl));
3072                                 M_ALD(REG_PV, REG_METHODPTR, s1);
3073                                 M_JSR(REG_RA, REG_PV);
3074                                 M_NOP;
3075                                 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3076                                 M_LDA(REG_PV, REG_RA, -disp);
3077                                 break;
3078
3079                         case ICMD_INVOKEINTERFACE:
3080                                 gen_nullptr_check(rd->argintregs[0]);
3081
3082                                 if (lm == NULL) {
3083                                         unresolved_method *um = iptr->target;
3084
3085                                         codegen_addpatchref(cd, mcodeptr,
3086                                                                                 PATCHER_invokeinterface, um, 0);
3087
3088                                         if (opt_showdisassemble) {
3089                                                 M_NOP; M_NOP;
3090                                         }
3091
3092                                         s1 = 0;
3093                                         s2 = 0;
3094                                         d = um->methodref->parseddesc.md->returntype.type;
3095
3096                                 } else {
3097                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3098                                                 sizeof(methodptr*) * lm->class->index;
3099
3100                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3101
3102                                         d = lm->parseddesc->returntype.type;
3103                                 }
3104
3105                                 M_ALD(REG_METHODPTR, rd->argintregs[0],
3106                                           OFFSET(java_objectheader, vftbl));
3107                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3108                                 M_ALD(REG_PV, REG_METHODPTR, s2);
3109                                 M_JSR(REG_RA, REG_PV);
3110                                 M_NOP;
3111                                 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3112                                 M_LDA(REG_PV, REG_RA, -disp);
3113                                 break;
3114                         }
3115
3116                         /* d contains return type */
3117
3118                         if (d != TYPE_VOID) {
3119                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3120                                         s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3121                                         M_INTMOVE(REG_RESULT, s1);
3122                                         store_reg_to_var_int(iptr->dst, s1);
3123                                 } else {
3124                                         s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3125                                         M_TFLTMOVE(iptr->dst->type, REG_FRESULT, s1);
3126                                         store_reg_to_var_flt(iptr->dst, s1);
3127                                 }
3128                         }
3129                         break;
3130
3131
3132                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3133                                       /* op1:   0 == array, 1 == class                */
3134                                       /* val.a: (classinfo*) superclass               */
3135
3136                         /*  superclass is an interface:
3137                          *
3138                          *  OK if ((sub == NULL) ||
3139                          *         (sub->vftbl->interfacetablelength > super->index) &&
3140                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
3141                          *
3142                          *  superclass is a class:
3143                          *
3144                          *  OK if ((sub == NULL) || (0
3145                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3146                          *         super->vftbl->diffvall));
3147                          */
3148
3149                         if (iptr->op1 == 1) {
3150                                 classinfo *super;
3151                                 vftbl_t   *supervftbl;
3152                                 s4         superindex;
3153
3154                                 super = (classinfo *) iptr->val.a;
3155
3156                                 if (!super) {
3157                                         superindex = 0;
3158                                         supervftbl = NULL;
3159
3160                                 } else {
3161                                         superindex = super->index;
3162                                         supervftbl = super->vftbl;
3163                                 }
3164                         
3165 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3166                                 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3167 #endif
3168
3169                                 var_to_reg_int(s1, src, REG_ITMP1);
3170
3171                                 /* calculate interface checkcast code size */
3172
3173                                 s2 = 8;
3174                                 if (!super)
3175                                         s2 += (opt_showdisassemble ? 2 : 0);
3176
3177                                 /* calculate class checkcast code size */
3178
3179                                 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3180                                 if (!super)
3181                                         s3 += (opt_showdisassemble ? 2 : 0);
3182
3183                                 /* if class is not resolved, check which code to call */
3184
3185                                 if (!super) {
3186                                         M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3187                                         M_NOP;
3188
3189                                         disp = dseg_adds4(cd, 0);                 /* super->flags */
3190
3191                                         codegen_addpatchref(cd, mcodeptr,
3192                                                                                 PATCHER_checkcast_instanceof_flags,
3193                                                                                 (constant_classref *) iptr->target,
3194                                                                                 disp);
3195
3196                                         if (opt_showdisassemble) {
3197                                                 M_NOP; M_NOP;
3198                                         }
3199
3200                                         /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3201                                         M_ILD(REG_ITMP2, REG_PV, disp);
3202                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3203                                         M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3204                                         M_NOP;
3205                                 }
3206
3207                                 /* interface checkcast code */
3208
3209                                 if (!super || super->flags & ACC_INTERFACE) {
3210                                         if (super) {
3211                                                 M_BEQZ(s1, 1 + s2);
3212                                                 M_NOP;
3213
3214                                         } else {
3215                                                 codegen_addpatchref(cd, mcodeptr,
3216                                                                                         PATCHER_checkcast_instanceof_interface,
3217                                                                                         (constant_classref *) iptr->target,
3218                                                                                         0);
3219
3220                                                 if (opt_showdisassemble) {
3221                                                         M_NOP; M_NOP;
3222                                                 }
3223                                         }
3224
3225                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3226                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3227                                         M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3228                                         M_BLEZ(REG_ITMP3, 0);
3229                                         codegen_addxcastrefs(cd, mcodeptr);
3230                                         M_NOP;
3231                                         M_ALD(REG_ITMP3, REG_ITMP2,
3232                                                   OFFSET(vftbl_t, interfacetable[0]) -
3233                                                   superindex * sizeof(methodptr*));
3234                                         M_BEQZ(REG_ITMP3, 0);
3235                                         codegen_addxcastrefs(cd, mcodeptr);
3236                                         M_NOP;
3237
3238                                         if (!super) {
3239                                                 M_BR(1 + s3);
3240                                                 M_NOP;
3241                                         }
3242                                 }
3243
3244                                 /* class checkcast code */
3245
3246                                 if (!super || !(super->flags & ACC_INTERFACE)) {
3247                                         disp = dseg_addaddress(cd, (void *) supervftbl);
3248
3249                                         if (super) {
3250                                                 M_BEQZ(s1, 1 + s3);
3251                                                 M_NOP;
3252
3253                                         } else {
3254                                                 codegen_addpatchref(cd, mcodeptr,
3255                                                                                         PATCHER_checkcast_instanceof_class,
3256                                                                                         (constant_classref *) iptr->target,
3257                                                                                         disp);
3258
3259                                                 if (opt_showdisassemble) {
3260                                                         M_NOP; M_NOP;
3261                                                 }
3262                                         }
3263
3264                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3265                                         M_ALD(REG_ITMP3, REG_PV, disp);
3266 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3267                                         codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3268 #endif
3269                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3270                                         /*                              if (s1 != REG_ITMP1) { */
3271                                         /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3272                                         /*                                      M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3273                                         /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3274                                         /*                                      codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3275                                         /* #endif */
3276                                         /*                                      M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3277                                         /*                              } else { */
3278                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3279                                         M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2); 
3280                                         M_ALD(REG_ITMP3, REG_PV, disp);
3281                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3282 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3283                                         codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3284 #endif
3285                                         /*                              } */
3286                                         M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3287                                         M_BNEZ(REG_ITMP3, 0);
3288                                         codegen_addxcastrefs(cd, mcodeptr);
3289                                         M_NOP;
3290                                 }
3291                                 d = reg_of_var(rd, iptr->dst, s1);
3292
3293                         } else {
3294                                 var_to_reg_int(s1, src, rd->argintregs[0]);
3295                                 M_INTMOVE(s1, rd->argintregs[0]);
3296
3297                                 disp = dseg_addaddress(cd, iptr->val.a);
3298
3299                                 if (iptr->val.a == NULL) {
3300                                         codegen_addpatchref(cd, mcodeptr,
3301                                                                                 PATCHER_builtin_arraycheckcast,
3302                                                                                 (constant_classref *) iptr->target,
3303                                                                                 disp);
3304
3305                                         if (opt_showdisassemble) {
3306                                                 M_NOP; M_NOP;
3307                                         }
3308                                 }
3309
3310                                 M_ALD(rd->argintregs[1], REG_PV, disp);
3311                                 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3312                                 M_ALD(REG_ITMP3, REG_PV, disp);
3313                                 M_JSR(REG_RA, REG_ITMP3);
3314                                 M_NOP;
3315
3316                                 M_BEQZ(REG_RESULT, 0);
3317                                 codegen_addxcastrefs(cd, mcodeptr);
3318                                 M_NOP;
3319
3320                                 var_to_reg_int(s1, src, REG_ITMP1);
3321                                 d = reg_of_var(rd, iptr->dst, s1);
3322                         }
3323                         M_INTMOVE(s1, d);
3324                         store_reg_to_var_int(iptr->dst, d);
3325                         break;
3326
3327                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3328                                       /* op1:   0 == array, 1 == class                */
3329                                       /* val.a: (classinfo*) superclass               */
3330
3331                         /*  superclass is an interface:
3332                          *
3333                          *  return (sub != NULL) &&
3334                          *         (sub->vftbl->interfacetablelength > super->index) &&
3335                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3336                          *
3337                          *  superclass is a class:
3338                          *
3339                          *  return ((sub != NULL) && (0
3340                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3341                          *          super->vftbl->diffvall));
3342                          */
3343
3344                         {
3345                         classinfo *super;
3346                         vftbl_t   *supervftbl;
3347                         s4         superindex;
3348
3349                         super = (classinfo *) iptr->val.a;
3350
3351                         if (!super) {
3352                                 superindex = 0;
3353                                 supervftbl = NULL;
3354
3355                         } else {
3356                                 superindex = super->index;
3357                                 supervftbl = super->vftbl;
3358                         }
3359                         
3360 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3361                         codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3362 #endif
3363
3364                         var_to_reg_int(s1, src, REG_ITMP1);
3365                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3366                         if (s1 == d) {
3367                                 M_MOV(s1, REG_ITMP1);
3368                                 s1 = REG_ITMP1;
3369                         }
3370
3371                         /* calculate interface instanceof code size */
3372
3373                         s2 = 7;
3374                         if (!super)
3375                                 s2 += (opt_showdisassemble ? 2 : 0);
3376
3377                         /* calculate class instanceof code size */
3378
3379                         s3 = 8;
3380                         if (!super)
3381                                 s3 += (opt_showdisassemble ? 2 : 0);
3382
3383                         M_CLR(d);
3384
3385                         /* if class is not resolved, check which code to call */
3386
3387                         if (!super) {
3388                                 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3389                                 M_NOP;
3390
3391                                 disp = dseg_adds4(cd, 0);                     /* super->flags */
3392
3393                                 codegen_addpatchref(cd, mcodeptr,
3394                                                                         PATCHER_checkcast_instanceof_flags,
3395                                                                         (constant_classref *) iptr->target, disp);
3396
3397                                 if (opt_showdisassemble) {
3398                                         M_NOP; M_NOP;
3399                                 }
3400
3401                                 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3402                                 M_ILD(REG_ITMP3, REG_PV, disp);
3403                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3404                                 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3405                                 M_NOP;
3406                         }
3407
3408                         /* interface instanceof code */
3409
3410                         if (!super || (super->flags & ACC_INTERFACE)) {
3411                                 if (super) {
3412                                         M_BEQZ(s1, 1 + s2);
3413                                         M_NOP;
3414
3415                                 } else {
3416                                         codegen_addpatchref(cd, mcodeptr,
3417                                                                                 PATCHER_checkcast_instanceof_interface,
3418                                                                                 (constant_classref *) iptr->target, 0);
3419
3420                                         if (opt_showdisassemble) {
3421                                                 M_NOP; M_NOP;
3422                                         }
3423                                 }
3424
3425                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3426                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3427                                 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3428                                 M_BLEZ(REG_ITMP3, 3);
3429                                 M_NOP;
3430                                 M_ALD(REG_ITMP1, REG_ITMP1,
3431                                           OFFSET(vftbl_t, interfacetable[0]) -
3432                                           superindex * sizeof(methodptr*));
3433                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3434
3435                                 if (!super) {
3436                                         M_BR(1 + s3);
3437                                         M_NOP;
3438                                 }
3439                         }
3440
3441                         /* class instanceof code */
3442
3443                         if (!super || !(super->flags & ACC_INTERFACE)) {
3444                                 disp = dseg_addaddress(cd, supervftbl);
3445
3446                                 if (super) {
3447                                         M_BEQZ(s1, 1 + s3);
3448                                         M_NOP;
3449
3450                                 } else {
3451                                         codegen_addpatchref(cd, mcodeptr,
3452                                                                                 PATCHER_checkcast_instanceof_class,
3453                                                                                 (constant_classref *) iptr->target,
3454                                                                                 disp);
3455
3456                                         if (opt_showdisassemble) {
3457                                                 M_NOP; M_NOP;
3458                                         }
3459                                 }
3460
3461                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3462                                 M_ALD(REG_ITMP2, REG_PV, disp);
3463 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3464                                 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3465 #endif
3466                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3467                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3468                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3469 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3470                                 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3471 #endif
3472                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3473                                 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3474                                 M_XOR_IMM(d, 1, d);
3475                         }
3476                         store_reg_to_var_int(iptr->dst, d);
3477                         }
3478                         break;
3479
3480                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3481                                       /* op1 = dimension, val.a = array descriptor    */
3482
3483                         /* check for negative sizes and copy sizes to stack if necessary  */
3484
3485                         MCODECHECK((iptr->op1 << 1) + 64);
3486
3487                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3488                                 /* copy SAVEDVAR sizes to stack */
3489
3490                                 if (src->varkind != ARGVAR) {
3491                                         var_to_reg_int(s2, src, REG_ITMP1);
3492                                         M_LST(s2, REG_SP, s1 * 8);
3493                                 }
3494                         }
3495
3496                         /* a0 = dimension count */
3497
3498                         ICONST(rd->argintregs[0], iptr->op1);
3499
3500                         /* is patcher function set? */
3501
3502                         if (iptr->target) {
3503                                 disp = dseg_addaddress(cd, NULL);
3504
3505                                 codegen_addpatchref(cd, mcodeptr,
3506                                                                         PATCHER_builtin_multianewarray,
3507                                                                         iptr->val.a, disp);
3508
3509                                 if (opt_showdisassemble) {
3510                                         M_NOP; M_NOP;
3511                                 }
3512
3513                         } else {
3514                                 disp = dseg_addaddress(cd, iptr->val.a);
3515                         }
3516
3517                         /* a1 = arraydescriptor */
3518
3519                         M_ALD(rd->argintregs[1], REG_PV, disp);
3520
3521                         /* a2 = pointer to dimensions = stack pointer */
3522
3523                         M_INTMOVE(REG_SP, rd->argintregs[2]);
3524
3525                         disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3526                         M_ALD(REG_ITMP3, REG_PV, disp);
3527                         M_JSR(REG_RA, REG_ITMP3);
3528                         M_NOP;
3529
3530                         /* check for exception before result assignment */
3531
3532                         M_BEQZ(REG_RESULT, 0);
3533                         codegen_addxexceptionrefs(cd, mcodeptr);
3534                         M_NOP;
3535
3536                         d = reg_of_var(rd, iptr->dst, REG_RESULT);
3537                         M_INTMOVE(REG_RESULT, d);
3538                         store_reg_to_var_int(iptr->dst, d);
3539                         break;
3540
3541                 default:
3542                         *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3543                         return false;
3544         } /* switch */
3545                 
3546         } /* for instruction */
3547                 
3548         /* copy values to interface registers */
3549
3550         src = bptr->outstack;
3551         len = bptr->outdepth;
3552         MCODECHECK(64+len);
3553 #ifdef LSRA
3554         if (!opt_lsra) 
3555 #endif
3556         while (src) {
3557                 len--;
3558                 if ((src->varkind != STACKVAR)) {
3559                         s2 = src->type;
3560                         if (IS_FLT_DBL_TYPE(s2)) {
3561                                 var_to_reg_flt(s1, src, REG_FTMP1);
3562                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3563                                         M_TFLTMOVE(s2, s1, rd->interfaces[len][s2].regoff);
3564
3565                                 } else {
3566                                         M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3567                                 }
3568
3569                         } else {
3570                                 var_to_reg_int(s1, src, REG_ITMP1);
3571                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3572                                         M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3573
3574                                 } else {
3575                                         M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3576                                 }
3577                         }
3578                 }
3579                 src = src->prev;
3580         }
3581
3582         /* At the end of a basic block we may have to append some nops,
3583            because the patcher stub calling code might be longer than the
3584            actual instruction. So codepatching does not change the
3585            following block unintentionally. */
3586
3587         if ((u1 *) mcodeptr < cd->lastmcodeptr) {
3588                 while ((u1 *) mcodeptr < cd->lastmcodeptr) {
3589                         M_NOP;
3590                 }
3591         }
3592
3593         } /* if (bptr -> flags >= BBREACHED) */
3594         } /* for basic block */
3595
3596         codegen_createlinenumbertable(cd);
3597
3598         {
3599         s4        *xcodeptr;
3600         branchref *bref;
3601
3602         /* generate ArithmeticException stubs */
3603
3604         xcodeptr = NULL;
3605         
3606         for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3607                 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, 
3608                                   bref->branchpos,
3609                                                   (u1 *) mcodeptr - cd->mcodebase);
3610
3611                 MCODECHECK(100);
3612
3613                 if (xcodeptr != NULL) {
3614                         M_BR(xcodeptr - mcodeptr);
3615                         M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);  /* delay */
3616
3617                 } else {
3618                         M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3619
3620                         xcodeptr = mcodeptr;
3621
3622                         M_MOV(REG_PV, rd->argintregs[0]);
3623                         M_MOV(REG_SP, rd->argintregs[1]);
3624
3625                         if (m->isleafmethod)
3626                                 M_MOV(REG_RA, rd->argintregs[2]);
3627                         else
3628                                 M_ALD(rd->argintregs[2],
3629                                           REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3630
3631                         M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3632
3633                         M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3634                         M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3635
3636                         if (m->isleafmethod)
3637                                 M_AST(REG_RA, REG_SP, 1 * 8);
3638
3639                         a = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
3640                         M_ALD(REG_ITMP3, REG_PV, a);
3641                         M_JSR(REG_RA, REG_ITMP3);
3642                         M_NOP;
3643                         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3644
3645                         if (m->isleafmethod)
3646                                 M_ALD(REG_RA, REG_SP, 1 * 8);
3647
3648                         M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3649                         M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3650
3651                         a = dseg_addaddress(cd, asm_handle_exception);
3652                         M_ALD(REG_ITMP3, REG_PV, a);
3653                         M_JMP(REG_ITMP3);
3654                         M_NOP;
3655                 }
3656         }
3657
3658         /* generate ArrayIndexOutOfBoundsException stubs */
3659
3660         xcodeptr = NULL;
3661
3662         for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3663                 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, 
3664                                   bref->branchpos,
3665                                                   (u1 *) mcodeptr - cd->mcodebase);
3666
3667                 MCODECHECK(100);
3668
3669                 /* move index register into REG_ITMP1 */
3670
3671                 M_MOV(bref->reg, REG_ITMP1);
3672                 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3673
3674                 if (xcodeptr != NULL) {
3675                         M_BR(xcodeptr - mcodeptr);
3676                         M_NOP;
3677
3678                 } else {
3679                         xcodeptr = mcodeptr;
3680
3681                         M_MOV(REG_PV, rd->argintregs[0]);
3682                         M_MOV(REG_SP, rd->argintregs[1]);
3683
3684                         if (m->isleafmethod)
3685                                 M_MOV(REG_RA, rd->argintregs[2]);
3686                         else
3687                                 M_ALD(rd->argintregs[2],
3688                                           REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3689
3690                         M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3691                         M_MOV(REG_ITMP1, rd->argintregs[4]);
3692
3693                         M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3694                         M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3695
3696                         if (m->isleafmethod)
3697                                 M_AST(REG_RA, REG_SP, 1 * 8);
3698
3699                         a = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
3700                         M_ALD(REG_ITMP3, REG_PV, a);
3701                         M_JSR(REG_RA, REG_ITMP3);
3702                         M_NOP;
3703                         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3704
3705                         if (m->isleafmethod)
3706                                 M_ALD(REG_RA, REG_SP, 1 * 8);
3707
3708                         M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3709                         M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3710
3711                         a = dseg_addaddress(cd, asm_handle_exception);
3712                         M_ALD(REG_ITMP3, REG_PV, a);
3713                         M_JMP(REG_ITMP3);
3714                         M_NOP;
3715                 }
3716         }
3717
3718         /* generate ArrayStoreException stubs */
3719
3720         xcodeptr = NULL;
3721         
3722         for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3723                 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, 
3724                                   bref->branchpos,
3725                                                   (u1 *) mcodeptr - cd->mcodebase);
3726
3727                 MCODECHECK(100);
3728
3729                 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3730
3731                 if (xcodeptr != NULL) {
3732                         M_BR(xcodeptr - mcodeptr);
3733                         M_NOP;
3734
3735                 } else {
3736                         xcodeptr = mcodeptr;
3737
3738                         M_MOV(REG_PV, rd->argintregs[0]);
3739                         M_MOV(REG_SP, rd->argintregs[1]);
3740                         M_ALD(rd->argintregs[2],
3741                                   REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3742                         M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3743
3744                         M_ASUB_IMM(REG_SP, 1 * 8, REG_SP);
3745                         M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3746
3747                         a = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
3748                         M_ALD(REG_ITMP3, REG_PV, a);
3749                         M_JSR(REG_RA, REG_ITMP3);
3750                         M_NOP;
3751                         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3752
3753                         M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3754                         M_AADD_IMM(REG_SP, 1 * 8, REG_SP);
3755
3756                         a = dseg_addaddress(cd, asm_handle_exception);
3757                         M_ALD(REG_ITMP3, REG_PV, a);
3758                         M_JMP(REG_ITMP3);
3759                         M_NOP;
3760                 }
3761         }
3762
3763         /* generate ClassCastException stubs */
3764
3765         xcodeptr = NULL;
3766         
3767         for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3768                 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, 
3769                                   bref->branchpos,
3770                                                   (u1 *) mcodeptr - cd->mcodebase);
3771
3772                 MCODECHECK(100);
3773
3774                 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3775
3776                 if (xcodeptr != NULL) {
3777                         M_BR(xcodeptr - mcodeptr);
3778                         M_NOP;
3779
3780                 } else {
3781                         xcodeptr = mcodeptr;
3782
3783                         M_MOV(REG_PV, rd->argintregs[0]);
3784                         M_MOV(REG_SP, rd->argintregs[1]);
3785
3786                         if (m->isleafmethod)
3787                                 M_MOV(REG_RA, rd->argintregs[2]);
3788                         else
3789                                 M_ALD(rd->argintregs[2],
3790                                           REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3791
3792                         M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3793
3794                         M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3795                         M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3796
3797                         if (m->isleafmethod)
3798                                 M_AST(REG_RA, REG_SP, 1 * 8);
3799
3800                         a = dseg_addaddress(cd, stacktrace_inline_classcastexception);
3801                         M_ALD(REG_ITMP3, REG_PV, a);
3802                         M_JSR(REG_RA, REG_ITMP3);
3803                         M_NOP;
3804                         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3805
3806                         if (m->isleafmethod)
3807                                 M_ALD(REG_RA, REG_SP, 1 * 8);
3808
3809                         M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3810                         M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3811
3812                         a = dseg_addaddress(cd, asm_handle_exception);
3813                         M_ALD(REG_ITMP3, REG_PV, a);
3814                         M_JMP(REG_ITMP3);
3815                         M_NOP;
3816                 }
3817         }
3818
3819         /* generate NullPointerException stubs */
3820
3821         xcodeptr = NULL;
3822
3823         for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3824                 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, 
3825                                   bref->branchpos,
3826                                                   (u1 *) mcodeptr - cd->mcodebase);
3827
3828                 MCODECHECK(100);
3829
3830                 M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3831
3832                 if (xcodeptr != NULL) {
3833                         M_BR(xcodeptr - mcodeptr);
3834                         M_NOP;
3835
3836                 } else {
3837                         xcodeptr = mcodeptr;
3838
3839                         M_MOV(REG_PV, rd->argintregs[0]);
3840                         M_MOV(REG_SP, rd->argintregs[1]);
3841
3842                         if (m->isleafmethod)
3843                                 M_MOV(REG_RA, rd->argintregs[2]);
3844                         else
3845                                 M_ALD(rd->argintregs[2],
3846                                           REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3847
3848                         M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3849
3850                         M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3851                         M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3852
3853                         if (m->isleafmethod)
3854                                 M_AST(REG_RA, REG_SP, 1 * 8);
3855
3856                         a = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
3857                         M_ALD(REG_ITMP3, REG_PV, a);
3858                         M_JSR(REG_RA, REG_ITMP3);
3859                         M_NOP;
3860                         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3861
3862                         if (m->isleafmethod)
3863                                 M_ALD(REG_RA, REG_SP, 1 * 8);
3864
3865                         M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3866                         M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3867
3868                         a = dseg_addaddress(cd, asm_handle_exception);
3869                         M_ALD(REG_ITMP3, REG_PV, a);
3870                         M_JMP(REG_ITMP3);
3871                         M_NOP;
3872                 }
3873         }
3874
3875         /* generate exception check stubs */
3876
3877         xcodeptr = NULL;
3878
3879         for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
3880                 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos, 
3881                                   bref->branchpos,
3882                                                   (u1 *) mcodeptr - cd->mcodebase);
3883
3884                 MCODECHECK(100);
3885
3886                 if (xcodeptr != NULL) {
3887                         M_BR(xcodeptr - mcodeptr);
3888                         M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);  /* delay */
3889
3890                 } else {
3891                         M_AADD_IMM(REG_PV, bref->branchpos - 4, REG_ITMP2_XPC);
3892
3893                         xcodeptr = mcodeptr;
3894
3895                         M_MOV(REG_PV, rd->argintregs[0]);
3896                         M_MOV(REG_SP, rd->argintregs[1]);
3897                         M_ALD(rd->argintregs[2],
3898                                   REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3899                         M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3900
3901                         M_ASUB_IMM(REG_SP, 1 * 8, REG_SP);
3902                         M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3903
3904                         a = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
3905                         M_ALD(REG_ITMP3, REG_PV, a);
3906                         M_JSR(REG_RA, REG_ITMP3);
3907                         M_NOP;
3908                         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3909
3910                         M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3911                         M_AADD_IMM(REG_SP, 1 * 8, REG_SP);
3912
3913                         a = dseg_addaddress(cd, asm_handle_exception);
3914                         M_ALD(REG_ITMP3, REG_PV, a);
3915                         M_JMP(REG_ITMP3);
3916                         M_NOP;
3917                 }
3918         }
3919
3920         /* generate patcher stub call code */
3921
3922         {
3923                 patchref *pref;
3924                 u8        mcode;
3925                 s4       *tmpmcodeptr;
3926
3927                 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3928                         /* check code segment size */
3929
3930                         MCODECHECK(100);
3931
3932                         /* Get machine code which is patched back in later. The call is   */
3933                         /* 2 instruction words long.                                      */
3934
3935                         xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
3936
3937                         /* We need to split this, because an unaligned 8 byte read causes */
3938                         /* a SIGSEGV.                                                     */
3939
3940                         mcode = ((u8) xcodeptr[1] << 32) + (u4) xcodeptr[0];
3941
3942                         /* patch in the call to call the following code (done at compile  */
3943                         /* time)                                                          */
3944
3945                         tmpmcodeptr = mcodeptr;         /* save current mcodeptr          */
3946                         mcodeptr = xcodeptr;            /* set mcodeptr to patch position */
3947
3948                         disp = (s4) (tmpmcodeptr - (xcodeptr + 1));
3949
3950                         if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3951                                 *exceptionptr =
3952                                         new_internalerror("Jump offset is out of range: %d > +/-%d",
3953                                                                           disp, 0x00007fff);
3954                                 return false;
3955                         }
3956
3957                         M_BR(disp);
3958                         M_NOP;
3959
3960                         mcodeptr = tmpmcodeptr;         /* restore the current mcodeptr   */
3961
3962                         /* create stack frame */
3963
3964                         M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
3965
3966                         /* calculate return address and move it onto the stack */
3967
3968                         M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3969                         M_AST(REG_ITMP3, REG_SP, 5 * 8);
3970
3971                         /* move pointer to java_objectheader onto stack */
3972
3973 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3974                         /* create a virtual java_objectheader */
3975
3976                         (void) dseg_addaddress(cd, get_dummyLR());          /* monitorPtr */
3977                         disp = dseg_addaddress(cd, NULL);                   /* vftbl      */
3978
3979                         M_LDA(REG_ITMP3, REG_PV, disp);
3980                         M_AST(REG_ITMP3, REG_SP, 4 * 8);
3981 #else
3982                         /* do nothing */
3983 #endif
3984
3985                         /* move machine code onto stack */
3986
3987                         disp = dseg_adds8(cd, mcode);
3988                         M_LLD(REG_ITMP3, REG_PV, disp);
3989                         M_LST(REG_ITMP3, REG_SP, 3 * 8);
3990
3991                         /* move class/method/field reference onto stack */
3992
3993                         disp = dseg_addaddress(cd, pref->ref);
3994                         M_ALD(REG_ITMP3, REG_PV, disp);
3995                         M_AST(REG_ITMP3, REG_SP, 2 * 8);
3996
3997                         /* move data segment displacement onto stack */
3998
3999                         disp = dseg_adds4(cd, pref->disp);
4000                         M_ILD(REG_ITMP3, REG_PV, disp);
4001                         M_IST(REG_ITMP3, REG_SP, 1 * 8);
4002
4003                         /* move patcher function pointer onto stack */
4004
4005                         disp = dseg_addaddress(cd, pref->patcher);
4006                         M_ALD(REG_ITMP3, REG_PV, disp);
4007                         M_AST(REG_ITMP3, REG_SP, 0 * 8);
4008
4009                         disp = dseg_addaddress(cd, asm_wrapper_patcher);
4010                         M_ALD(REG_ITMP3, REG_PV, disp);
4011                         M_JMP(REG_ITMP3);
4012                         M_NOP;
4013                 }
4014         }
4015         }
4016
4017         codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4018
4019         docacheflush((void *) m->entrypoint, ((u1 *) mcodeptr - cd->mcodebase));
4020
4021         /* everything's ok */
4022
4023         return true;
4024 }
4025
4026
4027 /* createcompilerstub **********************************************************
4028
4029    Creates a stub routine which calls the compiler.
4030         
4031 *******************************************************************************/
4032
4033 #define COMPILERSTUB_DATASIZE    2 * SIZEOF_VOID_P
4034 #define COMPILERSTUB_CODESIZE    4 * 4
4035
4036 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
4037
4038
4039 u1 *createcompilerstub(methodinfo *m)
4040 {
4041         ptrint *s;                          /* memory to hold the stub            */
4042         s4     *mcodeptr;                   /* code generation pointer            */
4043
4044         s = (ptrint *) CNEW(u1, COMPILERSTUB_SIZE);
4045
4046         s[0] = (ptrint) m;
4047         s[1] = (ptrint) asm_call_jit_compiler;
4048
4049         mcodeptr = (s4 *) (s + 2);
4050
4051         M_ALD(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* method pointer           */
4052         M_ALD(REG_PV, REG_PV, -1 * SIZEOF_VOID_P);    /* pointer to compiler      */
4053         M_JMP(REG_PV);
4054         M_NOP;
4055
4056         (void) docacheflush((void *) s, (char *) mcodeptr - (char *) s);
4057
4058 #if defined(STATISTICS)
4059         if (opt_stat)
4060                 count_cstub_len += COMPILERSTUB_SIZE;
4061 #endif
4062
4063         return (((u1 *) s) + COMPILERSTUB_DATASIZE);
4064 }
4065
4066
4067 /* createnativestub ************************************************************
4068
4069    Creates a stub routine which calls a native method.
4070
4071 *******************************************************************************/
4072
4073 u1 *createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4074                                          registerdata *rd, methoddesc *nmd)
4075 {
4076         s4         *mcodeptr;               /* code generation pointer            */
4077         s4          stackframesize;         /* size of stackframe if needed       */
4078         methoddesc *md;
4079         s4          nativeparams;
4080         s4          i, j;                   /* count variables                    */
4081         s4          t;
4082         s4          s1, s2, disp;
4083         s4          funcdisp;               /* displacement of the function       */
4084
4085
4086         /* initialize variables */
4087
4088         md = m->parseddesc;
4089         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4090
4091
4092         /* calculate stack frame size */
4093
4094         stackframesize =
4095                 1 +                             /* return address                     */
4096                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4097                 sizeof(localref_table) / SIZEOF_VOID_P +
4098                 md->paramcount +                /* for saving arguments over calls    */
4099                 1 +                             /* for saving return address          */
4100                 nmd->memuse;
4101
4102
4103         /* create method header */
4104
4105 #if SIZEOF_VOID_P == 4
4106         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
4107 #endif
4108         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
4109         (void) dseg_adds4(cd, stackframesize * 8);              /* FrameSize      */
4110         (void) dseg_adds4(cd, 0);                               /* IsSync         */
4111         (void) dseg_adds4(cd, 0);                               /* IsLeaf         */
4112         (void) dseg_adds4(cd, 0);                               /* IntSave        */
4113         (void) dseg_adds4(cd, 0);                               /* FltSave        */
4114         (void) dseg_addlinenumbertablesize(cd);
4115         (void) dseg_adds4(cd, 0);                               /* ExTableSize    */
4116
4117
4118         /* initialize mcode variables */
4119         
4120         mcodeptr = (s4 *) cd->mcodebase;
4121         cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
4122
4123
4124         /* generate stub code */
4125
4126         M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe        */
4127         M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra    */
4128
4129
4130         /* call trace function */
4131
4132         if (runverbose) {
4133                 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4134
4135                 /* save integer argument registers */
4136
4137                 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4138                         if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4139                                 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
4140
4141                 /* save and copy float arguments into integer registers */
4142
4143                 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4144                         t = md->paramtypes[i].type;
4145
4146                         if (IS_FLT_DBL_TYPE(t)) {
4147                                 if (IS_2_WORD_TYPE(t)) {
4148                                         M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4149                                         M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4150                                 } else {
4151                                         M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4152                                         M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4153                                 }
4154                         }
4155                 }
4156
4157                 disp = dseg_addaddress(cd, m);
4158                 M_ALD(REG_ITMP1, REG_PV, disp);
4159                 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4160                 disp = dseg_addaddress(cd, builtin_trace_args);
4161                 M_ALD(REG_ITMP3, REG_PV, disp);
4162                 M_JSR(REG_RA, REG_ITMP3);
4163                 M_NOP;
4164
4165                 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4166                         if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4167                                 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4168
4169                 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4170                         t = md->paramtypes[i].type;
4171
4172                         if (IS_FLT_DBL_TYPE(t)) {
4173                                 if (IS_2_WORD_TYPE(t)) {
4174                                         M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4175                                 } else {
4176                                         M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4177                                 }
4178                         }
4179                 }
4180
4181                 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4182         }
4183
4184
4185         /* get function address (this must happen before the stackframeinfo) */
4186
4187         funcdisp = dseg_addaddress(cd, f);
4188
4189 #if !defined(ENABLE_STATICVM)
4190         if (f == NULL) {
4191                 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
4192
4193                 if (opt_showdisassemble) {
4194                         M_NOP; M_NOP;
4195                 }
4196         }
4197 #endif
4198
4199         /* save integer and float argument registers */
4200
4201         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4202                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4203                         M_LST(rd->argintregs[i], REG_SP, j * 8);
4204                         j++;
4205                 }
4206         }
4207
4208         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4209                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4210                         M_DST(rd->argfltregs[i], REG_SP, j * 8);
4211                         j++;
4212                 }
4213         }
4214
4215         /* prepare data structures for native function call */
4216
4217         M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4218         M_MOV(REG_PV, rd->argintregs[1]);
4219         M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4220         M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4221         disp = dseg_addaddress(cd, codegen_start_native_call);
4222         M_ALD(REG_ITMP3, REG_PV, disp);
4223         M_JSR(REG_RA, REG_ITMP3);
4224         M_NOP; /* XXX fill me! */
4225
4226         /* restore integer and float argument registers */
4227
4228         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4229                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4230                         M_LLD(rd->argintregs[i], REG_SP, j * 8);
4231                         j++;
4232                 }
4233         }
4234
4235         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4236                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4237                         M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4238                         j++;
4239                 }
4240         }
4241
4242         /* copy or spill arguments to new locations */
4243
4244         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4245                 t = md->paramtypes[i].type;
4246
4247                 if (IS_INT_LNG_TYPE(t)) {
4248                         if (!md->params[i].inmemory) {
4249                                 s1 = rd->argintregs[md->params[i].regoff];
4250
4251                                 if (!nmd->params[j].inmemory) {
4252                                         s2 = rd->argintregs[nmd->params[j].regoff];
4253                                         M_INTMOVE(s1, s2);
4254                                 } else {
4255                                         s2 = nmd->params[j].regoff;
4256                                         M_AST(s1, REG_SP, s2 * 8);
4257                                 }
4258
4259                         } else {
4260                                 s1 = md->params[i].regoff + stackframesize;
4261                                 s2 = nmd->params[j].regoff;
4262                                 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4263                                 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4264                         }
4265
4266                 } else {
4267                         if (!md->params[i].inmemory) {
4268                                 s1 = rd->argfltregs[md->params[i].regoff];
4269
4270                                 if (!nmd->params[j].inmemory) {
4271                                         s2 = rd->argfltregs[nmd->params[j].regoff];
4272                                         M_TFLTMOVE(t, s1, s2);
4273                                 } else {
4274                                         s2 = nmd->params[j].regoff;
4275                                         if (IS_2_WORD_TYPE(t))
4276                                                 M_DST(s1, REG_SP, s2 * 8);
4277                                         else
4278                                                 M_FST(s1, REG_SP, s2 * 8);
4279                                 }
4280
4281                         } else {
4282                                 s1 = md->params[i].regoff + stackframesize;
4283                                 s2 = nmd->params[j].regoff;
4284                                 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4285                                 if (IS_2_WORD_TYPE(t))
4286                                         M_DST(REG_FTMP1, REG_SP, s2 * 8);
4287                                 else
4288                                         M_FST(REG_FTMP1, REG_SP, s2 * 8);
4289                         }
4290                 }
4291         }
4292
4293         /* put class into second argument register */
4294
4295         if (m->flags & ACC_STATIC) {
4296                 disp = dseg_addaddress(cd, m->class);
4297                 M_ALD(rd->argintregs[1], REG_PV, disp);
4298         }
4299
4300         /* put env into first argument register */
4301
4302         disp = dseg_addaddress(cd, &env);
4303         M_ALD(rd->argintregs[0], REG_PV, disp);
4304
4305         /* do the native function call */
4306
4307         M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method       */
4308         M_JSR(REG_RA, REG_ITMP3);           /* call native method                 */
4309         M_NOP;                              /* delay slot                         */
4310
4311         /* save return value */
4312
4313         if (IS_INT_LNG_TYPE(md->returntype.type))
4314                 M_LST(REG_RESULT, REG_SP, 0 * 8);
4315         else
4316                 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4317
4318         /* remove native stackframe info */
4319
4320         M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4321         disp = dseg_addaddress(cd, codegen_finish_native_call);
4322         M_ALD(REG_ITMP3, REG_PV, disp);
4323         M_JSR(REG_RA, REG_ITMP3);
4324         M_NOP; /* XXX fill me! */
4325
4326         /* call finished trace function */
4327
4328         if (runverbose) {
4329                 if (IS_INT_LNG_TYPE(md->returntype.type))
4330                         M_LLD(REG_RESULT, REG_SP, 0 * 8);
4331                 else
4332                         M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4333
4334                 disp = dseg_addaddress(cd, m);
4335                 M_ALD(rd->argintregs[0], REG_PV, disp);
4336
4337                 M_MOV(REG_RESULT, rd->argintregs[1]);
4338                 M_DMFC1(REG_ITMP1, REG_FRESULT);
4339                 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4340                 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4341
4342                 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4343                 M_ALD(REG_ITMP3, REG_PV, disp);
4344                 M_JSR(REG_RA, REG_ITMP3);
4345                 M_NOP;
4346         }
4347
4348         /* check for exception */
4349
4350 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4351         disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4352         M_ALD(REG_ITMP3, REG_PV, disp);
4353         M_JSR(REG_RA, REG_ITMP3);
4354         M_NOP;
4355         M_MOV(REG_RESULT, REG_ITMP3);
4356 #else
4357         disp = dseg_addaddress(cd, &_exceptionptr);
4358         M_ALD(REG_ITMP3, REG_PV, disp);     /* get address of exceptionptr        */
4359 #endif
4360         M_ALD(REG_ITMP1, REG_ITMP3, 0);     /* load exception into reg. itmp1     */
4361
4362         M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra     */
4363
4364         /* restore return value */
4365
4366         if (IS_INT_LNG_TYPE(md->returntype.type))
4367                 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4368         else
4369                 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4370
4371         M_BNEZ(REG_ITMP1, 2);               /* if no exception then return        */
4372         M_LDA(REG_SP, REG_SP, stackframesize * 8);/* remove stackframe, DELAY SLOT*/
4373
4374         M_RET(REG_RA);                      /* return to caller                   */
4375         M_NOP;                              /* DELAY SLOT                         */
4376
4377         /* handle exception */
4378         
4379         M_AST(REG_ZERO, REG_ITMP3, 0);      /* store NULL into exceptionptr       */
4380
4381         disp = dseg_addaddress(cd, asm_handle_nat_exception);
4382         M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
4383         M_JMP(REG_ITMP3);                   /* jump to asm exception handler      */
4384         M_LDA(REG_ITMP2, REG_RA, -4);       /* move fault address into reg. itmp2 */
4385                                             /* DELAY SLOT                         */
4386
4387         /* generate static stub call code                                         */
4388
4389         {
4390                 patchref *pref;
4391                 s4       *xcodeptr;
4392                 s8        mcode;
4393                 s4       *tmpmcodeptr;
4394
4395                 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4396                         /* Get machine code which is patched back in later. The call is   */
4397                         /* 2 instruction words long.                                      */
4398
4399                         xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4400
4401                         /* We need to split this, because an unaligned 8 byte read causes */
4402                         /* a SIGSEGV.                                                     */
4403
4404                         mcode = ((u8) xcodeptr[1] << 32) + (u4) xcodeptr[0];
4405
4406                         /* patch in the call to call the following code (done at compile  */
4407                         /* time)                                                          */
4408
4409                         tmpmcodeptr = mcodeptr;         /* save current mcodeptr          */
4410                         mcodeptr = xcodeptr;            /* set mcodeptr to patch position */
4411
4412                         M_BRS(tmpmcodeptr - (xcodeptr + 1));
4413                         M_NOP;                          /* branch delay slot              */
4414
4415                         mcodeptr = tmpmcodeptr;         /* restore the current mcodeptr   */
4416
4417                         /* create stack frame                                             */
4418
4419                         M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4420
4421                         /* move return address onto stack */
4422
4423                         M_AST(REG_RA, REG_SP, 5 * 8);
4424
4425                         /* move pointer to java_objectheader onto stack */
4426
4427 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4428                         /* order reversed because of data segment layout */
4429
4430                         (void) dseg_addaddress(cd, get_dummyLR());          /* monitorPtr */
4431                         disp = dseg_addaddress(cd, NULL);                   /* vftbl      */
4432
4433                         M_LDA(REG_ITMP3, REG_PV, disp);
4434                         M_AST(REG_ITMP3, REG_SP, 4 * 8);
4435 #else
4436                         M_AST(REG_ZERO, REG_SP, 4 * 8);
4437 #endif
4438
4439                         /* move machine code onto stack */
4440
4441                         disp = dseg_adds8(cd, mcode);
4442                         M_LLD(REG_ITMP3, REG_PV, disp);
4443                         M_LST(REG_ITMP3, REG_SP, 3 * 8);
4444
4445                         /* move class/method/field reference onto stack */
4446
4447                         disp = dseg_addaddress(cd, pref->ref);
4448                         M_ALD(REG_ITMP3, REG_PV, disp);
4449                         M_AST(REG_ITMP3, REG_SP, 2 * 8);
4450
4451                         /* move data segment displacement onto stack */
4452
4453                         disp = dseg_adds4(cd, pref->disp);
4454                         M_ILD(REG_ITMP3, REG_PV, disp);
4455                         M_IST(REG_ITMP3, REG_SP, 1 * 8);
4456
4457                         /* move patcher function pointer onto stack */
4458
4459                         disp = dseg_addaddress(cd, pref->patcher);
4460                         M_ALD(REG_ITMP3, REG_PV, disp);
4461                         M_AST(REG_ITMP3, REG_SP, 0 * 8);
4462
4463                         disp = dseg_addaddress(cd, asm_wrapper_patcher);
4464                         M_ALD(REG_ITMP3, REG_PV, disp);
4465                         M_JMP(REG_ITMP3);
4466                         M_NOP;
4467                 }
4468         }
4469
4470         codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4471
4472         docacheflush((void *) m->entrypoint, ((u1 *) mcodeptr - cd->mcodebase));
4473
4474         return m->entrypoint;
4475 }
4476
4477
4478 /*
4479  * These are local overrides for various environment variables in Emacs.
4480  * Please do not remove this and leave it at the end of the file, where
4481  * Emacs will automagically detect them.
4482  * ---------------------------------------------------------------------
4483  * Local variables:
4484  * mode: c
4485  * indent-tabs-mode: t
4486  * c-basic-offset: 4
4487  * tab-width: 4
4488  * End:
4489  */