Merged revisions 7940-8026 via svnmerge from
[cacao.git] / src / vm / jit / mips / codegen.c
1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: codegen.c 8011 2007-06-05 10:06:18Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdio.h>
34
35 #include "vm/types.h"
36
37 #include "md-abi.h"
38
39 #include "vm/jit/mips/arch.h"
40 #include "vm/jit/mips/codegen.h"
41
42 #include "mm/memory.h"
43
44 #include "native/native.h"
45
46 #include "threads/lock-common.h"
47
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "vm/vm.h"
51
52 #include "vm/jit/abi.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/md.h"
59 #include "vm/jit/patcher.h"
60 #include "vm/jit/reg.h"
61 #include "vm/jit/replace.h"
62
63 #if defined(ENABLE_LSRA)
64 # include "vm/jit/allocator/lsra.h"
65 #endif
66
67 #include "vmcore/class.h"
68 #include "vmcore/options.h"
69
70
71 /* codegen_emit ****************************************************************
72
73    Generates machine code.
74
75 *******************************************************************************/
76
77 bool codegen_emit(jitdata *jd)
78 {
79         methodinfo         *m;
80         codeinfo           *code;
81         codegendata        *cd;
82         registerdata       *rd;
83         s4                  len, s1, s2, s3, d, disp;
84         varinfo            *var;
85         basicblock         *bptr;
86         instruction        *iptr;
87         exception_entry    *ex;
88         u2                  currentline;
89         constant_classref  *cr;
90         unresolved_class   *uc;
91         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
92         unresolved_method  *um;
93         builtintable_entry *bte;
94         methoddesc         *md;
95         fieldinfo          *fi;
96         unresolved_field   *uf;
97         s4                  fieldtype;
98         s4                  varindex;
99
100         /* get required compiler data */
101
102         m    = jd->m;
103         code = jd->code;
104         cd   = jd->cd;
105         rd   = jd->rd;
106
107         /* prevent compiler warnings */
108
109         s1          = 0;
110         d           = 0;
111         fieldtype   = 0;
112         lm          = NULL;
113         um          = NULL;
114         bte         = NULL;
115         currentline = 0;
116         uf          = NULL;
117
118         {
119         s4 i, p, t, l;
120         s4 savedregs_num;
121
122         savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the RA */
123
124         /* space to save used callee saved registers */
125
126         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
127         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
128
129         cd->stackframesize = rd->memuse + savedregs_num;
130
131 #if defined(ENABLE_THREADS)
132         /* space to save argument of monitor_enter */
133
134         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
135 # if SIZEOF_VOID_P == 8
136                 cd->stackframesize++;
137 # else
138                 rd->memuse++;
139                 cd->stackframesize += 2;
140 # endif
141         }
142 #endif
143
144         /* keep stack 16-byte aligned */
145
146         if (cd->stackframesize & 1)
147                 cd->stackframesize++;
148
149         /* create method header */
150
151         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
152         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
153
154 #if defined(ENABLE_THREADS)
155         /* IsSync contains the offset relative to the stack pointer for the
156            argument of monitor_exit used in the exception handler. Since the
157            offset could be zero and give a wrong meaning of the flag it is
158            offset by one.
159         */
160
161         if (checksync && (m->flags & ACC_SYNCHRONIZED))
162                 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync        */
163         else
164 #endif
165                 (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
166                                                
167         (void) dseg_add_unique_s4(cd, jd->isleafmethod);       /* IsLeaf          */
168         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
169         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
170         dseg_addlinenumbertablesize(cd);
171         (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
172
173         /* create exception table */
174
175         for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
176                 dseg_add_target(cd, ex->start);
177                 dseg_add_target(cd, ex->end);
178                 dseg_add_target(cd, ex->handler);
179                 (void) dseg_add_unique_address(cd, ex->catchtype.any);
180         }
181         
182         /* create stack frame (if necessary) */
183
184         if (cd->stackframesize)
185                 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
186
187         /* save return address and used callee saved registers */
188
189         p = cd->stackframesize;
190         if (!jd->isleafmethod) {
191                 p--; M_AST(REG_RA, REG_SP, p * 8);
192         }
193         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
194                 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
195         }
196         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
197                 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
198         }
199
200         /* take arguments out of register or stack frame */
201
202         md = m->parseddesc;
203
204         for (p = 0, l = 0; p < md->paramcount; p++) {
205                 t = md->paramtypes[p].type;
206
207                 varindex = jd->local_map[l * 5 + t];
208
209                 l++;
210                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
211                         l++;
212
213                 if (varindex == UNUSED)
214                         continue;
215
216                 var = VAR(varindex);
217                 s1  = md->params[p].regoff;
218
219                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
220                         if (!md->params[p].inmemory) {           /* register arguments    */
221 #if SIZEOF_VOID_P == 8
222                                 if (!(var->flags & INMEMORY))
223                                         M_INTMOVE(s1, var->vv.regoff);
224                                 else
225                                         M_LST(s1, REG_SP, var->vv.regoff * 8);
226 #else
227                                 if (!(var->flags & INMEMORY)) {
228                                         if (IS_2_WORD_TYPE(t))
229                                                 M_LNGMOVE(s1, var->vv.regoff);
230                                         else
231                                                 M_INTMOVE(s1, var->vv.regoff);
232                                 }
233                                 else {
234                                         if (IS_2_WORD_TYPE(t))
235                                                 M_LST(s1, REG_SP, var->vv.regoff * 8);
236                                         else
237                                                 M_IST(s1, REG_SP, var->vv.regoff * 8);
238                                 }
239 #endif
240                         }
241                         else {                                   /* stack arguments       */
242                                 if (!(var->flags & INMEMORY)) {
243 #if SIZEOF_VOID_P == 8
244                                         M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
245 #else
246                                         if (IS_2_WORD_TYPE(t))
247                                                 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
248                                         else
249                                                 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
250 #endif
251                                 }
252                                 else
253                                         var->vv.regoff = cd->stackframesize + s1;
254                         }
255                 }
256                 else {                                       /* floating args         */
257                         if (!md->params[p].inmemory) {
258                                 if (!(var->flags & INMEMORY)) {
259                                         if (IS_2_WORD_TYPE(t))
260                                                 M_DBLMOVE(s1, var->vv.regoff);
261                                         else
262                                                 M_FLTMOVE(s1, var->vv.regoff);
263                                 }
264                                 else {
265                                         if (IS_2_WORD_TYPE(t))
266                                                 M_DST(s1, REG_SP, var->vv.regoff * 8);
267                                         else
268                                                 M_FST(s1, REG_SP, var->vv.regoff * 8);
269                                 }
270                         }
271                         else {
272                                 if (!(var->flags & INMEMORY)) {
273                                         if (IS_2_WORD_TYPE(t))
274                                                 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
275                                         else
276                                                 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
277                                 }
278                                 else
279                                         var->vv.regoff = cd->stackframesize + s1;
280                         }
281                 }
282         }
283
284         /* call monitorenter function */
285
286 #if defined(ENABLE_THREADS)
287         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
288                 /* stack offset for monitor argument */
289
290                 s1 = rd->memuse;
291
292 # if !defined(NDEBUG)
293                 if (opt_verbosecall) {
294                         M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
295
296                         for (p = 0; p < INT_ARG_CNT; p++)
297                                 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
298
299                         for (p = 0; p < FLT_ARG_CNT; p++)
300                                 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
301
302                         s1 += INT_ARG_CNT + FLT_ARG_CNT;
303                 }
304 # endif
305
306                 /* get correct lock object */
307
308                 if (m->flags & ACC_STATIC) {
309                         disp = dseg_add_address(cd, &m->class->object.header);
310                         M_ALD(REG_A0, REG_PV, disp);
311                         disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
312                         M_ALD(REG_ITMP3, REG_PV, disp);
313                 }
314                 else {
315 /*                      emit_nullpointer_check(cd, iptr, REG_A0); */
316                         M_BNEZ(REG_A0, 2);
317                         disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
318                         M_ALD(REG_ITMP3, REG_PV, disp);                   /* branch delay */
319                         M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
320                 }
321
322                 M_JSR(REG_RA, REG_ITMP3);
323                 M_AST(REG_A0, REG_SP, s1 * 8);                        /* branch delay */
324
325 # if !defined(NDEBUG)
326                 if (opt_verbosecall) {
327                         for (p = 0; p < INT_ARG_CNT; p++)
328                                 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
329
330                         for (p = 0; p < FLT_ARG_CNT; p++)
331                                 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
332
333
334                         M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
335                 }
336 # endif
337         }
338 #endif
339         }
340
341 #if !defined(NDEBUG)
342         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
343                 emit_verbosecall_enter(jd);
344 #endif
345
346         /* end of header generation */
347
348         /* create replacement points */
349
350         REPLACEMENT_POINTS_INIT(cd, jd);
351
352         /* walk through all basic blocks */
353
354         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
355
356                 /* handle replacement points */
357
358                 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
359
360                 /* store relative start of block */
361
362                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
363
364                 if (bptr->flags >= BBREACHED) {
365                         /* branch resolving */
366
367                         codegen_resolve_branchrefs(cd, bptr);
368
369                 /* copy interface registers to their destination */
370
371                 len = bptr->indepth;
372                 MCODECHECK(64+len);
373 #if defined(ENABLE_LSRA)
374                 if (opt_lsra) {
375                 while (len) {
376                         len--;
377                         src = bptr->invars[len];
378                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
379                                         /*                              d = reg_of_var(m, src, REG_ITMP1); */
380                                         if (!(src->flags & INMEMORY))
381                                                 d = src->vv.regoff;
382                                         else
383                                                 d = REG_ITMP1;
384                                         M_INTMOVE(REG_ITMP1, d);
385                                         emit_store(jd, NULL, src, d);
386                                 }
387                         }
388                 } else {
389 #endif
390                 while (len) {
391                         len--;
392                         var = VAR(bptr->invars[len]);
393                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
394                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
395                                 M_INTMOVE(REG_ITMP1, d);
396                                 emit_store(jd, NULL, var, d);
397                         } 
398                         else {
399                                 assert((var->flags & INOUT));
400                         }
401                 }
402 #if defined(ENABLE_LSRA)
403                 }
404 #endif
405                 /* walk through all instructions */
406                 
407                 len = bptr->icount;
408 /*              currentline = 0; */
409
410                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
411                         if (iptr->line != currentline) {
412                                 dseg_addlinenumber(cd, iptr->line);
413                                 currentline = iptr->line;
414                         }
415
416                 MCODECHECK(64);       /* an instruction usually needs < 64 words      */
417
418                 switch (iptr->opc) {
419
420                 case ICMD_NOP:        /* ...  ==> ...                                 */
421                 case ICMD_POP:        /* ..., value  ==> ...                          */
422                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
423                         break;
424
425                 case ICMD_INLINE_START:
426
427                         REPLACEMENT_POINT_INLINE_START(cd, iptr);
428                         break;
429
430                 case ICMD_INLINE_BODY:
431
432                         REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
433                         dseg_addlinenumber_inline_start(cd, iptr);
434                         dseg_addlinenumber(cd, iptr->line);
435                         break;
436
437                 case ICMD_INLINE_END:
438
439                         dseg_addlinenumber_inline_end(cd, iptr);
440                         dseg_addlinenumber(cd, iptr->line);
441                         break;
442
443                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
444
445                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
446                         emit_nullpointer_check(cd, iptr, s1);
447                         break;
448
449                 /* constant operations ************************************************/
450
451                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
452
453                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
454                         ICONST(d, iptr->sx.val.i);
455                         emit_store_dst(jd, iptr, d);
456                         break;
457
458                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
459
460 #if SIZEOF_VOID_P == 8
461                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
462 #else
463                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
464 #endif
465                         LCONST(d, iptr->sx.val.l);
466                         emit_store_dst(jd, iptr, d);
467                         break;
468
469                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
470
471                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
472                         disp = dseg_add_float(cd, iptr->sx.val.f);
473                         M_FLD(d, REG_PV, disp);
474                         emit_store_dst(jd, iptr, d);
475                         break;
476                         
477                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
478
479                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
480                         disp = dseg_add_double(cd, iptr->sx.val.d);
481                         M_DLD(d, REG_PV, disp);
482                         emit_store_dst(jd, iptr, d);
483                         break;
484
485                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
486
487                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
488
489                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
490                                 cr   = iptr->sx.val.c.ref;
491                                 disp = dseg_add_unique_address(cd, cr);
492
493                                 codegen_add_patch_ref(cd, PATCHER_aconst, 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_arrayheader, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, data[0]));
1966 #else
1967                         M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, 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, 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                                 codegen_add_patch_ref(cd, 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                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1999                         }
2000
2001                         M_ALD(REG_ITMP1, REG_PV, disp);
2002
2003                         switch (fieldtype) {
2004                         case TYPE_INT:
2005                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2006                                 M_ILD_INTERN(d, REG_ITMP1, 0);
2007                                 break;
2008                         case TYPE_LNG:
2009 #if SIZEOF_VOID_P == 8
2010                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2011 #else
2012                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2013 #endif
2014                                 M_LLD_INTERN(d, REG_ITMP1, 0);
2015                                 break;
2016                         case TYPE_ADR:
2017                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2018                                 M_ALD_INTERN(d, REG_ITMP1, 0);
2019                                 break;
2020                         case TYPE_FLT:
2021                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2022                                 M_FLD_INTERN(d, REG_ITMP1, 0);
2023                                 break;
2024                         case TYPE_DBL:                          
2025                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2026                                 M_DLD_INTERN(d, REG_ITMP1, 0);
2027                                 break;
2028                         }
2029                         emit_store_dst(jd, iptr, d);
2030                         break;
2031
2032                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2033
2034                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2035                                 uf        = iptr->sx.s23.s3.uf;
2036                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2037                                 disp      = dseg_add_unique_address(cd, uf);
2038
2039                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2040                         }
2041                         else {
2042                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2043                                 fieldtype = fi->type;
2044                                 disp      = dseg_add_address(cd, &(fi->value));
2045
2046                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2047                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2048                         }
2049
2050                         M_ALD(REG_ITMP1, REG_PV, disp);
2051
2052                         switch (fieldtype) {
2053                         case TYPE_INT:
2054                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2055                                 M_IST_INTERN(s1, REG_ITMP1, 0);
2056                                 break;
2057                         case TYPE_LNG:
2058 #if SIZEOF_VOID_P == 8
2059                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2060 #else
2061                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2062 #endif
2063                                 M_LST_INTERN(s1, REG_ITMP1, 0);
2064                                 break;
2065                         case TYPE_ADR:
2066                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2067                                 M_AST_INTERN(s1, REG_ITMP1, 0);
2068                                 break;
2069                         case TYPE_FLT:
2070                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2071                                 M_FST_INTERN(s1, REG_ITMP1, 0);
2072                                 break;
2073                         case TYPE_DBL:
2074                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2075                                 M_DST_INTERN(s1, REG_ITMP1, 0);
2076                                 break;
2077                         }
2078                         break;
2079
2080                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2081                                           /* val = value (in current instruction)     */
2082                                           /* following NOP)                           */
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                                 codegen_add_patch_ref(cd, 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                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2098                         }
2099
2100                         M_ALD(REG_ITMP1, REG_PV, disp);
2101
2102                         switch (fieldtype) {
2103                         case TYPE_INT:
2104                                 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2105                                 break;
2106                         case TYPE_LNG:
2107                                 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2108                                 break;
2109                         case TYPE_ADR:
2110                                 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2111                                 break;
2112                         case TYPE_FLT:
2113                                 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2114                                 break;
2115                         case TYPE_DBL:
2116                                 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2117                                 break;
2118                         }
2119                         break;
2120
2121
2122                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
2123
2124                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2125                         emit_nullpointer_check(cd, iptr, s1);
2126
2127                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2128                                 uf        = iptr->sx.s23.s3.uf;
2129                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2130                                 disp      = 0;
2131
2132                                 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2133                         }
2134                         else {
2135                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2136                                 fieldtype = fi->type;
2137                                 disp      = fi->offset;
2138                         }
2139
2140                         switch (fieldtype) {
2141                         case TYPE_INT:
2142                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2143                                 M_ILD(d, s1, disp);
2144                                 break;
2145                         case TYPE_LNG:
2146 #if SIZEOF_VOID_P == 8
2147                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2148                                 M_LLD(d, s1, disp);
2149 #else
2150                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2151                                 M_LLD_GETFIELD(d, s1, disp);
2152 #endif
2153                                 break;
2154                         case TYPE_ADR:
2155                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2156                                 M_ALD(d, s1, disp);
2157                                 break;
2158                         case TYPE_FLT:
2159                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2160                                 M_FLD(d, s1, disp);
2161                                 break;
2162                         case TYPE_DBL:                          
2163                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2164                                 M_DLD(d, s1, disp);
2165                                 break;
2166                         }
2167                         emit_store_dst(jd, iptr, d);
2168                         break;
2169
2170                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2171
2172                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2173                         emit_nullpointer_check(cd, iptr, s1);
2174
2175                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2176                                 uf        = iptr->sx.s23.s3.uf;
2177                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2178                                 disp      = 0;
2179                         }
2180                         else {
2181                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2182                                 fieldtype = fi->type;
2183                                 disp      = fi->offset;
2184                         }
2185
2186 #if SIZEOF_VOID_P == 8
2187                         if (IS_INT_LNG_TYPE(fieldtype))
2188                                 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2189                         else
2190                                 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2191 #else
2192                         if (IS_INT_LNG_TYPE(fieldtype)) {
2193                                 if (IS_2_WORD_TYPE(fieldtype))
2194                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2195                                 else
2196                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2197                         }
2198                         else
2199                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2200 #endif
2201
2202                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
2203                                 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2204
2205                         switch (fieldtype) {
2206                         case TYPE_INT:
2207                                 M_IST(s2, s1, disp);
2208                                 break;
2209                         case TYPE_LNG:
2210                                 M_LST(s2, s1, disp);
2211                                 break;
2212                         case TYPE_ADR:
2213                                 M_AST(s2, s1, disp);
2214                                 break;
2215                         case TYPE_FLT:
2216                                 M_FST(s2, s1, disp);
2217                                 break;
2218                         case TYPE_DBL:
2219                                 M_DST(s2, s1, disp);
2220                                 break;
2221                         }
2222                         break;
2223
2224                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2225
2226                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2227                         emit_nullpointer_check(cd, iptr, s1);
2228
2229                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2230                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2231
2232                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2233                                 disp      = 0;
2234
2235                                 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2236                         }
2237                         else {
2238                                 fieldinfo *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                                 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, 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                                 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, 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 * 8);
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 * 8);
3074                                                 }
3075                                                 else {
3076                                                         s1 = emit_load(jd, iptr, var, REG_ITMP1);
3077                                                         M_IST(s1, REG_SP, d * 8);
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 * 8);
3094                                                 else
3095                                                         M_FST(s1, REG_SP, d * 8);
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                                         codegen_add_patch_ref(cd, 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                                         codegen_add_patch_ref(cd, 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_objectheader, 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                                         codegen_add_patch_ref(cd, 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_objectheader, 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                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_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                                                 codegen_add_patch_ref(cd, 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_objectheader, 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                                                 codegen_add_patch_ref(cd,
3309                                                                                           PATCHER_checkcast_instanceof_class,
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_objectheader, 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                                         codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3363                                                                                   cr, disp);
3364                                 }
3365                                 else
3366                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3367
3368                                 M_ALD(REG_A1, REG_PV, disp);
3369                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3370                                 M_ALD(REG_ITMP3, REG_PV, disp);
3371                                 M_JSR(REG_RA, REG_ITMP3);
3372                                 M_NOP;
3373
3374                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3375                                 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3376
3377                                 d = codegen_reg_of_dst(jd, iptr, s1);
3378                         }
3379
3380                         M_INTMOVE(s1, d);
3381                         emit_store_dst(jd, iptr, d);
3382                         break;
3383
3384                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3385
3386                         {
3387                         classinfo *super;
3388                         s4         superindex;
3389
3390                         super = iptr->sx.s23.s3.c.cls;
3391
3392                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3393                                 super      = NULL;
3394                                 superindex = 0;
3395                         }
3396                         else {
3397                                 super      = iptr->sx.s23.s3.c.cls;
3398                                 superindex = super->index;
3399                         }
3400                         
3401                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3402                                 CODEGEN_CRITICAL_SECTION_NEW;
3403
3404                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3405                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3406
3407                         if (s1 == d) {
3408                                 M_MOV(s1, REG_ITMP1);
3409                                 s1 = REG_ITMP1;
3410                         }
3411
3412                         M_CLR(d);
3413
3414                         /* if class is not resolved, check which code to call */
3415
3416                         if (super == NULL) {
3417                                 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3418
3419                                 cr   = iptr->sx.s23.s3.c.ref;
3420                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
3421
3422                                 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3423                                                                           cr, disp);
3424
3425                                 M_ILD(REG_ITMP3, REG_PV, disp);
3426                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3427                                 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3428                         }
3429
3430                         /* interface instanceof code */
3431
3432                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3433                                 if (super == NULL) {
3434                                         cr = iptr->sx.s23.s3.c.ref;
3435
3436                                         codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
3437                                                                                   cr, 0);
3438                                 }
3439                                 else {
3440                                         emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3441                                 }
3442
3443                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3444                                 M_ILD(REG_ITMP3, REG_ITMP1,
3445                                           OFFSET(vftbl_t, interfacetablelength));
3446                                 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3447                                 M_BLEZ(REG_ITMP3, 3);
3448                                 M_NOP;
3449                                 M_ALD(REG_ITMP1, REG_ITMP1,
3450                                           OFFSET(vftbl_t, interfacetable[0]) -
3451                                           superindex * sizeof(methodptr*));
3452                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3453
3454                                 if (super == NULL)
3455                                         emit_label_br(cd, BRANCH_LABEL_4);
3456                                 else
3457                                         emit_label(cd, BRANCH_LABEL_3);
3458                         }
3459
3460                         /* class instanceof code */
3461
3462                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3463                                 if (super == NULL) {
3464                                         emit_label(cd, BRANCH_LABEL_2);
3465
3466                                         cr   = iptr->sx.s23.s3.c.ref;
3467                                         disp = dseg_add_unique_address(cd, NULL);
3468
3469                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
3470                                                                                   cr, disp);
3471                                 }
3472                                 else {
3473                                         disp = dseg_add_address(cd, super->vftbl);
3474
3475                                         emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3476                                 }
3477
3478                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3479                                 M_ALD(REG_ITMP2, REG_PV, disp);
3480
3481                                 CODEGEN_CRITICAL_SECTION_START;
3482
3483                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3484                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3485                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3486
3487                                 CODEGEN_CRITICAL_SECTION_END;
3488
3489                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3490                                 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3491                                 M_XOR_IMM(d, 1, d);
3492
3493                                 if (super != NULL)
3494                                         emit_label(cd, BRANCH_LABEL_5);
3495                         }
3496
3497                         if (super == NULL) {
3498                                 emit_label(cd, BRANCH_LABEL_1);
3499                                 emit_label(cd, BRANCH_LABEL_4);
3500                         }
3501
3502                         emit_store_dst(jd, iptr, d);
3503                         }
3504                         break;
3505
3506                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3507
3508                         /* check for negative sizes and copy sizes to stack if necessary  */
3509
3510                         MCODECHECK((iptr->s1.argcount << 1) + 64);
3511
3512                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3513
3514                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3515
3516                                 /* copy SAVEDVAR sizes to stack */
3517
3518                                 if (!(var->flags & PREALLOC)) {
3519                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
3520 #if SIZEOF_VOID_P == 8
3521                                         M_LST(s2, REG_SP, s1 * 8);
3522 #else
3523                                         M_IST(s2, REG_SP, (s1 + 2) * 8);
3524 #endif
3525                                 }
3526                         }
3527
3528                         /* a0 = dimension count */
3529
3530                         ICONST(REG_A0, iptr->s1.argcount);
3531
3532                         /* is patcher function set? */
3533
3534                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3535                                 cr   = iptr->sx.s23.s3.c.ref;
3536                                 disp = dseg_add_unique_address(cd, NULL);
3537
3538                                 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3539                                                                           cr, disp);
3540                         }
3541                         else
3542                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3543
3544                         /* a1 = arraydescriptor */
3545
3546                         M_ALD(REG_A1, REG_PV, disp);
3547
3548                         /* a2 = pointer to dimensions = stack pointer */
3549
3550 #if SIZEOF_VOID_P == 8
3551                         M_MOV(REG_SP, REG_A2);
3552 #else
3553                         M_AADD_IMM(REG_SP, 4*4, REG_A2);
3554 #endif
3555
3556                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3557                         M_ALD(REG_ITMP3, REG_PV, disp);
3558                         M_JSR(REG_RA, REG_ITMP3);
3559                         M_NOP;
3560
3561                         /* check for exception before result assignment */
3562
3563                         emit_exception_check(cd, iptr);
3564
3565                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3566                         M_INTMOVE(REG_RESULT, d);
3567                         emit_store_dst(jd, iptr, d);
3568                         break;
3569
3570                 default:
3571                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3572                                                                                    iptr->opc);
3573                         return false;
3574         } /* switch */
3575                 
3576         } /* for instruction */
3577                 
3578         MCODECHECK(64); /* XXX require smaller number? */
3579
3580         /* At the end of a basic block we may have to append some nops,
3581            because the patcher stub calling code might be longer than the
3582            actual instruction. So codepatching does not change the
3583            following block unintentionally. */
3584
3585         if (cd->mcodeptr < cd->lastmcodeptr) {
3586                 while (cd->mcodeptr < cd->lastmcodeptr)
3587                         M_NOP;
3588         }
3589
3590         } /* if (bptr -> flags >= BBREACHED) */
3591         } /* for basic block */
3592
3593         dseg_createlinenumbertable(cd);
3594
3595         /* generate stubs */
3596
3597         emit_patcher_stubs(jd);
3598         REPLACEMENT_EMIT_STUBS(jd);
3599
3600         /* everything's ok */
3601
3602         return true;
3603 }
3604
3605
3606 /* codegen_emit_stub_compiler **************************************************
3607
3608    Emits a stub routine which calls the compiler.
3609         
3610 *******************************************************************************/
3611
3612 void codegen_emit_stub_compiler(jitdata *jd)
3613 {
3614         methodinfo  *m;
3615         codegendata *cd;
3616
3617         /* get required compiler data */
3618
3619         m  = jd->m;
3620         cd = jd->cd;
3621
3622         /* code for the stub */
3623
3624         M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
3625         M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
3626         M_JMP(REG_PV);
3627         M_NOP;
3628 }
3629
3630
3631 /* codegen_emit_stub_native ****************************************************
3632
3633    Emits a stub routine which calls a native method.
3634
3635 *******************************************************************************/
3636
3637 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3638 {
3639         methodinfo  *m;
3640         codeinfo    *code;
3641         codegendata *cd;
3642         methoddesc  *md;
3643         s4           nativeparams;
3644         s4           i, j;
3645         s4           t;
3646         s4           s1, s2, disp;
3647         s4           funcdisp;              /* displacement of the function       */
3648
3649         /* get required compiler data */
3650
3651         m    = jd->m;
3652         code = jd->code;
3653         cd   = jd->cd;
3654
3655         /* initialize variables */
3656
3657         md = m->parseddesc;
3658         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3659
3660         /* calculate stack frame size */
3661
3662         cd->stackframesize =
3663                 1 +                             /* return address                     */
3664                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3665                 sizeof(localref_table) / SIZEOF_VOID_P +
3666                 md->paramcount +                /* for saving arguments over calls    */
3667 #if SIZEOF_VOID_P == 4
3668                 5 +                             /* additional save space (MIPS32)     */
3669 #endif
3670                 1 +                             /* for saving return address          */
3671                 nmd->memuse;
3672
3673         /* adjust stackframe size for 16-byte alignment */
3674
3675         if (cd->stackframesize & 1)
3676                 cd->stackframesize++;
3677
3678         /* create method header */
3679
3680         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3681         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
3682         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
3683         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3684         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3685         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3686         (void) dseg_addlinenumbertablesize(cd);
3687         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
3688
3689         /* generate stub code */
3690
3691         M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe    */
3692         M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA          */
3693
3694 #if !defined(NDEBUG)
3695         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3696                 emit_verbosecall_enter(jd);
3697 #endif
3698
3699         /* get function address (this must happen before the stackframeinfo) */
3700
3701         funcdisp = dseg_add_functionptr(cd, f);
3702
3703 #if !defined(WITH_STATIC_CLASSPATH)
3704         if (f == NULL)
3705                 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3706 #endif
3707
3708         /* save integer and float argument registers */
3709
3710 #if SIZEOF_VOID_P == 8
3711         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3712                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3713                         s1 = md->params[i].regoff;
3714                         M_AST(s1, REG_SP, j * 8);
3715                         j++;
3716                 }
3717         }
3718 #else
3719         for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3720                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3721                         if (!md->params[i].inmemory) {
3722                                 s1 = md->params[i].regoff;
3723
3724                                 if (IS_2_WORD_TYPE(md->params[i].type))
3725                                         M_LST(s1, REG_SP, j * 8);
3726                                 else
3727                                         M_IST(s1, REG_SP, j * 8);
3728
3729                                 j++;
3730                         }
3731                 }
3732         }
3733 #endif
3734
3735         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3736                 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3737                         s1 = md->params[i].regoff;
3738
3739                         if (IS_2_WORD_TYPE(md->params[i].type))
3740                                 M_DST(s1, REG_SP, j * 8);
3741                         else
3742                                 M_FST(s1, REG_SP, j * 8);
3743
3744                         j++;
3745                 }
3746         }
3747
3748         /* prepare data structures for native function call */
3749
3750         M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3751         M_MOV(REG_PV, REG_A1);
3752         M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3753         M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3754         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3755         M_ALD(REG_ITMP3, REG_PV, disp);
3756         M_JSR(REG_RA, REG_ITMP3);
3757         M_NOP; /* XXX fill me! */
3758
3759         /* restore integer and float argument registers */
3760
3761 #if SIZEOF_VOID_P == 8
3762         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3763                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3764                         s1 = md->params[i].regoff;
3765                         M_LLD(s1, REG_SP, j * 8);
3766                         j++;
3767                 }
3768         }
3769 #else
3770         for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3771                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3772                         if (!md->params[i].inmemory) {
3773                                 s1 = md->params[i].regoff;
3774
3775                                 if (IS_2_WORD_TYPE(md->params[i].type))
3776                                         M_LLD(s1, REG_SP, j * 8);
3777                                 else
3778                                         M_ILD(s1, REG_SP, j * 8);
3779
3780                                 j++;
3781                         }
3782                 }
3783         }
3784 #endif
3785
3786         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3787                 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3788                         s1 = md->params[i].regoff;
3789
3790                         if (IS_2_WORD_TYPE(md->params[i].type))
3791                                 M_DLD(s1, REG_SP, j * 8);
3792                         else
3793                                 M_FLD(s1, REG_SP, j * 8);
3794
3795                         j++;
3796                 }
3797         }
3798
3799         /* copy or spill arguments to new locations */
3800
3801         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3802                 t = md->params[i].type;
3803
3804                 if (IS_INT_LNG_TYPE(t)) {
3805                         if (!md->params[i].inmemory) {
3806                                 s1 = md->params[i].regoff;
3807                                 s2 = nmd->params[j].regoff;
3808
3809                                 if (!nmd->params[j].inmemory) {
3810 #if SIZEOF_VOID_P == 8
3811                                         M_INTMOVE(s1, s2);
3812 #else
3813                                         if (IS_2_WORD_TYPE(t))
3814                                                 M_LNGMOVE(s1, s2);
3815                                         else
3816                                                 M_INTMOVE(s1, s2);
3817 #endif
3818                                 }
3819                                 else {
3820 #if SIZEOF_VOID_P == 8
3821                                         M_LST(s1, REG_SP, s2 * 8);
3822 #else
3823                                         if (IS_2_WORD_TYPE(t))
3824                                                 M_LST(s1, REG_SP, s2 * 4);
3825                                         else
3826                                                 M_IST(s1, REG_SP, s2 * 4);
3827 #endif
3828                                 }
3829                         }
3830                         else {
3831                                 s1 = md->params[i].regoff + cd->stackframesize;
3832                                 s2 = nmd->params[j].regoff;
3833
3834 #if SIZEOF_VOID_P == 8
3835                                 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3836                                 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3837 #else
3838                                 if (IS_2_WORD_TYPE(t)) {
3839                                         M_LLD(REG_ITMP12_PACKED, REG_SP, s1 * 8);
3840                                         M_LST(REG_ITMP12_PACKED, REG_SP, s2 * 4);
3841                                 }
3842                                 else {
3843                                         M_ILD(REG_ITMP1, REG_SP, s1 * 8);
3844                                         M_IST(REG_ITMP1, REG_SP, s2 * 4);
3845                                 }
3846 #endif
3847                         }
3848                 }
3849                 else {
3850                         if (!md->params[i].inmemory) {
3851                                 s1 = md->params[i].regoff;
3852                                 s2 = nmd->params[j].regoff;
3853
3854                                 if (!nmd->params[j].inmemory) {
3855 #if SIZEOF_VOID_P == 8
3856                                         if (IS_2_WORD_TYPE(t))
3857                                                 M_DMOV(s1, s2);
3858                                         else
3859                                                 M_FMOV(s1, s2);
3860 #else
3861                                         /* On MIPS32 float arguments for native functions
3862                                            can never be in float argument registers, since
3863                                            the first argument is _always_ an integer
3864                                            argument (JNIEnv) */
3865
3866                                         if (IS_2_WORD_TYPE(t)) {
3867                                                 /* double high/low order is endian
3868                                                    independent: even numbered holds low
3869                                                    32-bits, odd numbered high 32-bits */
3870
3871                                                 M_MFC1(GET_LOW_REG(s2), s1);           /* low 32-bits */
3872                                                 M_MFC1(GET_HIGH_REG(s2), s1 + 1);     /* high 32-bits */
3873                                         }
3874                                         else
3875                                                 M_MFC1(s2, s1);
3876 #endif
3877                                 }
3878                                 else {
3879 #if SIZEOF_VOID_P == 8
3880                                         if (IS_2_WORD_TYPE(t))
3881                                                 M_DST(s1, REG_SP, s2 * 8);
3882                                         else
3883                                                 M_FST(s1, REG_SP, s2 * 8);
3884 #else
3885                                         /* s1 may have been originally in 2 int registers,
3886                                            but was moved out by the native function
3887                                            argument(s), just get low register */
3888
3889                                         if (IS_2_WORD_TYPE(t))
3890                                                 M_DST(GET_LOW_REG(s1), REG_SP, s2 * 4);
3891                                         else
3892                                                 M_FST(GET_LOW_REG(s1), REG_SP, s2 * 4);
3893 #endif
3894                                 }
3895                         }
3896                         else {
3897                                 s1 = md->params[i].regoff + cd->stackframesize;
3898                                 s2 = nmd->params[j].regoff;
3899
3900 #if SIZEOF_VOID_P == 8
3901                                 if (IS_2_WORD_TYPE(t)) {
3902                                         M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3903                                         M_DST(REG_FTMP1, REG_SP, s2 * 8);
3904                                 }
3905                                 else {
3906                                         M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3907                                         M_FST(REG_FTMP1, REG_SP, s2 * 8);
3908                                 }
3909 #else
3910                                 if (IS_2_WORD_TYPE(t)) {
3911                                         M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3912                                         M_DST(REG_FTMP1, REG_SP, s2 * 4);
3913                                 }
3914                                 else {
3915                                         M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3916                                         M_FST(REG_FTMP1, REG_SP, s2 * 4);
3917                                 }
3918 #endif
3919                         }
3920                 }
3921         }
3922
3923         /* put class into second argument register */
3924
3925         if (m->flags & ACC_STATIC) {
3926                 disp = dseg_add_address(cd, m->class);
3927                 M_ALD(REG_A1, REG_PV, disp);
3928         }
3929
3930         /* put env into first argument register */
3931
3932         disp = dseg_add_address(cd, _Jv_env);
3933         M_ALD(REG_A0, REG_PV, disp);
3934
3935         /* do the native function call */
3936
3937         M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method       */
3938         M_JSR(REG_RA, REG_ITMP3);           /* call native method                 */
3939         M_NOP;                              /* delay slot                         */
3940
3941         /* save return value */
3942
3943         switch (md->returntype.type) {
3944 #if SIZEOF_VOID_P == 8
3945         case TYPE_INT:
3946         case TYPE_LNG:
3947         case TYPE_ADR:
3948                 M_LST(REG_RESULT, REG_SP, 0 * 8);
3949                 break;
3950         case TYPE_FLT:
3951         case TYPE_DBL:
3952                 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3953                 break;
3954 #else
3955         case TYPE_INT:
3956         case TYPE_ADR:
3957                 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
3958                 break;
3959         case TYPE_LNG:
3960                 M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
3961                 break;
3962         case TYPE_FLT:
3963         case TYPE_DBL:
3964                 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
3965                 break;
3966 #endif
3967         case TYPE_VOID:
3968                 break;
3969         }
3970
3971 #if !defined(NDEBUG)
3972         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3973                 emit_verbosecall_exit(jd);
3974 #endif
3975
3976         /* remove native stackframe info */
3977
3978         M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3979         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3980         M_ALD(REG_ITMP3, REG_PV, disp);
3981         M_JSR(REG_RA, REG_ITMP3);
3982         M_NOP; /* XXX fill me! */
3983         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3984
3985         /* restore return value */
3986
3987         switch (md->returntype.type) {
3988 #if SIZEOF_VOID_P == 8
3989         case TYPE_INT:
3990         case TYPE_LNG:
3991         case TYPE_ADR:
3992                 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3993                 break;
3994         case TYPE_FLT:
3995         case TYPE_DBL:
3996                 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3997                 break;
3998 #else
3999         case TYPE_INT:
4000         case TYPE_ADR:
4001                 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4002                 break;
4003         case TYPE_LNG:
4004                 M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4005                 break;
4006         case TYPE_FLT:
4007         case TYPE_DBL:
4008                 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4009                 break;
4010 #endif
4011         case TYPE_VOID:
4012                 break;
4013         }
4014
4015         M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA           */
4016
4017         /* check for exception */
4018
4019         M_BNEZ(REG_ITMP1_XPTR, 2);          /* if no exception then return        */
4020         M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT              */
4021
4022         M_RET(REG_RA);                      /* return to caller                   */
4023         M_NOP;                              /* DELAY SLOT                         */
4024
4025         /* handle exception */
4026         
4027         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4028         M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
4029         M_JMP(REG_ITMP3);                   /* jump to asm exception handler      */
4030         M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY)    */
4031
4032         /* generate patcher stubs */
4033
4034         emit_patcher_stubs(jd);
4035 }
4036
4037
4038 /*
4039  * These are local overrides for various environment variables in Emacs.
4040  * Please do not remove this and leave it at the end of the file, where
4041  * Emacs will automagically detect them.
4042  * ---------------------------------------------------------------------
4043  * Local variables:
4044  * mode: c
4045  * indent-tabs-mode: t
4046  * c-basic-offset: 4
4047  * tab-width: 4
4048  * End:
4049  * vim:noexpandtab:sw=4:ts=4:
4050  */