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