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