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