Merged with tip.
[cacao.git] / src / vm / jit / sparc64 / codegen.c
1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30 #include <stdio.h>
31
32 #include "vm/types.h"
33
34 #include "md-abi.h"
35
36 /* #include "vm/jit/sparc64/arch.h" */
37 #include "vm/jit/sparc64/codegen.h"
38 #include "vm/jit/sparc64/emit.h"
39
40 #include "mm/memory.h"
41
42 #include "native/jni.h"
43 #include "native/localref.h"
44 #include "native/native.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48
49 #include "vm/jit/abi.h"
50 #include "vm/jit/asmpart.h"
51 #include "vm/jit/codegen-common.h"
52 #include "vm/jit/dseg.h"
53 #include "vm/jit/emit-common.h"
54 #include "vm/jit/jit.h"
55 #include "vm/jit/linenumbertable.h"
56 #include "vm/jit/parse.h"
57 #include "vm/jit/patcher.h"
58 #include "vm/jit/reg.h"
59 #include "vm/jit/replace.h"
60 #include "vm/jit/stacktrace.h"
61
62 #include "vmcore/loader.h"
63 #include "vmcore/options.h"
64
65 #include "vm/jit/sparc64/solaris/macro_rename.h"
66
67 #define BUILTIN_FLOAT_ARGS 1
68
69 /* XXX use something like this for window control ? 
70  * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
71  */
72 #define REG_PV REG_PV_CALLEE
73
74 bool fits_13(s4 disp)
75 {
76         /*
77         if ((disp < -4096) || (disp > 4095))
78                 printf("disp %d\n", disp);
79         */
80
81         return (disp >= -4096) && (disp <= 4095);
82 }
83
84 s4 get_lopart_disp(disp)
85 {
86         s4 lodisp;
87         
88         if (disp > 0)
89                 lodisp = setlo_part(disp);
90         else {
91                 if (setlo_part(disp) == 0)
92                         lodisp = 0;
93                 else
94                         lodisp = setlo_part(disp) | 0x1c00;
95         }
96                 
97         return lodisp;
98 }
99
100 #ifndef NDEBUG
101 bool check_13bit_imm(s8 imm)
102 {
103         s4 sign = (imm >> 12) & 0x1;
104
105         if (sign == 0) {
106                 if ((imm & ~0xfff) == 0) return true; /* pos imm. */
107         }
108         else
109                 if ((imm & ~0xfff) + 0xfff == -1) return true; /* neg imm. */
110         
111         printf("immediate out-of-bounds: %ld\n", imm);
112         return false;
113 }
114 #endif
115         
116
117 /* codegen_emit ****************************************************************
118
119    Generates machine code.
120
121 *******************************************************************************/
122
123 bool codegen_emit(jitdata *jd)
124 {
125         methodinfo         *m;
126         codeinfo           *code;
127         codegendata        *cd;
128         registerdata       *rd;
129         s4                  len, s1, s2, s3, d, disp, slots;
130         varinfo            *var;
131         basicblock         *bptr;
132         instruction        *iptr;
133         u2                  currentline;
134         constant_classref  *cr;
135         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
136         unresolved_method  *um;
137         builtintable_entry *bte;
138         methoddesc         *md;
139         fieldinfo          *fi;
140         unresolved_field   *uf;
141         s4                  fieldtype;
142         s4                  varindex;
143
144         /* get required compiler data */
145
146         m  = jd->m;
147         code = jd->code;
148         cd = jd->cd;
149         rd = jd->rd;
150         
151         /* prevent compiler warnings */
152
153         d = 0;
154         currentline = 0;
155         lm = NULL;
156         bte = NULL;
157
158         {
159         s4 i, p, t, l;
160         s4 savedregs_num;
161         s4 framesize_disp;
162
163 #if 0 /* no leaf optimization yet */
164         savedregs_num = (code_is_leafmethod(code)) ? 0 : 1;       /* space to save the RA */
165 #endif
166         savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */ 
167
168
169         /* space to save used callee saved registers */
170
171         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
172         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
173
174         cd->stackframesize = rd->memuse + savedregs_num;
175
176 #if defined(ENABLE_THREADS)        /* space to save argument of monitor_enter */
177         if (checksync && code_is_synchronized(code))
178                 cd->stackframesize++;
179 #endif
180
181         /* keep stack 16-byte aligned (ABI requirement) */
182
183         if (cd->stackframesize & 1)
184                 cd->stackframesize++;
185
186         /* create method header */
187
188         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
189         framesize_disp = dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
190
191         code->synchronizedoffset = JITSTACK + rd->memuse * 8;
192
193         /* REMOVEME: We still need it for exception handling in assembler. */
194
195         if (code_is_leafmethod(code))
196                 (void) dseg_add_unique_s4(cd, 1);
197         else
198                 (void) dseg_add_unique_s4(cd, 0);
199
200         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
201         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
202
203         /* save register window and create stack frame (if necessary) */
204
205         if (cd->stackframesize) {
206                 if (cd->stackframesize <= 4095)
207                         M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
208                 else {
209                         M_ILD_INTERN(REG_ITMP3, REG_PV_CALLER, framesize_disp);
210                         M_SUB(REG_ZERO, REG_ITMP3, REG_ITMP3);
211                         M_SAVE_REG(REG_SP, REG_ITMP3, REG_SP);
212                 }
213         }
214
215         /* save callee saved float registers (none right now) */
216 #if 0
217         p = cd->stackframesize;
218         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
219                 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
220         }
221 #endif
222
223 #if !defined(NDEBUG)
224         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
225                 emit_verbosecall_enter(jd);
226 #endif
227         
228         
229                 /* call monitorenter function */
230 #if defined(ENABLE_THREADS)
231         if (checksync && code_is_synchronized(code)) {
232                 /* stack offset for monitor argument */
233
234                 s1 = rd->memuse;
235
236                 /* save float argument registers */
237
238                 /* XXX jit-c-call */
239                 slots = FLT_ARG_CNT;
240                 ALIGN_STACK_SLOTS(slots);
241
242                 M_LDA(REG_SP, REG_SP, -(slots * 8));
243                 for (i = 0; i < FLT_ARG_CNT; i++)
244                         M_DST(abi_registers_float_argument[i], REG_SP, CSTACK +  i * 8);
245
246                 s1 += slots;
247
248                 /* get correct lock object */
249
250                 if (m->flags & ACC_STATIC) {
251                         disp = dseg_add_address(cd, &m->clazz->object.header);
252                         M_ALD(REG_OUT0, REG_PV, disp);
253                         disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
254                         M_ALD(REG_ITMP3, REG_PV, disp);
255                 }
256                 else {
257                         /* copy class pointer: $i0 -> $o0 */
258                         M_MOV(REG_RESULT_CALLEE, REG_OUT0);
259                         M_BNEZ(REG_OUT0, 3);
260                         disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
261                         M_ALD(REG_ITMP3, REG_PV, disp);                   /* branch delay */
262                         M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
263                 }
264
265                 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
266                 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8);             /* branch delay */
267
268                 /* restore float argument registers */
269
270                 for (i = 0; i < FLT_ARG_CNT; i++)
271                         M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
272
273                 M_LDA(REG_SP, REG_SP, slots * 8);
274         }
275 #endif
276
277
278         /* take arguments out of register or stack frame */
279         
280         md = m->parseddesc;
281
282         for (p = 0, l = 0; p < md->paramcount; p++) {
283                 t = md->paramtypes[p].type;
284
285                 varindex = jd->local_map[l * 5 + t];
286
287                 l++;
288                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
289                         l++;
290
291                 if (varindex == UNUSED)
292                         continue;
293
294                 var = VAR(varindex);
295                 s1 = md->params[p].regoff;
296                 
297                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */                        
298
299                         s2 = var->vv.regoff;
300                         
301                         if (!md->params[p].inmemory) {           /* register arguments    */
302                                 s1 = REG_WINDOW_TRANSPOSE(s1);
303                                 
304                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
305
306                                         /* the register allocator does not know about the window. */
307                                         /* avoid copying the locals from save to save regs by     */
308                                         /* swapping variables.                                    */
309
310                                         {
311                                         int old_dest = var->vv.regoff;
312                                         int new_dest = p + 24;
313
314                                         /* run through all variables */
315
316                                         for (i = 0; i < jd->varcount; i++) {
317                                                 varinfo* uvar = VAR(i);
318
319                                                 if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
320                                                         continue;
321
322                                                 s2 = uvar->vv.regoff;
323
324                                                 /* free the in reg by moving all other references */
325
326                                                 if (s2 == new_dest) {
327                                                         uvar->vv.regoff = old_dest;
328                                                         /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
329                                                 }
330
331                                                 /* move all variables to the in reg */
332
333                                                 if (s2 == old_dest) {
334                                                         uvar->vv.regoff = new_dest;
335                                                         /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
336                                                 }
337                                         }
338                                         }
339
340
341
342                                 } 
343                                 else {                             /* reg arg -> spilled    */
344                                         M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
345                                 }
346
347                         } else {                                 /* stack arguments       */
348                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
349                                         M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
350
351                                 } else {                             /* stack arg -> spilled  */
352                                         /* add the callers window save registers */
353                                         var->vv.regoff = cd->stackframesize * 8 + s1;
354                                 }
355                         }
356                 
357                 } else {                                     /* floating args         */
358                         if (!md->params[p].inmemory) {           /* register arguments    */
359                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
360                                         M_FLTMOVE(s1, var->vv.regoff);
361
362                                 } else {                                         /* reg arg -> spilled    */
363                                         M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
364                                 }
365
366                         } else {                                 /* stack arguments       */
367                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
368                                         M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
369
370                                 } else {                             /* stack-arg -> spilled  */
371                                         var->vv.regoff = cd->stackframesize * 8 + s1;
372                                 }
373                         }
374                 }
375         } /* end for */
376         
377         
378         }
379         
380         /* end of header generation */ 
381         
382         /* create replacement points */
383
384         REPLACEMENT_POINTS_INIT(cd, jd);
385
386         /* walk through all basic blocks */
387
388         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
389
390                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
391
392                 if (bptr->flags >= BBREACHED) {
393
394                 /* branch resolving */
395
396                 codegen_resolve_branchrefs(cd, bptr);
397                 
398                 /* handle replacement points */
399
400                 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
401
402
403                 /* copy interface registers to their destination */
404
405                 len = bptr->indepth;
406                 MCODECHECK(64+len);
407                 
408 #if defined(ENABLE_LSRA)
409 #error XXX LSRA not tested yet
410                 if (opt_lsra) {
411                 while (len) {
412                         len--;
413                         src = bptr->invars[len];
414                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
415                                         /*                              d = reg_of_var(m, src, REG_ITMP1); */
416                                         if (!(src->flags & INMEMORY))
417                                                 d = src->vv.regoff;
418                                         else
419                                                 d = REG_ITMP1;
420                                         M_INTMOVE(REG_ITMP1, d);
421                                         emit_store(jd, NULL, src, d);
422                                 }
423                         }
424                 } else {
425 #endif
426                 while (len) {
427                         len--;
428                         var = VAR(bptr->invars[len]);
429                         if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
430                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
431                                 M_INTMOVE(REG_ITMP2_XPTR, d);
432                                 emit_store(jd, NULL, var, d);
433                         }
434                         else {
435                                 assert((var->flags & INOUT));
436                         }
437                 }
438 #if defined(ENABLE_LSRA)
439                 }
440 #endif
441                 /* walk through all instructions */
442                 
443                 len = bptr->icount;
444
445                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
446                         if (iptr->line != currentline) {
447                                 linenumbertable_list_entry_add(cd, iptr->line);
448                                 currentline = iptr->line;
449                         }
450
451                 MCODECHECK(64);       /* an instruction usually needs < 64 words      */
452
453                 switch (iptr->opc) {
454
455                 case ICMD_INLINE_START:
456                 case ICMD_INLINE_END:
457                         break;
458
459                 case ICMD_NOP:        /* ...  ==> ...                                 */
460                         break;
461
462                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
463
464                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
465                         emit_nullpointer_check(cd, iptr, s1);
466                         break;
467         
468                 /* constant operations ************************************************/
469
470                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
471
472                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
473                         ICONST(d, iptr->sx.val.i);
474                         emit_store_dst(jd, iptr, d);
475                         break;
476
477                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
478
479                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
480                         LCONST(d, iptr->sx.val.l);
481                         emit_store_dst(jd, iptr, d);
482                         break;  
483
484                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
485
486                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
487                         disp = dseg_add_float(cd, iptr->sx.val.f);
488                         M_FLD(d, REG_PV, disp);
489                         emit_store_dst(jd, iptr, d);
490                         break;
491                         
492                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
493
494                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
495                         disp = dseg_add_double(cd, iptr->sx.val.d);
496                         M_DLD(d, REG_PV, disp);
497                         emit_store_dst(jd, iptr, d);
498                         break;
499
500                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
501
502                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
503
504                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
505                                 cr   = iptr->sx.val.c.ref;
506                                 disp = dseg_add_unique_address(cd, cr);
507
508                                 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
509
510                                 M_ALD(d, REG_PV, disp);
511
512                         } 
513                         else {
514                                 if (iptr->sx.val.anyptr == NULL) {
515                                         M_INTMOVE(REG_ZERO, d);
516                                 } 
517                                 else {
518                                         disp = dseg_add_address(cd, iptr->sx.val.anyptr);
519                                         M_ALD(d, REG_PV, disp);
520                                 }
521                         }
522                         emit_store_dst(jd, iptr, d);
523                         break;
524
525
526                 /* load/store/copy/move operations ************************************/
527
528                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
529                 case ICMD_LLOAD:
530                 case ICMD_ALOAD:
531                 case ICMD_FLOAD:
532                 case ICMD_DLOAD:
533                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
534                 case ICMD_LSTORE:
535                 case ICMD_FSTORE:
536                 case ICMD_DSTORE:
537                 case ICMD_COPY:
538                 case ICMD_MOVE:
539
540                         emit_copy(jd, iptr);
541                         break;
542         
543                 case ICMD_ASTORE:
544                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
545                                 emit_copy(jd, iptr);
546                         break;
547
548
549                 /* pop/dup/swap operations ********************************************/
550
551                 /* attention: double and longs are only one entry in CACAO ICMDs      */
552
553                 case ICMD_POP:        /* ..., value  ==> ...                          */
554                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
555                         break;
556
557
558                 /* integer operations *************************************************/
559
560                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
561                 case ICMD_LNEG:
562
563                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
564                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
565                         M_SUB(REG_ZERO, s1, d);
566                         emit_store_dst(jd, iptr, d);
567                         break;
568
569                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
570
571                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573                         M_INTMOVE(s1, d);
574                         emit_store_dst(jd, iptr, d);
575                         break;
576
577                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
578
579                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
580                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
581                         M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
582                         emit_store_dst(jd, iptr, d);
583                         break;
584
585                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
586
587                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
589                         M_SLLX_IMM(s1, 56, d);
590                         M_SRAX_IMM( d, 56, d);
591                         emit_store_dst(jd, iptr, d);
592                         break;
593
594                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
595                 
596                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
598                         M_SLLX_IMM(s1, 48, d);
599                         M_SRLX_IMM( d, 48, d);
600                         emit_store_dst(jd, iptr, d);
601                         break;
602                         
603                 case ICMD_INT2SHORT:   /* ..., value  ==> ..., value                   */
604
605                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
606                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
607                         M_SLLX_IMM(s1, 48, d);
608                         M_SRAX_IMM( d, 48, d);
609                         emit_store_dst(jd, iptr, d);
610                         break;
611
612                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
613                 case ICMD_LADD:
614
615                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
616                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
617                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
618                         M_ADD(s1, s2, d);
619                         emit_store_dst(jd, iptr, d);
620                         break;
621
622                 case ICMD_IINC:
623                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
624                                       /* sx.val.i = constant                             */
625
626                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
628                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
629                                 M_ADD_IMM(s1, iptr->sx.val.i, d);
630                         } else {
631                                 ICONST(REG_ITMP2, iptr->sx.val.i);
632                                 M_ADD(s1, REG_ITMP2, d);
633                         }
634                         emit_store_dst(jd, iptr, d);
635                         break;
636
637                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
638                                       /* sx.val.l = constant                             */
639
640                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
641                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
642                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
643                                 M_ADD_IMM(s1, iptr->sx.val.l, d);
644                         } else {
645                                 LCONST(REG_ITMP2, iptr->sx.val.l);
646                                 M_ADD(s1, REG_ITMP2, d);
647                         }
648                         emit_store_dst(jd, iptr, d);
649                         break;
650
651                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
652                 case ICMD_LSUB: 
653
654                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
655                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
656                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657                         M_SUB(s1, s2, d);
658                         emit_store_dst(jd, iptr, d);
659                         break;
660
661                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
662                                       /* sx.val.i = constant                             */
663
664                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
665                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
666                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
667                                 M_SUB_IMM(s1, iptr->sx.val.i, d);
668                         } else {
669                                 ICONST(REG_ITMP2, iptr->sx.val.i);
670                                 M_SUB(s1, REG_ITMP2, d);
671                         }
672                         emit_store_dst(jd, iptr, d);
673                         break;
674
675                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
676                                       /* sx.val.l = constant                             */
677
678                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
679                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
680                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
681                                 M_SUB_IMM(s1, iptr->sx.val.l, d);
682                         } else {
683                                 LCONST(REG_ITMP2, iptr->sx.val.l);
684                                 M_SUB(s1, REG_ITMP2, d);
685                         }
686                         emit_store_dst(jd, iptr, d);
687                         break;
688
689                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
690                 case ICMD_LMUL:
691
692                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
693                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
694                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
695                         M_MULX(s1, s2, d);
696                         emit_store_dst(jd, iptr, d);
697                         break;
698
699                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
700                                       /* sx.val.i = constant                             */
701
702                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
703                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
704                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
705                                 M_MULX_IMM(s1, iptr->sx.val.i, d);
706                         } else {
707                                 ICONST(REG_ITMP2, iptr->sx.val.i);
708                                 M_MULX(s1, REG_ITMP2, d);
709                         }
710                         emit_store_dst(jd, iptr, d);
711                         break;
712
713                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
714                                       /* sx.val.l = constant                             */
715
716                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
717                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
718                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
719                                 M_MULX_IMM(s1, iptr->sx.val.l, d);
720                         } else {
721                                 LCONST(REG_ITMP2, iptr->sx.val.l);
722                                 M_MULX(s1, REG_ITMP2, d);
723                         }
724                         emit_store_dst(jd, iptr, d);
725                         break;
726
727                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
728 /* XXX could also clear Y and use 32bit div */
729                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
730                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
731                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
732                         emit_arithmetic_check(cd, iptr, s2);
733                         M_ISEXT(s1, s1);
734                         /* XXX trim s2 like s1 ? */
735                         M_DIVX(s1, s2, d);
736                         emit_store_dst(jd, iptr, d);
737                         break;
738
739                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
740
741                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
742                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
743                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
744                         emit_arithmetic_check(cd, iptr, s2);
745                         M_DIVX(s1, s2, d);
746                         emit_store_dst(jd, iptr, d);
747                         break;
748
749                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
750
751                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
752                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
753                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
754                         emit_arithmetic_check(cd, iptr, s2);
755                         M_ISEXT(s1, s1);
756                         /* XXX trim s2 like s1 ? */
757                         M_DIVX(s1, s2, REG_ITMP3);
758                         M_MULX(s2, REG_ITMP3, REG_ITMP3);
759                         M_SUB(s1, REG_ITMP3, d);
760                         emit_store_dst(jd, iptr, d);
761                         break;
762
763                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
764
765                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
766                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
767                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
768                         emit_arithmetic_check(cd, iptr, s2);
769                         M_DIVX(s1, s2, REG_ITMP3);
770                         M_MULX(s2, REG_ITMP3, REG_ITMP3);
771                         M_SUB(s1, REG_ITMP3, d);
772                         emit_store_dst(jd, iptr, d);
773                         break;
774
775                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
776                 case ICMD_LDIVPOW2:   /* val.i = constant                             */
777                                       
778                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
779                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
780                         M_SRAX_IMM(s1, 63, REG_ITMP2);
781                         M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
782                         M_ADD(s1, REG_ITMP2, REG_ITMP2);
783                         M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
784                         emit_store_dst(jd, iptr, d);
785                         break;
786
787                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
788
789                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
790                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
791                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
792                         M_SLL(s1, s2, d);
793                         emit_store_dst(jd, iptr, d);
794                         break;
795                         
796                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
797
798                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
799                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
800                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
801                         M_SLLX(s1, s2, d);
802                         emit_store_dst(jd, iptr, d);
803                         break;
804
805                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
806                                       /* val.i = constant                             */
807
808                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
809                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
810                         M_SLL_IMM(s1, iptr->sx.val.i, d);
811                         emit_store_dst(jd, iptr, d);
812                         break;
813                         
814                 case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
815                                       /* val.i = constant                             */
816
817                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
818                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
819                         M_SLLX_IMM(s1, iptr->sx.val.i, d);
820                         emit_store_dst(jd, iptr, d);
821                         break;
822
823                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
824
825                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
826                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
827                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
828                         M_SRA(s1, s2, d);
829                         emit_store_dst(jd, iptr, d);
830                         break;
831
832                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
833                                       /* sx.val.i = constant                             */
834
835                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
836                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
837                         M_SRA_IMM(s1, iptr->sx.val.i, d);
838                         emit_store_dst(jd, iptr, d);
839                         break;
840
841                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
842
843                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
844                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
845                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
846                         M_SRL(s1, s2, d);
847                         emit_store_dst(jd, iptr, d);
848                         break;
849
850                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
851                                       /* sx.val.i = constant                             */
852
853                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855                         M_SRL_IMM(s1, iptr->sx.val.i, d);
856                         emit_store_dst(jd, iptr, d);
857                         break;
858
859                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
860
861                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
862                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
863                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
864                         M_SRAX(s1, s2, d);
865                         emit_store_dst(jd, iptr, d);
866                         break;
867
868                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
869                                       /* sx.val.i = constant                             */
870
871                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
872                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
873                         M_SRAX_IMM(s1, iptr->sx.val.i, d);
874                         emit_store_dst(jd, iptr, d);
875                         break;
876
877                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
878
879                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
880                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
881                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
882                         M_SRLX(s1, s2, d);
883                         emit_store_dst(jd, iptr, d);
884                         break;
885
886                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
887                                       /* sx.val.i = constant                             */
888
889                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
890                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
891                         M_SRLX_IMM(s1, iptr->sx.val.i, d);
892                         emit_store_dst(jd, iptr, d);
893                         break;
894
895                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
896                 case ICMD_LAND:
897
898                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
899                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
900                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
901                         M_AND(s1, s2, d);
902                         emit_store_dst(jd, iptr, d);
903                         break;
904
905                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
906                                       /* sx.val.i = constant                             */
907
908                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
909                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
910                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
911                                 M_AND_IMM(s1, iptr->sx.val.i, d);
912                         } else {
913                                 ICONST(REG_ITMP2, iptr->sx.val.i);
914                                 M_AND(s1, REG_ITMP2, d);
915                         }
916                         emit_store_dst(jd, iptr, d);
917                         break;
918
919                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant           */
920                                       /* sx.val.i = constant                             */
921                                       /* constant is actually constant - 1               */
922
923                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
924                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
925                         if (s1 == d) {
926                                 M_MOV(s1, REG_ITMP1);
927                                 s1 = REG_ITMP1;
928                         }
929                         M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
930                         if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
931                                 M_AND_IMM(s1, iptr->sx.val.i, d);
932                                 M_BGEZ(s1, 5);
933                                 M_NOP;
934                                 M_SUB(REG_ZERO, s1, d);
935                                 M_AND_IMM(d, iptr->sx.val.i, d);
936                         } else {
937                                 ICONST(REG_ITMP2, iptr->sx.val.i);
938                                 M_AND(s1, REG_ITMP2, d);
939                                 M_BGEZ(s1, 5);
940                                 M_NOP;
941                                 M_SUB(REG_ZERO, s1, d);
942                                 M_AND(d, REG_ITMP2, d);
943                         }
944                         M_SUB(REG_ZERO, d, d);
945                         emit_store_dst(jd, iptr, d);
946                         break;
947
948                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
949                                       /* sx.val.l = constant                             */
950
951                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
952                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
953                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
954                                 M_AND_IMM(s1, iptr->sx.val.l, d);
955                         } else {
956                                 LCONST(REG_ITMP2, iptr->sx.val.l);
957                                 M_AND(s1, REG_ITMP2, d);
958                         }
959                         emit_store_dst(jd, iptr, d);
960                         break;
961
962                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
963                                       /* sx.val.l = constant                             */
964
965                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
966                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
967                         if (s1 == d) {
968                                 M_MOV(s1, REG_ITMP1);
969                                 s1 = REG_ITMP1;
970                         }
971                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
972                                 M_AND_IMM(s1, iptr->sx.val.l, d);
973                                 M_BGEZ(s1, 4);
974                                 M_NOP;
975                                 M_SUB(REG_ZERO, s1, d);
976                                 M_AND_IMM(d, iptr->sx.val.l, d);
977                         } else {
978                                 LCONST(REG_ITMP2, iptr->sx.val.l);
979                                 M_AND(s1, REG_ITMP2, d);
980                                 M_BGEZ(s1, 4);
981                                 M_NOP;
982                                 M_SUB(REG_ZERO, s1, d);
983                                 M_AND(d, REG_ITMP2, d);
984                         }
985                         M_SUB(REG_ZERO, d, d);
986                         emit_store_dst(jd, iptr, d);
987                         break;
988
989                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
990                 case ICMD_LOR:
991
992                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
993                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
994                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
995                         M_OR(s1,s2, d);
996                         emit_store_dst(jd, iptr, d);
997                         break;
998
999                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1000                                       /* sx.val.i = constant                             */
1001
1002                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1003                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1004                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1005                                 M_OR_IMM(s1, iptr->sx.val.i, d);
1006                         } else {
1007                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1008                                 M_OR(s1, REG_ITMP2, d);
1009                         }
1010                         emit_store_dst(jd, iptr, d);
1011                         break;
1012
1013                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1014                                       /* sx.val.l = constant                             */
1015
1016                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1017                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1018                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1019                                 M_OR_IMM(s1, iptr->sx.val.l, d);
1020                         } else {
1021                                 LCONST(REG_ITMP2, iptr->sx.val.l);
1022                                 M_OR(s1, REG_ITMP2, d);
1023                         }
1024                         emit_store_dst(jd, iptr, d);
1025                         break;
1026
1027                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1028                 case ICMD_LXOR:
1029
1030                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1031                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1032                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1033                         M_XOR(s1, s2, d);
1034                         emit_store_dst(jd, iptr, d);
1035                         break;
1036
1037                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1038                                       /* sx.val.i = constant                             */
1039
1040                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1041                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1042                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1043                                 M_XOR_IMM(s1, iptr->sx.val.i, d);
1044                         } else {
1045                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1046                                 M_XOR(s1, REG_ITMP2, d);
1047                         }
1048                         emit_store_dst(jd, iptr, d);
1049                         break;
1050
1051                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1052                                       /* sx.val.l = constant                             */
1053
1054                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1055                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1056                         if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1057                                 M_XOR_IMM(s1, iptr->sx.val.l, d);
1058                         } else {
1059                                 LCONST(REG_ITMP2, iptr->sx.val.l);
1060                                 M_XOR(s1, REG_ITMP2, d);
1061                         }
1062                         emit_store_dst(jd, iptr, d);
1063                         break;
1064
1065
1066                 case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
1067
1068                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1069                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1070                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071                         M_CMP(s1, s2);
1072                         M_MOV(REG_ZERO, d);
1073                         M_XCMOVLT_IMM(-1, d);
1074                         M_XCMOVGT_IMM(1, d);
1075                         emit_store_dst(jd, iptr, d);
1076                         break;
1077
1078
1079                 /* floating operations ************************************************/
1080
1081                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1082
1083                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1084                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1085                         M_FNEG(s1, d);
1086                         emit_store_dst(jd, iptr, d);
1087                         break;
1088
1089                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1090
1091                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1092                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1093                         M_DNEG(s1, d);
1094                         emit_store_dst(jd, iptr, d);
1095                         break;
1096
1097                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1098
1099                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1100                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1101                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1102                         M_FADD(s1, s2, d);
1103                         emit_store_dst(jd, iptr, d);
1104                         break;
1105
1106                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1107
1108                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1109                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1110                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1111                         M_DADD(s1, s2, d);
1112                         emit_store_dst(jd, iptr, d);
1113                         break;
1114
1115                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1116
1117                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1118                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1119                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1120                         M_FSUB(s1, s2, d);
1121                         emit_store_dst(jd, iptr, d);
1122                         break;
1123
1124                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1125
1126                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1127                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1128                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1129                         M_DSUB(s1, s2, d);
1130                         emit_store_dst(jd, iptr, d);
1131                         break;
1132
1133                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1134
1135                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1136                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1137                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1138                         M_FMUL(s1, s2, d);
1139                         emit_store_dst(jd, iptr, d);
1140                         break;
1141
1142                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 *** val2      */
1143
1144                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1145                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1146                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1147                         M_DMUL(s1, s2, d);
1148                         emit_store_dst(jd, iptr, d);
1149                         break;
1150
1151                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1152
1153                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1154                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1155                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1156                         M_FDIV(s1, s2, d);
1157                         emit_store_dst(jd, iptr, d);
1158                         break;
1159
1160                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1161
1162                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1163                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1164                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1165                         M_DDIV(s1, s2, d);
1166                         emit_store_dst(jd, iptr, d);
1167                         break;  
1168
1169                 case ICMD_I2F:
1170                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1171                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1172                         disp = dseg_add_unique_float(cd, 0.0);
1173                         M_IST (s1, REG_PV_CALLEE, disp);
1174                         M_FLD (d, REG_PV_CALLEE, disp);
1175                         M_CVTIF (d, d); /* rd gets translated to double target register */
1176                         emit_store_dst(jd, iptr, d);
1177                         break;
1178                         
1179                 case ICMD_I2D:
1180                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1181                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1182                         disp = dseg_add_unique_float(cd, 0.0);
1183                         M_IST(s1, REG_PV_CALLEE, disp);
1184                         M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1185                         M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1186                         emit_store_dst(jd, iptr, d);
1187                         break;
1188                         
1189                 case ICMD_L2F:
1190                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1191                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1192                         disp = dseg_add_unique_double(cd, 0.0);
1193                         M_STX(s1, REG_PV_CALLEE, disp);
1194                         M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1195                         M_CVTLF(REG_FTMP3, d);
1196                         emit_store_dst(jd, iptr, d);
1197                         break;
1198                         
1199                 case ICMD_L2D:
1200                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1201                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1202                         disp = dseg_add_unique_double(cd, 0.0);
1203                         M_STX(s1, REG_PV_CALLEE, disp);
1204                         M_DLD(d, REG_PV_CALLEE, disp);
1205                         M_CVTLD(d, d);
1206                         emit_store_dst(jd, iptr, d);
1207                         break;
1208
1209                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1210                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1211                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1212                         disp = dseg_add_unique_float(cd, 0.0);
1213                         
1214                         /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
1215                         M_FCMP(s1, s1);
1216                         M_FBU(5);
1217                         M_MOV(REG_ZERO, d); /* delay slot */
1218                         
1219                         M_CVTFI(s1, REG_FTMP2);
1220                         M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1221                         M_ILD(d, REG_PV, disp);
1222                         emit_store_dst(jd, iptr, d);
1223                         break;
1224                         
1225                                
1226                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value             */
1227                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1228                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1229                         disp = dseg_add_unique_float(cd, 0.0);
1230                         
1231                         /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
1232                         M_DCMP(s1, s1);
1233                         M_FBU(5);
1234                         M_MOV(REG_ZERO, d); /* delay slot */
1235                         
1236                         M_CVTDI(s1, REG_FTMP2);
1237                         M_FST(REG_FTMP2, REG_PV, disp);
1238                         M_ILD(d, REG_PV, disp);
1239                         emit_store_dst(jd, iptr, d);
1240                         break;
1241
1242                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
1243                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1244                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1245                         disp = dseg_add_unique_double(cd, 0.0);
1246                         
1247                         /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
1248                         M_FCMP(s1, s1);
1249                         M_FBU(5);
1250                         M_MOV(REG_ZERO, d); /* delay slot */
1251                         
1252                         M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1253                         M_DST(REG_FTMP2, REG_PV, disp);
1254                         M_LDX(d, REG_PV, disp);
1255                         emit_store_dst(jd, iptr, d);
1256                         break;
1257                         
1258                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
1259                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1260                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1261                         disp = dseg_add_unique_double(cd, 0.0);
1262                         
1263                         /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
1264                         M_DCMP(s1, s1);
1265                         M_FBU(5);
1266                         M_MOV(REG_ZERO, d); /* delay slot */
1267                         
1268                         M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1269                         M_DST(REG_FTMP2, REG_PV, disp);
1270                         M_LDX(d, REG_PV, disp);
1271                         emit_store_dst(jd, iptr, d);
1272                         break;
1273
1274                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1275
1276                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1277                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1278                         M_CVTFD(s1, d);
1279                         emit_store_dst(jd, iptr, d);
1280                         break;
1281                                         
1282                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
1283
1284                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1285                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1286                         M_CVTDF(s1, d);
1287                         emit_store_dst(jd, iptr, d);
1288                         break;
1289         
1290         /* XXX merge F/D versions? only compare instr. is different */
1291                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1292
1293                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1294                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1295                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1296                         M_FCMP(s1,s2);
1297                         M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1298                         M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1299                         M_CMOVFGT_IMM(1, d); /* 1 if greater */
1300                         emit_store_dst(jd, iptr, d);
1301                         break;
1302                         
1303                 case ICMD_DCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1304
1305                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1306                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1307                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1308                         M_DCMP(s1,s2);
1309                         M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1310                         M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1311                         M_CMOVFGT_IMM(1, d); /* 1 if greater */
1312                         emit_store_dst(jd, iptr, d);
1313                         break;
1314                         
1315                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1316
1317                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1318                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1319                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);    
1320                         M_FCMP(s1,s2);
1321                         M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1322                         M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1323                         M_CMOVFLT_IMM(-1, d); /* -1 if less */
1324                         emit_store_dst(jd, iptr, d);
1325                         break;
1326                         
1327                 case ICMD_DCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1328
1329                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1330                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1331                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);    
1332                         M_DCMP(s1,s2);
1333                         M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1334                         M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1335                         M_CMOVFLT_IMM(-1, d); /* -1 if less */
1336                         emit_store_dst(jd, iptr, d);
1337                         break;
1338                         
1339
1340                 /* memory operations **************************************************/
1341
1342                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1343
1344                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1345                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1346                         emit_nullpointer_check(cd, iptr, s1);
1347                         M_ILD(d, s1, OFFSET(java_array_t, size));
1348                         emit_store_dst(jd, iptr, d);
1349                         break;
1350
1351                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1352
1353                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1354                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1355                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1356                         /* implicit null-pointer check */
1357                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1358                         M_AADD(s2, s1, REG_ITMP3);
1359                         M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1360                         emit_store_dst(jd, iptr, d);
1361                         break;
1362
1363                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1364
1365                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1366                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1367                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1368                         /* implicit null-pointer check */
1369                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1370                         M_AADD(s2, s1, REG_ITMP3);
1371                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1372                         M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1373                         emit_store_dst(jd, iptr, d);
1374                         break;                  
1375
1376                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1377
1378                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1379                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1380                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1381                         /* implicit null-pointer check */
1382                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1383                         M_AADD(s2, s1, REG_ITMP3);
1384                         M_AADD(s2, REG_ITMP3, REG_ITMP3);
1385                         M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1386                         emit_store_dst(jd, iptr, d);
1387                         break;
1388
1389                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1390
1391                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1392                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1393                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1394                         /* implicit null-pointer check */
1395                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1396                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1397                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1398                         M_ILD(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1399                         emit_store_dst(jd, iptr, d);
1400                         break;
1401
1402                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1403
1404                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1405                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1406                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1407                         /* implicit null-pointer check */
1408                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1409                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1410                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1411                         M_LDX(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1412                         emit_store_dst(jd, iptr, d);
1413                         break;
1414
1415                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1416
1417                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1418                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1419                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1420                         /* implicit null-pointer check */
1421                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1422                         M_ASLL_IMM(s2, 2, REG_ITMP3);
1423                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1424                         M_FLD(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1425                         emit_store_dst(jd, iptr, d);
1426                         break;
1427
1428                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1429
1430                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1431                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1432                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1433                         /* implicit null-pointer check */
1434                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1435                         M_ASLL_IMM(s2, 3, REG_ITMP3);
1436                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1437                         M_DLD(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1438                         emit_store_dst(jd, iptr, d);
1439                         break;
1440
1441                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
1442
1443                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1444                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1445                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1446                         /* implicit null-pointer check */
1447                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1448                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1449                         M_AADD(REG_ITMP3, s1, REG_ITMP3);
1450                         M_ALD(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1451                         emit_store_dst(jd, iptr, d);
1452                         break;
1453
1454         
1455                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
1456
1457                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1458                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1459                         /* implicit null-pointer check */
1460                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1461                         M_AADD(s2, s1, REG_ITMP1);
1462                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1463                         M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1464                         break;
1465
1466                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
1467                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
1468
1469                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1470                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1471                         /* implicit null-pointer check */
1472                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1473                         M_AADD(s2, s1, REG_ITMP1);
1474                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1475                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1476                         M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1477                         break;
1478
1479                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
1480
1481                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1482                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1483                         /* implicit null-pointer check */
1484                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1485                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1486                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1487                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1488                         M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1489                         break;
1490
1491                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
1492
1493                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1494                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1495                         /* implicit null-pointer check */
1496                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1497                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1498                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1499                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1500                         M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1501                         break;
1502
1503                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
1504
1505                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1506                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1507                         /* implicit null-pointer check */
1508                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1509                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1510                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1511                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1512                         M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1513                         break;
1514
1515                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
1516
1517                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1518                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1519                         /* implicit null-pointer check */
1520                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1521                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1522                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1523                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1524                         M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1525                         break;
1526
1527
1528                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
1529
1530                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1531                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1532                         /* implicit null-pointer check */
1533                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1534                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1535
1536                         M_MOV(s1, REG_OUT0);
1537                         M_MOV(s3, REG_OUT1);
1538                         disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1539                         M_ALD(REG_ITMP3, REG_PV, disp);
1540                         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1541                         M_NOP;
1542                         emit_arraystore_check(cd, iptr);
1543
1544                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1545                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1546                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1547                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1548                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1549                         /* implicit null-pointer check */
1550                         M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1551                         break;
1552
1553
1554                 case ICMD_BASTORECONST:   /* ..., arrayref, index  ==> ...            */
1555
1556                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1557                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1558                         /* implicit null-pointer check */
1559                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1560                         M_AADD(s2, s1, REG_ITMP1);
1561                         M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1562                         break;
1563
1564                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
1565                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
1566
1567                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1568                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1569                         /* implicit null-pointer check */
1570                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1571                         M_AADD(s2, s1, REG_ITMP1);
1572                         M_AADD(s2, REG_ITMP1, REG_ITMP1);
1573                         M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1574                         break;
1575
1576                 case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
1577
1578                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1579                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1580                         /* implicit null-pointer check */
1581                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1582                         M_ASLL_IMM(s2, 2, REG_ITMP2);
1583                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1584                         M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1585                         break;
1586
1587                 case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
1588
1589                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1590                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1591                         /* implicit null-pointer check */
1592                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1593                         M_ASLL_IMM(s2, 3, REG_ITMP2);
1594                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1595                         M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1596                         break;
1597
1598                 case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
1599
1600                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1601                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1602                         /* implicit null-pointer check */
1603                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1604                         M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1605                         M_AADD(REG_ITMP2, s1, REG_ITMP1);
1606                         M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1607                         break;
1608                 
1609
1610                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
1611
1612                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1613                                 uf        = iptr->sx.s23.s3.uf;
1614                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1615                                 disp      = dseg_add_unique_address(cd, uf);
1616
1617                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1618                         } 
1619                         else {
1620                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1621                                 fieldtype = fi->type;
1622                                 disp      = dseg_add_address(cd, fi->value);
1623
1624                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1625                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
1626                         }
1627
1628                         M_ALD(REG_ITMP1, REG_PV, disp);
1629
1630                         switch (fieldtype) {
1631                         case TYPE_INT:
1632                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1633                                 M_ILD_INTERN(d, REG_ITMP1, 0);
1634                                 break;
1635                         case TYPE_LNG:
1636                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1637                                 M_LDX_INTERN(d, REG_ITMP1, 0);
1638                                 break;
1639                         case TYPE_ADR:
1640                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1641                                 M_ALD_INTERN(d, REG_ITMP1, 0);
1642                                 break;
1643                         case TYPE_FLT:
1644                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1645                                 M_FLD_INTERN(d, REG_ITMP1, 0);
1646                                 break;
1647                         case TYPE_DBL:                          
1648                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1649                                 M_DLD_INTERN(d, REG_ITMP1, 0);
1650                                 break;
1651                         }
1652                         emit_store_dst(jd, iptr, d);
1653                         break;
1654
1655                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
1656
1657                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1658                                 uf        = iptr->sx.s23.s3.uf;
1659                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1660                                 disp      = dseg_add_unique_address(cd, uf);
1661
1662                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1663                         } 
1664                         else {
1665                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1666                                 fieldtype = fi->type;
1667                                 disp      = dseg_add_address(cd, fi->value);
1668
1669                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1670                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
1671                         }
1672
1673                         M_ALD(REG_ITMP1, REG_PV, disp);
1674
1675                         switch (fieldtype) {
1676                         case TYPE_INT:
1677                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1678                                 M_IST_INTERN(s1, REG_ITMP1, 0);
1679                                 break;
1680                         case TYPE_LNG:
1681                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1682                                 M_STX_INTERN(s1, REG_ITMP1, 0);
1683                                 break;
1684                         case TYPE_ADR:
1685                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1686                                 M_AST_INTERN(s1, REG_ITMP1, 0);
1687                                 break;
1688                         case TYPE_FLT:
1689                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1690                                 M_FST_INTERN(s1, REG_ITMP1, 0);
1691                                 break;
1692                         case TYPE_DBL:
1693                                 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1694                                 M_DST_INTERN(s1, REG_ITMP1, 0);
1695                                 break;
1696                         }
1697                         break;
1698
1699                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
1700                                           /* val = value (in current instruction)     */
1701                                           /* following NOP)                           */
1702
1703                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1704                                 uf        = iptr->sx.s23.s3.uf;
1705                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1706                                 disp      = dseg_add_unique_address(cd, uf);
1707
1708                                 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1709                         } 
1710                         else {
1711                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1712                                 fieldtype = fi->type;
1713                                 disp      = dseg_add_address(cd, fi->value);
1714
1715                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1716                                         codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
1717                         }
1718
1719                         M_ALD(REG_ITMP1, REG_PV, disp);
1720
1721                         switch (fieldtype) {
1722                         case TYPE_INT:
1723                                 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1724                                 break;
1725                         case TYPE_LNG:
1726                                 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1727                                 break;
1728                         case TYPE_ADR:
1729                                 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1730                                 break;
1731                         case TYPE_FLT:
1732                                 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1733                                 break;
1734                         case TYPE_DBL:
1735                                 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1736                                 break;
1737                         }
1738                         break;
1739
1740
1741                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
1742
1743                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1744                         emit_nullpointer_check(cd, iptr, s1);
1745
1746                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1747                                 uf = iptr->sx.s23.s3.uf;
1748
1749                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1750                                 disp      = 0;
1751
1752                                 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1753                         } 
1754                         else {
1755                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1756                                 fieldtype = fi->type;
1757                                 disp      = fi->offset;
1758                         }
1759
1760                         switch (fieldtype) {
1761                         case TYPE_INT:
1762                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1763                                 M_ILD(d, s1, disp);
1764                                 break;
1765                         case TYPE_LNG:
1766                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1767                                 M_LDX(d, s1, disp);
1768                                 break;
1769                         case TYPE_ADR:
1770                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1771                                 M_ALD(d, s1, disp);
1772                                 break;
1773                         case TYPE_FLT:
1774                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1775                                 M_FLD(d, s1, disp);
1776                                 break;
1777                         case TYPE_DBL:                          
1778                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1779                                 M_DLD(d, s1, disp);
1780                                 break;
1781                         default:
1782                                 assert(0);
1783                                 break;
1784                         }
1785                         emit_store_dst(jd, iptr, d);
1786                         break;
1787
1788                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
1789
1790                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1791                         emit_nullpointer_check(cd, iptr, s1);
1792
1793                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1794                                 uf = iptr->sx.s23.s3.uf;
1795                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1796                                 disp      = 0;
1797                         }
1798                         else {
1799                                 uf        = NULL;
1800                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
1801                                 fieldtype = fi->type;
1802                                 disp      = fi->offset;
1803                                 }
1804
1805                         if (IS_INT_LNG_TYPE(fieldtype))
1806                                 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1807                         else
1808                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1809
1810                         if (INSTRUCTION_IS_UNRESOLVED(iptr))
1811                                 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1812
1813                         switch (fieldtype) {
1814                         case TYPE_INT:
1815                                 M_IST(s2, s1, disp);
1816                                 break;
1817                         case TYPE_LNG:
1818                                 M_STX(s2, s1, disp);
1819                                 break;
1820                         case TYPE_ADR:
1821                                 M_AST(s2, s1, disp);
1822                                 break;
1823                         case TYPE_FLT:
1824                                 M_FST(s2, s1, disp);
1825                                 break;
1826                         case TYPE_DBL:
1827                                 M_DST(s2, s1, disp);
1828                                 break;
1829                         default:
1830                                 assert(0);
1831                                 break;
1832                         }
1833                         break;
1834
1835                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
1836                                           /* val = value (in current instruction)     */
1837                                           /* following NOP)                           */
1838
1839                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1840                         emit_nullpointer_check(cd, iptr, s1);
1841
1842                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1843                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
1844
1845                                 fieldtype = uf->fieldref->parseddesc.fd->type;
1846
1847                                 codegen_addpatchref(cd, PATCHER_get_putfield,
1848                                                                         uf, 0);
1849
1850                                 if (opt_showdisassemble) {
1851                                         M_NOP; M_NOP;
1852                                 }
1853
1854                                 disp = 0;
1855
1856                         } else {
1857                         {
1858                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1859
1860                                 fieldtype = fi->type;
1861                                 disp = fi->offset;
1862                         }
1863
1864                         }
1865
1866                         switch (fieldtype) {
1867                         case TYPE_INT:
1868                                 M_IST(REG_ZERO, s1, disp);
1869                                 break;
1870                         case TYPE_LNG:
1871                                 M_STX(REG_ZERO, s1, disp);
1872                                 break;
1873                         case TYPE_ADR:
1874                                 M_AST(REG_ZERO, s1, disp);
1875                                 break;
1876                         case TYPE_FLT:
1877                                 M_FST(REG_ZERO, s1, disp);
1878                                 break;
1879                         case TYPE_DBL:
1880                                 M_DST(REG_ZERO, s1, disp);
1881                                 break;
1882                         }
1883                         break;
1884
1885
1886                 /* branch operations **************************************************/
1887
1888                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
1889
1890                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1891                         M_INTMOVE(s1, REG_ITMP2_XPTR);
1892
1893 #ifdef ENABLE_VERIFIER
1894                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1895                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
1896
1897                                 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1898                         }
1899 #endif /* ENABLE_VERIFIER */
1900
1901                         disp = dseg_add_functionptr(cd, asm_handle_exception);
1902                         M_ALD(REG_ITMP1, REG_PV, disp);
1903                         M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1904                         M_NOP;
1905                         M_NOP;              /* nop ensures that XPC is less than the end */
1906                                             /* of basic block                            */
1907                         ALIGNCODENOP;
1908                         break;
1909
1910                 case ICMD_GOTO:         /* ... ==> ...                                */
1911                 case ICMD_RET:          /* ... ==> ...                                */
1912
1913                         emit_br(cd, iptr->dst.block);
1914                         ALIGNCODENOP;
1915                         break;
1916
1917                 case ICMD_JSR:          /* ... ==> ...                                */
1918
1919                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1920                         ALIGNCODENOP;
1921                         break;
1922
1923                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1924                 case ICMD_IFNONNULL:
1925
1926                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1927                         emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1928                         break;
1929                         
1930                 /* Note: int compares must not branch on the register directly.       */
1931                 /* Reason is, that register content is not 32-bit clean.              */
1932
1933                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
1934
1935                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1936                         
1937                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1938                                 M_CMP_IMM(s1, iptr->sx.val.i);
1939                         }
1940                         else {
1941                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1942                                 M_CMP(s1, REG_ITMP2);
1943                         }
1944                         emit_beq(cd, iptr->dst.block);
1945                         break;
1946
1947                 case ICMD_IFLT:         /* ..., value ==> ...                         */
1948
1949                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1950                         
1951                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1952                                 M_CMP_IMM(s1, iptr->sx.val.i);
1953                         } 
1954                         else {
1955                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1956                                 M_CMP(s1, REG_ITMP2);
1957                         }
1958                         emit_blt(cd, iptr->dst.block);
1959                         break;
1960
1961                 case ICMD_IFLE:         /* ..., value ==> ...                         */
1962
1963                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1964
1965                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1966                                 M_CMP_IMM(s1, iptr->sx.val.i);
1967                         }
1968                         else {
1969                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1970                                 M_CMP(s1, REG_ITMP2);
1971                         }
1972                         emit_ble(cd, iptr->dst.block);
1973                         break;
1974
1975                 case ICMD_IFNE:         /* ..., value ==> ...                         */
1976
1977                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1978                 
1979                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1980                                 M_CMP_IMM(s1, iptr->sx.val.i);
1981                         }
1982                         else {
1983                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1984                                 M_CMP(s1, REG_ITMP2);
1985                         }
1986                         emit_bne(cd, iptr->dst.block);
1987                         break;
1988                                                 
1989                 case ICMD_IFGT:         /* ..., value ==> ...                         */
1990
1991                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1992                 
1993                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1994                                 M_CMP_IMM(s1, iptr->sx.val.i);
1995                         } 
1996                         else {
1997                                 ICONST(REG_ITMP2, iptr->sx.val.i);
1998                                 M_CMP(s1, REG_ITMP2);
1999                         }
2000                         emit_bgt(cd, iptr->dst.block);          
2001                         break;
2002
2003                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2004
2005                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2006
2007                         if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2008                                 M_CMP_IMM(s1, iptr->sx.val.i);
2009                         }
2010                         else {
2011                                 ICONST(REG_ITMP2, iptr->sx.val.i);
2012                                 M_CMP(s1, REG_ITMP2);
2013                         }
2014                         emit_bge(cd, iptr->dst.block);
2015                         break;
2016                         
2017                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2018
2019                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2020                         if (iptr->sx.val.l == 0)
2021                                 emit_beqz(cd, iptr->dst.block, s1);
2022                         else {
2023                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2024                                         M_CMP_IMM(s1, iptr->sx.val.l);
2025                                 }
2026                                 else {
2027                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2028                                         M_CMP(s1, REG_ITMP2);
2029                                 }
2030                                 emit_beq_xcc(cd, iptr->dst.block);
2031                         }
2032                         break;
2033                         
2034                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2035
2036                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2037                         if (iptr->sx.val.l == 0)
2038                                 emit_bltz(cd, iptr->dst.block, s1);
2039                         else {
2040                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2041                                         M_CMP_IMM(s1, iptr->sx.val.l);
2042                                 } 
2043                                 else {
2044                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2045                                         M_CMP(s1, REG_ITMP2);
2046                                 }
2047                                 emit_blt_xcc(cd, iptr->dst.block);
2048                         }
2049                         break;
2050
2051                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2052
2053                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2054                         if (iptr->sx.val.l == 0)
2055                                 emit_blez(cd, iptr->dst.block, s1);
2056                         else {
2057                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2058                                         M_CMP_IMM(s1, iptr->sx.val.l);
2059                                 }
2060                                 else {
2061                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2062                                         M_CMP(s1, REG_ITMP2);
2063                                 }
2064                                 emit_ble_xcc(cd, iptr->dst.block);
2065                         }
2066                         break;
2067                         
2068                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2069
2070                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2071                         if (iptr->sx.val.l == 0)
2072                                 emit_bnez(cd, iptr->dst.block, s1);
2073                         else {
2074                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2075                                         M_CMP_IMM(s1, iptr->sx.val.l);
2076                                 }
2077                                 else {
2078                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2079                                         M_CMP(s1, REG_ITMP2);
2080                                 }
2081                                 emit_bne_xcc(cd, iptr->dst.block);
2082                         }
2083                         break;
2084                                                 
2085                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2086
2087                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2088                         if (iptr->sx.val.l == 0)
2089                                 emit_bgtz(cd, iptr->dst.block, s1);
2090                         else {
2091                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2092                                         M_CMP_IMM(s1, iptr->sx.val.l);
2093                                 } 
2094                                 else {
2095                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2096                                         M_CMP(s1, REG_ITMP2);
2097                                 }
2098                                 emit_bgt_xcc(cd, iptr->dst.block);
2099                         }
2100                         break;
2101
2102                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2103
2104                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2105                         if (iptr->sx.val.l == 0)
2106                                 emit_bgez(cd, iptr->dst.block, s1);
2107                         else {
2108                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2109                                         M_CMP_IMM(s1, iptr->sx.val.l);
2110                                 }
2111                                 else {
2112                                         LCONST(REG_ITMP2, iptr->sx.val.l);
2113                                         M_CMP(s1, REG_ITMP2);
2114                                 }
2115                                 emit_bge_xcc(cd, iptr->dst.block);
2116                         }
2117                         break;                  
2118                         
2119
2120                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
2121                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2122
2123                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2124                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2125                         M_CMP(s1, s2);
2126                         emit_beq_xcc(cd, iptr->dst.block);
2127                         break;
2128
2129                 case ICMD_IF_ICMPEQ:    /* 32-bit compare                             */
2130
2131                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2132                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2133                         M_CMP(s1, s2);
2134                         emit_beq(cd, iptr->dst.block);
2135                         break;
2136
2137                 case ICMD_IF_ACMPNE:    /* ..., value, value ==> ...                  */
2138                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2139
2140                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2141                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2142                         M_CMP(s1, s2);
2143                         emit_bne_xcc(cd, iptr->dst.block);
2144                         break;
2145                         
2146                 case ICMD_IF_ICMPNE:    /* 32-bit compare                             */
2147
2148                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2149                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2150                         M_CMP(s1, s2);
2151                         emit_bne(cd, iptr->dst.block);
2152                         break;
2153
2154                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2155
2156                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2157                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2158                         M_CMP(s1, s2);
2159                         emit_blt_xcc(cd, iptr->dst.block);
2160                         break;
2161                         
2162                 case ICMD_IF_ICMPLT:    /* 32-bit compare                             */
2163
2164                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2165                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2166                         M_CMP(s1, s2);
2167                         emit_blt(cd, iptr->dst.block);
2168                         break;
2169
2170                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2171
2172                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2173                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2174                         M_CMP(s1, s2);
2175                         emit_bgt_xcc(cd, iptr->dst.block);
2176                         break;
2177                         
2178                 case ICMD_IF_ICMPGT:    /* 32-bit compare                             */
2179
2180                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2181                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2182                         M_CMP(s1, s2);
2183                         emit_bgt(cd, iptr->dst.block);
2184                         break;
2185
2186                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2187
2188                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2189                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2190                         M_CMP(s1, s2);
2191                         emit_ble_xcc(cd, iptr->dst.block);
2192                         break;
2193                         
2194                 case ICMD_IF_ICMPLE:    /* 32-bit compare                             */
2195
2196                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2197                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2198                         M_CMP(s1, s2);
2199                         emit_ble(cd, iptr->dst.block);
2200                         break;                  
2201         
2202
2203                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2204
2205                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2206                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2207                         M_CMP(s1, s2);
2208                         emit_bge_xcc(cd, iptr->dst.block);
2209                         break;
2210                         
2211                 case ICMD_IF_ICMPGE:    /* 32-bit compare                             */
2212
2213                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2214                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2215                         M_CMP(s1, s2);
2216                         emit_bge(cd, iptr->dst.block);
2217                         break;
2218
2219
2220                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2221                 case ICMD_LRETURN:
2222
2223                         REPLACEMENT_POINT_RETURN(cd, iptr);
2224
2225                         s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2226                         M_INTMOVE(s1, REG_RESULT_CALLEE);
2227                         goto nowperformreturn;
2228
2229                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2230
2231                         REPLACEMENT_POINT_RETURN(cd, iptr);
2232
2233                         s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2234                         M_INTMOVE(s1, REG_RESULT_CALLEE);
2235
2236 #ifdef ENABLE_VERIFIER
2237                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2238                                 unresolved_class *uc = iptr->sx.s23.s2.uc;
2239
2240                                 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2241                         }
2242 #endif /* ENABLE_VERIFIER */
2243                         goto nowperformreturn;
2244
2245                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2246                 case ICMD_DRETURN:
2247
2248                         REPLACEMENT_POINT_RETURN(cd, iptr);
2249
2250                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2251                         M_DBLMOVE(s1, REG_FRESULT);
2252                         goto nowperformreturn;
2253
2254                 case ICMD_RETURN:       /* ...  ==> ...                               */
2255                         
2256                         REPLACEMENT_POINT_RETURN(cd, iptr);
2257
2258 nowperformreturn:
2259                         {
2260                         s4 i, p;
2261                         
2262                         p = cd->stackframesize;
2263
2264 #if !defined(NDEBUG)
2265                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2266                                 emit_verbosecall_exit(jd);
2267 #endif
2268
2269 #if defined(ENABLE_THREADS)
2270                         if (checksync && code_is_synchronized(code)) {
2271                                 /* XXX jit-c-call */
2272                                 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2273                                 M_ALD(REG_ITMP3, REG_PV, disp);
2274
2275                                 /* we need to save fp return value (int saved by window) */
2276
2277                                 switch (iptr->opc) {
2278                                 case ICMD_FRETURN:
2279                                 case ICMD_DRETURN:
2280                                         M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2281                                         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2282                                         M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2283
2284                                         /* restore the fp return value */
2285
2286                                         M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2287                                         break;
2288                                 case ICMD_IRETURN:
2289                                 case ICMD_LRETURN:
2290                                 case ICMD_ARETURN:
2291                                 case ICMD_RETURN:
2292                                         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2293                                         M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2294                                         break;
2295                                 default:
2296                                         assert(false);
2297                                         break;
2298                                 }
2299                         }
2300 #endif
2301
2302
2303
2304                         M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2305                         M_NOP;
2306                         ALIGNCODENOP;
2307                         }
2308                         break;
2309
2310                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2311                         {
2312                         s4 i, l;
2313                         branch_target_t *table;
2314
2315                         table = iptr->dst.table;
2316
2317                         l = iptr->sx.s23.s2.tablelow;
2318                         i = iptr->sx.s23.s3.tablehigh;
2319                         
2320                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2321                         if (l == 0) {
2322                                 M_INTMOVE(s1, REG_ITMP1);
2323                         }
2324                         else if (-l >= 4096 && -l <= 4095) {
2325                                 M_ADD_IMM(s1, -l, REG_ITMP1);
2326                         }
2327                         else {
2328                                 ICONST(REG_ITMP2, l);
2329                                 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2330                         }
2331
2332                         i = i - l + 1; /* number of targets (>0) */
2333
2334
2335                         /* range check */
2336                                         
2337                         if (i <= 4095) {
2338                                 M_CMP_IMM(REG_ITMP1, i - 1);
2339                         }
2340                         else {
2341                                 ICONST(REG_ITMP2, i - 1);
2342                                 M_CMP(REG_ITMP1, REG_ITMP2);
2343                         }               
2344                         emit_bugt(cd, table[0].block); /* default target */
2345
2346                         /* build jump table top down and use address of lowest entry */
2347
2348                         table += i;
2349
2350                         while (--i >= 0) {
2351                                 dseg_add_target(cd, table->block); 
2352                                 --table;
2353                                 }
2354                         }
2355
2356                         /* length of dataseg after last dseg_addtarget is used by load */
2357
2358                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2359                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2360                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2361                         M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2362                         M_NOP;
2363                         ALIGNCODENOP;
2364                         break;
2365                         
2366                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2367                         {
2368                         s4 i;
2369                         lookup_target_t *lookup;
2370
2371                         lookup = iptr->dst.lookup;
2372
2373                         i = iptr->sx.s23.s2.lookupcount;
2374                         
2375                         MCODECHECK((i<<2)+8);
2376                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2377
2378                         while (--i >= 0) {
2379                                 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2380                                         M_CMP_IMM(s1, lookup->value);
2381                                 } else {                                        
2382                                         ICONST(REG_ITMP2, lookup->value);
2383                                         M_CMP(s1, REG_ITMP2);
2384                                 }
2385                                 emit_beq(cd, lookup->target.block);
2386                                 ++lookup;
2387                         }
2388
2389                         emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2390                         ALIGNCODENOP;
2391                         break;
2392                         }
2393
2394
2395                 case ICMD_BUILTIN:      /* ..., arg1, arg2, arg3 ==> ...              */
2396
2397                         REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2398
2399                         bte = iptr->sx.s23.s3.bte;
2400                         md = bte->md;
2401                         
2402                         /* XXX: builtin calling with stack arguments not implemented */
2403                         assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2404                         
2405                         s3 = md->paramcount;
2406
2407                         MCODECHECK((s3 << 1) + 64);
2408
2409 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2410
2411                         /* copy float arguments according to ABI convention */
2412
2413                         int num_fltregargs = 0;
2414                         int fltregarg_inswap[16];
2415
2416                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2417                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2418
2419                                 if (IS_FLT_DBL_TYPE(var->type)) {
2420                                         if (!md->params[s3].inmemory) {
2421                                                 s1 = s3; /*native flt args use argument index directly*/
2422                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2423                                                 
2424                                                 M_DMOV(d, s1 + 16);
2425                                                 fltregarg_inswap[num_fltregargs] = s1;
2426                                                 num_fltregargs++;
2427                                                 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2428                                         }
2429                                         else {
2430                                                 assert(0);
2431                                         }
2432                                 }
2433                         }
2434                         
2435                         int i;
2436                         /* move swapped float args to target regs */
2437                         for (i = 0; i < num_fltregargs; i++) {
2438                                 s1 = fltregarg_inswap[i];
2439                                 M_DMOV(s1 + 16, s1);
2440                                 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2441                         }
2442                         
2443 #else
2444                         assert(md->argfltreguse == 0);
2445 #endif
2446                         
2447                         goto gen_method;
2448
2449                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2450                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2451                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2452                 case ICMD_INVOKEINTERFACE:
2453
2454                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2455
2456                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2457                                 lm = NULL;
2458                                 um = iptr->sx.s23.s3.um;
2459                                 md = um->methodref->parseddesc.md;
2460                         }
2461                         else {
2462                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2463                                 um = NULL;
2464                                 md = lm->parseddesc;
2465                         }
2466
2467 gen_method:
2468                         s3 = md->paramcount;
2469
2470                         MCODECHECK((s3 << 1) + 64);
2471
2472                         /* copy arguments to registers or stack location                  */
2473
2474                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2475                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2476                                 d  = md->params[s3].regoff;
2477
2478                                 if (var->flags & PREALLOC)
2479                                         continue;
2480
2481                                 if (IS_INT_LNG_TYPE(var->type)) {
2482                                         if (!md->params[s3].inmemory) {
2483                                                 s1 = emit_load(jd, iptr, var, d);
2484                                                 M_INTMOVE(s1, d);
2485                                         } 
2486                                         else {
2487                                                 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2488                                                 M_STX(s1, REG_SP, JITSTACK + d);
2489                                         }
2490                                 }
2491                                 else {
2492 #ifdef BUILTIN_FLOAT_ARGS
2493                                         if (iptr->opc == ICMD_BUILTIN)
2494                                                 continue;
2495 #endif
2496                                                 
2497                                         if (!md->params[s3].inmemory) {
2498                                                 s1 = emit_load(jd, iptr, var, d);
2499                                                 if (IS_2_WORD_TYPE(var->type))
2500                                                         M_DMOV(s1, d);
2501                                                 else
2502                                                         M_FMOV(s1, d);
2503                                         }
2504                                         else {
2505                                                 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2506                                                 M_DST(s1, REG_SP, JITSTACK + d);
2507                                         }
2508                                 }
2509                         }
2510
2511                         switch (iptr->opc) {
2512                         case ICMD_BUILTIN:
2513                                 if (bte->stub == NULL) {
2514                                         disp = dseg_add_functionptr(cd, bte->fp);
2515                                 }
2516                                 else {
2517                                         disp = dseg_add_functionptr(cd, bte->stub);
2518                                 }
2519
2520                                 M_ALD(REG_PV_CALLER, REG_PV, disp);  /* built-in-function pointer */
2521
2522                                 /* XXX jit-c-call */
2523                                 /* generate the actual call */
2524     
2525                             M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2526                             M_NOP;
2527                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2528                                 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2529                             disp = (s4) (cd->mcodeptr - cd->mcodebase);
2530                             /* REG_RA holds the value of the jmp instruction, therefore +8 */
2531                             M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
2532
2533                                 if (md->returntype.type == TYPE_FLT) {
2534                                         /* special handling for float return value in %f0 */
2535                                         M_FMOV_INTERN(0,1);
2536                                 }
2537                                 break;
2538
2539                         case ICMD_INVOKESPECIAL:
2540                                 emit_nullpointer_check(cd, iptr, REG_OUT0);
2541                                 /* fall-through */
2542
2543                         case ICMD_INVOKESTATIC:
2544                                 if (lm == NULL) {
2545                                         disp = dseg_add_unique_address(cd, NULL);
2546
2547                                         codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2548                                                                                 um, disp);
2549                                 }
2550                                 else
2551                                         disp = dseg_add_address(cd, lm->stubroutine);
2552
2553                                 M_ALD(REG_PV_CALLER, REG_PV, disp);          /* method pointer in pv */
2554                                 
2555                                 /* generate the actual call */
2556     
2557                             M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2558                             M_NOP;
2559                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2560                             disp = (s4) (cd->mcodeptr - cd->mcodebase);
2561                             /* REG_RA holds the value of the jmp instruction, therefore +8 */
2562                             M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
2563                                 break;
2564
2565                         case ICMD_INVOKEVIRTUAL:
2566                                 emit_nullpointer_check(cd, iptr, REG_OUT0);
2567
2568                                 if (lm == NULL) {
2569                                         codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2570
2571                                         s1 = 0;
2572                                 }
2573                                 else
2574                                         s1 = OFFSET(vftbl_t, table[0]) +
2575                                                 sizeof(methodptr) * lm->vftblindex;
2576
2577                                 /* implicit null-pointer check */
2578                                 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_object_t, vftbl));
2579                                 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2580                                 
2581                                 /* generate the actual call */
2582     
2583                             M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2584                             M_NOP;
2585                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2586                             disp = (s4) (cd->mcodeptr - cd->mcodebase);
2587                             /* REG_RA holds the value of the jmp instruction, therefore +8 */
2588                             M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
2589                                 break;
2590
2591                         case ICMD_INVOKEINTERFACE:
2592                                 emit_nullpointer_check(cd, iptr, REG_OUT0);
2593
2594                                 if (lm == NULL) {
2595                                         codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2596
2597                                         s1 = 0;
2598                                         s2 = 0;
2599                                 } 
2600                                 else {
2601                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2602                                                 sizeof(methodptr*) * lm->clazz->index;
2603
2604                                         s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2605                                 }
2606
2607                                 /* implicit null-pointer check */
2608                                 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_object_t, vftbl));
2609                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2610                                 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2611
2612                             /* generate the actual call */
2613     
2614                             M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2615                             M_NOP;
2616                                 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2617                             disp = (s4) (cd->mcodeptr - cd->mcodebase);
2618                             /* REG_RA holds the value of the jmp instruction, therefore +8 */
2619                             M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2620                                 break;
2621                         }
2622
2623                         /* store return value */
2624
2625                         d = md->returntype.type;
2626
2627                         if (d != TYPE_VOID) {
2628                                 if (IS_INT_LNG_TYPE(d)) {
2629                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2630                                         M_INTMOVE(REG_RESULT_CALLER, s1);
2631                                 } 
2632                                 else {
2633                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2634                                         if (IS_2_WORD_TYPE(d)) {
2635                                                 M_DBLMOVE(REG_FRESULT, s1);
2636                                         } else {
2637                                                 M_FLTMOVE(REG_FRESULT, s1);
2638                                         }
2639                                 }
2640                                 emit_store_dst(jd, iptr, s1);
2641                         }
2642                         break;
2643
2644
2645                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2646                                       /* val.a: (classinfo*) superclass               */
2647
2648                         /*  superclass is an interface:
2649                          *
2650                          *  OK if ((sub == NULL) ||
2651                          *         (sub->vftbl->interfacetablelength > super->index) &&
2652                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2653                          *
2654                          *  superclass is a class:
2655                          *
2656                          *  OK if ((sub == NULL) || (0
2657                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2658                          *         super->vftbl->diffvall));
2659                          */
2660
2661                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2662                                 classinfo *super;
2663                                 s4         superindex;
2664
2665                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2666                                         super      = NULL;
2667                                         superindex = 0;
2668                                 }
2669                                 else {
2670                                         super = iptr->sx.s23.s3.c.cls;
2671                                         superindex = super->index;
2672                                 }
2673
2674                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2675                                         CODEGEN_CRITICAL_SECTION_NEW;
2676
2677                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2678
2679                                 /* if class is not resolved, check which code to call */
2680
2681                                 if (super == NULL) {
2682                                         emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2683
2684                                         cr   = iptr->sx.s23.s3.c.ref;
2685                                         disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
2686
2687                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2688                                                                                   cr, disp);
2689
2690                                         M_ILD(REG_ITMP2, REG_PV, disp);
2691                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2692                                         emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2693                                 }
2694
2695                                 /* interface checkcast code */
2696
2697                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2698                                         if (super == NULL) {
2699                                                 cr = iptr->sx.s23.s3.c.ref;
2700
2701                                                 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2702                                                                                           cr, 0);
2703                                         }
2704                                         else {
2705                                                 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2706                                         }
2707
2708                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2709                                         M_ILD(REG_ITMP3, REG_ITMP2,
2710                                                         OFFSET(vftbl_t, interfacetablelength));
2711                                         M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2712                                         emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2713
2714                                         M_ALD(REG_ITMP3, REG_ITMP2,
2715                                                   OFFSET(vftbl_t, interfacetable[0]) -
2716                                                   superindex * sizeof(methodptr*));
2717                                         emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2718
2719                                         if (super == NULL)
2720                                                 emit_label_br(cd, BRANCH_LABEL_4);
2721                                         else
2722                                                 emit_label(cd, BRANCH_LABEL_3);
2723                                 }
2724
2725                                 /* class checkcast code */
2726
2727                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2728                                         if (super == NULL) {
2729                                                 emit_label(cd, BRANCH_LABEL_2);
2730
2731                                                 cr   = iptr->sx.s23.s3.c.ref;
2732                                                 disp = dseg_add_unique_address(cd, NULL);
2733
2734                                                 codegen_add_patch_ref(cd,
2735                                                                                         PATCHER_checkcast_instanceof_class,
2736                                                                                           cr, disp);
2737                                         }
2738                                         else {
2739                                                 disp = dseg_add_address(cd, super->vftbl);
2740
2741                                                 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2742                                         }
2743
2744                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2745                                         M_ALD(REG_ITMP3, REG_PV, disp);
2746                                         
2747                                         CODEGEN_CRITICAL_SECTION_START;
2748
2749                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2750                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2751                                         M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2752                                         M_ALD(REG_ITMP3, REG_PV, disp);
2753                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2754
2755                                         CODEGEN_CRITICAL_SECTION_END;
2756
2757                                         /*                              } */
2758                                         M_CMP(REG_ITMP3, REG_ITMP2);
2759                                         emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2760
2761                                         if (super != NULL)
2762                                                 emit_label(cd, BRANCH_LABEL_5);
2763                                 }
2764
2765                                 if (super == NULL) {
2766                                         emit_label(cd, BRANCH_LABEL_1);
2767                                         emit_label(cd, BRANCH_LABEL_4);
2768                                 }
2769
2770                                 d = codegen_reg_of_dst(jd, iptr, s1);
2771                         }
2772                         else {
2773                                 /* array type cast-check */
2774
2775                                 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2776                                 M_INTMOVE(s1, REG_OUT0);
2777
2778                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2779
2780                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2781                                         cr   = iptr->sx.s23.s3.c.ref;
2782                                         disp = dseg_add_unique_address(cd, NULL);
2783
2784                                         codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2785                                                                                   cr, disp);
2786                                 }
2787                                 else
2788                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2789
2790                                 M_ALD(REG_OUT1, REG_PV, disp);
2791                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2792                                 M_ALD(REG_ITMP3, REG_PV, disp);
2793                                 /* XXX jit-c-call */
2794                                 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2795                                 M_NOP;
2796
2797                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2798                                 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2799
2800                                 d = codegen_reg_of_dst(jd, iptr, s1);
2801                         }
2802
2803                         M_INTMOVE(s1, d);
2804                         emit_store_dst(jd, iptr, d);
2805                         break;
2806
2807                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2808                                       /* val.a: (classinfo*) superclass               */
2809
2810                         /*  superclass is an interface:
2811                          *      
2812                          *  return (sub != NULL) &&
2813                          *         (sub->vftbl->interfacetablelength > super->index) &&
2814                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
2815                          *      
2816                          *  superclass is a class:
2817                          *      
2818                          *  return ((sub != NULL) && (0
2819                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2820                          *          super->vftbl->diffvall));
2821                          */
2822
2823                         {
2824                         classinfo *super;
2825                         vftbl_t   *supervftbl;
2826                         s4         superindex;
2827
2828                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2829                                 super = NULL;
2830                                 superindex = 0;
2831                                 supervftbl = NULL;
2832
2833                         } else {
2834                                 super = iptr->sx.s23.s3.c.cls;
2835                                 superindex = super->index;
2836                                 supervftbl = super->vftbl;
2837                         }
2838
2839                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2840                                 CODEGEN_CRITICAL_SECTION_NEW;
2841
2842                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2843                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2844                         if (s1 == d) {
2845                                 M_MOV(s1, REG_ITMP1);
2846                                 s1 = REG_ITMP1;
2847                         }
2848
2849                         M_CLR(d);
2850
2851                         /* if class is not resolved, check which code to call */
2852
2853                         if (super == NULL) {
2854                                 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2855
2856                                 cr   = iptr->sx.s23.s3.c.ref;
2857                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
2858
2859                                 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2860                                                                           cr, disp);
2861
2862                                 M_ILD(REG_ITMP3, REG_PV, disp);
2863                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2864                                 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2865                         }
2866
2867                         /* interface instanceof code */
2868
2869                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2870                                 if (super == NULL) {
2871                                         cr = iptr->sx.s23.s3.c.ref;
2872
2873                                         codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2874                                                                                   cr, 0);
2875                                 }
2876                                 else {
2877                                         emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2878                                 }
2879
2880                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2881                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2882                                 M_CMP_IMM(REG_ITMP3, superindex);
2883                                 M_BLE(4);
2884                                 M_NOP;
2885                                 M_ALD(REG_ITMP1, REG_ITMP1,
2886                                           (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2887                                                         superindex * sizeof(methodptr*)));
2888                                 M_CMOVRNE_IMM(REG_ITMP1, 1, d);      /* REG_ITMP1 != 0  */
2889
2890                                 if (super == NULL)
2891                                         emit_label_br(cd, BRANCH_LABEL_4);
2892                                 else
2893                                         emit_label(cd, BRANCH_LABEL_3);
2894                         }
2895
2896                         /* class instanceof code */
2897
2898                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2899                                 if (super == NULL) {
2900                                         emit_label(cd, BRANCH_LABEL_2);
2901
2902                                         cr   = iptr->sx.s23.s3.c.ref;
2903                                         disp = dseg_add_unique_address(cd, NULL);
2904
2905                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2906                                                                                   cr, disp);
2907                                 }
2908                                 else {
2909                                         disp = dseg_add_address(cd, supervftbl);
2910
2911                                         emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2912                                 }
2913
2914                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2915                                 M_ALD(REG_ITMP2, REG_PV, disp);
2916
2917                                 CODEGEN_CRITICAL_SECTION_START;
2918
2919                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2920                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2921                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2922
2923                                 CODEGEN_CRITICAL_SECTION_END;
2924
2925                                 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2926                                 M_CMP(REG_ITMP1, REG_ITMP2);
2927                                 M_XCMOVULE_IMM(1, d);
2928
2929                                 if (super != NULL)
2930                                         emit_label(cd, BRANCH_LABEL_5);
2931                         }
2932
2933                         if (super == NULL) {
2934                                 emit_label(cd, BRANCH_LABEL_1);
2935                                 emit_label(cd, BRANCH_LABEL_4);
2936                         }
2937
2938                         emit_store_dst(jd, iptr, d);
2939                         }
2940                         break;
2941
2942                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2943
2944                         /* check for negative sizes and copy sizes to stack if necessary  */
2945
2946                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2947
2948                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2949
2950                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2951         
2952                                 /* copy SAVEDVAR sizes to stack */
2953
2954                                 /* Already Preallocated? */
2955
2956                                 if (!(var->flags & PREALLOC)) {
2957                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2958                                         M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2959                                 }
2960                         }
2961
2962                         /* arg 0 = dimension count */
2963
2964                         ICONST(REG_OUT0, iptr->s1.argcount);
2965
2966                         /* is patcher function set? */
2967
2968                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2969                                 disp = dseg_add_unique_address(cd, 0);
2970
2971                                 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2972                                                                           iptr->sx.s23.s3.c.ref,
2973                                                                           disp);
2974                         }
2975                         else
2976                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2977
2978                         /* arg 1 = arraydescriptor */
2979
2980                         M_ALD(REG_OUT1, REG_PV, disp);
2981
2982                         /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2983
2984                         M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2985
2986                         /* XXX c abi call */
2987                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2988                         M_ALD(REG_ITMP3, REG_PV, disp);
2989                         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2990                         M_NOP;
2991
2992                         /* check for exception before result assignment */
2993
2994                         emit_exception_check(cd, iptr);
2995
2996                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2997                         M_INTMOVE(REG_RESULT_CALLER, d);
2998                         emit_store_dst(jd, iptr, d);
2999                         break;
3000
3001                 default:
3002                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3003                                                                                    iptr->opc);
3004                         return false;
3005                         
3006         } /* switch */
3007                 
3008         } /* for instruction */
3009
3010         MCODECHECK(64);
3011         
3012         /* At the end of a basic block we may have to append some nops,
3013            because the patcher stub calling code might be longer than the
3014            actual instruction. So codepatching does not change the
3015            following block unintentionally. */
3016
3017         if (cd->mcodeptr < cd->lastmcodeptr) {
3018                 while (cd->mcodeptr < cd->lastmcodeptr) {
3019                         M_NOP;
3020                 }
3021         }
3022                 
3023         } /* if (bptr -> flags >= BBREACHED) */
3024         } /* for basic block */
3025         
3026         /* generate stubs */
3027
3028         emit_patcher_stubs(jd);
3029         
3030         /* everything's ok */
3031
3032         return true;    
3033 }
3034
3035
3036 /* codegen_emit_stub_compiler **************************************************
3037
3038    Emits a stub routine which calls the compiler.
3039         
3040 *******************************************************************************/
3041
3042 void codegen_emit_stub_compiler(jitdata *jd)
3043 {
3044         methodinfo  *m;
3045         codegendata *cd;
3046
3047         /* get required compiler data */
3048
3049         m  = jd->m;
3050         cd = jd->cd;
3051
3052         /* code for the stub */
3053
3054         /* no window save yet, user caller's PV */
3055         M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
3056         M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
3057         M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO);  /* jump to the compiler, RA is wasted */
3058         M_NOP;
3059 }
3060
3061
3062 /* codegen_emit_stub_builtin ***************************************************
3063
3064    Creates a stub routine which calls a builtin function.
3065
3066 *******************************************************************************/
3067
3068 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
3069 {
3070         codeinfo    *code;
3071         codegendata *cd;
3072         methoddesc  *md;
3073         s4           i;
3074         s4           disp;
3075         s4           s1, s2;
3076
3077         /* get required compiler data */
3078         code = jd->code;
3079         cd   = jd->cd;
3080
3081         /* set some variables */
3082         md = bte->md;
3083
3084         /* calculate stack frame size */
3085         cd->stackframesize =
3086                 WINSAVE_CNT +
3087                 ABIPARAMS_CNT +
3088                 FLT_ARG_CNT +
3089                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3090                 4;                              /* 4 arguments or return value        */
3091
3092
3093         /* keep stack 16-byte aligned (ABI requirement) */
3094
3095         if (cd->stackframesize & 1)
3096                 cd->stackframesize++;
3097
3098         /* create method header */
3099         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3100         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
3101         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3102         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3103         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3104
3105         /* generate stub code */
3106         M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe   */
3107
3108 #if defined(ENABLE_GC_CACAO)
3109         /* Save callee saved integer registers in stackframeinfo (GC may
3110            need to recover them during a collection). */
3111
3112         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3113                 OFFSET(stackframeinfo_t, intregs) + BIAS;
3114
3115         for (i = 0; i < INT_SAV_CNT; i++)
3116                 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3117 #endif
3118
3119         for (i = 0; i < md->paramcount; i++) {
3120                 s1 = md->params[i].regoff;
3121
3122                 switch (md->paramtypes[i].type) {
3123                 case TYPE_INT:
3124                 case TYPE_LNG:
3125                 case TYPE_ADR:
3126                         break;
3127                 case TYPE_FLT:
3128                 case TYPE_DBL:
3129                         M_DST(s1, REG_SP, JITSTACK + i * 8);
3130                         break;
3131                 }
3132         }
3133
3134         /* create dynamic stack info */
3135
3136         M_AADD_IMM(REG_SP, BIAS + cd->stackframesize * 8, REG_OUT0); /* data sp*/
3137         M_MOV(REG_PV_CALLEE, REG_OUT1); /* PV */
3138         M_MOV(REG_FP, REG_OUT2); /* java sp */
3139         M_MOV(REG_RA_CALLEE, REG_OUT3); /* ra */
3140
3141         disp = dseg_add_functionptr(cd, codegen_stub_builtin_enter);
3142         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3143         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3144         M_NOP; /* XXX fill me! */
3145
3146
3147         /* builtins are allowed to have 5 arguments max */
3148
3149         assert(md->paramcount <= 5);
3150
3151         /* copy arguments into position */
3152
3153         for (i = 0; i < md->paramcount; i++) {
3154                 assert(!md->params[i].inmemory);
3155
3156                 s1 = md->params[i].regoff;
3157
3158                 switch (md->paramtypes[i].type) {
3159                 case TYPE_INT:
3160                 case TYPE_LNG:
3161                 case TYPE_ADR:
3162                         M_MOV(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[i]), s1);
3163                         break;
3164                 case TYPE_FLT:
3165                 case TYPE_DBL:
3166                         M_DLD(s1, REG_SP, JITSTACK + i * 8);
3167                         break;
3168                 }
3169
3170         }
3171
3172         /* call the builtin function */
3173
3174         disp = dseg_add_functionptr(cd, bte->fp);
3175         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp); /* load adress of builtin */
3176         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call builtin                */
3177         M_NOP;                              /* delay slot                         */
3178
3179
3180         /* save return value */
3181
3182         if (md->returntype.type != TYPE_VOID) {
3183                 if (IS_INT_LNG_TYPE(md->returntype.type))
3184                         M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3185                 else
3186                         M_DST(REG_FRESULT, REG_SP, CSTACK);
3187         }       
3188
3189
3190         /* remove native stackframe info */
3191
3192         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3193         disp = dseg_add_functionptr(cd, codegen_stub_builtin_exit);
3194         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3195         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3196         M_NOP;
3197
3198         /* restore float return value, int return value already in our return reg */
3199
3200         if (md->returntype.type != TYPE_VOID) {
3201                 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3202                         if (IS_2_WORD_TYPE(md->returntype.type))
3203                                 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3204                         else
3205                                 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3206                 }
3207         }
3208
3209
3210 #if defined(ENABLE_GC_CACAO)
3211         /* Restore callee saved integer registers from stackframeinfo (GC
3212            might have modified them during a collection). */
3213         
3214         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3215                 OFFSET(stackframeinfo_t, intregs) + BIAS;
3216
3217         for (i = 0; i < INT_SAV_CNT; i++)
3218                 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3219 #endif
3220
3221         /* return */
3222         M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3223         M_NOP;
3224
3225         /* assert(0); */
3226 }
3227
3228
3229 /* codegen_emit_stub_native ****************************************************
3230
3231    Emits a stub routine which calls a native method.
3232
3233 *******************************************************************************/
3234
3235 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3236 {
3237         methodinfo   *m;
3238         codeinfo     *code;
3239         codegendata  *cd;
3240         methoddesc   *md;
3241         s4            nativeparams;
3242         s4            i, j;                 /* count variables                    */
3243         s4            t;
3244         s4            s1, s2, disp;
3245         s4            funcdisp;             /* displacement of the function       */
3246         s4            fltregarg_offset[FLT_ARG_CNT];
3247
3248         /* get required compiler data */
3249
3250         m    = jd->m;
3251         code = jd->code;
3252         cd   = jd->cd;
3253
3254         /* initialize variables */
3255
3256         md = m->parseddesc;
3257         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3258
3259         /* calculate stack frame size */
3260
3261         cd->stackframesize =
3262                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3263                 sizeof(localref_table) / SIZEOF_VOID_P +
3264                 md->paramcount +                /* for saving arguments over calls    */
3265                 nmd->memuse +              /* nmd->memuse includes the (6) abi params */
3266                 WINSAVE_CNT;
3267
3268
3269         /* keep stack 16-byte aligned (ABI requirement) */
3270
3271         if (cd->stackframesize & 1)
3272                 cd->stackframesize++;
3273
3274         /* create method header */
3275
3276         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3277         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
3278         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3279         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3280         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3281
3282         /* generate stub code */
3283
3284         M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe    */
3285
3286 #if !defined(NDEBUG)
3287         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3288                 emit_verbosecall_enter(jd);
3289 #endif
3290
3291         /* get function address (this must happen before the stackframeinfo) */
3292
3293         funcdisp = dseg_add_functionptr(cd, f);
3294
3295         if (f == NULL)
3296                 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3297
3298         /* save float argument registers */
3299
3300         assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3301
3302         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3303                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3304                         s1 = WINSAVE_CNT + nmd->memuse + j;
3305                         M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3306                         fltregarg_offset[i] = s1; /* remember stack offset */
3307                         j++;
3308                 }
3309         }
3310
3311         /* prepare data structures for native function call */
3312
3313         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3314         M_MOV(REG_PV_CALLEE, REG_OUT1);
3315         M_MOV(REG_FP, REG_OUT2); /* java sp */
3316         M_MOV(REG_RA_CALLEE, REG_OUT3);
3317         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3318         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3319         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3320         M_NOP; /* XXX fill me! */
3321
3322         /* remember class argument */
3323
3324         if (m->flags & ACC_STATIC)
3325                 M_MOV(REG_RESULT_CALLER, REG_ITMP3);
3326
3327         /* keep float arguments on stack */
3328 #if 0
3329         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3330                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3331                         M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3332                         j++;
3333                 }
3334         }
3335 #endif
3336
3337         /* copy or spill arguments to new locations */
3338
3339         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3340                 t = md->paramtypes[i].type;
3341
3342                 if (IS_INT_LNG_TYPE(t)) {
3343
3344                         /* integral types */
3345
3346                         if (!md->params[i].inmemory) {
3347                                 s1 = md->params[i].regoff;
3348                                 /* s1 refers to the old window, transpose */
3349                                 s1 = REG_WINDOW_TRANSPOSE(s1);
3350
3351                                 if (!nmd->params[j].inmemory) {
3352                                         s2 = nmd->params[j].regoff;
3353                                         M_INTMOVE(s1, s2);
3354                                 } else {
3355                                         /* nmd's regoff is relative to the start of the param array */
3356                                         s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3357                                         M_AST(s1, REG_SP, s2);
3358                                 }
3359
3360                         } else {
3361                                 if (!nmd->params[j].inmemory) {
3362                                         /* JIT stack arg -> NAT reg arg */
3363
3364                                         /* Due to the Env pointer that is always passed, the 6th JIT arg   */
3365                                         /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3366
3367                                         assert(false); /* path never taken */
3368                                 }
3369
3370                                 s1 = md->params[i].regoff + cd->stackframesize * 8;
3371                                 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3372                                 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3373                                 M_AST(REG_ITMP1, REG_SP, s2);
3374                         }
3375
3376                 } else {
3377
3378                         /* floating point types */
3379
3380                         if (!md->params[i].inmemory) {
3381                                 s1 = md->params[i].regoff;
3382
3383                                 if (!nmd->params[j].inmemory) {
3384
3385                                         /* no mapping to regs needed, native flt args use regoff */
3386                                         s2 = nmd->params[j].regoff;
3387
3388                                         /* JIT float regs are still on the stack */
3389                                         M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3390                                 } 
3391                                 else {
3392                                         /* not supposed to happen with 16 NAT flt args */
3393                                         assert(false); 
3394                                         /*
3395                                         s2 = nmd->params[j].regoff;
3396                                         if (IS_2_WORD_TYPE(t))
3397                                                 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3398                                         else
3399                                                 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3400                                         */
3401                                 }
3402
3403                         } 
3404                         else {
3405                                 s1 = md->params[i].regoff;
3406
3407                                 if (!nmd->params[j].inmemory) {
3408
3409                                         /* JIT stack -> NAT reg */
3410
3411                                         s2 = nmd->params[j].regoff;
3412                                         M_DLD(s2, REG_FP, JITSTACK + s1);
3413                                 }
3414                                 else {
3415
3416                                         /* JIT stack -> NAT stack */
3417
3418                                         s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
3419
3420                                         /* The FTMP register may already be loaded with args */
3421                                         /* we know $f0 is unused because of the env pointer  */
3422                                         M_DLD(REG_F0, REG_FP, JITSTACK + s1);
3423                                         M_DST(REG_F0, REG_SP, BIAS + s2);
3424                                 }
3425                         }
3426                 }
3427         }
3428         
3429
3430         /* put class into second argument register */
3431
3432         if (m->flags & ACC_STATIC)
3433                 M_MOV(REG_ITMP3, REG_OUT1);
3434
3435         /* put env into first argument register */
3436
3437         disp = dseg_add_address(cd, _Jv_env);
3438         M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3439
3440         /* do the native function call */
3441
3442         M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method       */
3443         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method                 */
3444         M_NOP;                              /* delay slot                         */
3445
3446         /* save return value */
3447
3448         if (md->returntype.type != TYPE_VOID) {
3449                 if (IS_INT_LNG_TYPE(md->returntype.type))
3450                         M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3451                 else
3452                         M_DST(REG_FRESULT, REG_SP, CSTACK);
3453         }
3454         
3455         /* Note: native functions return float values in %f0 (see ABI) */
3456         /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3457
3458 #if !defined(NDEBUG)
3459         /* But for the trace function we need to put a flt result into %f1 */
3460         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3461                 if (!IS_2_WORD_TYPE(md->returntype.type))
3462                         M_FLD(REG_FRESULT, REG_SP, CSTACK);
3463                 emit_verbosecall_exit(jd);
3464         }
3465 #endif
3466
3467         /* remove native stackframe info */
3468
3469         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3470         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3471         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3472         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3473         M_NOP; /* XXX fill me! */
3474         M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3475
3476         /* restore float return value, int return value already in our return reg */
3477
3478         if (md->returntype.type != TYPE_VOID) {
3479                 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3480                         if (IS_2_WORD_TYPE(md->returntype.type))
3481                                 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3482                         else
3483                                 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3484                 }
3485         }
3486
3487         /* check for exception */
3488         M_BNEZ(REG_ITMP2_XPTR, 4);          /* if no exception then return        */
3489         M_NOP;
3490
3491         M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3492         M_NOP;
3493
3494         /* handle exception */
3495         
3496         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3497         M_ALD(REG_ITMP1, REG_PV, disp);     /* load asm exception handler address */
3498         M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address             */
3499         M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler     */
3500         M_RESTORE(REG_ZERO, 0, REG_ZERO);   /* restore callers window (DELAY)     */
3501         
3502         /* generate patcher stubs */
3503
3504         emit_patcher_stubs(jd);
3505 }
3506
3507 /*
3508  * These are local overrides for various environment variables in Emacs.
3509  * Please do not remove this and leave it at the end of the file, where
3510  * Emacs will automagically detect them.
3511  * ---------------------------------------------------------------------
3512  * Local variables:
3513  * mode: c
3514  * indent-tabs-mode: t
3515  * c-basic-offset: 4
3516  * tab-width: 4
3517  * End:
3518  * vim:noexpandtab:sw=4:ts=4:
3519  */