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