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