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