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