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