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