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