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