df4212e37183a491ab8972c64d3ff9750880a551
[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, (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
2983                 
2984         } /* if (bptr -> flags >= BBREACHED) */
2985         } /* for basic block */
2986         
2987         dseg_createlinenumbertable(cd);
2988
2989         /* generate stubs */
2990
2991         emit_patcher_stubs(jd);
2992         REPLACEMENT_EMIT_STUBS(jd);
2993         
2994         /* everything's ok */
2995
2996         return true;    
2997 }
2998
2999
3000 /* codegen_emit_stub_compiler **************************************************
3001
3002    Emits a stub routine which calls the compiler.
3003         
3004 *******************************************************************************/
3005
3006 void codegen_emit_stub_compiler(jitdata *jd)
3007 {
3008         methodinfo  *m;
3009         codegendata *cd;
3010
3011         /* get required compiler data */
3012
3013         m  = jd->m;
3014         cd = jd->cd;
3015
3016         /* code for the stub */
3017
3018         /* no window save yet, user caller's PV */
3019         M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
3020         M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
3021         M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO);  /* jump to the compiler, RA is wasted */
3022         M_NOP;
3023 }
3024
3025
3026 /* codegen_emit_stub_native ****************************************************
3027
3028    Emits a stub routine which calls a native method.
3029
3030 *******************************************************************************/
3031
3032 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3033 {
3034         methodinfo   *m;
3035         codeinfo     *code;
3036         codegendata  *cd;
3037         methoddesc   *md;
3038         s4            nativeparams;
3039         s4            i, j;                 /* count variables                    */
3040         s4            t;
3041         s4            s1, s2, disp;
3042         s4            funcdisp;             /* displacement of the function       */
3043         s4            fltregarg_offset[FLT_ARG_CNT];
3044
3045         /* get required compiler data */
3046
3047         m    = jd->m;
3048         code = jd->code;
3049         cd   = jd->cd;
3050
3051         /* initialize variables */
3052
3053         md = m->parseddesc;
3054         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3055
3056         /* calculate stack frame size */
3057
3058         cd->stackframesize =
3059                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3060                 sizeof(localref_table) / SIZEOF_VOID_P +
3061                 md->paramcount +                /* for saving arguments over calls    */
3062                 nmd->memuse +  /* nmd knows about the native stackframe layout */
3063                 WINSAVE_CNT;
3064
3065
3066         /* keep stack 16-byte aligned (ABI requirement) */
3067
3068         if (cd->stackframesize & 1)
3069                 cd->stackframesize++;
3070
3071         /* create method header */
3072
3073         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3074         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
3075         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
3076         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3077         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3078         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3079         (void) dseg_addlinenumbertablesize(cd);
3080         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
3081
3082         /* generate stub code */
3083
3084         M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe    */
3085
3086 #if !defined(NDEBUG)
3087         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3088                 emit_verbosecall_enter(jd);
3089 #endif
3090
3091         /* get function address (this must happen before the stackframeinfo) */
3092
3093         funcdisp = dseg_add_functionptr(cd, f);
3094
3095 #if !defined(WITH_STATIC_CLASSPATH)
3096         if (f == NULL) {
3097                 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3098         }
3099 #endif
3100
3101         /* save float argument registers (into abi parameter slots) */
3102
3103         assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3104
3105         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3106                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3107                         s1 = WINSAVE_CNT + (j * 8);
3108                         M_DST(abi_registers_float_argument[i], REG_SP, BIAS + s1);
3109                         fltregarg_offset[i] = s1; /* remember stack offset */
3110                         j++;
3111                 }
3112         }
3113
3114         /* prepare data structures for native function call */
3115
3116         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
3117         M_MOV(REG_PV_CALLEE, REG_OUT1);
3118         M_MOV(REG_FP, REG_OUT2); /* java sp */
3119         M_MOV(REG_RA_CALLEE, REG_OUT3);
3120         disp = dseg_add_functionptr(cd, codegen_start_native_call);
3121         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3122         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3123         M_NOP; /* XXX fill me! */
3124
3125         /* keep float arguments on stack */
3126 #if 0
3127         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3128                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3129                         M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3130                         j++;
3131                 }
3132         }
3133 #endif
3134
3135         /* copy or spill arguments to new locations */
3136
3137         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3138                 t = md->paramtypes[i].type;
3139
3140                 if (IS_INT_LNG_TYPE(t)) {
3141
3142                         /* integral types */
3143
3144                         if (!md->params[i].inmemory) {
3145                                 s1 = md->params[i].regoff;
3146                                 /* s1 refers to the old window, transpose */
3147                                 s1 = REG_WINDOW_TRANSPOSE(s1);
3148
3149                                 if (!nmd->params[j].inmemory) {
3150                                         s2 = nat_argintregs[nmd->params[j].regoff];
3151                                         M_INTMOVE(s1, s2);
3152                                 } else {
3153                                         s2 = nmd->params[j].regoff - 6;
3154                                         M_AST(s1, REG_SP, CSTACK + s2 * 8);
3155                                 }
3156
3157                         } else {
3158                                 if (!nmd->params[j].inmemory) {
3159                                         /* JIT stack arg -> NAT reg arg */
3160
3161                                         /* Due to the Env pointer that is always passed, the 6th JIT arg   */
3162                                         /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3163
3164                                         assert(false); /* path never taken */
3165                                 }
3166
3167                                 s1 = md->params[i].regoff + cd->stackframesize;
3168                                 s2 = nmd->params[j].regoff - 6;
3169                                 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
3170                                 M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
3171                         }
3172
3173                 } else {
3174
3175                         /* floating point types */
3176
3177                         if (!md->params[i].inmemory) {
3178                                 s1 = md->params[i].regoff;
3179
3180                                 if (!nmd->params[j].inmemory) {
3181
3182                                         /* no mapping to regs needed, native flt args use regoff */
3183                                         s2 = nmd->params[j].regoff;
3184
3185                                         /* JIT float regs are still on the stack */
3186                                         M_DLD(s2, REG_SP, BIAS + fltregarg_offset[i]);
3187                                 } 
3188                                 else {
3189                                         /* not supposed to happen with 16 NAT flt args */
3190                                         assert(false); 
3191                                         /*
3192                                         s2 = nmd->params[j].regoff;
3193                                         if (IS_2_WORD_TYPE(t))
3194                                                 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3195                                         else
3196                                                 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3197                                         */
3198                                 }
3199
3200                         } 
3201                         else {
3202                                 s1 = md->params[i].regoff + cd->stackframesize;
3203
3204                                 if (!nmd->params[j].inmemory) {
3205
3206                                         /* JIT stack -> NAT reg */
3207
3208                                         s2 = nmd->params[j].regoff; 
3209                                         M_DLD(s2, REG_SP, CSTACK + s1 * 8);
3210                                 }
3211                                 else {
3212
3213                                         /* JIT stack -> NAT stack */
3214
3215                                         s2 = nmd->params[j].regoff - 6;
3216
3217                                         /* The FTMP register may already be loaded with args */
3218                                         /* we know $f0 is unused because of the env pointer  */
3219                                         M_DLD(REG_F0, REG_SP, CSTACK + s1 * 8);
3220                                         M_DST(REG_F0, REG_SP, CSTACK + s2 * 8);
3221                                 }
3222                         }
3223                 }
3224         }
3225         
3226
3227         /* put class into second argument register */
3228
3229         if (m->flags & ACC_STATIC) {
3230                 disp = dseg_add_address(cd, m->class);
3231                 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3232         }
3233
3234         /* put env into first argument register */
3235
3236         disp = dseg_add_address(cd, _Jv_env);
3237         M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3238
3239         /* do the native function call */
3240
3241         M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method       */
3242         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method                 */
3243         M_NOP;                              /* delay slot                         */
3244
3245         /* save return value */
3246
3247         if (md->returntype.type != TYPE_VOID) {
3248                 if (IS_INT_LNG_TYPE(md->returntype.type))
3249                         M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3250                 else
3251                         M_DST(REG_FRESULT, REG_SP, CSTACK);
3252         }
3253         
3254         /* Note: native functions return float values in %f0 (see ABI) */
3255         /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3256
3257 #if !defined(NDEBUG)
3258         /* But for the trace function we need to put a flt result into %f1 */
3259         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3260                 if (!IS_2_WORD_TYPE(md->returntype.type))
3261                         M_FLD(REG_FRESULT, REG_SP, CSTACK);
3262                 emit_verbosecall_exit(jd);
3263         }
3264 #endif
3265
3266         /* remove native stackframe info */
3267
3268         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3269         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3270         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3271         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3272         M_NOP; /* XXX fill me! */
3273         M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3274
3275         /* restore float return value, int return value already in our return reg */
3276
3277         if (md->returntype.type != TYPE_VOID) {
3278                 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3279                         if (IS_2_WORD_TYPE(md->returntype.type))
3280                                 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3281                         else
3282                                 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3283                 }
3284         }
3285
3286         /* check for exception */
3287         M_BNEZ(REG_ITMP2_XPTR, 4);          /* if no exception then return        */
3288         M_NOP;
3289
3290         M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3291         M_NOP;
3292
3293         /* handle exception */
3294         
3295         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3296         M_ALD(REG_ITMP1, REG_PV, disp);     /* load asm exception handler address */
3297         M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address             */
3298         M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler     */
3299         M_RESTORE(REG_ZERO, 0, REG_ZERO);   /* restore callers window (DELAY)     */
3300         
3301         /* generate patcher stubs */
3302
3303         emit_patcher_stubs(jd);
3304 }
3305
3306 /*
3307  * These are local overrides for various environment variables in Emacs.
3308  * Please do not remove this and leave it at the end of the file, where
3309  * Emacs will automagically detect them.
3310  * ---------------------------------------------------------------------
3311  * Local variables:
3312  * mode: c
3313  * indent-tabs-mode: t
3314  * c-basic-offset: 4
3315  * tab-width: 4
3316  * End:
3317  * vim:noexpandtab:sw=4:ts=4:
3318  */