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