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