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