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