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