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