* src/native/localref.c: Moved to C++.
[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.h"
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.h"
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.h"
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                         M_BNEZ(d, 4);
1407                         M_NOP;
1408                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1409                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1410                         M_CMPULT(s1, s2, REG_ITMP3);
1411                         M_CMPULT(s2, s1, REG_ITMP1);
1412                         M_ISUB(REG_ITMP1, REG_ITMP3, d);
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                                 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2434                                 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2435                                 M_NOP;
2436                                 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2437                                 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2438                                 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
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                                 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2464                                 M_NOP;
2465                                 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2466                                 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
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                                 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2474                                 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2475                                 M_NOP;
2476                                 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2477                                 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2478                                 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
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                                 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2534                                 M_NOP;
2535                                 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
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                                 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2543                                 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2544                                 M_NOP;
2545                                 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2546                                 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2547                                 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
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                                 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2580                                 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2581                                 M_NOP;
2582                                 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2583                                 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2584                                 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
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                         M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2607                         M_NOP;
2608                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2609                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2610                         emit_beq(cd, iptr->dst.block, s1, s2);
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                         /* load low-bits before the branch, so we know the distance */
2658                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2659                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2660                         M_BNEZ(REG_ITMP3, 4); /* XXX */
2661                         M_NOP;
2662                         M_CMPULT(s1, s2, REG_ITMP3);
2663                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2664                         break;
2665 #endif
2666
2667                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2668 #if SIZEOF_VOID_P == 8
2669                 case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
2670 #endif
2671
2672                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2673                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2674                         M_CMPGT(s1, s2, REG_ITMP3);
2675                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2676                         break;
2677
2678 #if SIZEOF_VOID_P == 4
2679                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2680
2681                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2682                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2683                         M_CMPGT(s1, s2, REG_ITMP3);
2684                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2685                         M_CMPLT(s1, s2, REG_ITMP3);
2686                         /* load low-bits before the branch, so we know the distance */
2687                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2688                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2689                         M_BNEZ(REG_ITMP3, 4); /* XXX */
2690                         M_NOP;
2691                         M_CMPUGT(s1, s2, REG_ITMP3);
2692                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2693                         break;
2694 #endif
2695
2696                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2697 #if SIZEOF_VOID_P == 8
2698                 case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
2699 #endif
2700
2701                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2702                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2703                         M_CMPGT(s1, s2, REG_ITMP3);
2704                         emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2705                         break;
2706
2707 #if SIZEOF_VOID_P == 4
2708                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2709
2710                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2711                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2712                         M_CMPLT(s1, s2, REG_ITMP3);
2713                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2714                         M_CMPGT(s1, s2, REG_ITMP3);
2715                         /* load low-bits before the branch, so we know the distance */
2716                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2717                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2718                         M_BNEZ(REG_ITMP3, 4); /* XXX */
2719                         M_NOP;
2720                         M_CMPUGT(s1, s2, REG_ITMP3);
2721                         emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2722                         break;
2723 #endif
2724
2725                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2726 #if SIZEOF_VOID_P == 8
2727                 case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
2728 #endif
2729
2730                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2731                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2732                         M_CMPLT(s1, s2, REG_ITMP3);
2733                         emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2734                         break;
2735
2736 #if SIZEOF_VOID_P == 4
2737                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2738
2739                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2740                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2741                         M_CMPGT(s1, s2, REG_ITMP3);
2742                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2743                         M_CMPLT(s1, s2, REG_ITMP3);
2744                         /* load low-bits before the branch, so we know the distance */
2745                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2746                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2747                         M_BNEZ(REG_ITMP3, 4); /* XXX */
2748                         M_NOP;
2749                         M_CMPULT(s1, s2, REG_ITMP3);
2750                         emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2751                         break;
2752 #endif
2753
2754                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2755 #if SIZEOF_VOID_P == 8
2756                 case ICMD_LRETURN:
2757 #endif
2758
2759                         REPLACEMENT_POINT_RETURN(cd, iptr);
2760                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2761                         M_INTMOVE(s1, REG_RESULT);
2762                         goto nowperformreturn;
2763
2764                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2765
2766                         REPLACEMENT_POINT_RETURN(cd, iptr);
2767                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2768                         M_INTMOVE(s1, REG_RESULT);
2769
2770 #ifdef ENABLE_VERIFIER
2771                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2772                                 uc = iptr->sx.s23.s2.uc;
2773
2774                                 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2775                         }
2776 #endif /* ENABLE_VERIFIER */
2777                         goto nowperformreturn;
2778
2779 #if SIZEOF_VOID_P == 4
2780                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2781
2782                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2783                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2784                         goto nowperformreturn;
2785 #endif
2786
2787             case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2788                         REPLACEMENT_POINT_RETURN(cd, iptr);
2789                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2790                         M_FLTMOVE(s1, REG_FRESULT);
2791                         goto nowperformreturn;
2792
2793             case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
2794
2795                         REPLACEMENT_POINT_RETURN(cd, iptr);
2796                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2797                         M_DBLMOVE(s1, REG_FRESULT);
2798                         goto nowperformreturn;
2799
2800                 case ICMD_RETURN:      /* ...  ==> ...                                */
2801
2802                         REPLACEMENT_POINT_RETURN(cd, iptr);
2803
2804 nowperformreturn:
2805                         {
2806                         s4 i, p;
2807                         
2808                         p = cd->stackframesize;
2809
2810 #if !defined(NDEBUG)
2811                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2812                                 emit_verbosecall_exit(jd);
2813 #endif
2814
2815 #if defined(ENABLE_THREADS)
2816                         if (checksync && code_is_synchronized(code)) {
2817                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2818                                 M_ALD(REG_ITMP3, REG_PV, disp);
2819
2820                                 /* we need to save the proper return value */
2821
2822                                 switch (iptr->opc) {
2823                                 case ICMD_IRETURN:
2824                                 case ICMD_ARETURN:
2825 #if SIZEOF_VOID_P == 8
2826                                 case ICMD_LRETURN:
2827 #endif
2828                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2829                                         M_JSR(REG_RA, REG_ITMP3);
2830                                         M_AST(REG_RESULT, REG_SP, rd->memuse * 8);  /* delay slot */
2831                                         break;
2832 #if SIZEOF_VOID_P == 4
2833                                 case ICMD_LRETURN:
2834                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2835                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2836                                         M_JSR(REG_RA, REG_ITMP3);
2837                                         M_NOP;
2838                                         break;
2839 #endif
2840                                 case ICMD_FRETURN:
2841                                 case ICMD_DRETURN:
2842                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2843                                         M_JSR(REG_RA, REG_ITMP3);
2844                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2845                                         break;
2846                                 case ICMD_RETURN:
2847                                         M_JSR(REG_RA, REG_ITMP3);
2848                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2849                                         break;
2850                                 }
2851
2852                                 /* and now restore the proper return value */
2853
2854                                 switch (iptr->opc) {
2855                                 case ICMD_IRETURN:
2856                                 case ICMD_ARETURN:
2857 #if SIZEOF_VOID_P == 8
2858                                 case ICMD_LRETURN:
2859 #endif
2860                                         M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2861                                         break;
2862 #if SIZEOF_VOID_P == 4
2863                                 case ICMD_LRETURN:
2864                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2865                                         break;
2866 #endif
2867                                 case ICMD_FRETURN:
2868                                 case ICMD_DRETURN:
2869                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2870                                         break;
2871                                 }
2872                         }
2873 #endif
2874
2875                         /* restore return address                                         */
2876
2877                         if (!code_is_leafmethod(code)) {
2878                                 p--; M_ALD(REG_RA, REG_SP, p * 8);
2879                         }
2880
2881                         /* restore saved registers                                        */
2882
2883                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2884                                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2885                         }
2886                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2887                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2888                         }
2889
2890                         /* deallocate stack and return                                    */
2891
2892                         if (cd->stackframesize) {
2893                                 s4 lo, hi;
2894
2895                                 disp = cd->stackframesize * 8;
2896                                 lo = (short) (disp);
2897                                 hi = (short) (((disp) - lo) >> 16);
2898
2899                                 if (hi == 0) {
2900                                         M_RET(REG_RA);
2901                                         M_AADD_IMM(REG_SP, lo, REG_SP);             /* delay slot */
2902                                 } else {
2903                                         M_LUI(REG_ITMP3,hi);
2904                                         M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2905                                         M_RET(REG_RA);
2906                                         M_AADD(REG_ITMP3,REG_SP,REG_SP);            /* delay slot */
2907                                 }
2908
2909                         } else {
2910                                 M_RET(REG_RA);
2911                                 M_NOP;
2912                         }
2913
2914                         ALIGNCODENOP;
2915                         }
2916                         break;
2917
2918
2919                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2920                         {
2921                         s4 i, l;
2922                         branch_target_t *table;
2923
2924                         table = iptr->dst.table;
2925
2926                         l = iptr->sx.s23.s2.tablelow;
2927                         i = iptr->sx.s23.s3.tablehigh;
2928
2929                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2930                         if (l == 0)
2931                                 {M_INTMOVE(s1, REG_ITMP1);}
2932                         else if (l <= 32768) {
2933                                 M_IADD_IMM(s1, -l, REG_ITMP1);
2934                                 }
2935                         else {
2936                                 ICONST(REG_ITMP2, l);
2937                                 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2938                                 }
2939
2940                         /* number of targets */
2941                         i = i - l + 1;
2942
2943                         /* range check */
2944
2945                         M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2946                         emit_beqz(cd, table[0].block, REG_ITMP2);
2947
2948                         /* build jump table top down and use address of lowest entry */
2949
2950                         table += i;
2951
2952                         while (--i >= 0) {
2953                                 dseg_add_target(cd, table->block); 
2954                                 --table;
2955                         }
2956                         }
2957
2958                         /* length of dataseg after last dseg_add_target is used by load */
2959
2960                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2961                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2962                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2963                         M_JMP(REG_ITMP2);
2964                         M_NOP;
2965                         ALIGNCODENOP;
2966                         break;
2967
2968
2969                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2970                         {
2971                         s4 i;
2972                         lookup_target_t *lookup;
2973
2974                         lookup = iptr->dst.lookup;
2975
2976                         i = iptr->sx.s23.s2.lookupcount;
2977                         
2978                         MCODECHECK((i<<2)+8);
2979                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2980
2981                         while (--i >= 0) {
2982                                 ICONST(REG_ITMP2, lookup->value);
2983                                 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
2984                                 ++lookup;
2985                         }
2986
2987                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2988                         ALIGNCODENOP;
2989                         break;
2990                         }
2991
2992
2993                 case ICMD_BUILTIN:      /* ..., arg1 ==> ...                          */
2994
2995                         bte = iptr->sx.s23.s3.bte;
2996                         md  = bte->md;
2997                         goto gen_method;
2998
2999                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
3000
3001                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3002                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
3003                 case ICMD_INVOKEINTERFACE:
3004
3005                         REPLACEMENT_POINT_INVOKE(cd, iptr);
3006
3007                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3008                                 lm = NULL;
3009                                 um = iptr->sx.s23.s3.um;
3010                                 md = um->methodref->parseddesc.md;
3011                         }
3012                         else {
3013                                 lm = iptr->sx.s23.s3.fmiref->p.method;
3014                                 um = NULL;
3015                                 md = lm->parseddesc;
3016                         }
3017
3018 gen_method:
3019                         s3 = md->paramcount;
3020
3021                         MCODECHECK((s3 << 1) + 64);
3022
3023                         /* copy arguments to registers or stack location                  */
3024
3025                         for (s3 = s3 - 1; s3 >= 0; s3--) {
3026                                 var = VAR(iptr->sx.s23.s2.args[s3]);
3027                                 d   = md->params[s3].regoff;
3028
3029                                 if (var->flags & PREALLOC)
3030                                         continue;
3031
3032                                 if (IS_INT_LNG_TYPE(var->type)) {
3033 #if SIZEOF_VOID_P == 8
3034                                         if (!md->params[s3].inmemory) {
3035                                                 s1 = emit_load(jd, iptr, var, d);
3036                                                 M_INTMOVE(s1, d);
3037                                         }
3038                                         else  {
3039                                                 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3040                                                 M_LST(s1, REG_SP, d);
3041                                         }
3042 #else
3043                                         if (!md->params[s3].inmemory) {
3044                                                 s1 = emit_load(jd, iptr, var, d);
3045
3046                                                 if (IS_2_WORD_TYPE(var->type))
3047                                                         M_LNGMOVE(s1, d);
3048                                                 else
3049                                                         M_INTMOVE(s1, d);
3050                                         }
3051                                         else {
3052                                                 if (IS_2_WORD_TYPE(var->type)) {
3053                                                         s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3054                                                         M_LST(s1, REG_SP, d);
3055                                                 }
3056                                                 else {
3057                                                         s1 = emit_load(jd, iptr, var, REG_ITMP1);
3058                                                         M_IST(s1, REG_SP, d);
3059                                                 }
3060                                         }
3061 #endif
3062                                 }
3063                                 else {
3064                                         if (!md->params[s3].inmemory) {
3065                                                 s1 = emit_load(jd, iptr, var, d);
3066                                                 if (IS_2_WORD_TYPE(var->type))
3067                                                         M_DBLMOVE(s1, d);
3068                                                 else
3069                                                         M_FLTMOVE(s1, d);
3070                                         }
3071                                         else {
3072                                                 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3073                                                 if (IS_2_WORD_TYPE(var->type))
3074                                                         M_DST(s1, REG_SP, d);
3075                                                 else
3076                                                         M_FST(s1, REG_SP, d);
3077                                         }
3078                                 }
3079                         }
3080
3081                         switch (iptr->opc) {
3082                         case ICMD_BUILTIN:
3083                                 if (bte->stub == NULL) {
3084                                         disp = dseg_add_functionptr(cd, bte->fp);
3085                                         M_ALD(REG_ITMP3, REG_PV, disp);  /* built-in-function pointer */
3086
3087                                         /* generate the actual call */
3088
3089                                         /* TWISTI: i actually don't know the reason for using
3090                                            REG_ITMP3 here instead of REG_PV. */
3091
3092                                         M_JSR(REG_RA, REG_ITMP3);
3093                                         M_NOP;
3094                                 }
3095                                 else {
3096                                         disp = dseg_add_functionptr(cd, bte->stub);
3097                                         M_ALD(REG_PV, REG_PV, disp);          /* method pointer in pv */
3098
3099                                         /* generate the actual call */
3100
3101                                         M_JSR(REG_RA, REG_PV);
3102                                         M_NOP;
3103                                 }
3104
3105                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3106                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3107                                 M_LDA(REG_PV, REG_RA, -disp);
3108                                 break;
3109
3110                         case ICMD_INVOKESPECIAL:
3111                                 emit_nullpointer_check(cd, iptr, REG_A0);
3112                                 /* fall through */
3113
3114                         case ICMD_INVOKESTATIC:
3115                                 if (lm == NULL) {
3116                                         disp = dseg_add_unique_address(cd, um);
3117
3118                                         patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3119                                                                                   disp);
3120                                 }
3121                                 else
3122                                         disp = dseg_add_address(cd, lm->stubroutine);
3123
3124                                 M_ALD(REG_PV, REG_PV, disp);          /* method pointer in pv */
3125
3126                                 /* generate the actual call */
3127
3128                                 M_JSR(REG_RA, REG_PV);
3129                                 M_NOP;
3130                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3131                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3132                                 M_LDA(REG_PV, REG_RA, -disp);
3133                                 break;
3134
3135                         case ICMD_INVOKEVIRTUAL:
3136                                 emit_nullpointer_check(cd, iptr, REG_A0);
3137
3138                                 if (lm == NULL) {
3139                                         patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3140
3141                                         s1 = 0;
3142                                 }
3143                                 else
3144                                         s1 = OFFSET(vftbl_t, table[0]) +
3145                                                 sizeof(methodptr) * lm->vftblindex;
3146
3147                                 /* implicit null-pointer check */
3148                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3149                                 M_ALD(REG_PV, REG_METHODPTR, s1);
3150
3151                                 /* generate the actual call */
3152
3153                                 M_JSR(REG_RA, REG_PV);
3154                                 M_NOP;
3155                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3156                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3157                                 M_LDA(REG_PV, REG_RA, -disp);
3158                                 break;
3159
3160                         case ICMD_INVOKEINTERFACE:
3161                                 emit_nullpointer_check(cd, iptr, REG_A0);
3162
3163                                 if (lm == NULL) {
3164                                         patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3165
3166                                         s1 = 0;
3167                                         s2 = 0;
3168                                 }
3169                                 else {
3170                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3171                                                 sizeof(methodptr*) * lm->clazz->index;
3172
3173                                         s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
3174                                 }
3175
3176                                 /* implicit null-pointer check */
3177                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3178                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3179                                 M_ALD(REG_PV, REG_METHODPTR, s2);
3180
3181                                 /* generate the actual call */
3182
3183                                 M_JSR(REG_RA, REG_PV);
3184                                 M_NOP;
3185                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3186                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3187                                 M_LDA(REG_PV, REG_RA, -disp);
3188                                 break;
3189                         }
3190
3191                         /* store return value */
3192
3193                         d = md->returntype.type;
3194
3195                         if (d != TYPE_VOID) {
3196                                 if (IS_INT_LNG_TYPE(d)) {
3197 #if SIZEOF_VOID_P == 8
3198                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3199                                         M_INTMOVE(REG_RESULT, s1);
3200 #else
3201                                         if (IS_2_WORD_TYPE(d)) {
3202                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3203                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
3204                                         }
3205                                         else {
3206                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3207                                                 M_INTMOVE(REG_RESULT, s1);
3208                                         }
3209 #endif
3210                                 }
3211                                 else {
3212                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3213                                         if (IS_2_WORD_TYPE(d))
3214                                                 M_DMOV(REG_FRESULT, s1);
3215                                         else
3216                                                 M_FMOV(REG_FRESULT, s1);
3217                                 }
3218                                 emit_store_dst(jd, iptr, s1);
3219                         }
3220                         break;
3221
3222
3223                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3224
3225                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3226                                 classinfo *super;
3227                                 s4         superindex;
3228
3229                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3230                                         super      = NULL;
3231                                         superindex = 0;
3232                                 }
3233                                 else {
3234                                         super      = iptr->sx.s23.s3.c.cls;
3235                                         superindex = super->index;
3236                                 }
3237                         
3238                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3239
3240                                 /* if class is not resolved, check which code to call */
3241
3242                                 if (super == NULL) {
3243                                         emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3244
3245                                         cr   = iptr->sx.s23.s3.c.ref;
3246                                         disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
3247
3248                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3249                                                                                   cr, disp);
3250
3251                                         M_ILD(REG_ITMP2, REG_PV, disp);
3252                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3253                                         emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3254                                 }
3255
3256                                 /* interface checkcast code */
3257
3258                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3259                                         if (super == NULL) {
3260                                                 cr = iptr->sx.s23.s3.c.ref;
3261
3262                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3263                                                                                           cr, 0);
3264                                         }
3265                                         else {
3266                                                 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3267                                         }
3268
3269                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3270                                         M_ILD(REG_ITMP3, REG_ITMP2,
3271                                                   OFFSET(vftbl_t, interfacetablelength));
3272                                         M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3273                                         emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3274
3275                                         M_ALD(REG_ITMP3, REG_ITMP2,
3276                                                   OFFSET(vftbl_t, interfacetable[0]) -
3277                                                   superindex * sizeof(methodptr*));
3278                                         emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3279
3280                                         if (super == NULL)
3281                                                 emit_label_br(cd, BRANCH_LABEL_4);
3282                                         else
3283                                                 emit_label(cd, BRANCH_LABEL_3);
3284                                 }
3285
3286                                 /* class checkcast code */
3287
3288                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3289                                         if (super == NULL) {
3290                                                 emit_label(cd, BRANCH_LABEL_2);
3291
3292                                                 cr   = iptr->sx.s23.s3.c.ref;
3293                                                 disp = dseg_add_unique_address(cd, NULL);
3294
3295                                                 patcher_add_patch_ref(jd,
3296                                                                                           PATCHER_resolve_classref_to_vftbl,
3297                                                                                           cr, disp);
3298                                         }
3299                                         else {
3300                                                 disp = dseg_add_address(cd, super->vftbl);
3301
3302                                                 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3303                                         }
3304
3305                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3306                                         M_ALD(REG_ITMP3, REG_PV, disp);
3307
3308                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3309                                         /*                              if (s1 != REG_ITMP1) { */
3310                                         /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3311                                         /*                                      M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3312                                         /* #if defined(ENABLE_THREADS) */
3313                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3314                                         /* #endif */
3315                                         /*                                      M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3316                                         /*                              } else { */
3317                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3318                                         M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2); 
3319                                         M_ALD(REG_ITMP3, REG_PV, disp);
3320                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3321
3322                                         /*                              } */
3323                                         M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3324                                         emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3325
3326                                         if (super != NULL)
3327                                                 emit_label(cd, BRANCH_LABEL_5);
3328                                 }
3329
3330                                 if (super == NULL) {
3331                                         emit_label(cd, BRANCH_LABEL_1);
3332                                         emit_label(cd, BRANCH_LABEL_4);
3333                                 }
3334
3335                                 d = codegen_reg_of_dst(jd, iptr, s1);
3336                         }
3337                         else {
3338                                 s1 = emit_load_s1(jd, iptr, REG_A0);
3339                                 M_INTMOVE(s1, REG_A0);
3340
3341                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3342                                         cr   = iptr->sx.s23.s3.c.ref;
3343                                         disp = dseg_add_unique_address(cd, NULL);
3344
3345                                         patcher_add_patch_ref(jd,
3346                                                                                   PATCHER_resolve_classref_to_classinfo,
3347                                                                                   cr, disp);
3348                                 }
3349                                 else {
3350                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3351                                 }
3352
3353                                 M_ALD(REG_A1, REG_PV, disp);
3354                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3355                                 M_ALD(REG_ITMP3, REG_PV, disp);
3356                                 M_JSR(REG_RA, REG_ITMP3);
3357                                 M_NOP;
3358
3359                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3360                                 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3361
3362                                 d = codegen_reg_of_dst(jd, iptr, s1);
3363                         }
3364
3365                         M_INTMOVE(s1, d);
3366                         emit_store_dst(jd, iptr, d);
3367                         break;
3368
3369                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3370
3371                         {
3372                         classinfo *super;
3373                         s4         superindex;
3374
3375                         super = iptr->sx.s23.s3.c.cls;
3376
3377                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3378                                 super      = NULL;
3379                                 superindex = 0;
3380                         }
3381                         else {
3382                                 super      = iptr->sx.s23.s3.c.cls;
3383                                 superindex = super->index;
3384                         }
3385                         
3386                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3387                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3388
3389                         if (s1 == d) {
3390                                 M_MOV(s1, REG_ITMP1);
3391                                 s1 = REG_ITMP1;
3392                         }
3393
3394                         M_CLR(d);
3395
3396                         /* if class is not resolved, check which code to call */
3397
3398                         if (super == NULL) {
3399                                 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3400
3401                                 cr   = iptr->sx.s23.s3.c.ref;
3402                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
3403
3404                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3405                                                                           cr, disp);
3406
3407                                 M_ILD(REG_ITMP3, REG_PV, disp);
3408                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3409                                 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3410                         }
3411
3412                         /* interface instanceof code */
3413
3414                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3415                                 if (super == NULL) {
3416                                         cr = iptr->sx.s23.s3.c.ref;
3417
3418                                         patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3419                                                                                   cr, 0);
3420                                 }
3421                                 else {
3422                                         emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3423                                 }
3424
3425                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3426                                 M_ILD(REG_ITMP3, REG_ITMP1,
3427                                           OFFSET(vftbl_t, interfacetablelength));
3428                                 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3429                                 M_BLEZ(REG_ITMP3, 3);
3430                                 M_NOP;
3431                                 M_ALD(REG_ITMP1, REG_ITMP1,
3432                                           OFFSET(vftbl_t, interfacetable[0]) -
3433                                           superindex * sizeof(methodptr*));
3434                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3435
3436                                 if (super == NULL)
3437                                         emit_label_br(cd, BRANCH_LABEL_4);
3438                                 else
3439                                         emit_label(cd, BRANCH_LABEL_3);
3440                         }
3441
3442                         /* class instanceof code */
3443
3444                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3445                                 if (super == NULL) {
3446                                         emit_label(cd, BRANCH_LABEL_2);
3447
3448                                         cr   = iptr->sx.s23.s3.c.ref;
3449                                         disp = dseg_add_unique_address(cd, NULL);
3450
3451                                         patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3452                                                                                   cr, disp);
3453                                 }
3454                                 else {
3455                                         disp = dseg_add_address(cd, super->vftbl);
3456
3457                                         emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3458                                 }
3459
3460                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3461                                 M_ALD(REG_ITMP2, REG_PV, disp);
3462
3463                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3464                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3465                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3466
3467                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3468                                 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3469                                 M_XOR_IMM(d, 1, d);
3470
3471                                 if (super != NULL)
3472                                         emit_label(cd, BRANCH_LABEL_5);
3473                         }
3474
3475                         if (super == NULL) {
3476                                 emit_label(cd, BRANCH_LABEL_1);
3477                                 emit_label(cd, BRANCH_LABEL_4);
3478                         }
3479
3480                         emit_store_dst(jd, iptr, d);
3481                         }
3482                         break;
3483
3484                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3485
3486                         /* check for negative sizes and copy sizes to stack if necessary  */
3487
3488                         MCODECHECK((iptr->s1.argcount << 1) + 64);
3489
3490                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3491
3492                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3493
3494                                 /* copy SAVEDVAR sizes to stack */
3495
3496                                 if (!(var->flags & PREALLOC)) {
3497                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
3498 #if SIZEOF_VOID_P == 8
3499                                         M_LST(s2, REG_SP, s1 * 8);
3500 #else
3501                                         M_IST(s2, REG_SP, (s1 + 2) * 8);
3502 #endif
3503                                 }
3504                         }
3505
3506                         /* a0 = dimension count */
3507
3508                         ICONST(REG_A0, iptr->s1.argcount);
3509
3510                         /* is patcher function set? */
3511
3512                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3513                                 cr   = iptr->sx.s23.s3.c.ref;
3514                                 disp = dseg_add_unique_address(cd, NULL);
3515
3516                                 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3517                                                                           cr, disp);
3518                         }
3519                         else {
3520                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3521                         }
3522
3523                         /* a1 = arraydescriptor */
3524
3525                         M_ALD(REG_A1, REG_PV, disp);
3526
3527                         /* a2 = pointer to dimensions = stack pointer */
3528
3529 #if SIZEOF_VOID_P == 8
3530                         M_MOV(REG_SP, REG_A2);
3531 #else
3532                         M_AADD_IMM(REG_SP, 4*4, REG_A2);
3533 #endif
3534
3535                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3536                         M_ALD(REG_ITMP3, REG_PV, disp);
3537                         M_JSR(REG_RA, REG_ITMP3);
3538                         M_NOP;
3539
3540                         /* check for exception before result assignment */
3541
3542                         emit_exception_check(cd, iptr);
3543
3544                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3545                         M_INTMOVE(REG_RESULT, d);
3546                         emit_store_dst(jd, iptr, d);
3547                         break;
3548
3549                 default:
3550                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3551                                                                                    iptr->opc);
3552                         return false;
3553         } /* switch */
3554                 
3555         } /* for instruction */
3556                 
3557         MCODECHECK(64); /* XXX require smaller number? */
3558
3559         /* At the end of a basic block we may have to append some nops,
3560            because the patcher stub calling code might be longer than the
3561            actual instruction. So codepatching does not change the
3562            following block unintentionally. */
3563
3564         if (cd->mcodeptr < cd->lastmcodeptr) {
3565                 while (cd->mcodeptr < cd->lastmcodeptr)
3566                         M_NOP;
3567         }
3568
3569         } /* if (bptr -> flags >= BBREACHED) */
3570         } /* for basic block */
3571
3572         /* generate traps */
3573
3574         emit_patcher_traps(jd);
3575
3576         /* everything's ok */
3577
3578         return true;
3579 }
3580
3581
3582 /* codegen_emit_stub_native ****************************************************
3583
3584    Emits a stub routine which calls a native method.
3585
3586 *******************************************************************************/
3587
3588 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3589 {
3590         methodinfo  *m;
3591         codeinfo    *code;
3592         codegendata *cd;
3593         methoddesc  *md;
3594         s4           i, j;
3595         s4           t;
3596         int          s1, s2;
3597         int          disp;
3598
3599         /* get required compiler data */
3600
3601         m    = jd->m;
3602         code = jd->code;
3603         cd   = jd->cd;
3604
3605         /* initialize variables */
3606
3607         md = m->parseddesc;
3608
3609         /* calculate stack frame size */
3610
3611         cd->stackframesize =
3612                 1 +                             /* return address                     */
3613                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3614                 sizeof(localref_table) / SIZEOF_VOID_P +
3615                 md->paramcount +                /* for saving arguments over calls    */
3616 #if SIZEOF_VOID_P == 4
3617                 5 +                             /* additional save space (MIPS32)     */
3618 #endif
3619                 1 +                             /* for saving return address          */
3620                 nmd->memuse;
3621
3622         /* adjust stackframe size for 16-byte alignment */
3623
3624         if (cd->stackframesize & 1)
3625                 cd->stackframesize++;
3626
3627         /* create method header */
3628
3629         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3630         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
3631         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3632         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3633         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3634
3635         /* generate stub code */
3636
3637         M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe    */
3638         M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA          */
3639
3640 #if !defined(NDEBUG)
3641         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3642                 emit_verbosecall_enter(jd);
3643 #endif
3644
3645         /* save integer and float argument registers */
3646
3647 #if SIZEOF_VOID_P == 8
3648         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3649                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3650                         s1 = md->params[i].regoff;
3651                         M_AST(s1, REG_SP, j * 8);
3652                         j++;
3653                 }
3654         }
3655 #else
3656         for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3657                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3658                         if (!md->params[i].inmemory) {
3659                                 s1 = md->params[i].regoff;
3660
3661                                 if (IS_2_WORD_TYPE(md->params[i].type))
3662                                         M_LST(s1, REG_SP, j * 8);
3663                                 else
3664                                         M_IST(s1, REG_SP, j * 8);
3665
3666                                 j++;
3667                         }
3668                 }
3669         }
3670 #endif
3671
3672         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3673                 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3674                         s1 = md->params[i].regoff;
3675
3676                         if (IS_2_WORD_TYPE(md->params[i].type))
3677                                 M_DST(s1, REG_SP, j * 8);
3678                         else
3679                                 M_FST(s1, REG_SP, j * 8);
3680
3681                         j++;
3682                 }
3683         }
3684
3685         /* prepare data structures for native function call */
3686
3687         M_MOV(REG_SP, REG_A0);
3688         M_MOV(REG_PV, REG_A1);
3689         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3690         M_ALD(REG_ITMP3, REG_PV, disp);
3691         M_JSR(REG_RA, REG_ITMP3);
3692         M_NOP; /* XXX fill me! */
3693
3694         /* remember class argument */
3695
3696         if (m->flags & ACC_STATIC)
3697                 M_MOV(REG_RESULT, REG_ITMP3);
3698
3699         /* restore integer and float argument registers */
3700
3701 #if SIZEOF_VOID_P == 8
3702         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3703                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3704                         s1 = md->params[i].regoff;
3705                         M_LLD(s1, REG_SP, j * 8);
3706                         j++;
3707                 }
3708         }
3709 #else
3710         for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3711                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3712                         if (!md->params[i].inmemory) {
3713                                 s1 = md->params[i].regoff;
3714
3715                                 if (IS_2_WORD_TYPE(md->params[i].type))
3716                                         M_LLD(s1, REG_SP, j * 8);
3717                                 else
3718                                         M_ILD(s1, REG_SP, j * 8);
3719
3720                                 j++;
3721                         }
3722                 }
3723         }
3724 #endif
3725
3726         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3727                 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3728                         s1 = md->params[i].regoff;
3729
3730                         if (IS_2_WORD_TYPE(md->params[i].type))
3731                                 M_DLD(s1, REG_SP, j * 8);
3732                         else
3733                                 M_FLD(s1, REG_SP, j * 8);
3734
3735                         j++;
3736                 }
3737         }
3738
3739         /* copy or spill arguments to new locations */
3740
3741         for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3742                 t = md->params[i].type;
3743
3744                 if (IS_INT_LNG_TYPE(t)) {
3745                         if (!md->params[i].inmemory) {
3746                                 s1 = md->params[i].regoff;
3747                                 s2 = nmd->params[j].regoff;
3748
3749                                 if (!nmd->params[j].inmemory) {
3750 #if SIZEOF_VOID_P == 8
3751                                         M_INTMOVE(s1, s2);
3752 #else
3753                                         if (IS_2_WORD_TYPE(t))
3754                                                 M_LNGMOVE(s1, s2);
3755                                         else
3756                                                 M_INTMOVE(s1, s2);
3757 #endif
3758                                 }
3759                                 else {
3760 #if SIZEOF_VOID_P == 8
3761                                         M_LST(s1, REG_SP, s2);
3762 #else
3763                                         if (IS_2_WORD_TYPE(t))
3764                                                 M_LST(s1, REG_SP, s2);
3765                                         else
3766                                                 M_IST(s1, REG_SP, s2);
3767 #endif
3768                                 }
3769                         }
3770                         else {
3771                                 s1 = md->params[i].regoff + cd->stackframesize * 8;
3772                                 s2 = nmd->params[j].regoff;
3773
3774 #if SIZEOF_VOID_P == 8
3775                                 M_LLD(REG_ITMP1, REG_SP, s1);
3776                                 M_LST(REG_ITMP1, REG_SP, s2);
3777 #else
3778                                 if (IS_2_WORD_TYPE(t)) {
3779                                         M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3780                                         M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3781                                 }
3782                                 else {
3783                                         M_ILD(REG_ITMP1, REG_SP, s1);
3784                                         M_IST(REG_ITMP1, REG_SP, s2);
3785                                 }
3786 #endif
3787                         }
3788                 }
3789                 else {
3790                         if (!md->params[i].inmemory) {
3791                                 s1 = md->params[i].regoff;
3792                                 s2 = nmd->params[j].regoff;
3793
3794                                 if (!nmd->params[j].inmemory) {
3795 #if SIZEOF_VOID_P == 8
3796                                         if (IS_2_WORD_TYPE(t))
3797                                                 M_DMOV(s1, s2);
3798                                         else
3799                                                 M_FMOV(s1, s2);
3800 #else
3801                                         /* On MIPS32 float arguments for native functions
3802                                            can never be in float argument registers, since
3803                                            the first argument is _always_ an integer
3804                                            argument (JNIEnv) */
3805
3806                                         if (IS_2_WORD_TYPE(t)) {
3807                                                 /* double high/low order is endian
3808                                                    independent: even numbered holds low
3809                                                    32-bits, odd numbered high 32-bits */
3810
3811                                                 M_MFC1(GET_LOW_REG(s2), s1);           /* low 32-bits */
3812                                                 M_MFC1(GET_HIGH_REG(s2), s1 + 1);     /* high 32-bits */
3813                                         }
3814                                         else
3815                                                 M_MFC1(s2, s1);
3816 #endif
3817                                 }
3818                                 else {
3819 #if SIZEOF_VOID_P == 8
3820                                         if (IS_2_WORD_TYPE(t))
3821                                                 M_DST(s1, REG_SP, s2);
3822                                         else
3823                                                 M_FST(s1, REG_SP, s2);
3824 #else
3825                                         /* s1 may have been originally in 2 int registers,
3826                                            but was moved out by the native function
3827                                            argument(s), just get low register */
3828
3829                                         if (IS_2_WORD_TYPE(t))
3830                                                 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3831                                         else
3832                                                 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3833 #endif
3834                                 }
3835                         }
3836                         else {
3837                                 s1 = md->params[i].regoff + cd->stackframesize * 8;
3838                                 s2 = nmd->params[j].regoff;
3839
3840 #if SIZEOF_VOID_P == 8
3841                                 if (IS_2_WORD_TYPE(t)) {
3842                                         M_DLD(REG_FTMP1, REG_SP, s1);
3843                                         M_DST(REG_FTMP1, REG_SP, s2);
3844                                 }
3845                                 else {
3846                                         M_FLD(REG_FTMP1, REG_SP, s1);
3847                                         M_FST(REG_FTMP1, REG_SP, s2);
3848                                 }
3849 #else
3850                                 if (IS_2_WORD_TYPE(t)) {
3851                                         M_DLD(REG_FTMP1, REG_SP, s1);
3852                                         M_DST(REG_FTMP1, REG_SP, s2);
3853                                 }
3854                                 else {
3855                                         M_FLD(REG_FTMP1, REG_SP, s1);
3856                                         M_FST(REG_FTMP1, REG_SP, s2);
3857                                 }
3858 #endif
3859                         }
3860                 }
3861         }
3862
3863         /* Handle native Java methods. */
3864
3865         if (m->flags & ACC_NATIVE) {
3866                 /* put class into second argument register */
3867
3868                 if (m->flags & ACC_STATIC)
3869                         M_MOV(REG_ITMP3, REG_A1);
3870
3871                 /* put env into first argument register */
3872
3873                 disp = dseg_add_address(cd, VM_get_jnienv());
3874                 M_ALD(REG_A0, REG_PV, disp);
3875         }
3876
3877         /* Call the native function. */
3878
3879         disp = dseg_add_functionptr(cd, f);
3880         M_ALD(REG_ITMP3, REG_PV, disp);     /* load adress of native method       */
3881         M_JSR(REG_RA, REG_ITMP3);           /* call native method                 */
3882         M_NOP;                              /* delay slot                         */
3883
3884         /* save return value */
3885
3886         switch (md->returntype.type) {
3887 #if SIZEOF_VOID_P == 8
3888         case TYPE_INT:
3889         case TYPE_LNG:
3890         case TYPE_ADR:
3891                 M_LST(REG_RESULT, REG_SP, 0 * 8);
3892                 break;
3893         case TYPE_FLT:
3894         case TYPE_DBL:
3895                 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3896                 break;
3897 #else
3898         case TYPE_INT:
3899         case TYPE_ADR:
3900                 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3901                 break;
3902         case TYPE_LNG:
3903                 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3904                 break;
3905         case TYPE_FLT:
3906         case TYPE_DBL:
3907                 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3908                 break;
3909 #endif
3910         case TYPE_VOID:
3911                 break;
3912         }
3913
3914 #if !defined(NDEBUG)
3915         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3916                 emit_verbosecall_exit(jd);
3917 #endif
3918
3919         /* remove native stackframe info */
3920
3921         M_MOV(REG_SP, REG_A0);
3922         M_MOV(REG_PV, REG_A1);
3923         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3924         M_ALD(REG_ITMP3, REG_PV, disp);
3925         M_JSR(REG_RA, REG_ITMP3);
3926         M_NOP; /* XXX fill me! */
3927         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3928
3929         /* restore return value */
3930
3931         switch (md->returntype.type) {
3932 #if SIZEOF_VOID_P == 8
3933         case TYPE_INT:
3934         case TYPE_LNG:
3935         case TYPE_ADR:
3936                 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3937                 break;
3938         case TYPE_FLT:
3939         case TYPE_DBL:
3940                 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3941                 break;
3942 #else
3943         case TYPE_INT:
3944         case TYPE_ADR:
3945                 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3946                 break;
3947         case TYPE_LNG:
3948                 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3949                 break;
3950         case TYPE_FLT:
3951         case TYPE_DBL:
3952                 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3953                 break;
3954 #endif
3955         case TYPE_VOID:
3956                 break;
3957         }
3958
3959         M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA           */
3960
3961         /* check for exception */
3962
3963         M_BNEZ(REG_ITMP1_XPTR, 2);          /* if no exception then return        */
3964         M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT              */
3965
3966         M_RET(REG_RA);                      /* return to caller                   */
3967         M_NOP;                              /* DELAY SLOT                         */
3968
3969         /* handle exception */
3970         
3971         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3972         M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
3973         M_JMP(REG_ITMP3);                   /* jump to asm exception handler      */
3974         M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY)    */
3975
3976         /* Generate patcher traps. */
3977
3978         emit_patcher_traps(jd);
3979 }
3980
3981
3982 /*
3983  * These are local overrides for various environment variables in Emacs.
3984  * Please do not remove this and leave it at the end of the file, where
3985  * Emacs will automagically detect them.
3986  * ---------------------------------------------------------------------
3987  * Local variables:
3988  * mode: c
3989  * indent-tabs-mode: t
3990  * c-basic-offset: 4
3991  * tab-width: 4
3992  * End:
3993  * vim:noexpandtab:sw=4:ts=4:
3994  */