Merged changes from trunk.
[cacao.git] / src / vm / jit / mips / codegen.c
1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
2
3    Copyright (C) 1996-2005, 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: Christian Thalinger
31             Christian Ullrich
32             Edwin Steiner
33
34    Contains the codegenerator for an MIPS (R4000 or higher) processor.
35    This module generates MIPS machine code for a sequence of
36    intermediate code commands (ICMDs).
37
38    $Id: codegen.c 5324 2006-09-05 17:11:32Z twisti $
39
40 */
41
42
43 #include "config.h"
44
45 #include <assert.h>
46 #include <stdio.h>
47
48 #include "vm/types.h"
49
50 #include "md.h"
51 #include "md-abi.h"
52
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
55
56 #include "native/native.h"
57
58 #if defined(ENABLE_THREADS)
59 # include "threads/native/lock.h"
60 #endif
61
62 #include "vm/builtin.h"
63 #include "vm/class.h"
64 #include "vm/exceptions.h"
65 #include "vm/options.h"
66 #include "vm/stringlocal.h"
67 #include "vm/vm.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/codegen-common.h"
70 #include "vm/jit/dseg.h"
71 #include "vm/jit/emit.h"
72 #include "vm/jit/jit.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
76
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
79 #endif
80
81
82 /* codegen *********************************************************************
83
84    Generates machine code.
85
86 *******************************************************************************/
87
88 bool codegen(jitdata *jd)
89 {
90         methodinfo         *m;
91         codeinfo           *code;
92         codegendata        *cd;
93         registerdata       *rd;
94         s4                  len, s1, s2, s3, d, disp;
95         ptrint              a;
96         stackptr            src;
97         varinfo            *var;
98         basicblock         *bptr;
99         instruction        *iptr;
100         exceptiontable     *ex;
101         u2                  currentline;
102         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
103         builtintable_entry *bte;
104         methoddesc         *md;
105         rplpoint           *replacementpoint;
106
107         /* get required compiler data */
108
109         m    = jd->m;
110         code = jd->code;
111         cd   = jd->cd;
112         rd   = jd->rd;
113
114         {
115         s4 i, p, t, l;
116         s4 savedregs_num;
117
118         savedregs_num = (jd->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         cd->stackframesize = rd->memuse + savedregs_num;
126
127 #if defined(ENABLE_THREADS)
128         /* space to save argument of monitor_enter */
129
130         if (checksync && (m->flags & ACC_SYNCHRONIZED))
131                 cd->stackframesize++;
132 #endif
133
134         /* keep stack 16-byte aligned */
135
136         if (cd->stackframesize & 1)
137                 cd->stackframesize++;
138
139         /* create method header */
140
141 #if SIZEOF_VOID_P == 4
142         (void) dseg_addaddress(cd, code);                      /* Filler          */
143 #endif
144         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
145         (void) dseg_adds4(cd, cd->stackframesize * 8);         /* FrameSize       */
146
147 #if defined(ENABLE_THREADS)
148         /* IsSync contains the offset relative to the stack pointer for the
149            argument of monitor_exit used in the exception handler. Since the
150            offset could be zero and give a wrong meaning of the flag it is
151            offset by one.
152         */
153
154         if (checksync && (m->flags & ACC_SYNCHRONIZED))
155                 (void) dseg_adds4(cd, (rd->memuse + 1) * 8);       /* IsSync          */
156         else
157 #endif
158                 (void) dseg_adds4(cd, 0);                          /* IsSync          */
159                                                
160         (void) dseg_adds4(cd, jd->isleafmethod);               /* IsLeaf          */
161         (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave         */
162         (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave         */
163         dseg_addlinenumbertablesize(cd);
164         (void) dseg_adds4(cd, cd->exceptiontablelength);       /* ExTableSize     */
165
166         /* create exception table */
167
168         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
169                 dseg_addtarget(cd, ex->start);
170                 dseg_addtarget(cd, ex->end);
171                 dseg_addtarget(cd, ex->handler);
172                 (void) dseg_addaddress(cd, ex->catchtype.cls);
173         }
174         
175         /* create stack frame (if necessary) */
176
177         if (cd->stackframesize)
178                 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
179
180         /* save return address and used callee saved registers */
181
182         p = cd->stackframesize;
183         if (!jd->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_AST(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                                 } else {                             /* reg arg -> spilled    */
212                                         M_LST(s2, REG_SP, var->regoff * 8);
213                                 }
214
215                         } else {                                 /* stack arguments       */
216                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
217                                         M_LLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
218                                 } else {                             /* stack arg -> spilled  */
219                                         var->regoff = cd->stackframesize + s1;
220                                 }
221                         }
222
223                 } else {                                     /* floating args         */
224                         if (!md->params[p].inmemory) {           /* register arguments    */
225                                 s2 = rd->argfltregs[s1];
226                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
227                                         if (IS_2_WORD_TYPE(t))
228                                                 M_DMOV(s2, var->regoff);
229                                         else
230                                                 M_FMOV(s2, var->regoff);
231                                 } else {                                         /* reg arg -> spilled    */
232                                         if (IS_2_WORD_TYPE(t))
233                                                 M_DST(s2, REG_SP, var->regoff * 8);
234                                         else
235                                                 M_FST(s2, REG_SP, var->regoff * 8);
236                                 }
237
238                         } else {                                 /* stack arguments       */
239                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
240                                         if (IS_2_WORD_TYPE(t))
241                                                 M_DLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
242                                         else
243                                                 M_FLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
244                                 } else                               /* stack-arg -> spilled  */
245                                         var->regoff = cd->stackframesize + s1;
246                         }
247                 }
248         } /* end for */
249
250         /* call monitorenter function */
251
252 #if defined(ENABLE_THREADS)
253         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
254                 /* stack offset for monitor argument */
255
256                 s1 = rd->memuse;
257
258 # if !defined(NDEBUG)
259                 if (opt_verbosecall) {
260                         M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
261
262                         for (p = 0; p < INT_ARG_CNT; p++)
263                                 M_LST(rd->argintregs[p], REG_SP, p * 8);
264
265                         for (p = 0; p < FLT_ARG_CNT; p++)
266                                 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
267
268                         s1 += INT_ARG_CNT + FLT_ARG_CNT;
269                 }
270 # endif
271
272                 /* get correct lock object */
273
274                 if (m->flags & ACC_STATIC) {
275                         p = dseg_addaddress(cd, &m->class->object.header);
276                         M_ALD(rd->argintregs[0], REG_PV, p);
277                 }
278                 else {
279                         M_BEQZ(rd->argintregs[0], 0);
280                         codegen_add_nullpointerexception_ref(cd);
281                 }
282
283                 p = dseg_addaddress(cd, LOCK_monitor_enter);
284                 M_ALD(REG_ITMP3, REG_PV, p);
285                 M_JSR(REG_RA, REG_ITMP3);
286                 M_AST(rd->argintregs[0], REG_SP, s1 * 8);         /* branch delay */
287
288 # if !defined(NDEBUG)
289                 if (opt_verbosecall) {
290                         for (p = 0; p < INT_ARG_CNT; p++)
291                                 M_LLD(rd->argintregs[p], REG_SP, p * 8);
292
293                         for (p = 0; p < FLT_ARG_CNT; p++)
294                                 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
295
296
297                         M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
298                 }
299 # endif
300         }
301 #endif
302
303 #if !defined(NDEBUG)
304         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
305                 emit_verbosecall_enter(jd);
306 #endif
307
308         }
309
310         /* end of header generation */
311
312         replacementpoint = jd->code->rplpoints;
313
314         /* walk through all basic blocks */
315
316         for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
317
318                 /* handle replacement points */
319
320                 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
321
322                         /* 8-byte align pc */
323                         if ((ptrint) cd->mcodeptr & 4) {
324                                 M_NOP;
325                         }
326                         
327                         replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
328                         replacementpoint++;
329
330                         assert(cd->lastmcodeptr <= cd->mcodeptr);
331                         cd->lastmcodeptr = cd->mcodeptr + 2 * 4;       /* br + delay slot */
332                 }
333
334                 /* store relative start of block */
335
336                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
337
338                 if (bptr->flags >= BBREACHED) {
339
340                         /* branch resolving */
341                         {
342                                 branchref *bref;
343                                 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
344                                         gen_resolvebranch(cd->mcodebase + bref->branchpos, 
345                                                                           bref->branchpos,
346                                                                           bptr->mpc);
347                                 }
348                         }
349
350                 /* copy interface registers to their destination */
351
352                 src = bptr->instack;
353                 len = bptr->indepth;
354                 MCODECHECK(64+len);
355 #if defined(ENABLE_LSRA)
356                 if (opt_lsra) {
357                 while (src != NULL) {
358                         len--;
359                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
360                                         /*                              d = reg_of_var(m, src, REG_ITMP1); */
361                                         if (!(src->flags & INMEMORY))
362                                                 d= src->regoff;
363                                         else
364                                                 d=REG_ITMP1;
365                                         M_INTMOVE(REG_ITMP1, d);
366                                         emit_store(jd, NULL, src, d);
367                                 }
368                                 src = src->prev;
369                         }
370                 } else {
371 #endif
372                 while (src != NULL) {
373                         len--;
374                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
375                                 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
376                                 M_INTMOVE(REG_ITMP1, d);
377                                 emit_store(jd, NULL, src, d);
378
379                         } else {
380                                 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
381                                 if ((src->varkind != STACKVAR)) {
382                                         s2 = src->type;
383                                         s1 = rd->interfaces[len][s2].regoff;
384                                         if (IS_FLT_DBL_TYPE(s2)) {
385                                                 if (rd->interfaces[len][s2].flags & INMEMORY) {
386                                                         if (IS_2_WORD_TYPE(s2))
387                                                                 M_DLD(d, REG_SP, s1 * 8);
388                                                         else
389                                                                 M_FLD(d, REG_SP, s1 * 8);
390
391                                                 } else {
392                                                         if (IS_2_WORD_TYPE(s2))
393                                                                 M_DMOV(s1, d);
394                                                         else
395                                                                 M_FMOV(s1, d);
396                                                 }
397
398                                         } else {
399                                                 if (rd->interfaces[len][s2].flags & INMEMORY)
400                                                         M_LLD(d, REG_SP, s1 * 8);
401                                                 else
402                                                         M_INTMOVE(s1,d);
403                                         }
404
405                                         emit_store(jd, NULL, src, d);
406                                 }
407                         }
408                         src = src->prev;
409                 }
410 #if defined(ENABLE_LSRA)
411                 }
412 #endif
413                 /* walk through all instructions */
414                 
415                 src = bptr->instack;
416                 len = bptr->icount;
417                 currentline = 0;
418
419                 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
420                         if (iptr->line != currentline) {
421                                 dseg_addlinenumber(cd, iptr->line);
422                                 currentline = iptr->line;
423                         }
424
425                         MCODECHECK(64);   /* an instruction usually needs < 64 words      */
426
427                         switch (iptr->opc) {
428
429                 case ICMD_NOP:        /* ...  ==> ...                                 */
430                         break;
431
432                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
433
434                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
435                         M_BEQZ(s1, 0);
436                         codegen_add_nullpointerexception_ref(cd);
437                         M_NOP;
438                         break;
439
440                 /* constant operations ************************************************/
441
442                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
443                                       /* op1 = 0, val.i = constant                    */
444
445                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
446                         ICONST(d, iptr->val.i);
447                         emit_store(jd, iptr, iptr->dst, d);
448                         break;
449
450                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
451                                       /* op1 = 0, val.l = constant                    */
452
453                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
454                         LCONST(d, iptr->val.l);
455                         emit_store(jd, iptr, iptr->dst, d);
456                         break;
457
458                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
459                                       /* op1 = 0, val.f = constant                    */
460
461                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
462                         disp = dseg_addfloat(cd, iptr->val.f);
463                         M_FLD(d, REG_PV, disp);
464                         emit_store(jd, iptr, iptr->dst, d);
465                         break;
466                         
467                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
468                                       /* op1 = 0, val.d = constant                    */
469
470                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
471                         disp = dseg_adddouble(cd, iptr->val.d);
472                         M_DLD(d, REG_PV, disp);
473                         emit_store(jd, iptr, iptr->dst, d);
474                         break;
475
476                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
477                                       /* op1 = 0, val.a = constant                    */
478
479                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
480
481                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
482                                 disp = dseg_addaddress(cd, NULL);
483
484                                 codegen_addpatchref(cd, PATCHER_aconst,
485                                                                         ICMD_ACONST_UNRESOLVED_CLASSREF(iptr),
486                                                                     disp);
487
488                                 if (opt_showdisassemble) {
489                                         M_NOP; M_NOP;
490                                 }
491
492                                 M_ALD(d, REG_PV, disp);
493
494                         } else {
495                                 if (iptr->val.a == NULL) {
496                                         M_INTMOVE(REG_ZERO, d);
497                                 } else {
498                                         disp = dseg_addaddress(cd, iptr->val.a);
499                                         M_ALD(d, REG_PV, disp);
500                                 }
501                         }
502                         emit_store(jd, iptr, iptr->dst, d);
503                         break;
504
505
506                 /* load/store operations **********************************************/
507
508                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
509                                       /* op1 = local variable                         */
510
511                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
512                         if ((iptr->dst->varkind == LOCALVAR) &&
513                             (iptr->dst->varnum == iptr->op1))
514                                 break;
515                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
516                         if (var->flags & INMEMORY)
517 #if SIZEOF_VOID_P == 8
518                                 M_LLD(d, REG_SP, var->regoff * 8);
519 #else
520                                 M_ILD(d, REG_SP, var->regoff * 8);
521 #endif
522                         else
523                                 M_INTMOVE(var->regoff,d);
524                         emit_store(jd, iptr, iptr->dst, d);
525                         break;
526
527                 case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
528                                       /* op1 = local variable                         */
529
530                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
531                         if ((iptr->dst->varkind == LOCALVAR) &&
532                             (iptr->dst->varnum == iptr->op1))
533                                 break;
534                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
535                         if (var->flags & INMEMORY)
536                                 M_LLD(d, REG_SP, var->regoff * 8);
537                         else
538                                 M_INTMOVE(var->regoff,d);
539                         emit_store(jd, iptr, iptr->dst, d);
540                         break;
541
542                 case ICMD_ALOAD:      /* ...  ==> ..., content of local variable      */
543                                       /* op1 = local variable                         */
544
545                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
546                         if ((iptr->dst->varkind == LOCALVAR) &&
547                             (iptr->dst->varnum == iptr->op1))
548                                 break;
549                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
550                         if (var->flags & INMEMORY)
551                                 M_ALD(d, REG_SP, var->regoff * 8);
552                         else
553                                 M_INTMOVE(var->regoff,d);
554                         emit_store(jd, iptr, iptr->dst, d);
555                         break;
556
557                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
558                                       /* op1 = local variable                         */
559
560                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
561                         if ((iptr->dst->varkind == LOCALVAR) &&
562                             (iptr->dst->varnum == iptr->op1))
563                                 break;
564                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
565                         if (var->flags & INMEMORY)
566                                 M_FLD(d, REG_SP, var->regoff * 8);
567                         else
568                                 M_FMOV(var->regoff, d);
569                         emit_store(jd, iptr, iptr->dst, d);
570                         break;
571
572                 case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
573                                       /* op1 = local variable                         */
574
575                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
576                         if ((iptr->dst->varkind == LOCALVAR) &&
577                             (iptr->dst->varnum == iptr->op1))
578                                 break;
579                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
580                         if (var->flags & INMEMORY)
581                                 M_DLD(d, REG_SP, var->regoff * 8);
582                         else
583                                 M_DMOV(var->regoff, d);
584                         emit_store(jd, iptr, iptr->dst, d);
585                         break;
586
587
588                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
589                                       /* op1 = local variable                         */
590
591                         if ((src->varkind == LOCALVAR) &&
592                             (src->varnum == iptr->op1))
593                                 break;
594                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
595                         if (var->flags & INMEMORY) {
596                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
597 #if SIZEOF_VOID_P == 8
598                                 M_LST(s1, REG_SP, var->regoff * 8);
599 #else
600                                 M_IST(s1, REG_SP, var->regoff * 8);
601 #endif
602                         } else {
603                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
604                                 M_INTMOVE(s1, var->regoff);
605                         }
606                         break;
607
608                 case ICMD_LSTORE:     /* ..., value  ==> ...                          */
609                                       /* op1 = local variable                         */
610
611                         if ((src->varkind == LOCALVAR) &&
612                             (src->varnum == iptr->op1))
613                                 break;
614                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
615                         if (var->flags & INMEMORY) {
616                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
617                                 M_LST(s1, REG_SP, var->regoff * 8);
618                         } else {
619                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
620                                 M_INTMOVE(s1, var->regoff);
621                         }
622                         break;
623
624                 case ICMD_ASTORE:     /* ..., value  ==> ...                          */
625                                       /* op1 = local variable                         */
626
627                         if ((src->varkind == LOCALVAR) &&
628                             (src->varnum == iptr->op1))
629                                 break;
630                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
631                         if (var->flags & INMEMORY) {
632                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
633                                 M_AST(s1, REG_SP, var->regoff * 8);
634                         } else {
635                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
636                                 M_INTMOVE(s1, var->regoff);
637                         }
638                         break;
639
640                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
641                                       /* op1 = local variable                         */
642
643                         if ((src->varkind == LOCALVAR) &&
644                             (src->varnum == iptr->op1))
645                                 break;
646                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
647                         if (var->flags & INMEMORY) {
648                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
649                                 M_FST(s1, REG_SP, var->regoff * 8);
650                         } else {
651                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
652                                 M_FMOV(s1, var->regoff);
653                         }
654                         break;
655
656                 case ICMD_DSTORE:     /* ..., value  ==> ...                          */
657                                       /* op1 = local variable                         */
658
659                         if ((src->varkind == LOCALVAR) &&
660                             (src->varnum == iptr->op1))
661                                 break;
662                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
663                         if (var->flags & INMEMORY) {
664                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
665                                 M_DST(s1, REG_SP, var->regoff * 8);
666                         } else {
667                                 s1 = emit_load_s1(jd, iptr, src, var->regoff);
668                                 M_DMOV(s1, var->regoff);
669                         }
670                         break;
671
672
673                 /* pop/dup/swap operations ********************************************/
674
675                 /* attention: double and longs are only one entry in CACAO ICMDs      */
676
677                 case ICMD_POP:        /* ..., value  ==> ...                          */
678                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
679                         break;
680
681                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
682                         M_COPY(src, iptr->dst);
683                         break;
684
685                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
686
687                         M_COPY(src,       iptr->dst);
688                         M_COPY(src->prev, iptr->dst->prev);
689                         M_COPY(iptr->dst, iptr->dst->prev->prev);
690                         break;
691
692                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
693
694                         M_COPY(src,             iptr->dst);
695                         M_COPY(src->prev,       iptr->dst->prev);
696                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
697                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
698                         break;
699
700                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
701
702                         M_COPY(src,       iptr->dst);
703                         M_COPY(src->prev, iptr->dst->prev);
704                         break;
705
706                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
707
708                         M_COPY(src,             iptr->dst);
709                         M_COPY(src->prev,       iptr->dst->prev);
710                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
711                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
712                         M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
713                         break;
714
715                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
716
717                         M_COPY(src,                   iptr->dst);
718                         M_COPY(src->prev,             iptr->dst->prev);
719                         M_COPY(src->prev->prev,       iptr->dst->prev->prev);
720                         M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
721                         M_COPY(iptr->dst,             iptr->dst->prev->prev->prev->prev);
722                         M_COPY(iptr->dst->prev,       iptr->dst->prev->prev->prev->prev->prev);
723                         break;
724
725                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
726
727                         M_COPY(src,       iptr->dst->prev);
728                         M_COPY(src->prev, iptr->dst);
729                         break;
730
731
732                 /* integer operations *************************************************/
733
734                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
735
736                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1); 
737                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
738                         M_ISUB(REG_ZERO, s1, d);
739                         emit_store(jd, iptr, iptr->dst, d);
740                         break;
741
742                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
743
744                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
745                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
746                         M_LSUB(REG_ZERO, s1, d);
747                         emit_store(jd, iptr, iptr->dst, d);
748                         break;
749
750                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
751
752                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
753                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
754                         M_INTMOVE(s1, d);
755                         emit_store(jd, iptr, iptr->dst, d);
756                         break;
757
758                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
759
760                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
761                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
762                         M_ISLL_IMM(s1, 0, d );
763                         emit_store(jd, iptr, iptr->dst, d);
764                         break;
765
766                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
767
768                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
769                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
770                         M_LSLL_IMM(s1, 56, d);
771                         M_LSRA_IMM( d, 56, d);
772                         emit_store(jd, iptr, iptr->dst, d);
773                         break;
774
775                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
776
777                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
778                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
779             M_CZEXT(s1, d);
780                         emit_store(jd, iptr, iptr->dst, d);
781                         break;
782
783                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
784
785                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
786                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
787                         M_LSLL_IMM(s1, 48, d);
788                         M_LSRA_IMM( d, 48, d);
789                         emit_store(jd, iptr, iptr->dst, d);
790                         break;
791
792
793                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
794
795                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
796                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
797                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
798                         M_IADD(s1, s2, d);
799                         emit_store(jd, iptr, iptr->dst, d);
800                         break;
801
802                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
803                                       /* val.i = constant                             */
804
805                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
806                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
807                         if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
808                                 M_IADD_IMM(s1, iptr->val.i, d);
809                         } else {
810                                 ICONST(REG_ITMP2, iptr->val.i);
811                                 M_IADD(s1, REG_ITMP2, d);
812                         }
813                         emit_store(jd, iptr, iptr->dst, d);
814                         break;
815
816                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
817
818                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
819                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
820                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
821                         M_LADD(s1, s2, d);
822                         emit_store(jd, iptr, iptr->dst, d);
823                         break;
824
825                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
826                                       /* val.l = constant                             */
827
828                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
829                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
830                         if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
831                                 M_LADD_IMM(s1, iptr->val.l, d);
832                         } else {
833                                 LCONST(REG_ITMP2, iptr->val.l);
834                                 M_LADD(s1, REG_ITMP2, d);
835                         }
836                         emit_store(jd, iptr, iptr->dst, d);
837                         break;
838
839                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
840
841                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
842                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
843                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
844                         M_ISUB(s1, s2, d);
845                         emit_store(jd, iptr, iptr->dst, d);
846                         break;
847
848                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
849                                       /* val.i = constant                             */
850
851                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
852                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
853                         if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
854                                 M_IADD_IMM(s1, -iptr->val.i, d);
855                         } else {
856                                 ICONST(REG_ITMP2, iptr->val.i);
857                                 M_ISUB(s1, REG_ITMP2, d);
858                         }
859                         emit_store(jd, iptr, iptr->dst, d);
860                         break;
861
862                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
863
864                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
865                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
866                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
867                         M_LSUB(s1, s2, d);
868                         emit_store(jd, iptr, iptr->dst, d);
869                         break;
870
871                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
872                                       /* val.l = constant                             */
873
874                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
875                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
876                         if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
877                                 M_LADD_IMM(s1, -iptr->val.l, d);
878                         } else {
879                                 LCONST(REG_ITMP2, iptr->val.l);
880                                 M_LSUB(s1, REG_ITMP2, d);
881                         }
882                         emit_store(jd, iptr, iptr->dst, d);
883                         break;
884
885                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
886
887                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
888                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
889                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
890                         M_IMUL(s1, s2);
891                         M_MFLO(d);
892                         M_NOP;
893                         M_NOP;
894                         emit_store(jd, iptr, iptr->dst, d);
895                         break;
896
897                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
898                                       /* val.i = constant                             */
899
900                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
901                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
902                         ICONST(REG_ITMP2, iptr->val.i);
903                         M_IMUL(s1, REG_ITMP2);
904                         M_MFLO(d);
905                         M_NOP;
906                         M_NOP;
907                         emit_store(jd, iptr, iptr->dst, d);
908                         break;
909
910                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
911
912                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
913                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
914                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
915                         M_LMUL(s1, s2);
916                         M_MFLO(d);
917                         M_NOP;
918                         M_NOP;
919                         emit_store(jd, iptr, iptr->dst, d);
920                         break;
921
922                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
923                                       /* val.l = constant                             */
924
925                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
926                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
927                         LCONST(REG_ITMP2, iptr->val.l);
928                         M_LMUL(s1, REG_ITMP2);
929                         M_MFLO(d);
930                         M_NOP;
931                         M_NOP;
932                         emit_store(jd, iptr, iptr->dst, d);
933                         break;
934
935                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
936
937                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
938                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
939                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
940                         gen_div_check(s2);
941                         M_IDIV(s1, s2);
942                         M_MFLO(d);
943                         M_NOP;
944                         M_NOP;
945                         emit_store(jd, iptr, iptr->dst, d);
946                         break;
947
948                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
949
950                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
951                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
952                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
953                         gen_div_check(s2);
954                         M_LDIV(s1, s2);
955                         M_MFLO(d);
956                         M_NOP;
957                         M_NOP;
958                         emit_store(jd, iptr, iptr->dst, d);
959                         break;
960
961                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
962
963                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
964                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
965                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
966                         gen_div_check(s2);
967                         M_IDIV(s1, s2);
968                         M_MFHI(d);
969                         M_NOP;
970                         M_NOP;
971                         emit_store(jd, iptr, iptr->dst, d);
972                         break;
973
974                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
975
976                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
977                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
978                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
979                         gen_div_check(s2);
980                         M_LDIV(s1, s2);
981                         M_MFHI(d);
982                         M_NOP;
983                         M_NOP;
984                         emit_store(jd, iptr, iptr->dst, d);
985                         break;
986
987                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
988                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
989                                       
990                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
991                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
992                         M_LSRA_IMM(s1, 63, REG_ITMP2);
993                         M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
994                         M_LADD(s1, REG_ITMP2, REG_ITMP2);
995                         M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
996                         emit_store(jd, iptr, iptr->dst, d);
997                         break;
998
999                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1000
1001                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1002                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1003                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1004                         M_ISLL(s1, s2, d);
1005                         emit_store(jd, iptr, iptr->dst, d);
1006                         break;
1007
1008                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1009                                       /* val.i = constant                             */
1010
1011                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1012                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1013                         M_ISLL_IMM(s1, iptr->val.i, d);
1014                         emit_store(jd, iptr, iptr->dst, d);
1015                         break;
1016
1017                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1018
1019                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1020                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1021                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1022                         M_ISRA(s1, s2, d);
1023                         emit_store(jd, iptr, iptr->dst, d);
1024                         break;
1025
1026                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1027                                       /* val.i = constant                             */
1028
1029                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1030                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1031                         M_ISRA_IMM(s1, iptr->val.i, d);
1032                         emit_store(jd, iptr, iptr->dst, d);
1033                         break;
1034
1035                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1036
1037                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1038                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1039                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1040                         M_ISRL(s1, s2, d);
1041                         emit_store(jd, iptr, iptr->dst, d);
1042                         break;
1043
1044                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1045                                       /* val.i = constant                             */
1046
1047                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1048                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1049                         M_ISRL_IMM(s1, iptr->val.i, d);
1050                         emit_store(jd, iptr, iptr->dst, d);
1051                         break;
1052
1053                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1054
1055                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1056                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1057                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1058                         M_LSLL(s1, s2, d);
1059                         emit_store(jd, iptr, iptr->dst, d);
1060                         break;
1061
1062                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1063                                       /* val.i = constant                             */
1064
1065                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1066                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1067                         M_LSLL_IMM(s1, iptr->val.i, d);
1068                         emit_store(jd, iptr, iptr->dst, d);
1069                         break;
1070
1071                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1072
1073                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1074                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1075                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1076                         M_LSRA(s1, s2, d);
1077                         emit_store(jd, iptr, iptr->dst, d);
1078                         break;
1079
1080                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1081                                       /* val.i = constant                             */
1082
1083                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1084                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1085                         M_LSRA_IMM(s1, iptr->val.i, d);
1086                         emit_store(jd, iptr, iptr->dst, d);
1087                         break;
1088
1089                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1090
1091                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1092                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1093                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1094                         M_LSRL(s1, s2, d);
1095                         emit_store(jd, iptr, iptr->dst, d);
1096                         break;
1097
1098                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1099                                       /* val.i = constant                             */
1100
1101                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1102                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1103                         M_LSRL_IMM(s1, iptr->val.i, d);
1104                         emit_store(jd, iptr, iptr->dst, d);
1105                         break;
1106
1107                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1108                 case ICMD_LAND:
1109
1110                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1111                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1112                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1113                         M_AND(s1, s2, d);
1114                         emit_store(jd, iptr, iptr->dst, d);
1115                         break;
1116
1117                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1118                                       /* val.i = constant                             */
1119
1120                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1121                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1122                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1123                                 M_AND_IMM(s1, iptr->val.i, d);
1124                         } else {
1125                                 ICONST(REG_ITMP2, iptr->val.i);
1126                                 M_AND(s1, REG_ITMP2, d);
1127                         }
1128                         emit_store(jd, iptr, iptr->dst, d);
1129                         break;
1130
1131                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1132                                       /* val.i = constant                             */
1133
1134                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1135                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1136                         if (s1 == d) {
1137                                 M_MOV(s1, REG_ITMP1);
1138                                 s1 = REG_ITMP1;
1139                         }
1140                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1141                                 M_AND_IMM(s1, iptr->val.i, d);
1142                                 M_BGEZ(s1, 4);
1143                                 M_NOP;
1144                                 M_ISUB(REG_ZERO, s1, d);
1145                                 M_AND_IMM(d, iptr->val.i, d);
1146                         } else {
1147                                 ICONST(REG_ITMP2, iptr->val.i);
1148                                 M_AND(s1, REG_ITMP2, d);
1149                                 M_BGEZ(s1, 4);
1150                                 M_NOP;
1151                                 M_ISUB(REG_ZERO, s1, d);
1152                                 M_AND(d, REG_ITMP2, d);
1153                         }
1154                         M_ISUB(REG_ZERO, d, d);
1155                         emit_store(jd, iptr, iptr->dst, d);
1156                         break;
1157
1158                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1159                                       /* val.l = constant                             */
1160
1161                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1162                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1163                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1164                                 M_AND_IMM(s1, iptr->val.l, d);
1165                         } else {
1166                                 LCONST(REG_ITMP2, iptr->val.l);
1167                                 M_AND(s1, REG_ITMP2, d);
1168                         }
1169                         emit_store(jd, iptr, iptr->dst, d);
1170                         break;
1171
1172                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1173                                       /* val.l = constant                             */
1174
1175                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1176                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1177                         if (s1 == d) {
1178                                 M_MOV(s1, REG_ITMP1);
1179                                 s1 = REG_ITMP1;
1180                         }
1181                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1182                                 M_AND_IMM(s1, iptr->val.l, d);
1183                                 M_BGEZ(s1, 4);
1184                                 M_NOP;
1185                                 M_LSUB(REG_ZERO, s1, d);
1186                                 M_AND_IMM(d, iptr->val.l, d);
1187                         } else {
1188                                 LCONST(REG_ITMP2, iptr->val.l);
1189                                 M_AND(s1, REG_ITMP2, d);
1190                                 M_BGEZ(s1, 4);
1191                                 M_NOP;
1192                                 M_LSUB(REG_ZERO, s1, d);
1193                                 M_AND(d, REG_ITMP2, d);
1194                         }
1195                         M_LSUB(REG_ZERO, d, d);
1196                         emit_store(jd, iptr, iptr->dst, d);
1197                         break;
1198
1199                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1200                 case ICMD_LOR:
1201
1202                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1203                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1204                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1205                         M_OR(s1,s2, d);
1206                         emit_store(jd, iptr, iptr->dst, d);
1207                         break;
1208
1209                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1210                                       /* val.i = constant                             */
1211
1212                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1213                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1214                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1215                                 M_OR_IMM(s1, iptr->val.i, d);
1216                         } else {
1217                                 ICONST(REG_ITMP2, iptr->val.i);
1218                                 M_OR(s1, REG_ITMP2, d);
1219                         }
1220                         emit_store(jd, iptr, iptr->dst, d);
1221                         break;
1222
1223                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1224                                       /* val.l = constant                             */
1225
1226                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1227                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1228                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1229                                 M_OR_IMM(s1, iptr->val.l, d);
1230                         } else {
1231                                 LCONST(REG_ITMP2, iptr->val.l);
1232                                 M_OR(s1, REG_ITMP2, d);
1233                         }
1234                         emit_store(jd, iptr, iptr->dst, d);
1235                         break;
1236
1237                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1238                 case ICMD_LXOR:
1239
1240                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1241                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1242                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1243                         M_XOR(s1, s2, d);
1244                         emit_store(jd, iptr, iptr->dst, d);
1245                         break;
1246
1247                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1248                                       /* val.i = constant                             */
1249
1250                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1251                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1252                         if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1253                                 M_XOR_IMM(s1, iptr->val.i, d);
1254                         } else {
1255                                 ICONST(REG_ITMP2, iptr->val.i);
1256                                 M_XOR(s1, REG_ITMP2, d);
1257                         }
1258                         emit_store(jd, iptr, iptr->dst, d);
1259                         break;
1260
1261                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1262                                       /* val.l = constant                             */
1263
1264                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1265                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1266                         if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1267                                 M_XOR_IMM(s1, iptr->val.l, d);
1268                         } else {
1269                                 LCONST(REG_ITMP2, iptr->val.l);
1270                                 M_XOR(s1, REG_ITMP2, d);
1271                         }
1272                         emit_store(jd, iptr, iptr->dst, d);
1273                         break;
1274
1275
1276                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1277
1278                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1279                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1280                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1281                         M_CMPLT(s1, s2, REG_ITMP3);
1282                         M_CMPLT(s2, s1, REG_ITMP1);
1283                         M_LSUB(REG_ITMP1, REG_ITMP3, d);
1284                         emit_store(jd, iptr, iptr->dst, d);
1285                         break;
1286
1287
1288                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
1289                                       /* op1 = variable, val.i = constant             */
1290
1291                         var = &(rd->locals[iptr->op1][TYPE_INT]);
1292                         if (var->flags & INMEMORY) {
1293                                 s1 = REG_ITMP1;
1294                                 M_LLD(s1, REG_SP, var->regoff * 8);
1295                         } else
1296                                 s1 = var->regoff;
1297                         M_IADD_IMM(s1, iptr->val.i, s1);
1298                         if (var->flags & INMEMORY)
1299                                 M_LST(s1, REG_SP, var->regoff * 8);
1300                         break;
1301
1302
1303                 /* floating operations ************************************************/
1304
1305                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1306
1307                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1308                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1309                         M_FNEG(s1, d);
1310                         emit_store(jd, iptr, iptr->dst, d);
1311                         break;
1312
1313                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1314
1315                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1316                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1317                         M_DNEG(s1, d);
1318                         emit_store(jd, iptr, iptr->dst, d);
1319                         break;
1320
1321                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1322
1323                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1324                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1325                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1326                         M_FADD(s1, s2, d);
1327                         emit_store(jd, iptr, iptr->dst, d);
1328                         break;
1329
1330                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1331
1332                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1333                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1334                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1335                         M_DADD(s1, s2, d);
1336                         emit_store(jd, iptr, iptr->dst, d);
1337                         break;
1338
1339                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1340
1341                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1342                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1343                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1344                         M_FSUB(s1, s2, d);
1345                         emit_store(jd, iptr, iptr->dst, d);
1346                         break;
1347
1348                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1349
1350                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1351                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1352                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1353                         M_DSUB(s1, s2, d);
1354                         emit_store(jd, iptr, iptr->dst, d);
1355                         break;
1356
1357                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1358
1359                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1360                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1361                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1362                         M_FMUL(s1, s2, d);
1363                         emit_store(jd, iptr, iptr->dst, d);
1364                         break;
1365
1366                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2      */
1367
1368                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1369                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1370                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1371                         M_DMUL(s1, s2, d);
1372                         emit_store(jd, iptr, iptr->dst, d);
1373                         break;
1374
1375                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1376
1377                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1378                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1379                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1380                         M_FDIV(s1, s2, d);
1381                         emit_store(jd, iptr, iptr->dst, d);
1382                         break;
1383
1384                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1385
1386                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1387                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1388                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1389                         M_DDIV(s1, s2, d);
1390                         emit_store(jd, iptr, iptr->dst, d);
1391                         break;
1392
1393 #if 0           
1394                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1395
1396                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1397                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1398                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1399                         M_FDIV(s1,s2, REG_FTMP3);
1400                         M_FLOORFL(REG_FTMP3, REG_FTMP3);
1401                         M_CVTLF(REG_FTMP3, REG_FTMP3);
1402                         M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1403                         M_FSUB(s1, REG_FTMP3, d);
1404                         emit_store(jd, iptr, iptr->dst, d);
1405                     break;
1406
1407                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1408
1409                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1410                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1411                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1412                         M_DDIV(s1,s2, REG_FTMP3);
1413                         M_FLOORDL(REG_FTMP3, REG_FTMP3);
1414                         M_CVTLD(REG_FTMP3, REG_FTMP3);
1415                         M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1416                         M_DSUB(s1, REG_FTMP3, d);
1417                         emit_store(jd, iptr, iptr->dst, d);
1418                     break;
1419 #endif
1420
1421                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1422                 case ICMD_L2F:
1423                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1424                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1425                         M_MOVLD(s1, d);
1426                         M_CVTLF(d, d);
1427                         emit_store(jd, iptr, iptr->dst, d);
1428                         break;
1429
1430                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1431                 case ICMD_L2D:
1432                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1433                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1434                         M_MOVLD(s1, d);
1435                         M_CVTLD(d, d);
1436                         emit_store(jd, iptr, iptr->dst, d);
1437                         break;
1438
1439 #if 0
1440                 /* XXX these do not work correctly */
1441
1442                 case ICMD_F2I:       /* ..., (float) value  ==> ..., (int) value      */
1443
1444                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1445                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1446                         M_TRUNCFI(s1, REG_FTMP1);
1447                         M_MOVDI(REG_FTMP1, d);
1448                         M_NOP;
1449                         emit_store(jd, iptr, iptr->dst, d);
1450                         break;
1451                 
1452                 case ICMD_D2I:       /* ..., (double) value  ==> ..., (int) value     */
1453
1454                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1455                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1456                         M_TRUNCDI(s1, REG_FTMP1);
1457                         M_MOVDI(REG_FTMP1, d);
1458                         M_NOP;
1459                         emit_store(jd, iptr, iptr->dst, d);
1460                         break;
1461                 
1462                 case ICMD_F2L:       /* ..., (float) value  ==> ..., (long) value     */
1463
1464                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1465                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1466                         M_TRUNCFL(s1, REG_FTMP1);
1467                         M_MOVDL(REG_FTMP1, d);
1468                         M_NOP;
1469                         emit_store(jd, iptr, iptr->dst, d);
1470                         break;
1471
1472                 case ICMD_D2L:       /* ..., (double) value  ==> ..., (long) value    */
1473
1474                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1475                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1476                         M_TRUNCDL(s1, REG_FTMP1);
1477                         M_MOVDL(REG_FTMP1, d);
1478                         M_NOP;
1479                         emit_store(jd, iptr, iptr->dst, d);
1480                         break;
1481 #endif
1482
1483                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1484
1485                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1486                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1487                         M_CVTFD(s1, d);
1488                         emit_store(jd, iptr, iptr->dst, d);
1489                         break;
1490                                         
1491                 case ICMD_D2F:       /* ..., value  ==> ..., (double) value           */
1492
1493                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1494                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1495                         M_CVTDF(s1, d);
1496                         emit_store(jd, iptr, iptr->dst, d);
1497                         break;
1498                 
1499                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1500
1501                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1502                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1503                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1504                         M_FCMPULEF(s1, s2);
1505                         M_FBT(3);
1506                         M_LADD_IMM(REG_ZERO, 1, d);
1507                         M_BR(4);
1508                         M_NOP;
1509                         M_FCMPEQF(s1, s2);
1510                         M_LSUB_IMM(REG_ZERO, 1, d);
1511                         M_CMOVT(REG_ZERO, d);
1512                         emit_store(jd, iptr, iptr->dst, d);
1513                         break;
1514
1515                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1516
1517                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1518                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1519                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1520                         M_FCMPULED(s1, s2);
1521                         M_FBT(3);
1522                         M_LADD_IMM(REG_ZERO, 1, d);
1523                         M_BR(4);
1524                         M_NOP;
1525                         M_FCMPEQD(s1, s2);
1526                         M_LSUB_IMM(REG_ZERO, 1, d);
1527                         M_CMOVT(REG_ZERO, d);
1528                         emit_store(jd, iptr, iptr->dst, d);
1529                         break;
1530                         
1531                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1532
1533                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1534                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1535                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1536                         M_FCMPOLTF(s1, s2);
1537                         M_FBF(3);
1538                         M_LSUB_IMM(REG_ZERO, 1, d);
1539                         M_BR(4);
1540                         M_NOP;
1541                         M_FCMPEQF(s1, s2);
1542                         M_LADD_IMM(REG_ZERO, 1, d);
1543                         M_CMOVT(REG_ZERO, d);
1544                         emit_store(jd, iptr, iptr->dst, d);
1545                         break;
1546
1547                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1548
1549                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1550                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1551                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1552                         M_FCMPOLTD(s1, s2);
1553                         M_FBF(3);
1554                         M_LSUB_IMM(REG_ZERO, 1, d);
1555                         M_BR(4);
1556                         M_NOP;
1557                         M_FCMPEQD(s1, s2);
1558                         M_LADD_IMM(REG_ZERO, 1, d);
1559                         M_CMOVT(REG_ZERO, d);
1560                         emit_store(jd, iptr, iptr->dst, d);
1561                         break;
1562
1563
1564                 /* memory operations **************************************************/
1565
1566                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1567
1568                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1569                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1570                         gen_nullptr_check(s1);
1571                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1572                         emit_store(jd, iptr, iptr->dst, d);
1573                         break;
1574
1575                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1576
1577                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1578                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1579                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1580                         if (iptr->op1 == 0) {
1581                                 gen_nullptr_check(s1);
1582                                 gen_bound_check;
1583                         }
1584                         M_AADD(s2, s1, REG_ITMP3);
1585                         M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1586                         emit_store(jd, iptr, iptr->dst, d);
1587                         break;
1588
1589                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1590
1591                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1592                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1593                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1594                         if (iptr->op1 == 0) {
1595                                 gen_nullptr_check(s1);
1596                                 gen_bound_check;
1597                         }
1598                         M_AADD(s2, s1, REG_ITMP3);
1599                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1600                         M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1601                         emit_store(jd, iptr, iptr->dst, d);
1602                         break;                  
1603
1604                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1605
1606                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1607                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1608                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1609                         if (iptr->op1 == 0) {
1610                                 gen_nullptr_check(s1);
1611                                 gen_bound_check;
1612                         }
1613                         M_AADD(s2, s1, REG_ITMP3);
1614                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1615                         M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1616                         emit_store(jd, iptr, iptr->dst, d);
1617                         break;
1618
1619                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1620
1621                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1622                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1623                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1624                         if (iptr->op1 == 0) {
1625                                 gen_nullptr_check(s1);
1626                                 gen_bound_check;
1627                         }
1628                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1629                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1630                         M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1631                         emit_store(jd, iptr, iptr->dst, d);
1632                         break;
1633
1634                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1635
1636                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1637                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1638                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1639                         if (iptr->op1 == 0) {
1640                                 gen_nullptr_check(s1);
1641                                 gen_bound_check;
1642                         }
1643                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1644                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1645                         M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1646                         emit_store(jd, iptr, iptr->dst, d);
1647                         break;
1648
1649                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1650
1651                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1652                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1653                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1654                         if (iptr->op1 == 0) {
1655                                 gen_nullptr_check(s1);
1656                                 gen_bound_check;
1657                         }
1658                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1659                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1660                         M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1661                         emit_store(jd, iptr, iptr->dst, d);
1662                         break;
1663
1664                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1665
1666                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1667                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1668                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1669                         if (iptr->op1 == 0) {
1670                                 gen_nullptr_check(s1);
1671                                 gen_bound_check;
1672                         }
1673                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1674                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1675                         M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1676                         emit_store(jd, iptr, iptr->dst, d);
1677                         break;
1678
1679                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1680
1681                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1682                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1683                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1684                         if (iptr->op1 == 0) {
1685                                 gen_nullptr_check(s1);
1686                                 gen_bound_check;
1687                         }
1688                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1689                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1690                         M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1691                         emit_store(jd, iptr, iptr->dst, d);
1692                         break;
1693
1694
1695                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1696
1697                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1698                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1699                         if (iptr->op1 == 0) {
1700                                 gen_nullptr_check(s1);
1701                                 gen_bound_check;
1702                         }
1703                         M_AADD(s2, s1, REG_ITMP1);
1704                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1705                         M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1706                         break;
1707
1708                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1709                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1710
1711                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1712                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1713                         if (iptr->op1 == 0) {
1714                                 gen_nullptr_check(s1);
1715                                 gen_bound_check;
1716                         }
1717                         M_AADD(s2, s1, REG_ITMP1);
1718                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1719                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1720                         M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1721                         break;
1722
1723                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1724
1725                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1726                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1727                         if (iptr->op1 == 0) {
1728                                 gen_nullptr_check(s1);
1729                                 gen_bound_check;
1730                         }
1731                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1732                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1733                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1734                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1735                         break;
1736
1737                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1738
1739                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1740                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1741                         if (iptr->op1 == 0) {
1742                                 gen_nullptr_check(s1);
1743                                 gen_bound_check;
1744                         }
1745                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1746                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1747                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1748                         M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1749                         break;
1750
1751                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1752
1753                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1754                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1755                         if (iptr->op1 == 0) {
1756                                 gen_nullptr_check(s1);
1757                                 gen_bound_check;
1758                         }
1759                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1760                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1761                         s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1762                         M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1763                         break;
1764
1765                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1766
1767                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1768                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1769                         if (iptr->op1 == 0) {
1770                                 gen_nullptr_check(s1);
1771                                 gen_bound_check;
1772                         }
1773                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1774                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1775                         s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1776                         M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1777                         break;
1778
1779
1780                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1781
1782                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1783                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1784                         if (iptr->op1 == 0) {
1785                                 gen_nullptr_check(s1);
1786                                 gen_bound_check;
1787                         }
1788                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1789
1790                         M_MOV(s1, rd->argintregs[0]);
1791                         M_MOV(s3, rd->argintregs[1]);
1792                         disp = dseg_addaddress(cd, BUILTIN_canstore);
1793                         M_ALD(REG_ITMP3, REG_PV, disp);
1794                         M_JSR(REG_RA, REG_ITMP3);
1795                         M_NOP;
1796
1797                         M_BEQZ(REG_RESULT, 0);
1798                         codegen_add_arraystoreexception_ref(cd);
1799                         M_NOP;
1800
1801                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1802                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1803                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1804                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1805                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1806                         M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1807                         break;
1808
1809
1810                 case ICMD_BASTORECONST:   /* ..., arrayref, index  ==> ...            */
1811
1812                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1813                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1814                         if (iptr->op1 == 0) {
1815                                 gen_nullptr_check(s1);
1816                                 gen_bound_check;
1817                         }
1818                         M_AADD(s2, s1, REG_ITMP1);
1819                         M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1820                         break;
1821
1822                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1823                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1824
1825                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1826                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1827                         if (iptr->op1 == 0) {
1828                                 gen_nullptr_check(s1);
1829                                 gen_bound_check;
1830                         }
1831                         M_AADD(s2, s1, REG_ITMP1);
1832                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1833                         M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1834                         break;
1835
1836                 case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
1837
1838                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1839                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1840                         if (iptr->op1 == 0) {
1841                                 gen_nullptr_check(s1);
1842                                 gen_bound_check;
1843                         }
1844                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1845                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1846                         M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1847                         break;
1848
1849                 case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
1850
1851                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1852                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1853                         if (iptr->op1 == 0) {
1854                                 gen_nullptr_check(s1);
1855                                 gen_bound_check;
1856                         }
1857                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1858                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1859                         M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1860                         break;
1861
1862                 case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
1863
1864                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1865                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1866                         if (iptr->op1 == 0) {
1867                                 gen_nullptr_check(s1);
1868                                 gen_bound_check;
1869                         }
1870                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1871                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1872                         M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1873                         break;
1874
1875
1876                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1877                                       /* op1 = type, val.a = field address            */
1878
1879                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1880                                 disp = dseg_addaddress(cd, NULL);
1881
1882                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
1883                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1884
1885                                 if (opt_showdisassemble) {
1886                                         M_NOP; M_NOP;
1887                                 }
1888
1889                         } else {
1890                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1891
1892                                 disp = dseg_addaddress(cd, &(fi->value));
1893
1894                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1895                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1896
1897                                         if (opt_showdisassemble) {
1898                                                 M_NOP; M_NOP;
1899                                         }
1900                                 }
1901                         }
1902
1903                         M_ALD(REG_ITMP1, REG_PV, disp);
1904                         switch (iptr->op1) {
1905                         case TYPE_INT:
1906                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1907                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1908                                 emit_store(jd, iptr, iptr->dst, d);
1909                                 break;
1910                         case TYPE_LNG:
1911                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1912                                 M_LLD_INTERN(d, REG_ITMP1, 0);
1913                                 emit_store(jd, iptr, iptr->dst, d);
1914                                 break;
1915                         case TYPE_ADR:
1916                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1917                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1918                                 emit_store(jd, iptr, iptr->dst, d);
1919                                 break;
1920                         case TYPE_FLT:
1921                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1922                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1923                                 emit_store(jd, iptr, iptr->dst, d);
1924                                 break;
1925                         case TYPE_DBL:                          
1926                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1927                                 M_DLD_INTERN(d, REG_ITMP1, 0);
1928                                 emit_store(jd, iptr, iptr->dst, d);
1929                                 break;
1930                         }
1931                         break;
1932
1933                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1934                                       /* op1 = type, val.a = field address            */
1935
1936                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1937                                 disp = dseg_addaddress(cd, NULL);
1938
1939                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
1940                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1941
1942                                 if (opt_showdisassemble) {
1943                                         M_NOP; M_NOP;
1944                                 }
1945
1946                         } else {
1947                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1948
1949                                 disp = dseg_addaddress(cd, &(fi->value));
1950
1951                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1952                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1953
1954                                         if (opt_showdisassemble) {
1955                                                 M_NOP; M_NOP;
1956                                         }
1957                                 }
1958                         }
1959
1960                         M_ALD(REG_ITMP1, REG_PV, disp);
1961                         switch (iptr->op1) {
1962                         case TYPE_INT:
1963                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1964                                 M_IST_INTERN(s1, REG_ITMP1, 0);
1965                                 break;
1966                         case TYPE_LNG:
1967                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1968                                 M_LST_INTERN(s1, REG_ITMP1, 0);
1969                                 break;
1970                         case TYPE_ADR:
1971                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1972                                 M_AST_INTERN(s1, REG_ITMP1, 0);
1973                                 break;
1974                         case TYPE_FLT:
1975                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1976                                 M_FST_INTERN(s1, REG_ITMP1, 0);
1977                                 break;
1978                         case TYPE_DBL:
1979                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1980                                 M_DST_INTERN(s1, REG_ITMP1, 0);
1981                                 break;
1982                         }
1983                         break;
1984
1985                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
1986                                           /* val = value (in current instruction)     */
1987                                           /* op1 = type, val.a = field address (in    */
1988                                           /* following NOP)                           */
1989
1990                         if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
1991                                 disp = dseg_addaddress(cd, NULL);
1992
1993                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
1994                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
1995
1996                                 if (opt_showdisassemble) {
1997                                         M_NOP; M_NOP;
1998                                 }
1999
2000                         } else {
2001                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2002
2003                                 disp = dseg_addaddress(cd, &(fi->value));
2004
2005                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2006                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2007
2008                                         if (opt_showdisassemble) {
2009                                                 M_NOP; M_NOP;
2010                                         }
2011                                 }
2012                         }
2013
2014                         M_ALD(REG_ITMP1, REG_PV, disp);
2015                         switch (iptr->op1) {
2016                         case TYPE_INT:
2017                                 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2018                                 break;
2019                         case TYPE_LNG:
2020                                 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2021                                 break;
2022                         case TYPE_ADR:
2023                                 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2024                                 break;
2025                         case TYPE_FLT:
2026                                 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2027                                 break;
2028                         case TYPE_DBL:
2029                                 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2030                                 break;
2031                         }
2032                         break;
2033
2034
2035                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
2036                                       /* op1 = type, val.i = field offset             */
2037
2038                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2039                         gen_nullptr_check(s1);
2040
2041                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2042                                 codegen_addpatchref(cd, PATCHER_get_putfield,
2043                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2044
2045                                 if (opt_showdisassemble) {
2046                                         M_NOP; M_NOP;
2047                                 }
2048
2049                                 a = 0;
2050
2051                         } else {
2052                                 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2053                         }
2054
2055                         switch (iptr->op1) {
2056                         case TYPE_INT:
2057                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2058                                 M_ILD(d, s1, a);
2059                                 emit_store(jd, iptr, iptr->dst, d);
2060                                 break;
2061                         case TYPE_LNG:
2062                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2063                                 M_LLD(d, s1, a);
2064                                 emit_store(jd, iptr, iptr->dst, d);
2065                                 break;
2066                         case TYPE_ADR:
2067                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2068                                 M_ALD(d, s1, a);
2069                                 emit_store(jd, iptr, iptr->dst, d);
2070                                 break;
2071                         case TYPE_FLT:
2072                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2073                                 M_FLD(d, s1, a);
2074                                 emit_store(jd, iptr, iptr->dst, d);
2075                                 break;
2076                         case TYPE_DBL:                          
2077                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2078                                 M_DLD(d, s1, a);
2079                                 emit_store(jd, iptr, iptr->dst, d);
2080                                 break;
2081                         }
2082                         break;
2083
2084                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2085                                       /* op1 = type, val.a = field address            */
2086
2087                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2088                         gen_nullptr_check(s1);
2089
2090                         if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2091                                 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2092                         } else {
2093                                 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2094                         }
2095
2096                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2097                                 codegen_addpatchref(cd, PATCHER_get_putfield,
2098                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2099
2100                                 if (opt_showdisassemble) {
2101                                         M_NOP; M_NOP;
2102                                 }
2103
2104                                 a = 0;
2105
2106                         } else {
2107                                 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2108                         }
2109
2110                         switch (iptr->op1) {
2111                         case TYPE_INT:
2112                                 M_IST(s2, s1, a);
2113                                 break;
2114                         case TYPE_LNG:
2115                                 M_LST(s2, s1, a);
2116                                 break;
2117                         case TYPE_ADR:
2118                                 M_AST(s2, s1, a);
2119                                 break;
2120                         case TYPE_FLT:
2121                                 M_FST(s2, s1, a);
2122                                 break;
2123                         case TYPE_DBL:
2124                                 M_DST(s2, s1, a);
2125                                 break;
2126                         }
2127                         break;
2128
2129                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2130                                           /* val = value (in current instruction)     */
2131                                           /* op1 = type, val.a = field address (in    */
2132                                           /* following NOP)                           */
2133
2134                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2135                         gen_nullptr_check(s1);
2136
2137                         if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2138                                 codegen_addpatchref(cd, PATCHER_get_putfield,
2139                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2140
2141                                 if (opt_showdisassemble) {
2142                                         M_NOP; M_NOP;
2143                                 }
2144
2145                                 a = 0;
2146
2147                         } else {
2148                                 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2149                         }
2150
2151                         switch (iptr[1].op1) {
2152                         case TYPE_INT:
2153                                 M_IST(REG_ZERO, s1, a);
2154                                 break;
2155                         case TYPE_LNG:
2156                                 M_LST(REG_ZERO, s1, a);
2157                                 break;
2158                         case TYPE_ADR:
2159                                 M_AST(REG_ZERO, s1, a);
2160                                 break;
2161                         case TYPE_FLT:
2162                                 M_FST(REG_ZERO, s1, a);
2163                                 break;
2164                         case TYPE_DBL:
2165                                 M_DST(REG_ZERO, s1, a);
2166                                 break;
2167                         }
2168                         break;
2169
2170
2171                 /* branch operations **************************************************/
2172
2173                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2174
2175                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2176                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2177                         
2178 #ifdef ENABLE_VERIFIER
2179                         if (iptr->val.a) {
2180                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2181                                                                         (unresolved_class *) iptr->val.a, 0);
2182
2183                                 if (opt_showdisassemble) {
2184                                         M_NOP; M_NOP;
2185                                 }
2186                         }
2187 #endif /* ENABLE_VERIFIER */
2188
2189                         disp = dseg_addaddress(cd, asm_handle_exception);
2190                         M_ALD(REG_ITMP2, REG_PV, disp);
2191                         M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2192                         M_NOP;
2193                         M_NOP;              /* nop ensures that XPC is less than the end */
2194                                             /* of basic block                            */
2195                         ALIGNCODENOP;
2196                         break;
2197
2198                 case ICMD_GOTO:         /* ... ==> ...                                */
2199                                         /* op1 = target JavaVM pc                     */
2200                         M_BR(0);
2201                         codegen_addreference(cd, (basicblock *) iptr->target);
2202                         M_NOP;
2203                         ALIGNCODENOP;
2204                         break;
2205
2206                 case ICMD_JSR:          /* ... ==> ...                                */
2207                                         /* op1 = target JavaVM pc                     */
2208
2209                         dseg_addtarget(cd, (basicblock *) iptr->target);
2210                         M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2211                         M_JSR(REG_ITMP1, REG_ITMP1);        /* REG_ITMP1 = return address */
2212                         M_NOP;
2213                         break;
2214                         
2215                 case ICMD_RET:          /* ... ==> ...                                */
2216                                         /* op1 = local variable                       */
2217                         var = &(rd->locals[iptr->op1][TYPE_ADR]);
2218                         if (var->flags & INMEMORY) {
2219                                 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2220                                 M_RET(REG_ITMP1);
2221                         } else
2222                                 M_RET(var->regoff);
2223                         M_NOP;
2224                         ALIGNCODENOP;
2225                         break;
2226
2227                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2228                                         /* op1 = target JavaVM pc                     */
2229
2230                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2231                         M_BEQZ(s1, 0);
2232                         codegen_addreference(cd, (basicblock *) iptr->target);
2233                         M_NOP;
2234                         break;
2235
2236                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2237                                         /* op1 = target JavaVM pc                     */
2238
2239                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2240                         M_BNEZ(s1, 0);
2241                         codegen_addreference(cd, (basicblock *) iptr->target);
2242                         M_NOP;
2243                         break;
2244
2245                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2246                                         /* op1 = target JavaVM pc, val.i = constant   */
2247
2248                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2249                         if (iptr->val.i == 0) {
2250                                 M_BEQZ(s1, 0);
2251                         } else {
2252                                 ICONST(REG_ITMP2, iptr->val.i);
2253                                 M_BEQ(s1, REG_ITMP2, 0);
2254                         }
2255                         codegen_addreference(cd, (basicblock *) iptr->target);
2256                         M_NOP;
2257                         break;
2258
2259                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2260                                         /* op1 = target JavaVM pc, val.i = constant   */
2261
2262                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2263                         if (iptr->val.i == 0) {
2264                                 M_BLTZ(s1, 0);
2265                         } else {
2266                                 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2267                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2268                                 } else {
2269                                         ICONST(REG_ITMP2, iptr->val.i);
2270                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2271                                 }
2272                                 M_BNEZ(REG_ITMP1, 0);
2273                         }
2274                         codegen_addreference(cd, (basicblock *) iptr->target);
2275                         M_NOP;
2276                         break;
2277
2278                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2279                                         /* op1 = target JavaVM pc, val.i = constant   */
2280
2281                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2282                         if (iptr->val.i == 0) {
2283                                 M_BLEZ(s1, 0);
2284                                 }
2285                         else {
2286                                 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2287                                         M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2288                                         M_BNEZ(REG_ITMP1, 0);
2289                                         }
2290                                 else {
2291                                         ICONST(REG_ITMP2, iptr->val.i);
2292                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2293                                         M_BEQZ(REG_ITMP1, 0);
2294                                         }
2295                                 }
2296                         codegen_addreference(cd, (basicblock *) iptr->target);
2297                         M_NOP;
2298                         break;
2299
2300                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2301                                         /* op1 = target JavaVM pc, val.i = constant   */
2302
2303                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2304                         if (iptr->val.i == 0) {
2305                                 M_BNEZ(s1, 0);
2306                                 }
2307                         else {
2308                                 ICONST(REG_ITMP2, iptr->val.i);
2309                                 M_BNE(s1, REG_ITMP2, 0);
2310                                 }
2311                         codegen_addreference(cd, (basicblock *) iptr->target);
2312                         M_NOP;
2313                         break;
2314
2315                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2316                                         /* op1 = target JavaVM pc, val.i = constant   */
2317
2318                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2319                         if (iptr->val.i == 0) {
2320                                 M_BGTZ(s1, 0);
2321                                 }
2322                         else {
2323                                 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2324                                         M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2325                                         M_BEQZ(REG_ITMP1, 0);
2326                                         }
2327                                 else {
2328                                         ICONST(REG_ITMP2, iptr->val.i);
2329                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2330                                         M_BNEZ(REG_ITMP1, 0);
2331                                         }
2332                                 }
2333                         codegen_addreference(cd, (basicblock *) iptr->target);
2334                         M_NOP;
2335                         break;
2336
2337                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2338                                         /* op1 = target JavaVM pc, val.i = constant   */
2339
2340                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2341                         if (iptr->val.i == 0) {
2342                                 M_BGEZ(s1, 0);
2343                                 }
2344                         else {
2345                                 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2346                                         M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2347                                         }
2348                                 else {
2349                                         ICONST(REG_ITMP2, iptr->val.i);
2350                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2351                                         }
2352                                 M_BEQZ(REG_ITMP1, 0);
2353                                 }
2354                         codegen_addreference(cd, (basicblock *) iptr->target);
2355                         M_NOP;
2356                         break;
2357
2358                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2359                                         /* op1 = target JavaVM pc, val.l = constant   */
2360
2361                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2362                         if (iptr->val.l == 0) {
2363                                 M_BEQZ(s1, 0);
2364                                 }
2365                         else {
2366                                 LCONST(REG_ITMP2, iptr->val.l);
2367                                 M_BEQ(s1, REG_ITMP2, 0);
2368                                 }
2369                         codegen_addreference(cd, (basicblock *) iptr->target);
2370                         M_NOP;
2371                         break;
2372
2373                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2374                                         /* op1 = target JavaVM pc, val.l = constant   */
2375
2376                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2377                         if (iptr->val.l == 0) {
2378                                 M_BLTZ(s1, 0);
2379                                 }
2380                         else {
2381                                 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2382                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2383                                         }
2384                                 else {
2385                                         LCONST(REG_ITMP2, iptr->val.l);
2386                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2387                                         }
2388                                 M_BNEZ(REG_ITMP1, 0);
2389                                 }
2390                         codegen_addreference(cd, (basicblock *) iptr->target);
2391                         M_NOP;
2392                         break;
2393
2394                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2395                                         /* op1 = target JavaVM pc, val.l = constant   */
2396
2397                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2398                         if (iptr->val.l == 0) {
2399                                 M_BLEZ(s1, 0);
2400                                 }
2401                         else {
2402                                 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2403                                         M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2404                                         M_BNEZ(REG_ITMP1, 0);
2405                                         }
2406                                 else {
2407                                         LCONST(REG_ITMP2, iptr->val.l);
2408                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2409                                         M_BEQZ(REG_ITMP1, 0);
2410                                         }
2411                                 }
2412                         codegen_addreference(cd, (basicblock *) iptr->target);
2413                         M_NOP;
2414                         break;
2415
2416                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2417                                         /* op1 = target JavaVM pc, val.l = constant   */
2418
2419                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2420                         if (iptr->val.l == 0) {
2421                                 M_BNEZ(s1, 0);
2422                                 }
2423                         else {
2424                                 LCONST(REG_ITMP2, iptr->val.l);
2425                                 M_BNE(s1, REG_ITMP2, 0);
2426                                 }
2427                         codegen_addreference(cd, (basicblock *) iptr->target);
2428                         M_NOP;
2429                         break;
2430
2431                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2432                                         /* op1 = target JavaVM pc, val.l = constant   */
2433
2434                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2435                         if (iptr->val.l == 0) {
2436                                 M_BGTZ(s1, 0);
2437                                 }
2438                         else {
2439                                 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2440                                         M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2441                                         M_BEQZ(REG_ITMP1, 0);
2442                                         }
2443                                 else {
2444                                         LCONST(REG_ITMP2, iptr->val.l);
2445                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2446                                         M_BNEZ(REG_ITMP1, 0);
2447                                         }
2448                                 }
2449                         codegen_addreference(cd, (basicblock *) iptr->target);
2450                         M_NOP;
2451                         break;
2452
2453                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2454                                         /* op1 = target JavaVM pc, val.l = constant   */
2455
2456                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2457                         if (iptr->val.l == 0) {
2458                                 M_BGEZ(s1, 0);
2459                                 }
2460                         else {
2461                                 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2462                                         M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2463                                         }
2464                                 else {
2465                                         LCONST(REG_ITMP2, iptr->val.l);
2466                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2467                                         }
2468                                 M_BEQZ(REG_ITMP1, 0);
2469                                 }
2470                         codegen_addreference(cd, (basicblock *) iptr->target);
2471                         M_NOP;
2472                         break;
2473
2474                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2475                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2476                 case ICMD_IF_ACMPEQ:
2477
2478                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2479                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2480                         M_BEQ(s1, s2, 0);
2481                         codegen_addreference(cd, (basicblock *) iptr->target);
2482                         M_NOP;
2483                         break;
2484
2485                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2486                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2487                 case ICMD_IF_ACMPNE:
2488
2489                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2490                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2491                         M_BNE(s1, s2, 0);
2492                         codegen_addreference(cd, (basicblock *) iptr->target);
2493                         M_NOP;
2494                         break;
2495
2496                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2497                 case ICMD_IF_LCMPLT:    /* op1 = target JavaVM pc                     */
2498
2499                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2500                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2501                         M_CMPLT(s1, s2, REG_ITMP1);
2502                         M_BNEZ(REG_ITMP1, 0);
2503                         codegen_addreference(cd, (basicblock *) iptr->target);
2504                         M_NOP;
2505                         break;
2506
2507                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2508                 case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
2509
2510                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2511                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2512                         M_CMPGT(s1, s2, REG_ITMP1);
2513                         M_BNEZ(REG_ITMP1, 0);
2514                         codegen_addreference(cd, (basicblock *) iptr->target);
2515                         M_NOP;
2516                         break;
2517
2518                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2519                 case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
2520
2521                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2522                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2523                         M_CMPGT(s1, s2, REG_ITMP1);
2524                         M_BEQZ(REG_ITMP1, 0);
2525                         codegen_addreference(cd, (basicblock *) iptr->target);
2526                         M_NOP;
2527                         break;
2528
2529                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2530                 case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
2531
2532                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2533                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2534                         M_CMPLT(s1, s2, REG_ITMP1);
2535                         M_BEQZ(REG_ITMP1, 0);
2536                         codegen_addreference(cd, (basicblock *) iptr->target);
2537                         M_NOP;
2538                         break;
2539
2540
2541                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2542                 case ICMD_LRETURN:
2543
2544                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2545                         M_INTMOVE(s1, REG_RESULT);
2546                         goto nowperformreturn;
2547
2548                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2549
2550                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2551                         M_INTMOVE(s1, REG_RESULT);
2552
2553 #ifdef ENABLE_VERIFIER
2554                         if (iptr->val.a) {
2555                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2556                                                                         (unresolved_class *) iptr->val.a, 0);
2557
2558                                 if (opt_showdisassemble) {
2559                                         M_NOP; M_NOP;
2560                                 }
2561                         }
2562 #endif /* ENABLE_VERIFIER */
2563                         goto nowperformreturn;
2564
2565             case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2566
2567                         s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2568                         M_FLTMOVE(s1, REG_FRESULT);
2569                         goto nowperformreturn;
2570
2571             case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
2572
2573                         s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2574                         M_DBLMOVE(s1, REG_FRESULT);
2575                         goto nowperformreturn;
2576
2577                 case ICMD_RETURN:      /* ...  ==> ...                                */
2578
2579 nowperformreturn:
2580                         {
2581                         s4 i, p;
2582                         
2583                         p = cd->stackframesize;
2584
2585 #if !defined(NDEBUG)
2586                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2587                                 emit_verbosecall_exit(jd);
2588 #endif
2589
2590 #if defined(ENABLE_THREADS)
2591                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2592                                 disp = dseg_addaddress(cd, LOCK_monitor_exit);
2593                                 M_ALD(REG_ITMP3, REG_PV, disp);
2594
2595                                 /* we need to save the proper return value */
2596
2597                                 switch (iptr->opc) {
2598                                 case ICMD_IRETURN:
2599                                 case ICMD_ARETURN:
2600                                 case ICMD_LRETURN:
2601                                         M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2602                                         M_JSR(REG_RA, REG_ITMP3);
2603                                         M_LST(REG_RESULT, REG_SP, rd->memuse * 8);  /* delay slot */
2604                                         break;
2605                                 case ICMD_FRETURN:
2606                                 case ICMD_DRETURN:
2607                                         M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2608                                         M_JSR(REG_RA, REG_ITMP3);
2609                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2610                                         break;
2611                                 case ICMD_RETURN:
2612                                         M_JSR(REG_RA, REG_ITMP3);
2613                                         M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2614                                         break;
2615                                 }
2616
2617                                 /* and now restore the proper return value */
2618
2619                                 switch (iptr->opc) {
2620                                 case ICMD_IRETURN:
2621                                 case ICMD_ARETURN:
2622                                 case ICMD_LRETURN:
2623                                         M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2624                                         break;
2625                                 case ICMD_FRETURN:
2626                                 case ICMD_DRETURN:
2627                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2628                                         break;
2629                                 }
2630                         }
2631 #endif
2632
2633                         /* restore return address                                         */
2634
2635                         if (!jd->isleafmethod) {
2636                                 p--; M_ALD(REG_RA, REG_SP, p * 8);
2637                         }
2638
2639                         /* restore saved registers                                        */
2640
2641                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2642                                 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2643                         }
2644                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2645                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2646                         }
2647
2648                         /* deallocate stack and return                                    */
2649
2650                         if (cd->stackframesize) {
2651                                 s4 lo, hi;
2652
2653                                 disp = cd->stackframesize * 8;
2654                                 lo = (short) (disp);
2655                                 hi = (short) (((disp) - lo) >> 16);
2656
2657                                 if (hi == 0) {
2658                                         M_RET(REG_RA);
2659                                         M_LADD_IMM(REG_SP, lo, REG_SP);             /* delay slot */
2660                                 } else {
2661                                         M_LUI(REG_ITMP3,hi);
2662                                         M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2663                                         M_RET(REG_RA);
2664                                         M_LADD(REG_ITMP3,REG_SP,REG_SP);            /* delay slot */
2665                                 }
2666
2667                         } else {
2668                                 M_RET(REG_RA);
2669                                 M_NOP;
2670                         }
2671
2672                         ALIGNCODENOP;
2673                         }
2674                         break;
2675
2676
2677                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2678                         {
2679                         s4 i, l, *s4ptr;
2680                         void **tptr;
2681
2682                         tptr = (void **) iptr->target;
2683
2684                         s4ptr = iptr->val.a;
2685                         l = s4ptr[1];                          /* low     */
2686                         i = s4ptr[2];                          /* high    */
2687                         
2688                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2689                         if (l == 0)
2690                                 {M_INTMOVE(s1, REG_ITMP1);}
2691                         else if (l <= 32768) {
2692                                 M_IADD_IMM(s1, -l, REG_ITMP1);
2693                                 }
2694                         else {
2695                                 ICONST(REG_ITMP2, l);
2696                                 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2697                                 }
2698                         i = i - l + 1;
2699
2700                         /* range check */
2701
2702                         M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2703                         M_BEQZ(REG_ITMP2, 0);
2704                         codegen_addreference(cd, (basicblock *) tptr[0]);
2705                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
2706
2707                         /* build jump table top down and use address of lowest entry */
2708
2709                         /* s4ptr += 3 + i; */
2710                         tptr += i;
2711
2712                         while (--i >= 0) {
2713                                 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
2714                                 dseg_addtarget(cd, (basicblock *) tptr[0]); 
2715                                 --tptr;
2716                                 }
2717                         }
2718
2719                         /* length of dataseg after last dseg_addtarget is used by load */
2720
2721                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2722                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2723                         M_JMP(REG_ITMP2);
2724                         M_NOP;
2725                         ALIGNCODENOP;
2726                         break;
2727
2728
2729                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2730                         {
2731                         s4 i, /*l, */val, *s4ptr;
2732                         void **tptr;
2733
2734                         tptr = (void **) iptr->target;
2735
2736                         s4ptr = iptr->val.a;
2737                         /*l = s4ptr[0];*/                          /* default  */
2738                         i = s4ptr[1];                          /* count    */
2739                         
2740                         MCODECHECK((i<<2)+8);
2741                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2742                         while (--i >= 0) {
2743                                 s4ptr += 2;
2744                                 ++tptr;
2745
2746                                 val = s4ptr[0];
2747                                 ICONST(REG_ITMP2, val);
2748                                 M_BEQ(s1, REG_ITMP2, 0);
2749                                 codegen_addreference(cd, (basicblock *) tptr[0]); 
2750                                 M_NOP;
2751                         }
2752
2753                         M_BR(0);
2754                         tptr = (void **) iptr->target;
2755                         codegen_addreference(cd, (basicblock *) tptr[0]);
2756                         M_NOP;
2757                         ALIGNCODENOP;
2758                         break;
2759                         }
2760
2761
2762                 case ICMD_BUILTIN:      /* ..., arg1 ==> ...                          */
2763                                         /* op1 = arg count val.a = builtintable entry */
2764
2765                         bte = iptr->val.a;
2766                         md = bte->md;
2767                         goto gen_method;
2768
2769                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2770                                         /* op1 = arg count, val.a = method pointer    */
2771
2772                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2773                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2774                 case ICMD_INVOKEINTERFACE:
2775
2776                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2777                                 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
2778                                 lm = NULL;
2779                         }
2780                         else {
2781                                 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
2782                                 md = lm->parseddesc;
2783                         }
2784
2785 gen_method:
2786                         s3 = md->paramcount;
2787
2788                         MCODECHECK((s3 << 1) + 64);
2789
2790                         /* copy arguments to registers or stack location                  */
2791
2792                         for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
2793                                 if (src->varkind == ARGVAR)
2794                                         continue;
2795                                 if (IS_INT_LNG_TYPE(src->type)) {
2796                                         if (!md->params[s3].inmemory) {
2797                                                 s1 = rd->argintregs[md->params[s3].regoff];
2798                                                 d = emit_load_s1(jd, iptr, src, s1);
2799                                                 M_INTMOVE(d, s1);
2800                                         } else  {
2801                                                 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
2802                                                 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2803                                         }
2804
2805                                 } else {
2806                                         if (!md->params[s3].inmemory) {
2807                                                 s1 = rd->argfltregs[md->params[s3].regoff];
2808                                                 d = emit_load_s1(jd, iptr, src, s1);
2809                                                 if (IS_2_WORD_TYPE(src->type))
2810                                                         M_DMOV(d, s1);
2811                                                 else
2812                                                         M_FMOV(d, s1);
2813
2814                                         } else {
2815                                                 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
2816                                                 if (IS_2_WORD_TYPE(src->type))
2817                                                         M_DST(d, REG_SP, md->params[s3].regoff * 8);
2818                                                 else
2819                                                         M_FST(d, REG_SP, md->params[s3].regoff * 8);
2820                                         }
2821                                 }
2822                         }
2823
2824                         switch (iptr->opc) {
2825                         case ICMD_BUILTIN:
2826                                 disp = dseg_addaddress(cd, bte->fp);
2827                                 d = md->returntype.type;
2828
2829                                 M_ALD(REG_ITMP3, REG_PV, disp);  /* built-in-function pointer */
2830                                 M_JSR(REG_RA, REG_ITMP3);
2831                                 M_NOP;
2832                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2833                                 M_LDA(REG_PV, REG_RA, -disp);
2834
2835                                 /* if op1 == true, we need to check for an exception */
2836
2837                                 if (iptr->op1 == true) {
2838                                         M_BEQZ(REG_RESULT, 0);
2839                                         codegen_add_fillinstacktrace_ref(cd);
2840                                         M_NOP;
2841                                 }
2842                                 break;
2843
2844                         case ICMD_INVOKESPECIAL:
2845                                 M_BEQZ(rd->argintregs[0], 0);
2846                                 codegen_add_nullpointerexception_ref(cd);
2847                                 M_NOP;
2848                                 /* fall through */
2849
2850                         case ICMD_INVOKESTATIC:
2851                                 if (lm == NULL) {
2852                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2853
2854                                         disp = dseg_addaddress(cd, NULL);
2855
2856                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
2857                                                                                 um, disp);
2858
2859                                         if (opt_showdisassemble) {
2860                                                 M_NOP; M_NOP;
2861                                         }
2862
2863                                         d = um->methodref->parseddesc.md->returntype.type;
2864
2865                                 } else {
2866                                         disp = dseg_addaddress(cd, lm->stubroutine);
2867                                         d = lm->parseddesc->returntype.type;
2868                                 }
2869
2870                                 M_ALD(REG_PV, REG_PV, disp);          /* method pointer in pv */
2871                                 M_JSR(REG_RA, REG_PV);
2872                                 M_NOP;
2873                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2874                                 M_LDA(REG_PV, REG_RA, -disp);
2875                                 break;
2876
2877                         case ICMD_INVOKEVIRTUAL:
2878                                 gen_nullptr_check(rd->argintregs[0]);
2879
2880                                 if (lm == NULL) {
2881                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2882
2883                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2884
2885                                         if (opt_showdisassemble) {
2886                                                 M_NOP; M_NOP;
2887                                         }
2888
2889                                         s1 = 0;
2890                                         d = um->methodref->parseddesc.md->returntype.type;
2891
2892                                 } else {
2893                                         s1 = OFFSET(vftbl_t, table[0]) +
2894                                                 sizeof(methodptr) * lm->vftblindex;
2895                                         d = lm->parseddesc->returntype.type;
2896                                 }
2897
2898                                 M_ALD(REG_METHODPTR, rd->argintregs[0],
2899                                           OFFSET(java_objectheader, vftbl));
2900                                 M_ALD(REG_PV, REG_METHODPTR, s1);
2901                                 M_JSR(REG_RA, REG_PV);
2902                                 M_NOP;
2903                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2904                                 M_LDA(REG_PV, REG_RA, -disp);
2905                                 break;
2906
2907                         case ICMD_INVOKEINTERFACE:
2908                                 gen_nullptr_check(rd->argintregs[0]);
2909
2910                                 if (lm == NULL) {
2911                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2912
2913                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2914
2915                                         if (opt_showdisassemble) {
2916                                                 M_NOP; M_NOP;
2917                                         }
2918
2919                                         s1 = 0;
2920                                         s2 = 0;
2921                                         d = um->methodref->parseddesc.md->returntype.type;
2922
2923                                 } else {
2924                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2925                                                 sizeof(methodptr*) * lm->class->index;
2926
2927                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
2928
2929                                         d = lm->parseddesc->returntype.type;
2930                                 }
2931
2932                                 M_ALD(REG_METHODPTR, rd->argintregs[0],
2933                                           OFFSET(java_objectheader, vftbl));
2934                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2935                                 M_ALD(REG_PV, REG_METHODPTR, s2);
2936                                 M_JSR(REG_RA, REG_PV);
2937                                 M_NOP;
2938                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2939                                 M_LDA(REG_PV, REG_RA, -disp);
2940                                 break;
2941                         }
2942
2943                         /* d contains return type */
2944
2945                         if (d != TYPE_VOID) {
2946                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2947                                         s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
2948                                         M_INTMOVE(REG_RESULT, s1);
2949                                 } else {
2950                                         s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
2951                                         if (IS_2_WORD_TYPE(iptr->dst->type))
2952                                                 M_DMOV(REG_FRESULT, s1);
2953                                         else
2954                                                 M_FMOV(REG_FRESULT, s1);
2955                                 }
2956                                 emit_store(jd, iptr, iptr->dst, s1);
2957                         }
2958                         break;
2959
2960
2961                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2962                                       /* op1:   0 == array, 1 == class                */
2963                                       /* val.a: (classinfo*) superclass               */
2964
2965                         /*  superclass is an interface:
2966                          *
2967                          *  OK if ((sub == NULL) ||
2968                          *         (sub->vftbl->interfacetablelength > super->index) &&
2969                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2970                          *
2971                          *  superclass is a class:
2972                          *
2973                          *  OK if ((sub == NULL) || (0
2974                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2975                          *         super->vftbl->diffvall));
2976                          */
2977
2978                         if (iptr->op1 == 1) {
2979                                 classinfo *super;
2980                                 vftbl_t   *supervftbl;
2981                                 s4         superindex;
2982
2983                                 super = (classinfo *) iptr->val.a;
2984
2985                                 if (super == NULL) {
2986                                         superindex = 0;
2987                                         supervftbl = NULL;
2988                                 }
2989                                 else {
2990                                         superindex = super->index;
2991                                         supervftbl = super->vftbl;
2992                                 }
2993                         
2994 #if defined(ENABLE_THREADS)
2995                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2996 #endif
2997
2998                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2999
3000                                 /* calculate interface checkcast code size */
3001
3002                                 s2 = 8;
3003                                 if (super == NULL)
3004                                         s2 += (opt_showdisassemble ? 2 : 0);
3005
3006                                 /* calculate class checkcast code size */
3007
3008                                 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3009                                 if (super == NULL)
3010                                         s3 += (opt_showdisassemble ? 2 : 0);
3011
3012                                 /* if class is not resolved, check which code to call */
3013
3014                                 if (super == NULL) {
3015                                         M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3016                                         M_NOP;
3017
3018                                         disp = dseg_adds4(cd, 0);                 /* super->flags */
3019
3020                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3021                                                                                 (constant_classref *) iptr->target,
3022                                                                                 disp);
3023
3024                                         if (opt_showdisassemble) {
3025                                                 M_NOP; M_NOP;
3026                                         }
3027
3028                                         /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3029                                         M_ILD(REG_ITMP2, REG_PV, disp);
3030                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3031                                         M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3032                                         M_NOP;
3033                                 }
3034
3035                                 /* interface checkcast code */
3036
3037                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3038                                         if (super != NULL) {
3039                                                 M_BEQZ(s1, 1 + s2);
3040                                                 M_NOP;
3041                                         }
3042                                         else {
3043                                                 codegen_addpatchref(cd,
3044                                                                                         PATCHER_checkcast_instanceof_interface,
3045                                                                                         (constant_classref *) iptr->target,
3046                                                                                         0);
3047
3048                                                 if (opt_showdisassemble) {
3049                                                         M_NOP; M_NOP;
3050                                                 }
3051                                         }
3052
3053                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3054                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3055                                         M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3056                                         M_BLEZ(REG_ITMP3, 0);
3057                                         codegen_add_classcastexception_ref(cd, s1);
3058                                         M_NOP;
3059                                         M_ALD(REG_ITMP3, REG_ITMP2,
3060                                                   OFFSET(vftbl_t, interfacetable[0]) -
3061                                                   superindex * sizeof(methodptr*));
3062                                         M_BEQZ(REG_ITMP3, 0);
3063                                         codegen_add_classcastexception_ref(cd, s1);
3064                                         M_NOP;
3065
3066                                         if (super == NULL) {
3067                                                 M_BR(1 + s3);
3068                                                 M_NOP;
3069                                         }
3070                                 }
3071
3072                                 /* class checkcast code */
3073
3074                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3075                                         disp = dseg_addaddress(cd, (void *) supervftbl);
3076
3077                                         if (super != NULL) {
3078                                                 M_BEQZ(s1, 1 + s3);
3079                                                 M_NOP;
3080                                         }
3081                                         else {
3082                                                 codegen_addpatchref(cd,
3083                                                                                         PATCHER_checkcast_instanceof_class,
3084                                                                                         (constant_classref *) iptr->target,
3085                                                                                         disp);
3086
3087                                                 if (opt_showdisassemble) {
3088                                                         M_NOP; M_NOP;
3089                                                 }
3090                                         }
3091
3092                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3093                                         M_ALD(REG_ITMP3, REG_PV, disp);
3094 #if defined(ENABLE_THREADS)
3095                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3096 #endif
3097                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3098                                         /*                              if (s1 != REG_ITMP1) { */
3099                                         /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3100                                         /*                                      M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3101                                         /* #if defined(ENABLE_THREADS) */
3102                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3103                                         /* #endif */
3104                                         /*                                      M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3105                                         /*                              } else { */
3106                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3107                                         M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2); 
3108                                         M_ALD(REG_ITMP3, REG_PV, disp);
3109                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3110 #if defined(ENABLE_THREADS)
3111                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3112 #endif
3113                                         /*                              } */
3114                                         M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3115                                         M_BNEZ(REG_ITMP3, 0);
3116                                         codegen_add_classcastexception_ref(cd, s1);
3117                                         M_NOP;
3118                                 }
3119
3120                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3121                         }
3122                         else {
3123                                 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3124                                 M_INTMOVE(s1, rd->argintregs[0]);
3125
3126                                 disp = dseg_addaddress(cd, iptr->val.a);
3127
3128                                 if (iptr->val.a == NULL) {
3129                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3130                                                                                 (constant_classref *) iptr->target,
3131                                                                                 disp);
3132
3133                                         if (opt_showdisassemble) {
3134                                                 M_NOP; M_NOP;
3135                                         }
3136                                 }
3137
3138                                 M_ALD(rd->argintregs[1], REG_PV, disp);
3139                                 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3140                                 M_ALD(REG_ITMP3, REG_PV, disp);
3141                                 M_JSR(REG_RA, REG_ITMP3);
3142                                 M_NOP;
3143
3144                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3145                                 M_BEQZ(REG_RESULT, 0);
3146                                 codegen_add_classcastexception_ref(cd, s1);
3147                                 M_NOP;
3148
3149                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3150                         }
3151
3152                         M_INTMOVE(s1, d);
3153                         emit_store(jd, iptr, iptr->dst, d);
3154                         break;
3155
3156                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3157                                       /* op1:   0 == array, 1 == class                */
3158                                       /* val.a: (classinfo*) superclass               */
3159
3160                         /*  superclass is an interface:
3161                          *
3162                          *  return (sub != NULL) &&
3163                          *         (sub->vftbl->interfacetablelength > super->index) &&
3164                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3165                          *
3166                          *  superclass is a class:
3167                          *
3168                          *  return ((sub != NULL) && (0
3169                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3170                          *          super->vftbl->diffvall));
3171                          */
3172
3173                         {
3174                         classinfo *super;
3175                         vftbl_t   *supervftbl;
3176                         s4         superindex;
3177
3178                         super = (classinfo *) iptr->val.a;
3179
3180                         if (super == NULL) {
3181                                 superindex = 0;
3182                                 supervftbl = NULL;
3183                         }
3184                         else {
3185                                 superindex = super->index;
3186                                 supervftbl = super->vftbl;
3187                         }
3188                         
3189 #if defined(ENABLE_THREADS)
3190                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3191 #endif
3192
3193                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3194                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3195                         if (s1 == d) {
3196                                 M_MOV(s1, REG_ITMP1);
3197                                 s1 = REG_ITMP1;
3198                         }
3199
3200                         /* calculate interface instanceof code size */
3201
3202                         s2 = 7;
3203                         if (super == NULL)
3204                                 s2 += (opt_showdisassemble ? 2 : 0);
3205
3206                         /* calculate class instanceof code size */
3207
3208                         s3 = 8;
3209                         if (super == NULL)
3210                                 s3 += (opt_showdisassemble ? 2 : 0);
3211
3212                         M_CLR(d);
3213
3214                         /* if class is not resolved, check which code to call */
3215
3216                         if (super == NULL) {
3217                                 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3218                                 M_NOP;
3219
3220                                 disp = dseg_adds4(cd, 0);                     /* super->flags */
3221
3222                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3223                                                                         (constant_classref *) iptr->target, disp);
3224
3225                                 if (opt_showdisassemble) {
3226                                         M_NOP; M_NOP;
3227                                 }
3228
3229                                 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3230                                 M_ILD(REG_ITMP3, REG_PV, disp);
3231                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3232                                 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3233                                 M_NOP;
3234                         }
3235
3236                         /* interface instanceof code */
3237
3238                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3239                                 if (super != NULL) {
3240                                         M_BEQZ(s1, 1 + s2);
3241                                         M_NOP;
3242                                 }
3243                                 else {
3244                                         codegen_addpatchref(cd,
3245                                                                                 PATCHER_checkcast_instanceof_interface,
3246                                                                                 (constant_classref *) iptr->target, 0);
3247
3248                                         if (opt_showdisassemble) {
3249                                                 M_NOP; M_NOP;
3250                                         }
3251                                 }
3252
3253                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3254                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3255                                 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3256                                 M_BLEZ(REG_ITMP3, 3);
3257                                 M_NOP;
3258                                 M_ALD(REG_ITMP1, REG_ITMP1,
3259                                           OFFSET(vftbl_t, interfacetable[0]) -
3260                                           superindex * sizeof(methodptr*));
3261                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3262
3263                                 if (super == NULL) {
3264                                         M_BR(1 + s3);
3265                                         M_NOP;
3266                                 }
3267                         }
3268
3269                         /* class instanceof code */
3270
3271                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3272                                 disp = dseg_addaddress(cd, supervftbl);
3273
3274                                 if (super != NULL) {
3275                                         M_BEQZ(s1, 1 + s3);
3276                                         M_NOP;
3277                                 }
3278                                 else {
3279                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3280                                                                                 (constant_classref *) iptr->target,
3281                                                                                 disp);
3282
3283                                         if (opt_showdisassemble) {
3284                                                 M_NOP; M_NOP;
3285                                         }
3286                                 }
3287
3288                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3289                                 M_ALD(REG_ITMP2, REG_PV, disp);
3290 #if defined(ENABLE_THREADS)
3291                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3292 #endif
3293                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3294                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3295                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3296 #if defined(ENABLE_THREADS)
3297                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3298 #endif
3299                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3300                                 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3301                                 M_XOR_IMM(d, 1, d);
3302                         }
3303                         emit_store(jd, iptr, iptr->dst, d);
3304                         }
3305                         break;
3306
3307                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3308                                       /* op1 = dimension, val.a = class               */
3309
3310                         /* check for negative sizes and copy sizes to stack if necessary  */
3311
3312                         MCODECHECK((iptr->op1 << 1) + 64);
3313
3314                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3315                                 /* copy SAVEDVAR sizes to stack */
3316
3317                                 if (src->varkind != ARGVAR) {
3318                                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3319                                         M_LST(s2, REG_SP, s1 * 8);
3320                                 }
3321                         }
3322
3323                         /* a0 = dimension count */
3324
3325                         ICONST(rd->argintregs[0], iptr->op1);
3326
3327                         /* is patcher function set? */
3328
3329                         if (iptr->val.a == NULL) {
3330                                 disp = dseg_addaddress(cd, NULL);
3331
3332                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3333                                                                         (constant_classref *) iptr->target, disp);
3334
3335                                 if (opt_showdisassemble) {
3336                                         M_NOP; M_NOP;
3337                                 }
3338
3339                         } else {
3340                                 disp = dseg_addaddress(cd, iptr->val.a);
3341                         }
3342
3343                         /* a1 = arraydescriptor */
3344
3345                         M_ALD(rd->argintregs[1], REG_PV, disp);
3346
3347                         /* a2 = pointer to dimensions = stack pointer */
3348
3349                         M_INTMOVE(REG_SP, rd->argintregs[2]);
3350
3351                         disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3352                         M_ALD(REG_ITMP3, REG_PV, disp);
3353                         M_JSR(REG_RA, REG_ITMP3);
3354                         M_NOP;
3355
3356                         /* check for exception before result assignment */
3357
3358                         M_BEQZ(REG_RESULT, 0);
3359                         codegen_add_fillinstacktrace_ref(cd);
3360                         M_NOP;
3361
3362                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3363                         M_INTMOVE(REG_RESULT, d);
3364                         emit_store(jd, iptr, iptr->dst, d);
3365                         break;
3366
3367                 default:
3368                         *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3369                         return false;
3370         } /* switch */
3371                 
3372         } /* for instruction */
3373                 
3374         /* copy values to interface registers */
3375
3376         src = bptr->outstack;
3377         len = bptr->outdepth;
3378         MCODECHECK(64+len);
3379 #if defined(ENABLE_LSRA)
3380         if (!opt_lsra) 
3381 #endif
3382         while (src) {
3383                 len--;
3384                 if ((src->varkind != STACKVAR)) {
3385                         s2 = src->type;
3386                         if (IS_FLT_DBL_TYPE(s2)) {
3387                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3388                                 if (rd->interfaces[len][s2].flags & INMEMORY) {
3389                                         if (IS_2_WORD_TYPE(s2))
3390                                                 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3391                                         else
3392                                                 M_FST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3393
3394                                 } else {
3395                                         if (IS_2_WORD_TYPE(s2))
3396                                                 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3397                                         else
3398                                                 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3399                                 }
3400
3401                         } else {
3402                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3403                                 if (rd->interfaces[len][s2].flags & INMEMORY)
3404                                         M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3405                                 else
3406                                         M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3407                         }
3408                 }
3409                 src = src->prev;
3410         }
3411
3412         /* At the end of a basic block we may have to append some nops,
3413            because the patcher stub calling code might be longer than the
3414            actual instruction. So codepatching does not change the
3415            following block unintentionally. */
3416
3417         if (cd->mcodeptr < cd->lastmcodeptr) {
3418                 while (cd->mcodeptr < cd->lastmcodeptr)
3419                         M_NOP;
3420         }
3421
3422         } /* if (bptr -> flags >= BBREACHED) */
3423         } /* for basic block */
3424
3425         dseg_createlinenumbertable(cd);
3426
3427         /* generate exception and patcher stubs */
3428
3429         emit_exception_stubs(jd);
3430         emit_patcher_stubs(jd);
3431         emit_replacement_stubs(jd);
3432
3433         codegen_finish(jd);
3434
3435         /* everything's ok */
3436
3437         return true;
3438 }
3439
3440
3441 /* createcompilerstub **********************************************************
3442
3443    Creates a stub routine which calls the compiler.
3444         
3445 *******************************************************************************/
3446
3447 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
3448 #define COMPILERSTUB_CODESIZE    4 * 4
3449
3450 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3451
3452
3453 u1 *createcompilerstub(methodinfo *m)
3454 {
3455         u1          *s;                     /* memory to hold the stub            */
3456         ptrint      *d;
3457         codeinfo    *code;
3458         codegendata *cd;
3459         s4           dumpsize;
3460
3461         s = CNEW(u1, COMPILERSTUB_SIZE);
3462
3463         /* set data pointer and code pointer */
3464
3465         d = (ptrint *) s;
3466         s = s + COMPILERSTUB_DATASIZE;
3467
3468         /* mark start of dump memory area */
3469
3470         dumpsize = dump_size();
3471
3472         cd = DNEW(codegendata);
3473         cd->mcodeptr = s;
3474
3475         /* Store the codeinfo pointer in the same place as in the
3476            methodheader for compiled methods. */
3477
3478         code = code_codeinfo_new(m);
3479
3480         d[0] = (ptrint) asm_call_jit_compiler;
3481         d[1] = (ptrint) m;
3482         d[2] = (ptrint) code;
3483
3484         M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
3485         M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
3486         M_JMP(REG_PV);
3487         M_NOP;
3488
3489         md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3490
3491 #if defined(ENABLE_STATISTICS)
3492         if (opt_stat)
3493                 count_cstub_len += COMPILERSTUB_SIZE;
3494 #endif
3495
3496         /* release dump area */
3497
3498         dump_release(dumpsize);
3499
3500         return s;
3501 }
3502
3503
3504 /* createnativestub ************************************************************
3505
3506    Creates a stub routine which calls a native method.
3507
3508 *******************************************************************************/
3509
3510 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3511 {
3512         methodinfo   *m;
3513         codeinfo     *code;
3514         codegendata  *cd;
3515         registerdata *rd;
3516         methoddesc   *md;
3517         s4            nativeparams;
3518         s4            i, j;                 /* count variables                    */
3519         s4            t;
3520         s4            s1, s2, disp;
3521         s4            funcdisp;             /* displacement of the function       */
3522
3523         /* get required compiler data */
3524
3525         m    = jd->m;
3526         code = jd->code;
3527         cd   = jd->cd;
3528         rd   = jd->rd;
3529
3530         /* initialize variables */
3531
3532         md = m->parseddesc;
3533         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3534
3535         /* calculate stack frame size */
3536
3537         cd->stackframesize =
3538                 1 +                             /* return address                     */
3539                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3540                 sizeof(localref_table) / SIZEOF_VOID_P +
3541                 md->paramcount +                /* for saving arguments over calls    */
3542                 1 +                             /* for saving return address          */
3543                 nmd->memuse;
3544
3545         /* create method header */
3546
3547 #if SIZEOF_VOID_P == 4
3548         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
3549 #endif
3550         (void) dseg_addaddress(cd, code);                      /* MethodPointer   */
3551         (void) dseg_adds4(cd, cd->stackframesize * 8);         /* FrameSize       */
3552         (void) dseg_adds4(cd, 0);                              /* IsSync          */
3553         (void) dseg_adds4(cd, 0);                              /* IsLeaf          */
3554         (void) dseg_adds4(cd, 0);                              /* IntSave         */
3555         (void) dseg_adds4(cd, 0);                              /* FltSave         */
3556         (void) dseg_addlinenumbertablesize(cd);
3557         (void) dseg_adds4(cd, 0);                              /* ExTableSize     */
3558
3559         /* generate stub code */
3560
3561         M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe    */
3562         M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P); /* store RA*/
3563
3564 #if !defined(NDEBUG)
3565         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3566                 emit_verbosecall_enter(jd);
3567 #endif
3568
3569         /* get function address (this must happen before the stackframeinfo) */
3570
3571         funcdisp = dseg_addaddress(cd, f);
3572
3573 #if !defined(WITH_STATIC_CLASSPATH)
3574         if (f == NULL) {
3575                 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
3576
3577                 if (opt_showdisassemble) {
3578                         M_NOP; M_NOP;
3579                 }
3580         }
3581 #endif
3582
3583         /* save integer and float argument registers */
3584
3585         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3586                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3587                         M_LST(rd->argintregs[i], REG_SP, j * 8);
3588                         j++;
3589                 }
3590         }
3591
3592         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3593                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3594                         M_DST(rd->argfltregs[i], REG_SP, j * 8);
3595                         j++;
3596                 }
3597         }
3598
3599         /* prepare data structures for native function call */
3600
3601         M_AADD_IMM(REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
3602         M_MOV(REG_PV, rd->argintregs[1]);
3603         M_AADD_IMM(REG_SP, cd->stackframesize * 8, rd->argintregs[2]);
3604         M_ALD(rd->argintregs[3], REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3605         disp = dseg_addaddress(cd, codegen_start_native_call);
3606         M_ALD(REG_ITMP3, REG_PV, disp);
3607         M_JSR(REG_RA, REG_ITMP3);
3608         M_NOP; /* XXX fill me! */
3609
3610         /* restore integer and float argument registers */
3611
3612         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3613                 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3614                         M_LLD(rd->argintregs[i], REG_SP, j * 8);
3615                         j++;
3616                 }
3617         }
3618
3619         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3620                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3621                         M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3622                         j++;
3623                 }
3624         }
3625
3626         /* copy or spill arguments to new locations */
3627
3628         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3629                 t = md->paramtypes[i].type;
3630
3631                 if (IS_INT_LNG_TYPE(t)) {
3632                         if (!md->params[i].inmemory) {
3633                                 s1 = rd->argintregs[md->params[i].regoff];
3634
3635                                 if (!nmd->params[j].inmemory) {
3636                                         s2 = rd->argintregs[nmd->params[j].regoff];
3637                                         M_INTMOVE(s1, s2);
3638                                 } else {
3639                                         s2 = nmd->params[j].regoff;
3640                                         M_AST(s1, REG_SP, s2 * 8);
3641                                 }
3642
3643                         } else {
3644                                 s1 = md->params[i].regoff + cd->stackframesize;
3645                                 s2 = nmd->params[j].regoff;
3646                                 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
3647                                 M_AST(REG_ITMP1, REG_SP, s2 * 8);
3648                         }
3649
3650                 } else {
3651                         if (!md->params[i].inmemory) {
3652                                 s1 = rd->argfltregs[md->params[i].regoff];
3653
3654                                 if (!nmd->params[j].inmemory) {
3655                                         s2 = rd->argfltregs[nmd->params[j].regoff];
3656                                         if (IS_2_WORD_TYPE(t))
3657                                                 M_DMOV(s1, s2);
3658                                         else
3659                                                 M_FMOV(s1, s2);
3660
3661                                 } else {
3662                                         s2 = nmd->params[j].regoff;
3663                                         if (IS_2_WORD_TYPE(t))
3664                                                 M_DST(s1, REG_SP, s2 * 8);
3665                                         else
3666                                                 M_FST(s1, REG_SP, s2 * 8);
3667                                 }
3668
3669                         } else {
3670                                 s1 = md->params[i].regoff + cd->stackframesize;
3671                                 s2 = nmd->params[j].regoff;
3672                                 if (IS_2_WORD_TYPE(t)) {
3673                                         M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3674                                         M_DST(REG_FTMP1, REG_SP, s2 * 8);
3675                                 } else {
3676                                         M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3677                                         M_FST(REG_FTMP1, REG_SP, s2 * 8);
3678                                 }
3679                         }
3680                 }
3681         }
3682
3683         /* put class into second argument register */
3684
3685         if (m->flags & ACC_STATIC) {
3686                 disp = dseg_addaddress(cd, m->class);
3687                 M_ALD(rd->argintregs[1], REG_PV, disp);
3688         }
3689
3690         /* put env into first argument register */
3691
3692         disp = dseg_addaddress(cd, _Jv_env);
3693         M_ALD(rd->argintregs[0], REG_PV, disp);
3694
3695         /* do the native function call */
3696
3697         M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method       */
3698         M_JSR(REG_RA, REG_ITMP3);           /* call native method                 */
3699         M_NOP;                              /* delay slot                         */
3700
3701         /* save return value */
3702
3703         if (md->returntype.type != TYPE_VOID) {
3704                 if (IS_INT_LNG_TYPE(md->returntype.type))
3705                         M_LST(REG_RESULT, REG_SP, 0 * 8);
3706                 else
3707                         M_DST(REG_FRESULT, REG_SP, 0 * 8);
3708         }
3709
3710 #if !defined(NDEBUG)
3711         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3712                 emit_verbosecall_exit(jd);
3713 #endif
3714
3715         /* remove native stackframe info */
3716
3717         M_AADD_IMM(REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
3718         disp = dseg_addaddress(cd, codegen_finish_native_call);
3719         M_ALD(REG_ITMP3, REG_PV, disp);
3720         M_JSR(REG_RA, REG_ITMP3);
3721         M_NOP; /* XXX fill me! */
3722         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3723
3724         /* restore return value */
3725
3726         if (md->returntype.type != TYPE_VOID) {
3727                 if (IS_INT_LNG_TYPE(md->returntype.type))
3728                         M_LLD(REG_RESULT, REG_SP, 0 * 8);
3729                 else
3730                         M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3731         }
3732
3733         M_ALD(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P); /* load RA */
3734
3735         /* check for exception */
3736
3737         M_BNEZ(REG_ITMP1_XPTR, 2);          /* if no exception then return        */
3738         M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT              */
3739
3740         M_RET(REG_RA);                      /* return to caller                   */
3741         M_NOP;                              /* DELAY SLOT                         */
3742
3743         /* handle exception */
3744         
3745         disp = dseg_addaddress(cd, asm_handle_nat_exception);
3746         M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
3747         M_JMP(REG_ITMP3);                   /* jump to asm exception handler      */
3748         M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY)    */
3749
3750         /* generate patcher stubs */
3751
3752         emit_patcher_stubs(jd);
3753
3754         codegen_finish(jd);
3755
3756         return code->entrypoint;
3757 }
3758
3759
3760 /*
3761  * These are local overrides for various environment variables in Emacs.
3762  * Please do not remove this and leave it at the end of the file, where
3763  * Emacs will automagically detect them.
3764  * ---------------------------------------------------------------------
3765  * Local variables:
3766  * mode: c
3767  * indent-tabs-mode: t
3768  * c-basic-offset: 4
3769  * tab-width: 4
3770  * End:
3771  * vim:noexpandtab:sw=4:ts=4:
3772  */