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