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