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