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