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