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