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