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