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