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