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