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