* Merged in new atomic instructions (twisti branch).
[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                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2675
2676                                 /* if class is not resolved, check which code to call */
2677
2678                                 if (super == NULL) {
2679                                         emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2680
2681                                         cr   = iptr->sx.s23.s3.c.ref;
2682                                         disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
2683
2684                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2685                                                                                   cr, disp);
2686
2687                                         M_ILD(REG_ITMP2, REG_PV, disp);
2688                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2689                                         emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2690                                 }
2691
2692                                 /* interface checkcast code */
2693
2694                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2695                                         if (super == NULL) {
2696                                                 cr = iptr->sx.s23.s3.c.ref;
2697
2698                                                 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2699                                                                                           cr, 0);
2700                                         }
2701                                         else {
2702                                                 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2703                                         }
2704
2705                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2706                                         M_ILD(REG_ITMP3, REG_ITMP2,
2707                                                         OFFSET(vftbl_t, interfacetablelength));
2708                                         M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2709                                         emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2710
2711                                         M_ALD(REG_ITMP3, REG_ITMP2,
2712                                                   OFFSET(vftbl_t, interfacetable[0]) -
2713                                                   superindex * sizeof(methodptr*));
2714                                         emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2715
2716                                         if (super == NULL)
2717                                                 emit_label_br(cd, BRANCH_LABEL_4);
2718                                         else
2719                                                 emit_label(cd, BRANCH_LABEL_3);
2720                                 }
2721
2722                                 /* class checkcast code */
2723
2724                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2725                                         if (super == NULL) {
2726                                                 emit_label(cd, BRANCH_LABEL_2);
2727
2728                                                 cr   = iptr->sx.s23.s3.c.ref;
2729                                                 disp = dseg_add_unique_address(cd, NULL);
2730
2731                                                 codegen_add_patch_ref(cd,
2732                                                                                         PATCHER_checkcast_instanceof_class,
2733                                                                                           cr, disp);
2734                                         }
2735                                         else {
2736                                                 disp = dseg_add_address(cd, super->vftbl);
2737
2738                                                 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2739                                         }
2740
2741                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2742                                         M_ALD(REG_ITMP3, REG_PV, disp);
2743                                         
2744                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2745                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2746                                         M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2747                                         M_ALD(REG_ITMP3, REG_PV, disp);
2748                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2749
2750                                         /*                              } */
2751                                         M_CMP(REG_ITMP3, REG_ITMP2);
2752                                         emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2753
2754                                         if (super != NULL)
2755                                                 emit_label(cd, BRANCH_LABEL_5);
2756                                 }
2757
2758                                 if (super == NULL) {
2759                                         emit_label(cd, BRANCH_LABEL_1);
2760                                         emit_label(cd, BRANCH_LABEL_4);
2761                                 }
2762
2763                                 d = codegen_reg_of_dst(jd, iptr, s1);
2764                         }
2765                         else {
2766                                 /* array type cast-check */
2767
2768                                 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2769                                 M_INTMOVE(s1, REG_OUT0);
2770
2771                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2772
2773                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2774                                         cr   = iptr->sx.s23.s3.c.ref;
2775                                         disp = dseg_add_unique_address(cd, NULL);
2776
2777                                         codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2778                                                                                   cr, disp);
2779                                 }
2780                                 else
2781                                         disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2782
2783                                 M_ALD(REG_OUT1, REG_PV, disp);
2784                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2785                                 M_ALD(REG_ITMP3, REG_PV, disp);
2786                                 /* XXX jit-c-call */
2787                                 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2788                                 M_NOP;
2789
2790                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2791                                 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2792
2793                                 d = codegen_reg_of_dst(jd, iptr, s1);
2794                         }
2795
2796                         M_INTMOVE(s1, d);
2797                         emit_store_dst(jd, iptr, d);
2798                         break;
2799
2800                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
2801                                       /* val.a: (classinfo*) superclass               */
2802
2803                         /*  superclass is an interface:
2804                          *      
2805                          *  return (sub != NULL) &&
2806                          *         (sub->vftbl->interfacetablelength > super->index) &&
2807                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
2808                          *      
2809                          *  superclass is a class:
2810                          *      
2811                          *  return ((sub != NULL) && (0
2812                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2813                          *          super->vftbl->diffvall));
2814                          */
2815
2816                         {
2817                         classinfo *super;
2818                         vftbl_t   *supervftbl;
2819                         s4         superindex;
2820
2821                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2822                                 super = NULL;
2823                                 superindex = 0;
2824                                 supervftbl = NULL;
2825
2826                         } else {
2827                                 super = iptr->sx.s23.s3.c.cls;
2828                                 superindex = super->index;
2829                                 supervftbl = super->vftbl;
2830                         }
2831
2832                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2833                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2834                         if (s1 == d) {
2835                                 M_MOV(s1, REG_ITMP1);
2836                                 s1 = REG_ITMP1;
2837                         }
2838
2839                         M_CLR(d);
2840
2841                         /* if class is not resolved, check which code to call */
2842
2843                         if (super == NULL) {
2844                                 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2845
2846                                 cr   = iptr->sx.s23.s3.c.ref;
2847                                 disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
2848
2849                                 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2850                                                                           cr, disp);
2851
2852                                 M_ILD(REG_ITMP3, REG_PV, disp);
2853                                 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2854                                 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2855                         }
2856
2857                         /* interface instanceof code */
2858
2859                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2860                                 if (super == NULL) {
2861                                         cr = iptr->sx.s23.s3.c.ref;
2862
2863                                         codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2864                                                                                   cr, 0);
2865                                 }
2866                                 else {
2867                                         emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2868                                 }
2869
2870                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2871                                 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2872                                 M_CMP_IMM(REG_ITMP3, superindex);
2873                                 M_BLE(4);
2874                                 M_NOP;
2875                                 M_ALD(REG_ITMP1, REG_ITMP1,
2876                                           (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2877                                                         superindex * sizeof(methodptr*)));
2878                                 M_CMOVRNE_IMM(REG_ITMP1, 1, d);      /* REG_ITMP1 != 0  */
2879
2880                                 if (super == NULL)
2881                                         emit_label_br(cd, BRANCH_LABEL_4);
2882                                 else
2883                                         emit_label(cd, BRANCH_LABEL_3);
2884                         }
2885
2886                         /* class instanceof code */
2887
2888                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2889                                 if (super == NULL) {
2890                                         emit_label(cd, BRANCH_LABEL_2);
2891
2892                                         cr   = iptr->sx.s23.s3.c.ref;
2893                                         disp = dseg_add_unique_address(cd, NULL);
2894
2895                                         codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2896                                                                                   cr, disp);
2897                                 }
2898                                 else {
2899                                         disp = dseg_add_address(cd, supervftbl);
2900
2901                                         emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2902                                 }
2903
2904                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2905                                 M_ALD(REG_ITMP2, REG_PV, disp);
2906
2907                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2908                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2909                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2910
2911                                 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2912                                 M_CMP(REG_ITMP1, REG_ITMP2);
2913                                 M_XCMOVULE_IMM(1, d);
2914
2915                                 if (super != NULL)
2916                                         emit_label(cd, BRANCH_LABEL_5);
2917                         }
2918
2919                         if (super == NULL) {
2920                                 emit_label(cd, BRANCH_LABEL_1);
2921                                 emit_label(cd, BRANCH_LABEL_4);
2922                         }
2923
2924                         emit_store_dst(jd, iptr, d);
2925                         }
2926                         break;
2927
2928                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
2929
2930                         /* check for negative sizes and copy sizes to stack if necessary  */
2931
2932                         MCODECHECK((iptr->s1.argcount << 1) + 64);
2933
2934                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2935
2936                                 var = VAR(iptr->sx.s23.s2.args[s1]);
2937         
2938                                 /* copy SAVEDVAR sizes to stack */
2939
2940                                 /* Already Preallocated? */
2941
2942                                 if (!(var->flags & PREALLOC)) {
2943                                         s2 = emit_load(jd, iptr, var, REG_ITMP1);
2944                                         M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2945                                 }
2946                         }
2947
2948                         /* arg 0 = dimension count */
2949
2950                         ICONST(REG_OUT0, iptr->s1.argcount);
2951
2952                         /* is patcher function set? */
2953
2954                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2955                                 disp = dseg_add_unique_address(cd, 0);
2956
2957                                 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2958                                                                           iptr->sx.s23.s3.c.ref,
2959                                                                           disp);
2960                         }
2961                         else
2962                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2963
2964                         /* arg 1 = arraydescriptor */
2965
2966                         M_ALD(REG_OUT1, REG_PV, disp);
2967
2968                         /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2969
2970                         M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2971
2972                         /* XXX c abi call */
2973                         disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2974                         M_ALD(REG_ITMP3, REG_PV, disp);
2975                         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2976                         M_NOP;
2977
2978                         /* check for exception before result assignment */
2979
2980                         emit_exception_check(cd, iptr);
2981
2982                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2983                         M_INTMOVE(REG_RESULT_CALLER, d);
2984                         emit_store_dst(jd, iptr, d);
2985                         break;
2986
2987                 default:
2988                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2989                                                                                    iptr->opc);
2990                         return false;
2991                         
2992         } /* switch */
2993                 
2994         } /* for instruction */
2995
2996         MCODECHECK(64);
2997         
2998         /* At the end of a basic block we may have to append some nops,
2999            because the patcher stub calling code might be longer than the
3000            actual instruction. So codepatching does not change the
3001            following block unintentionally. */
3002
3003         if (cd->mcodeptr < cd->lastmcodeptr) {
3004                 while (cd->mcodeptr < cd->lastmcodeptr) {
3005                         M_NOP;
3006                 }
3007         }
3008                 
3009         } /* if (bptr -> flags >= BBREACHED) */
3010         } /* for basic block */
3011         
3012         /* generate stubs */
3013
3014         emit_patcher_stubs(jd);
3015         
3016         /* everything's ok */
3017
3018         return true;    
3019 }
3020
3021
3022 /* codegen_emit_stub_compiler **************************************************
3023
3024    Emits a stub routine which calls the compiler.
3025         
3026 *******************************************************************************/
3027
3028 void codegen_emit_stub_compiler(jitdata *jd)
3029 {
3030         methodinfo  *m;
3031         codegendata *cd;
3032
3033         /* get required compiler data */
3034
3035         m  = jd->m;
3036         cd = jd->cd;
3037
3038         /* code for the stub */
3039
3040         /* no window save yet, user caller's PV */
3041         M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
3042         M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
3043         M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO);  /* jump to the compiler, RA is wasted */
3044         M_NOP;
3045 }
3046
3047
3048 /* codegen_emit_stub_builtin ***************************************************
3049
3050    Creates a stub routine which calls a builtin function.
3051
3052 *******************************************************************************/
3053
3054 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
3055 {
3056         codeinfo    *code;
3057         codegendata *cd;
3058         methoddesc  *md;
3059         s4           i;
3060         s4           disp;
3061         s4           s1, s2;
3062
3063         /* get required compiler data */
3064         code = jd->code;
3065         cd   = jd->cd;
3066
3067         /* set some variables */
3068         md = bte->md;
3069
3070         /* calculate stack frame size */
3071         cd->stackframesize =
3072                 WINSAVE_CNT +
3073                 ABIPARAMS_CNT +
3074                 FLT_ARG_CNT +
3075                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3076                 4;                              /* 4 arguments or return value        */
3077
3078
3079         /* keep stack 16-byte aligned (ABI requirement) */
3080
3081         if (cd->stackframesize & 1)
3082                 cd->stackframesize++;
3083
3084         /* create method header */
3085         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3086         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
3087         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3088         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3089         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3090
3091         /* generate stub code */
3092         M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe   */
3093
3094 #if defined(ENABLE_GC_CACAO)
3095         /* Save callee saved integer registers in stackframeinfo (GC may
3096            need to recover them during a collection). */
3097
3098         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3099                 OFFSET(stackframeinfo_t, intregs) + BIAS;
3100
3101         for (i = 0; i < INT_SAV_CNT; i++)
3102                 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3103 #endif
3104
3105         for (i = 0; i < md->paramcount; i++) {
3106                 s1 = md->params[i].regoff;
3107
3108                 switch (md->paramtypes[i].type) {
3109                 case TYPE_INT:
3110                 case TYPE_LNG:
3111                 case TYPE_ADR:
3112                         break;
3113                 case TYPE_FLT:
3114                 case TYPE_DBL:
3115                         M_DST(s1, REG_SP, JITSTACK + i * 8);
3116                         break;
3117                 }
3118         }
3119
3120         /* create dynamic stack info */
3121
3122         M_AADD_IMM(REG_SP, BIAS + cd->stackframesize * 8, REG_OUT0); /* data sp*/
3123         M_MOV(REG_PV_CALLEE, REG_OUT1); /* PV */
3124         M_MOV(REG_FP, REG_OUT2); /* java sp */
3125         M_MOV(REG_RA_CALLEE, REG_OUT3); /* ra */
3126
3127         disp = dseg_add_functionptr(cd, codegen_stub_builtin_enter);
3128         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3129         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3130         M_NOP; /* XXX fill me! */
3131
3132
3133         /* builtins are allowed to have 5 arguments max */
3134
3135         assert(md->paramcount <= 5);
3136
3137         /* copy arguments into position */
3138
3139         for (i = 0; i < md->paramcount; i++) {
3140                 assert(!md->params[i].inmemory);
3141
3142                 s1 = md->params[i].regoff;
3143
3144                 switch (md->paramtypes[i].type) {
3145                 case TYPE_INT:
3146                 case TYPE_LNG:
3147                 case TYPE_ADR:
3148                         M_MOV(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[i]), s1);
3149                         break;
3150                 case TYPE_FLT:
3151                 case TYPE_DBL:
3152                         M_DLD(s1, REG_SP, JITSTACK + i * 8);
3153                         break;
3154                 }
3155
3156         }
3157
3158         /* call the builtin function */
3159
3160         disp = dseg_add_functionptr(cd, bte->fp);
3161         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp); /* load adress of builtin */
3162         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call builtin                */
3163         M_NOP;                              /* delay slot                         */
3164
3165
3166         /* save return value */
3167
3168         if (md->returntype.type != TYPE_VOID) {
3169                 if (IS_INT_LNG_TYPE(md->returntype.type))
3170                         M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3171                 else
3172                         M_DST(REG_FRESULT, REG_SP, CSTACK);
3173         }       
3174
3175
3176         /* remove native stackframe info */
3177
3178         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3179         disp = dseg_add_functionptr(cd, codegen_stub_builtin_exit);
3180         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3181         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3182         M_NOP;
3183
3184         /* restore float return value, int return value already in our return reg */
3185
3186         if (md->returntype.type != TYPE_VOID) {
3187                 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3188                         if (IS_2_WORD_TYPE(md->returntype.type))
3189                                 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3190                         else
3191                                 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3192                 }
3193         }
3194
3195
3196 #if defined(ENABLE_GC_CACAO)
3197         /* Restore callee saved integer registers from stackframeinfo (GC
3198            might have modified them during a collection). */
3199         
3200         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3201                 OFFSET(stackframeinfo_t, intregs) + BIAS;
3202
3203         for (i = 0; i < INT_SAV_CNT; i++)
3204                 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3205 #endif
3206
3207         /* return */
3208         M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3209         M_NOP;
3210
3211         /* assert(0); */
3212 }
3213
3214
3215 /* codegen_emit_stub_native ****************************************************
3216
3217    Emits a stub routine which calls a native method.
3218
3219 *******************************************************************************/
3220
3221 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3222 {
3223         methodinfo   *m;
3224         codeinfo     *code;
3225         codegendata  *cd;
3226         methoddesc   *md;
3227         s4            nativeparams;
3228         s4            i, j;                 /* count variables                    */
3229         s4            t;
3230         s4            s1, s2, disp;
3231         s4            funcdisp;             /* displacement of the function       */
3232         s4            fltregarg_offset[FLT_ARG_CNT];
3233
3234         /* get required compiler data */
3235
3236         m    = jd->m;
3237         code = jd->code;
3238         cd   = jd->cd;
3239
3240         /* initialize variables */
3241
3242         md = m->parseddesc;
3243         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3244
3245         /* calculate stack frame size */
3246
3247         cd->stackframesize =
3248                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3249                 sizeof(localref_table) / SIZEOF_VOID_P +
3250                 md->paramcount +                /* for saving arguments over calls    */
3251                 nmd->memuse +              /* nmd->memuse includes the (6) abi params */
3252                 WINSAVE_CNT;
3253
3254
3255         /* keep stack 16-byte aligned (ABI requirement) */
3256
3257         if (cd->stackframesize & 1)
3258                 cd->stackframesize++;
3259
3260         /* create method header */
3261
3262         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3263         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
3264         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3265         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3266         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3267
3268         /* generate stub code */
3269
3270         M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe    */
3271
3272 #if !defined(NDEBUG)
3273         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3274                 emit_verbosecall_enter(jd);
3275 #endif
3276
3277         /* get function address (this must happen before the stackframeinfo) */
3278
3279         funcdisp = dseg_add_functionptr(cd, f);
3280
3281         if (f == NULL)
3282                 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3283
3284         /* save float argument registers */
3285
3286         assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3287
3288         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3289                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3290                         s1 = WINSAVE_CNT + nmd->memuse + j;
3291                         M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3292                         fltregarg_offset[i] = s1; /* remember stack offset */
3293                         j++;
3294                 }
3295         }
3296
3297         /* prepare data structures for native function call */
3298
3299         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3300         M_MOV(REG_PV_CALLEE, REG_OUT1);
3301         M_MOV(REG_FP, REG_OUT2); /* java sp */
3302         M_MOV(REG_RA_CALLEE, REG_OUT3);
3303         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3304         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3305         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3306         M_NOP; /* XXX fill me! */
3307
3308         /* remember class argument */
3309
3310         if (m->flags & ACC_STATIC)
3311                 M_MOV(REG_RESULT_CALLER, REG_ITMP3);
3312
3313         /* keep float arguments on stack */
3314 #if 0
3315         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3316                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3317                         M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3318                         j++;
3319                 }
3320         }
3321 #endif
3322
3323         /* copy or spill arguments to new locations */
3324
3325         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3326                 t = md->paramtypes[i].type;
3327
3328                 if (IS_INT_LNG_TYPE(t)) {
3329
3330                         /* integral types */
3331
3332                         if (!md->params[i].inmemory) {
3333                                 s1 = md->params[i].regoff;
3334                                 /* s1 refers to the old window, transpose */
3335                                 s1 = REG_WINDOW_TRANSPOSE(s1);
3336
3337                                 if (!nmd->params[j].inmemory) {
3338                                         s2 = nmd->params[j].regoff;
3339                                         M_INTMOVE(s1, s2);
3340                                 } else {
3341                                         /* nmd's regoff is relative to the start of the param array */
3342                                         s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3343                                         M_AST(s1, REG_SP, s2);
3344                                 }
3345
3346                         } else {
3347                                 if (!nmd->params[j].inmemory) {
3348                                         /* JIT stack arg -> NAT reg arg */
3349
3350                                         /* Due to the Env pointer that is always passed, the 6th JIT arg   */
3351                                         /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3352
3353                                         assert(false); /* path never taken */
3354                                 }
3355
3356                                 s1 = md->params[i].regoff + cd->stackframesize * 8;
3357                                 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3358                                 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3359                                 M_AST(REG_ITMP1, REG_SP, s2);
3360                         }
3361
3362                 } else {
3363
3364                         /* floating point types */
3365
3366                         if (!md->params[i].inmemory) {
3367                                 s1 = md->params[i].regoff;
3368
3369                                 if (!nmd->params[j].inmemory) {
3370
3371                                         /* no mapping to regs needed, native flt args use regoff */
3372                                         s2 = nmd->params[j].regoff;
3373
3374                                         /* JIT float regs are still on the stack */
3375                                         M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3376                                 } 
3377                                 else {
3378                                         /* not supposed to happen with 16 NAT flt args */
3379                                         assert(false); 
3380                                         /*
3381                                         s2 = nmd->params[j].regoff;
3382                                         if (IS_2_WORD_TYPE(t))
3383                                                 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3384                                         else
3385                                                 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3386                                         */
3387                                 }
3388
3389                         } 
3390                         else {
3391                                 s1 = md->params[i].regoff;
3392
3393                                 if (!nmd->params[j].inmemory) {
3394
3395                                         /* JIT stack -> NAT reg */
3396
3397                                         s2 = nmd->params[j].regoff;
3398                                         M_DLD(s2, REG_FP, JITSTACK + s1);
3399                                 }
3400                                 else {
3401
3402                                         /* JIT stack -> NAT stack */
3403
3404                                         s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
3405
3406                                         /* The FTMP register may already be loaded with args */
3407                                         /* we know $f0 is unused because of the env pointer  */
3408                                         M_DLD(REG_F0, REG_FP, JITSTACK + s1);
3409                                         M_DST(REG_F0, REG_SP, BIAS + s2);
3410                                 }
3411                         }
3412                 }
3413         }
3414         
3415
3416         /* put class into second argument register */
3417
3418         if (m->flags & ACC_STATIC)
3419                 M_MOV(REG_ITMP3, REG_OUT1);
3420
3421         /* put env into first argument register */
3422
3423         disp = dseg_add_address(cd, _Jv_env);
3424         M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3425
3426         /* do the native function call */
3427
3428         M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method       */
3429         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method                 */
3430         M_NOP;                              /* delay slot                         */
3431
3432         /* save return value */
3433
3434         if (md->returntype.type != TYPE_VOID) {
3435                 if (IS_INT_LNG_TYPE(md->returntype.type))
3436                         M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3437                 else
3438                         M_DST(REG_FRESULT, REG_SP, CSTACK);
3439         }
3440         
3441         /* Note: native functions return float values in %f0 (see ABI) */
3442         /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3443
3444 #if !defined(NDEBUG)
3445         /* But for the trace function we need to put a flt result into %f1 */
3446         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3447                 if (!IS_2_WORD_TYPE(md->returntype.type))
3448                         M_FLD(REG_FRESULT, REG_SP, CSTACK);
3449                 emit_verbosecall_exit(jd);
3450         }
3451 #endif
3452
3453         /* remove native stackframe info */
3454
3455         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3456         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3457         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3458         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3459         M_NOP; /* XXX fill me! */
3460         M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3461
3462         /* restore float return value, int return value already in our return reg */
3463
3464         if (md->returntype.type != TYPE_VOID) {
3465                 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3466                         if (IS_2_WORD_TYPE(md->returntype.type))
3467                                 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3468                         else
3469                                 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3470                 }
3471         }
3472
3473         /* check for exception */
3474         M_BNEZ(REG_ITMP2_XPTR, 4);          /* if no exception then return        */
3475         M_NOP;
3476
3477         M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3478         M_NOP;
3479
3480         /* handle exception */
3481         
3482         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3483         M_ALD(REG_ITMP1, REG_PV, disp);     /* load asm exception handler address */
3484         M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address             */
3485         M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler     */
3486         M_RESTORE(REG_ZERO, 0, REG_ZERO);   /* restore callers window (DELAY)     */
3487         
3488         /* generate patcher stubs */
3489
3490         emit_patcher_stubs(jd);
3491 }
3492
3493 /*
3494  * These are local overrides for various environment variables in Emacs.
3495  * Please do not remove this and leave it at the end of the file, where
3496  * Emacs will automagically detect them.
3497  * ---------------------------------------------------------------------
3498  * Local variables:
3499  * mode: c
3500  * indent-tabs-mode: t
3501  * c-basic-offset: 4
3502  * tab-width: 4
3503  * End:
3504  * vim:noexpandtab:sw=4:ts=4:
3505  */