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