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