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