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