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