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