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