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