* Merged in twisti-branch.
[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 7570 2007-03-24 22:20:09Z 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                                 M_BEQZ(s1, 0);
2453                         else {
2454                                 LCONST(REG_ITMP2, iptr->sx.val.l);
2455                                 M_BEQ(s1, REG_ITMP2, 0);
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                                 M_BLTZ(s1, 0);
2482                         } else {
2483                                 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2484                                         M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2485                                 } else {
2486                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2487                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2488                                 }
2489                                 M_BNEZ(REG_ITMP1, 0);
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                                 M_BLEZ(s1, 0);
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_ITMP1);
2521                                         M_BNEZ(REG_ITMP1, 0);
2522                                 } else {
2523                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2524                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2525                                         M_BEQZ(REG_ITMP1, 0);
2526                                 }
2527                         }
2528 #else
2529                         if (iptr->sx.val.l == 0) {
2530                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2531                                 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2532                                 M_NOP;
2533                                 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2534                                 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2535                         }
2536                         else {
2537                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2538                                 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2539                                 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2540                                 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2541                                 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2542                                 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2543                                 M_NOP;
2544                                 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2545                                 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2546                                 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2547                         }
2548 #endif
2549                         break;
2550
2551                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2552
2553 #if SIZEOF_VOID_P == 8
2554                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2555                         if (iptr->sx.val.l == 0) {
2556                                 M_BNEZ(s1, 0);
2557                         } else {
2558                                 LCONST(REG_ITMP2, iptr->sx.val.l);
2559                                 M_BNE(s1, REG_ITMP2, 0);
2560                         }
2561 #else
2562                         if (iptr->sx.val.l == 0) {
2563                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2564                                 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2565                                 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2566                         }
2567                         else {
2568                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2569                                 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2570                                 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2571                                 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2572                                 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2573                                 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2574                                 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2575                                 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2576                         }
2577 #endif
2578                         break;
2579
2580                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2581
2582 #if SIZEOF_VOID_P == 8
2583                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2584                         if (iptr->sx.val.l == 0) {
2585                                 M_BGTZ(s1, 0);
2586                         } else {
2587                                 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2588                                         M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2589                                         M_BEQZ(REG_ITMP1, 0);
2590                                 } else {
2591                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2592                                         M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2593                                         M_BNEZ(REG_ITMP1, 0);
2594                                 }
2595                         }
2596 #else
2597                         if (iptr->sx.val.l == 0) {
2598                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2599                                 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2600                                 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2601                                 M_NOP;
2602                                 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2603                         }
2604                         else {
2605                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2606                                 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2607                                 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2608                                 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2609                                 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2610                                 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2611                                 M_NOP;
2612                                 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2613                                 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2614                                 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2615                         }
2616 #endif
2617                         break;
2618
2619                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2620
2621 #if SIZEOF_VOID_P == 8
2622                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2623                         if (iptr->sx.val.l == 0) {
2624                                 M_BGEZ(s1, 0);
2625                         } else {
2626                                 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2627                                         M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2628                                 } else {
2629                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2630                                         M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2631                                 }
2632                                 M_BEQZ(REG_ITMP1, 0);
2633                         }
2634 #else
2635                         if (iptr->sx.val.l == 0) {
2636                                 /* if high word is greater equal zero, the whole long is too */
2637                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2638                                 emit_bgez(cd, iptr->dst.block, s1);
2639                         }
2640                         else {
2641                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2642                                 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2643                                 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2644                                 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2645                                 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2646                                 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2647                                 M_NOP;
2648                                 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2649                                 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2650                                 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2651                         }
2652 #endif
2653                         break;
2654
2655                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2656                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
2657 #if SIZEOF_VOID_P == 8
2658                 case ICMD_IF_LCMPEQ:
2659 #endif
2660
2661                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2662                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2663                         emit_beq(cd, iptr->dst.block, s1, s2);
2664                         break;
2665
2666 #if SIZEOF_VOID_P == 4
2667                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2668                                         /* op1 = target JavaVM pc                     */
2669
2670                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2671                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2672                         M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2673                         M_NOP;
2674                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2675                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2676                         emit_beq(cd, iptr->dst.block, s1, s2);
2677                         break;
2678 #endif
2679
2680                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
2681                 case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
2682 #if SIZEOF_VOID_P == 8
2683                 case ICMD_IF_LCMPNE:
2684 #endif
2685
2686                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2687                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2688                         emit_bne(cd, iptr->dst.block, s1, s2);
2689                         break;
2690
2691 #if SIZEOF_VOID_P == 4
2692                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
2693
2694                         /* TODO: could be optimized (XOR or SUB) */
2695                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2696                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2697                         emit_bne(cd, iptr->dst.block, s1, s2);
2698                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2699                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2700                         emit_bne(cd, iptr->dst.block, s1, s2);
2701                         break;
2702 #endif
2703
2704                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
2705 #if SIZEOF_VOID_P == 8
2706                 case ICMD_IF_LCMPLT:    /* op1 = target JavaVM pc                     */
2707 #endif
2708
2709                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2710                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2711                         M_CMPLT(s1, s2, REG_ITMP3);
2712                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2713                         break;
2714
2715 #if SIZEOF_VOID_P == 4
2716                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2717
2718                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2719                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2720                         M_CMPLT(s1, s2, REG_ITMP3);
2721                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2722                         M_CMPGT(s1, s2, REG_ITMP3);
2723                         /* load low-bits before the branch, so we know the distance */
2724                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2725                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2726                         M_BNEZ(REG_ITMP3, 4); /* XXX */
2727                         M_NOP;
2728                         M_CMPULT(s1, s2, REG_ITMP3);
2729                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2730                         break;
2731 #endif
2732
2733                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
2734 #if SIZEOF_VOID_P == 8
2735                 case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
2736 #endif
2737
2738                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2739                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2740                         M_CMPGT(s1, s2, REG_ITMP3);
2741                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2742                         break;
2743
2744 #if SIZEOF_VOID_P == 4
2745                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2746
2747                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2748                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2749                         M_CMPGT(s1, s2, REG_ITMP3);
2750                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2751                         M_CMPLT(s1, s2, REG_ITMP3);
2752                         /* load low-bits before the branch, so we know the distance */
2753                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2754                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2755                         M_BNEZ(REG_ITMP3, 4); /* XXX */
2756                         M_NOP;
2757                         M_CMPUGT(s1, s2, REG_ITMP3);
2758                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2759                         break;
2760 #endif
2761
2762                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
2763 #if SIZEOF_VOID_P == 8
2764                 case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
2765 #endif
2766
2767                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2768                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2769                         M_CMPGT(s1, s2, REG_ITMP3);
2770                         emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2771                         break;
2772
2773 #if SIZEOF_VOID_P == 4
2774                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2775
2776                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2777                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2778                         M_CMPLT(s1, s2, REG_ITMP3);
2779                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2780                         M_CMPGT(s1, s2, REG_ITMP3);
2781                         /* load low-bits before the branch, so we know the distance */
2782                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2783                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2784                         M_BNEZ(REG_ITMP3, 4); /* XXX */
2785                         M_NOP;
2786                         M_CMPUGT(s1, s2, REG_ITMP3);
2787                         emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2788                         break;
2789 #endif
2790
2791                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
2792 #if SIZEOF_VOID_P == 8
2793                 case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
2794 #endif
2795
2796                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2797                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2798                         M_CMPLT(s1, s2, REG_ITMP3);
2799                         emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2800                         break;
2801
2802 #if SIZEOF_VOID_P == 4
2803                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2804
2805                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2806                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2807                         M_CMPGT(s1, s2, REG_ITMP3);
2808                         emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2809                         M_CMPLT(s1, s2, REG_ITMP3);
2810                         /* load low-bits before the branch, so we know the distance */
2811                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2812                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2813                         M_BNEZ(REG_ITMP3, 4); /* XXX */
2814                         M_NOP;
2815                         M_CMPULT(s1, s2, REG_ITMP3);
2816                         emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2817                         break;
2818 #endif
2819
2820                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2821 #if SIZEOF_VOID_P == 8
2822                 case ICMD_LRETURN:
2823 #endif
2824
2825                         REPLACEMENT_POINT_RETURN(cd, iptr);
2826                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2827                         M_INTMOVE(s1, REG_RESULT);
2828                         goto nowperformreturn;
2829
2830                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2831
2832                         REPLACEMENT_POINT_RETURN(cd, iptr);
2833                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2834                         M_INTMOVE(s1, REG_RESULT);
2835
2836 #ifdef ENABLE_VERIFIER
2837                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2838                                 uc = iptr->sx.s23.s2.uc;
2839
2840                                 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2841                         }
2842 #endif /* ENABLE_VERIFIER */
2843                         goto nowperformreturn;
2844
2845 #if SIZEOF_VOID_P == 4
2846                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2847
2848                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2849                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2850                         goto nowperformreturn;
2851 #endif
2852
2853             case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2854                         REPLACEMENT_POINT_RETURN(cd, iptr);
2855                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2856                         M_FLTMOVE(s1, REG_FRESULT);
2857                         goto nowperformreturn;
2858
2859             case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
2860
2861                         REPLACEMENT_POINT_RETURN(cd, iptr);
2862                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2863                         M_DBLMOVE(s1, REG_FRESULT);
2864                         goto nowperformreturn;
2865
2866                 case ICMD_RETURN:      /* ...  ==> ...                                */
2867
2868                         REPLACEMENT_POINT_RETURN(cd, iptr);
2869
2870 nowperformreturn:
2871                         {
2872                         s4 i, p;
2873                         
2874                         p = cd->stackframesize;
2875
2876 #if !defined(NDEBUG)
2877                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2878                                 emit_verbosecall_exit(jd);
2879 #endif
2880
2881 #if defined(ENABLE_THREADS)
2882                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2883                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2884                                 M_ALD(REG_ITMP3, REG_PV, disp);
2885
2886                                 /* we need to save the proper return value */
2887
2888                                 switch (iptr->opc) {
2889                                 case ICMD_IRETURN:
2890                                 case ICMD_ARETURN:
2891 #if SIZEOF_VOID_P == 8
2892                                 case ICMD_LRETURN:
2893 #endif
2894                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2895                                         M_JSR(REG_RA, REG_ITMP3);
2896                                         M_AST(REG_RESULT, REG_SP, rd->memuse * 8);  /* delay slot */
2897                                         break;
2898 #if SIZEOF_VOID_P == 4
2899                                 case ICMD_LRETURN:
2900                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2901                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2902                                         M_JSR(REG_RA, REG_ITMP3);
2903                                         M_NOP;
2904                                         break;
2905 #endif
2906                                 case ICMD_FRETURN:
2907                                 case ICMD_DRETURN:
2908                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2909                                         M_JSR(REG_RA, REG_ITMP3);
2910                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2911                                         break;
2912                                 case ICMD_RETURN:
2913                                         M_JSR(REG_RA, REG_ITMP3);
2914                                         M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2915                                         break;
2916                                 }
2917
2918                                 /* and now restore the proper return value */
2919
2920                                 switch (iptr->opc) {
2921                                 case ICMD_IRETURN:
2922                                 case ICMD_ARETURN:
2923 #if SIZEOF_VOID_P == 8
2924                                 case ICMD_LRETURN:
2925 #endif
2926                                         M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2927                                         break;
2928 #if SIZEOF_VOID_P == 4
2929                                 case ICMD_LRETURN:
2930                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2931                                         break;
2932 #endif
2933                                 case ICMD_FRETURN:
2934                                 case ICMD_DRETURN:
2935                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2936                                         break;
2937                                 }
2938                         }
2939 #endif
2940
2941                         /* restore return address                                         */
2942
2943                         if (!jd->isleafmethod) {
2944                                 p--; M_ALD(REG_RA, REG_SP, p * 8);
2945                         }
2946
2947                         /* restore saved registers                                        */
2948
2949                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2950                                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2951                         }
2952                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2953                                 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2954                         }
2955
2956                         /* deallocate stack and return                                    */
2957
2958                         if (cd->stackframesize) {
2959                                 s4 lo, hi;
2960
2961                                 disp = cd->stackframesize * 8;
2962                                 lo = (short) (disp);
2963                                 hi = (short) (((disp) - lo) >> 16);
2964
2965                                 if (hi == 0) {
2966                                         M_RET(REG_RA);
2967                                         M_AADD_IMM(REG_SP, lo, REG_SP);             /* delay slot */
2968                                 } else {
2969                                         M_LUI(REG_ITMP3,hi);
2970                                         M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2971                                         M_RET(REG_RA);
2972                                         M_AADD(REG_ITMP3,REG_SP,REG_SP);            /* delay slot */
2973                                 }
2974
2975                         } else {
2976                                 M_RET(REG_RA);
2977                                 M_NOP;
2978                         }
2979
2980                         ALIGNCODENOP;
2981                         }
2982                         break;
2983
2984
2985                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2986                         {
2987                         s4 i, l;
2988                         branch_target_t *table;
2989
2990                         table = iptr->dst.table;
2991
2992                         l = iptr->sx.s23.s2.tablelow;
2993                         i = iptr->sx.s23.s3.tablehigh;
2994
2995                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2996                         if (l == 0)
2997                                 {M_INTMOVE(s1, REG_ITMP1);}
2998                         else if (l <= 32768) {
2999                                 M_IADD_IMM(s1, -l, REG_ITMP1);
3000                                 }
3001                         else {
3002                                 ICONST(REG_ITMP2, l);
3003                                 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3004                                 }
3005
3006                         /* number of targets */
3007                         i = i - l + 1;
3008
3009                         /* range check */
3010
3011                         M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
3012                         emit_beqz(cd, table[0].block, REG_ITMP2);
3013
3014                         /* build jump table top down and use address of lowest entry */
3015
3016                         table += i;
3017
3018                         while (--i >= 0) {
3019                                 dseg_add_target(cd, table->block); 
3020                                 --table;
3021                         }
3022                         }
3023
3024                         /* length of dataseg after last dseg_add_target is used by load */
3025
3026                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
3027                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3028                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3029                         M_JMP(REG_ITMP2);
3030                         M_NOP;
3031                         ALIGNCODENOP;
3032                         break;
3033
3034
3035                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
3036                         {
3037                         s4 i;
3038                         lookup_target_t *lookup;
3039
3040                         lookup = iptr->dst.lookup;
3041
3042                         i = iptr->sx.s23.s2.lookupcount;
3043                         
3044                         MCODECHECK((i<<2)+8);
3045                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3046
3047                         while (--i >= 0) {
3048                                 ICONST(REG_ITMP2, lookup->value);
3049                                 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3050                                 ++lookup;
3051                         }
3052
3053                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3054                         ALIGNCODENOP;
3055                         break;
3056                         }
3057
3058
3059                 case ICMD_BUILTIN:      /* ..., arg1 ==> ...                          */
3060
3061                         bte = iptr->sx.s23.s3.bte;
3062                         md  = bte->md;
3063                         goto gen_method;
3064
3065                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
3066
3067                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3068                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
3069                 case ICMD_INVOKEINTERFACE:
3070
3071                         REPLACEMENT_POINT_INVOKE(cd, iptr);
3072
3073                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3074                                 lm = NULL;
3075                                 um = iptr->sx.s23.s3.um;
3076                                 md = um->methodref->parseddesc.md;
3077                         }
3078                         else {
3079                                 lm = iptr->sx.s23.s3.fmiref->p.method;
3080                                 um = NULL;
3081                                 md = lm->parseddesc;
3082                         }
3083
3084 gen_method:
3085                         s3 = md->paramcount;
3086
3087                         MCODECHECK((s3 << 1) + 64);
3088
3089                         /* copy arguments to registers or stack location                  */
3090
3091                         for (s3 = s3 - 1; s3 >= 0; s3--) {
3092                                 var = VAR(iptr->sx.s23.s2.args[s3]);
3093
3094                                 if (var->flags & PREALLOC)
3095                                         continue;
3096
3097                                 if (IS_INT_LNG_TYPE(var->type)) {
3098 #if SIZEOF_VOID_P == 8
3099                                         if (!md->params[s3].inmemory) {
3100                                                 s1 = rd->argintregs[md->params[s3].regoff];
3101                                                 d = emit_load(jd, iptr, var, s1);
3102                                                 M_INTMOVE(d, s1);
3103                                         }
3104                                         else  {
3105                                                 d = emit_load(jd, iptr, var, REG_ITMP1);
3106                                                 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3107                                         }
3108 #else
3109                                         if (!md->params[s3].inmemory) {
3110                                                 if (IS_2_WORD_TYPE(var->type)) {
3111                                                         s1 = md->params[s3].regoff;
3112                                                         s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3113                                                                                    rd->argintregs[GET_HIGH_REG(s1)]);
3114                                                         d = emit_load(jd, iptr, var, s1);
3115                                                         M_LNGMOVE(d, s1);
3116                                                 }
3117                                                 else {
3118                                                         s1 = rd->argintregs[md->params[s3].regoff];
3119                                                         d = emit_load(jd, iptr, var, s1);
3120                                                         M_INTMOVE(d, s1);
3121                                                 }
3122                                         }
3123                                         else {
3124                                                 if (IS_2_WORD_TYPE(var->type)) {
3125                                                         d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3126                                                         M_LST(d, REG_SP, md->params[s3].regoff * 8);
3127                                                 }
3128                                                 else {
3129                                                         d = emit_load(jd, iptr, var, REG_ITMP1);
3130                                                         M_IST(d, REG_SP, md->params[s3].regoff * 8);
3131                                                 }
3132                                         }
3133 #endif
3134                                 }
3135                                 else {
3136                                         if (!md->params[s3].inmemory) {
3137 #if SIZEOF_VOID_P == 8
3138                                                 s1 = rd->argfltregs[md->params[s3].regoff];
3139                                                 d = emit_load(jd, iptr, var, s1);
3140                                                 if (IS_2_WORD_TYPE(var->type))
3141                                                         M_DMOV(d, s1);
3142                                                 else
3143                                                         M_FMOV(d, s1);
3144 #else
3145                                                 if ((s3 == 0) ||
3146                                                         ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
3147                                                         s1 = rd->argfltregs[md->params[s3].regoff];
3148                                                         d = emit_load(jd, iptr, var, s1);
3149                                                         if (IS_2_WORD_TYPE(var->type))
3150                                                                 M_DBLMOVE(d, s1);
3151                                                         else
3152                                                                 M_FLTMOVE(d, s1);
3153                                                 }
3154                                                 else {
3155                                                         if (IS_2_WORD_TYPE(var->type)) {
3156                                                                 s1 = md->params[s3].regoff;
3157                                                                 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3158                                                                                            rd->argintregs[GET_HIGH_REG(s1)]);
3159                                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
3160                                                                 M_MFC1(GET_LOW_REG(s2), d);
3161                                                                 M_MFC1(GET_HIGH_REG(s2), d + 1);
3162                                                                 M_NOP;
3163                                                         }
3164                                                         else {
3165                                                                 s1 = rd->argintregs[md->params[s3].regoff];
3166                                                                 d = emit_load(jd, iptr, var, s1);
3167                                                                 M_MFC1(s1, d);
3168                                                                 M_NOP;
3169                                                         }
3170                                                 }       
3171 #endif
3172                                         }
3173                                         else {
3174                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
3175                                                 if (IS_2_WORD_TYPE(var->type))
3176                                                         M_DST(d, REG_SP, md->params[s3].regoff * 8);
3177                                                 else
3178                                                         M_FST(d, REG_SP, md->params[s3].regoff * 8);
3179                                         }
3180                                 }
3181                         }
3182
3183                         switch (iptr->opc) {
3184                         case ICMD_BUILTIN:
3185                                 disp = dseg_add_functionptr(cd, bte->fp);
3186
3187                                 M_ALD(REG_ITMP3, REG_PV, disp);  /* built-in-function pointer */
3188
3189                                 /* generate the actual call */
3190
3191                                 /* TWISTI: i actually don't know the reason for using
3192                                    REG_ITMP3 here instead of REG_PV. */
3193
3194                                 M_JSR(REG_RA, REG_ITMP3);
3195                                 M_NOP;
3196                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3197                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3198                                 M_LDA(REG_PV, REG_RA, -disp);
3199
3200                                 emit_exception_check(cd, iptr);
3201                                 break;
3202
3203                         case ICMD_INVOKESPECIAL:
3204                                 emit_nullpointer_check(cd, iptr, REG_A0);
3205                                 /* fall through */
3206
3207                         case ICMD_INVOKESTATIC:
3208                                 if (lm == NULL) {
3209                                         disp = dseg_add_unique_address(cd, um);
3210
3211                                         codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
3212                                                                                   disp);
3213                                 }
3214                                 else
3215                                         disp = dseg_add_address(cd, lm->stubroutine);
3216
3217                                 M_ALD(REG_PV, REG_PV, disp);          /* method pointer in pv */
3218
3219                                 /* generate the actual call */
3220
3221                                 M_JSR(REG_RA, REG_PV);
3222                                 M_NOP;
3223                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3224                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3225                                 M_LDA(REG_PV, REG_RA, -disp);
3226                                 break;
3227
3228                         case ICMD_INVOKEVIRTUAL:
3229                                 emit_nullpointer_check(cd, iptr, REG_A0);
3230
3231                                 if (lm == NULL) {
3232                                         codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
3233
3234                                         s1 = 0;
3235                                 }
3236                                 else
3237                                         s1 = OFFSET(vftbl_t, table[0]) +
3238                                                 sizeof(methodptr) * lm->vftblindex;
3239
3240                                 /* implicit null-pointer check */
3241                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3242                                 M_ALD(REG_PV, REG_METHODPTR, s1);
3243
3244                                 /* generate the actual call */
3245
3246                                 M_JSR(REG_RA, REG_PV);
3247                                 M_NOP;
3248                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3249                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3250                                 M_LDA(REG_PV, REG_RA, -disp);
3251                                 break;
3252
3253                         case ICMD_INVOKEINTERFACE:
3254                                 emit_nullpointer_check(cd, iptr, REG_A0);
3255
3256                                 if (lm == NULL) {
3257                                         codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
3258
3259                                         s1 = 0;
3260                                         s2 = 0;
3261                                 }
3262                                 else {
3263                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3264                                                 sizeof(methodptr*) * lm->class->index;
3265
3266                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3267                                 }
3268
3269                                 /* implicit null-pointer check */
3270                                 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3271                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3272                                 M_ALD(REG_PV, REG_METHODPTR, s2);
3273
3274                                 /* generate the actual call */
3275
3276                                 M_JSR(REG_RA, REG_PV);
3277                                 M_NOP;
3278                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3279                                 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3280                                 M_LDA(REG_PV, REG_RA, -disp);
3281                                 break;
3282                         }
3283
3284                         /* store return value */
3285
3286                         d = md->returntype.type;
3287
3288                         if (d != TYPE_VOID) {
3289                                 if (IS_INT_LNG_TYPE(d)) {
3290 #if SIZEOF_VOID_P == 8
3291                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3292                                         M_INTMOVE(REG_RESULT, s1);
3293 #else
3294                                         if (IS_2_WORD_TYPE(d)) {
3295                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3296                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
3297                                         }
3298                                         else {
3299                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3300                                                 M_INTMOVE(REG_RESULT, s1);
3301                                         }
3302 #endif
3303                                 }
3304                                 else {
3305                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3306                                         if (IS_2_WORD_TYPE(d))
3307                                                 M_DMOV(REG_FRESULT, s1);
3308                                         else
3309                                                 M_FMOV(REG_FRESULT, s1);
3310                                 }
3311                                 emit_store_dst(jd, iptr, s1);
3312                         }
3313                         break;
3314
3315
3316                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3317                                       /* val.a: (classinfo*) superclass               */
3318
3319                         /*  superclass is an interface:
3320                          *
3321                          *  OK if ((sub == NULL) ||
3322                          *         (sub->vftbl->interfacetablelength > super->index) &&
3323                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
3324                          *
3325                          *  superclass is a class:
3326                          *
3327                          *  OK if ((sub == NULL) || (0
3328                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3329                          *         super->vftbl->diffvall));
3330                          */
3331
3332                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3333                                 classinfo *super;
3334                                 s4         superindex;
3335
3336                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3337                                         super      = NULL;
3338                                         superindex = 0;
3339                                 }
3340                                 else {
3341                                         super = iptr->sx.s23.s3.c.cls;
3342                                         superindex = super->index;
3343                                 }
3344                         
3345 #if defined(ENABLE_THREADS)
3346                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3347 #endif
3348
3349                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3350
3351                                 /* if class is not resolved, check which code to call */
3352
3353                                 if (super == NULL) {
3354                                         emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3355
3356                                         cr   = iptr->sx.s23.s3.c.ref;
3357                                         disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
3358
3359                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3360                                                                                   cr, disp);
3361
3362                                         M_ILD(REG_ITMP2, REG_PV, disp);
3363                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3364                                         emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3365                                 }
3366
3367                                 /* interface checkcast code */
3368
3369                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3370                                         if (super == NULL) {
3371                                                 cr = iptr->sx.s23.s3.c.ref;
3372
3373                                                 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
3374                                                                                           cr, 0);
3375                                         }
3376                                         else {
3377                                                 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3378                                         }
3379
3380                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3381                                         M_ILD(REG_ITMP3, REG_ITMP2,
3382                                                   OFFSET(vftbl_t, interfacetablelength));
3383                                         M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3384                                         emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3385
3386                                         M_ALD(REG_ITMP3, REG_ITMP2,
3387                                                   OFFSET(vftbl_t, interfacetable[0]) -
3388                                                   superindex * sizeof(methodptr*));
3389                                         emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3390
3391                                         if (super == NULL)
3392                                                 emit_label_br(cd, BRANCH_LABEL_4);
3393                                         else
3394                                                 emit_label(cd, BRANCH_LABEL_3);
3395                                 }
3396
3397                                 /* class checkcast code */
3398
3399                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3400                                         if (super == NULL) {
3401                                                 emit_label(cd, BRANCH_LABEL_2);
3402
3403                                                 cr   = iptr->sx.s23.s3.c.ref;
3404                                                 disp = dseg_add_unique_address(cd, NULL);
3405
3406                                                 codegen_add_patch_ref(cd,
3407                                                                                           PATCHER_checkcast_instanceof_class,
3408                                                                                           cr, disp);
3409                                         }
3410                                         else {
3411                                                 disp = dseg_add_address(cd, super->vftbl);
3412
3413                                                 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3414                                         }
3415
3416                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3417                                         M_ALD(REG_ITMP3, REG_PV, disp);
3418 #if defined(ENABLE_THREADS)
3419                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3420 #endif
3421                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3422                                         /*                              if (s1 != REG_ITMP1) { */
3423                                         /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3424                                         /*                                      M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3425                                         /* #if defined(ENABLE_THREADS) */
3426                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3427                                         /* #endif */
3428                                         /*                                      M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3429                                         /*                              } else { */
3430                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3431                                         M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2); 
3432                                         M_ALD(REG_ITMP3, REG_PV, disp);
3433                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3434 #if defined(ENABLE_THREADS)
3435                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3436 #endif
3437                                         /*                              } */
3438                                         M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3439                                         emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3440
3441                                         if (super != NULL)
3442                                                 emit_label(cd, BRANCH_LABEL_5);
3443                                 }
3444
3445                                 if (super == NULL) {
3446                                         emit_label(cd, BRANCH_LABEL_1);
3447                                         emit_label(cd, BRANCH_LABEL_4);
3448                                 }
3449
3450                                 d = codegen_reg_of_dst(jd, iptr, s1);
3451                         }
3452                         else {
3453                                 s1 = emit_load_s1(jd, iptr, REG_A0);
3454                                 M_INTMOVE(s1, REG_A0);
3455
3456                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3457                                         cr   = iptr->sx.s23.s3.c.ref;
3458                                         disp = dseg_add_unique_address(cd, NULL);
3459
3460                                         codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3461                                                                                   cr, disp);
3462                                 }
3463                                 else
3464                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3465
3466                                 M_ALD(REG_A1, REG_PV, disp);
3467                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3468                                 M_ALD(REG_ITMP3, REG_PV, disp);
3469                                 M_JSR(REG_RA, REG_ITMP3);
3470                                 M_NOP;
3471
3472                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3473                                 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3474
3475                                 d = codegen_reg_of_dst(jd, iptr, s1);
3476                         }
3477
3478                         M_INTMOVE(s1, d);
3479                         emit_store_dst(jd, iptr, d);
3480                         break;
3481
3482                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3483                                       /* val.a: (classinfo*) superclass               */
3484
3485                         /*  superclass is an interface:
3486                          *
3487                          *  return (sub != NULL) &&
3488                          *         (sub->vftbl->interfacetablelength > super->index) &&
3489                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3490                          *
3491                          *  superclass is a class:
3492                          *
3493                          *  return ((sub != NULL) && (0
3494                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3495                          *          super->vftbl->diffvall));
3496                          */
3497
3498                         {
3499                         classinfo *super;
3500                         s4         superindex;
3501
3502                         super = iptr->sx.s23.s3.c.cls;
3503
3504                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3505                                 super      = NULL;
3506                                 superindex = 0;
3507                         }
3508                         else {
3509                                 super      = iptr->sx.s23.s3.c.cls;
3510                                 superindex = super->index;
3511                         }
3512                         
3513 #if defined(ENABLE_THREADS)
3514                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3515 #endif
3516
3517                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3518                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3519
3520                         if (s1 == d) {
3521                                 M_MOV(s1, REG_ITMP1);
3522                                 s1 = REG_ITMP1;
3523                         }
3524
3525                         M_CLR(d);
3526
3527                         /* if class is not resolved, check which code to call */
3528
3529                         if (super == NULL) {
3530                                 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3531
3532                                 cr   = iptr->sx.s23.s3.c.ref;
3533                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
3534
3535                                 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3536                                                                           cr, disp);
3537
3538                                 M_ILD(REG_ITMP3, REG_PV, disp);
3539                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3540                                 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3541                         }
3542
3543                         /* interface instanceof code */
3544
3545                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3546                                 if (super == NULL) {
3547                                         cr = iptr->sx.s23.s3.c.ref;
3548
3549                                         codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
3550                                                                                   cr, 0);
3551                                 }
3552                                 else {
3553                                         emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3554                                 }
3555
3556                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3557                                 M_ILD(REG_ITMP3, REG_ITMP1,
3558                                           OFFSET(vftbl_t, interfacetablelength));
3559                                 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3560                                 M_BLEZ(REG_ITMP3, 3);
3561                                 M_NOP;
3562                                 M_ALD(REG_ITMP1, REG_ITMP1,
3563                                           OFFSET(vftbl_t, interfacetable[0]) -
3564                                           superindex * sizeof(methodptr*));
3565                                 M_CMPULT(REG_ZERO, REG_ITMP1, d);      /* REG_ITMP1 != 0  */
3566
3567                                 if (super == NULL)
3568                                         emit_label_br(cd, BRANCH_LABEL_4);
3569                                 else
3570                                         emit_label(cd, BRANCH_LABEL_3);
3571                         }
3572
3573                         /* class instanceof code */
3574
3575                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3576                                 if (super == NULL) {
3577                                         emit_label(cd, BRANCH_LABEL_2);
3578
3579                                         cr   = iptr->sx.s23.s3.c.ref;
3580                                         disp = dseg_add_unique_address(cd, NULL);
3581
3582                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
3583                                                                                   cr, disp);
3584                                 }
3585                                 else {
3586                                         disp = dseg_add_address(cd, super->vftbl);
3587
3588                                         emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3589                                 }
3590
3591                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3592                                 M_ALD(REG_ITMP2, REG_PV, disp);
3593 #if defined(ENABLE_THREADS)
3594                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3595 #endif
3596                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3597                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3598                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3599 #if defined(ENABLE_THREADS)
3600                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3601 #endif
3602                                 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
3603                                 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3604                                 M_XOR_IMM(d, 1, d);
3605
3606                                 if (super != NULL)
3607                                         emit_label(cd, BRANCH_LABEL_5);
3608                         }
3609
3610                         if (super == NULL) {
3611                                 emit_label(cd, BRANCH_LABEL_1);
3612                                 emit_label(cd, BRANCH_LABEL_4);
3613                         }
3614
3615                         emit_store_dst(jd, iptr, d);
3616                         }
3617                         break;
3618
3619                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3620
3621                         /* check for negative sizes and copy sizes to stack if necessary  */
3622
3623                         MCODECHECK((iptr->s1.argcount << 1) + 64);
3624
3625                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3626
3627                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3628
3629                                 /* copy SAVEDVAR sizes to stack */
3630
3631                                 if (!(var->flags & PREALLOC)) {
3632                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
3633 #if SIZEOF_VOID_P == 8
3634                                         M_LST(s2, REG_SP, s1 * 8);
3635 #else
3636                                         M_IST(s2, REG_SP, (s1 + 2) * 8);
3637 #endif
3638                                 }
3639                         }
3640
3641                         /* a0 = dimension count */
3642
3643                         ICONST(REG_A0, iptr->s1.argcount);
3644
3645                         /* is patcher function set? */
3646
3647                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3648                                 cr   = iptr->sx.s23.s3.c.ref;
3649                                 disp = dseg_add_unique_address(cd, NULL);
3650
3651                                 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3652                                                                           cr, disp);
3653                         }
3654                         else
3655                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3656
3657                         /* a1 = arraydescriptor */
3658
3659                         M_ALD(REG_A1, REG_PV, disp);
3660
3661                         /* a2 = pointer to dimensions = stack pointer */
3662
3663 #if SIZEOF_VOID_P == 8
3664                         M_MOV(REG_SP, REG_A2);
3665 #else
3666                         M_AADD_IMM(REG_SP, 4*4, REG_A2);
3667 #endif
3668
3669                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3670                         M_ALD(REG_ITMP3, REG_PV, disp);
3671                         M_JSR(REG_RA, REG_ITMP3);
3672                         M_NOP;
3673
3674                         /* check for exception before result assignment */
3675
3676                         emit_exception_check(cd, iptr);
3677
3678                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3679                         M_INTMOVE(REG_RESULT, d);
3680                         emit_store_dst(jd, iptr, d);
3681                         break;
3682
3683                 default:
3684                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3685                                                                                    iptr->opc);
3686                         return false;
3687         } /* switch */
3688                 
3689         } /* for instruction */
3690                 
3691         MCODECHECK(64); /* XXX require smaller number? */
3692
3693         /* At the end of a basic block we may have to append some nops,
3694            because the patcher stub calling code might be longer than the
3695            actual instruction. So codepatching does not change the
3696            following block unintentionally. */
3697
3698         if (cd->mcodeptr < cd->lastmcodeptr) {
3699                 while (cd->mcodeptr < cd->lastmcodeptr)
3700                         M_NOP;
3701         }
3702
3703         } /* if (bptr -> flags >= BBREACHED) */
3704         } /* for basic block */
3705
3706         dseg_createlinenumbertable(cd);
3707
3708         /* generate stubs */
3709
3710         emit_patcher_stubs(jd);
3711         REPLACEMENT_EMIT_STUBS(jd);
3712
3713         /* everything's ok */
3714
3715         return true;
3716 }
3717
3718
3719 /* createcompilerstub **********************************************************
3720
3721    Creates a stub routine which calls the compiler.
3722         
3723 *******************************************************************************/
3724
3725 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
3726 #define COMPILERSTUB_CODESIZE    4 * 4
3727
3728 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3729
3730
3731 u1 *createcompilerstub(methodinfo *m)
3732 {
3733         u1          *s;                     /* memory to hold the stub            */
3734         ptrint      *d;
3735         codegendata *cd;
3736         s4           dumpsize;
3737
3738         s = CNEW(u1, COMPILERSTUB_SIZE);
3739
3740         /* set data pointer and code pointer */
3741
3742         d = (ptrint *) s;
3743         s = s + COMPILERSTUB_DATASIZE;
3744
3745         /* mark start of dump memory area */
3746
3747         dumpsize = dump_size();
3748
3749         cd = DNEW(codegendata);
3750         cd->mcodeptr = s;
3751
3752         /* The codeinfo pointer is actually a pointer to the
3753            methodinfo. This fakes a codeinfo structure. */
3754
3755         d[0] = (ptrint) asm_call_jit_compiler;
3756         d[1] = (ptrint) m;
3757         d[2] = (ptrint) &d[1];                                    /* fake code->m */
3758
3759         M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
3760         M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
3761         M_JMP(REG_PV);
3762         M_NOP;
3763
3764         md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3765
3766 #if defined(ENABLE_STATISTICS)
3767         if (opt_stat)
3768                 count_cstub_len += COMPILERSTUB_SIZE;
3769 #endif
3770
3771         /* release dump area */
3772
3773         dump_release(dumpsize);
3774
3775         return s;
3776 }
3777
3778
3779 /* createnativestub ************************************************************
3780
3781    Creates a stub routine which calls a native method.
3782
3783 *******************************************************************************/
3784
3785 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3786 {
3787         methodinfo   *m;
3788         codeinfo     *code;
3789         codegendata  *cd;
3790         registerdata *rd;
3791         methoddesc   *md;
3792         s4            nativeparams;
3793         s4            i, j;                 /* count variables                    */
3794         s4            t;
3795         s4            s1, s2, disp;
3796         s4            funcdisp;             /* displacement of the function       */
3797
3798         /* get required compiler data */
3799
3800         m    = jd->m;
3801         code = jd->code;
3802         cd   = jd->cd;
3803         rd   = jd->rd;
3804
3805         /* initialize variables */
3806
3807         md = m->parseddesc;
3808         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3809
3810         /* calculate stack frame size */
3811
3812         cd->stackframesize =
3813                 1 +                             /* return address                     */
3814                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3815                 sizeof(localref_table) / SIZEOF_VOID_P +
3816                 md->paramcount +                /* for saving arguments over calls    */
3817 #if SIZEOF_VOID_P == 4
3818                 5 +                             /* additional save space (MIPS32)     */
3819 #endif
3820                 1 +                             /* for saving return address          */
3821                 nmd->memuse;
3822
3823         /* adjust stackframe size for 16-byte alignment */
3824
3825         if (cd->stackframesize & 1)
3826                 cd->stackframesize++;
3827
3828         /* create method header */
3829
3830         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3831         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
3832         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
3833         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3834         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3835         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3836         (void) dseg_addlinenumbertablesize(cd);
3837         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
3838
3839         /* generate stub code */
3840
3841         M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe    */
3842         M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA          */
3843
3844 #if !defined(NDEBUG)
3845         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3846                 emit_verbosecall_enter(jd);
3847 #endif
3848
3849         /* get function address (this must happen before the stackframeinfo) */
3850
3851         funcdisp = dseg_add_functionptr(cd, f);
3852
3853 #if !defined(WITH_STATIC_CLASSPATH)
3854         if (f == NULL)
3855                 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3856 #endif
3857
3858         /* save integer and float argument registers */
3859
3860 #if SIZEOF_VOID_P == 8
3861         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3862                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3863                         M_AST(rd->argintregs[i], REG_SP, j * 8);
3864                         j++;
3865                 }
3866         }
3867 #else
3868         for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3869                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3870                         if (!md->params[i].inmemory) {
3871                                 s1 = md->params[i].regoff;
3872                                 if (IS_2_WORD_TYPE(md->params[i].type)) {
3873                                         s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3874                                                                    rd->argintregs[GET_HIGH_REG(s1)]);
3875                                         M_LST(s1, REG_SP, j * 8);
3876                                 }
3877                                 else {
3878                                         M_IST(rd->argintregs[s1], REG_SP, j * 8);
3879                                 }
3880                                 j++;
3881                         }
3882                 }
3883         }
3884 #endif
3885
3886         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3887                 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3888                         if (IS_2_WORD_TYPE(md->params[i].type))
3889                                 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3890                         else
3891                                 M_FST(rd->argfltregs[i], REG_SP, j * 8);
3892                         j++;
3893                 }
3894         }
3895
3896         /* prepare data structures for native function call */
3897
3898         M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3899         M_MOV(REG_PV, REG_A1);
3900         M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3901         M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3902         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3903         M_ALD(REG_ITMP3, REG_PV, disp);
3904         M_JSR(REG_RA, REG_ITMP3);
3905         M_NOP; /* XXX fill me! */
3906
3907         /* restore integer and float argument registers */
3908
3909 #if SIZEOF_VOID_P == 8
3910         for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3911                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3912                         M_LLD(rd->argintregs[i], REG_SP, j * 8);
3913                         j++;
3914                 }
3915         }
3916 #else
3917         for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3918                 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3919                         if (!md->params[i].inmemory) {
3920                                 s1 = md->params[i].regoff;
3921                                 if (IS_2_WORD_TYPE(md->params[i].type)) {
3922                                         s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3923                                                                    rd->argintregs[GET_HIGH_REG(s1)]);
3924                                         M_LLD(s1, REG_SP, j * 8);
3925                                 }
3926                                 else {
3927                                         M_ILD(rd->argintregs[s1], REG_SP, j * 8);
3928                                 }
3929                                 j++;
3930                         }
3931                 }
3932         }
3933 #endif
3934
3935         for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3936                 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3937                         if (IS_2_WORD_TYPE(md->params[i].type))
3938                                 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3939                         else
3940                                 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
3941                         j++;
3942                 }
3943         }
3944
3945         /* copy or spill arguments to new locations */
3946
3947         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3948                 t = md->params[i].type;
3949
3950                 if (IS_INT_LNG_TYPE(t)) {
3951                         if (!md->params[i].inmemory) {
3952                                 s1 = md->params[i].regoff;
3953 #if SIZEOF_VOID_P == 8
3954                                 s1 = rd->argintregs[s1];
3955 #else
3956                                 if (IS_2_WORD_TYPE(t))
3957                                         s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3958                                                                    rd->argintregs[GET_HIGH_REG(s1)]);
3959                                 else
3960                                         s1 = rd->argintregs[s1];
3961 #endif
3962
3963                                 if (!nmd->params[j].inmemory) {
3964                                         s2 = nmd->params[j].regoff;
3965 #if SIZEOF_VOID_P == 8
3966                                         s2 = rd->argintregs[s2];
3967                                         M_INTMOVE(s1, s2);
3968 #else
3969                                         if (IS_2_WORD_TYPE(t)) {
3970                                                 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
3971                                                                            rd->argintregs[GET_HIGH_REG(s2)]);
3972                                                 M_LNGMOVE(s1, s2);
3973                                         }
3974                                         else {
3975                                                 s2 = rd->argintregs[s2];
3976                                                 M_INTMOVE(s1, s2);
3977                                         }
3978 #endif
3979                                 }
3980                                 else {
3981                                         s2 = nmd->params[j].regoff;
3982
3983 #if SIZEOF_VOID_P == 8
3984                                         M_LST(s1, REG_SP, s2 * 8);
3985 #else
3986                                         if (IS_2_WORD_TYPE(t))
3987                                                 M_LST(s1, REG_SP, s2 * 4);
3988                                         else
3989                                                 M_IST(s1, REG_SP, s2 * 4);
3990 #endif
3991                                 }
3992                         }
3993                         else {
3994                                 s1 = md->params[i].regoff + cd->stackframesize;
3995                                 s2 = nmd->params[j].regoff;
3996
3997 #if SIZEOF_VOID_P == 8
3998                                 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3999                                 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4000 #else
4001                                 if (IS_2_WORD_TYPE(t)) {
4002                                         M_LLD(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s1 * 8);
4003                                         M_LST(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s2 * 4);
4004                                 }
4005                                 else {
4006                                         M_ILD(REG_ITMP1, REG_SP, s1 * 8);
4007                                         M_IST(REG_ITMP1, REG_SP, s2 * 4);
4008                                 }
4009 #endif
4010                         }
4011                 }
4012                 else {
4013                         if (!md->params[i].inmemory) {
4014                                 s1 = md->params[i].regoff;
4015                                 s2 = nmd->params[j].regoff;
4016
4017                                 if (!nmd->params[j].inmemory) {
4018 #if SIZEOF_VOID_P == 8
4019                                         s1 = rd->argfltregs[s1];
4020                                         s2 = rd->argfltregs[s2];
4021                                         if (IS_2_WORD_TYPE(t))
4022                                                 M_DMOV(s1, s2);
4023                                         else
4024                                                 M_FMOV(s1, s2);
4025 #else
4026                                         /* On MIPS32 float arguments for native functions
4027                                            can never be in float argument registers, since
4028                                            the first argument is _always_ an integer
4029                                            argument (JNIenv) */
4030
4031                                         if (IS_2_WORD_TYPE(t)) {
4032                                                 s1 = rd->argfltregs[s1];
4033                                                 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
4034                                                                            rd->argintregs[GET_HIGH_REG(s2)]);
4035
4036                                                 /* double high/low order is endian
4037                                                    independent: even numbered holds low
4038                                                    32-bits, odd numbered high 32-bits */
4039
4040                                                 M_MFC1(GET_LOW_REG(s2), s1);           /* low 32-bits */
4041                                                 M_MFC1(GET_HIGH_REG(s2), s1 + 1);     /* high 32-bits */
4042                                         }
4043                                         else {
4044                                                 s1 = rd->argfltregs[s1];
4045                                                 s2 = rd->argintregs[s2];
4046                                                 M_MFC1(s2, s1);
4047                                         }
4048 #endif
4049                                 }
4050                                 else {
4051 #if SIZEOF_VOID_P == 8
4052                                         s1 = rd->argfltregs[s1];
4053
4054                                         if (IS_2_WORD_TYPE(t))
4055                                                 M_DST(s1, REG_SP, s2 * 8);
4056                                         else
4057                                                 M_FST(s1, REG_SP, s2 * 8);
4058 #else
4059                                         /* s1 may have been originally in 2 int registers,
4060                                            but was moved out by the native function
4061                                            argument(s), just get low register */
4062
4063                                         s1 = rd->argfltregs[GET_LOW_REG(s1)];
4064
4065                                         if (IS_2_WORD_TYPE(t))
4066                                                 M_DST(s1, REG_SP, s2 * 4);
4067                                         else
4068                                                 M_FST(s1, REG_SP, s2 * 4);
4069 #endif
4070                                 }
4071                         }
4072                         else {
4073                                 s1 = md->params[i].regoff + cd->stackframesize;
4074                                 s2 = nmd->params[j].regoff;
4075
4076                                 if (IS_2_WORD_TYPE(t)) {
4077                                         M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4078                                         M_DST(REG_FTMP1, REG_SP, s2 * 8);
4079                                 }
4080                                 else {
4081                                         M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4082                                         M_FST(REG_FTMP1, REG_SP, s2 * 8);
4083                                 }
4084                         }
4085                 }
4086         }
4087
4088         /* put class into second argument register */
4089
4090         if (m->flags & ACC_STATIC) {
4091                 disp = dseg_add_address(cd, m->class);
4092                 M_ALD(REG_A1, REG_PV, disp);
4093         }
4094
4095         /* put env into first argument register */
4096
4097         disp = dseg_add_address(cd, _Jv_env);
4098         M_ALD(REG_A0, REG_PV, disp);
4099
4100         /* do the native function call */
4101
4102         M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method       */
4103         M_JSR(REG_RA, REG_ITMP3);           /* call native method                 */
4104         M_NOP;                              /* delay slot                         */
4105
4106         /* save return value */
4107
4108         if (md->returntype.type != TYPE_VOID) {
4109 #if SIZEOF_VOID_P == 8
4110                 if (IS_INT_LNG_TYPE(md->returntype.type))
4111                         M_LST(REG_RESULT, REG_SP, 0 * 8);
4112                 else
4113                         M_DST(REG_FRESULT, REG_SP, 0 * 8);
4114 #else
4115                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4116                         M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4117                         if (IS_2_WORD_TYPE(md->returntype.type))
4118                                 M_IST(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4119                 }
4120                 else
4121                         M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4122 #endif
4123         }
4124
4125 #if !defined(NDEBUG)
4126         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4127                 emit_verbosecall_exit(jd);
4128 #endif
4129
4130         /* remove native stackframe info */
4131
4132         M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
4133         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
4134         M_ALD(REG_ITMP3, REG_PV, disp);
4135         M_JSR(REG_RA, REG_ITMP3);
4136         M_NOP; /* XXX fill me! */
4137         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4138
4139         /* restore return value */
4140
4141         if (md->returntype.type != TYPE_VOID) {
4142 #if SIZEOF_VOID_P == 8
4143                 if (IS_INT_LNG_TYPE(md->returntype.type))
4144                         M_LLD(REG_RESULT, REG_SP, 0 * 8);
4145                 else
4146                         M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4147 #else
4148                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4149                         M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4150                         if (IS_2_WORD_TYPE(md->returntype.type))
4151                                 M_ILD(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4152                 }
4153                 else
4154                         M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4155 #endif
4156         }
4157
4158         M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA           */
4159
4160         /* check for exception */
4161
4162         M_BNEZ(REG_ITMP1_XPTR, 2);          /* if no exception then return        */
4163         M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT              */
4164
4165         M_RET(REG_RA);                      /* return to caller                   */
4166         M_NOP;                              /* DELAY SLOT                         */
4167
4168         /* handle exception */
4169         
4170         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4171         M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
4172         M_JMP(REG_ITMP3);                   /* jump to asm exception handler      */
4173         M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY)    */
4174
4175         /* generate patcher stubs */
4176
4177         emit_patcher_stubs(jd);
4178
4179         codegen_finish(jd);
4180
4181         return code->entrypoint;
4182 }
4183
4184
4185 /*
4186  * These are local overrides for various environment variables in Emacs.
4187  * Please do not remove this and leave it at the end of the file, where
4188  * Emacs will automagically detect them.
4189  * ---------------------------------------------------------------------
4190  * Local variables:
4191  * mode: c
4192  * indent-tabs-mode: t
4193  * c-basic-offset: 4
4194  * tab-width: 4
4195  * End:
4196  * vim:noexpandtab:sw=4:ts=4:
4197  */