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