* src/vm/jit/sparc64/asmpart.S: Fixed some exception handling.
[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                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1781                                                                         iptr->sx.s23.s2.uc, 0);
1782
1783                                 if (opt_showdisassemble) {
1784                                         M_NOP; M_NOP;
1785                                 }
1786                         }
1787 #endif /* ENABLE_VERIFIER */
1788
1789                         disp = dseg_add_functionptr(cd, asm_handle_exception);
1790                         M_ALD(REG_ITMP2, REG_PV, disp);
1791                         M_JMP(REG_ITMP3_XPC, REG_ITMP2, REG_ZERO);
1792                         M_NOP;
1793                         M_NOP;              /* nop ensures that XPC is less than the end */
1794                                             /* of basic block                            */
1795                         ALIGNCODENOP;
1796                         break;
1797
1798                 case ICMD_GOTO:         /* ... ==> ...                                */
1799                 case ICMD_RET:          /* ... ==> ...                                */
1800
1801                         M_BR(0);
1802                         codegen_add_branch_ref(cd, iptr->dst.block);
1803                         M_NOP;
1804                         ALIGNCODENOP;
1805                         break;
1806
1807                 case ICMD_JSR:          /* ... ==> ...                                */
1808
1809                         M_BR(0);
1810                         codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
1811                         M_NOP;
1812                         ALIGNCODENOP;
1813                         break;
1814
1815                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
1816
1817                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1818                         M_BEQZ(s1, 0);
1819                         codegen_add_branch_ref(cd, iptr->dst.block);
1820                         M_NOP;
1821                         break;
1822
1823                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
1824
1825                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1826                         M_BNEZ(s1, 0);
1827                         codegen_add_branch_ref(cd, iptr->dst.block);
1828                         M_NOP;
1829                         break;
1830
1831                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
1832
1833                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1834                         if (iptr->sx.val.i == 0) {
1835                                 M_BEQZ(s1, 0);
1836                         } else {
1837                                 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1838                                         M_CMP_IMM(s1, iptr->sx.val.i);
1839                                         }
1840                                 else {
1841                                         ICONST(REG_ITMP2, iptr->sx.val.i);
1842                                         M_CMP(s1, REG_ITMP2);
1843                                         }
1844                                 M_BEQ(0);
1845                                 }
1846                         codegen_add_branch_ref(cd, iptr->dst.block);
1847                         M_NOP;
1848                         break;
1849
1850                 case ICMD_IFLT:         /* ..., value ==> ...                         */
1851
1852                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1853                         if (iptr->sx.val.i == 0) {
1854                                 M_BLTZ(s1, 0);
1855                         } else {
1856                                 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1857                                         M_CMP_IMM(s1, iptr->sx.val.i);
1858                                 } else {
1859                                         ICONST(REG_ITMP2, iptr->sx.val.i);
1860                                         M_CMP(s1, REG_ITMP2);
1861                                 }
1862                                 M_BLT(0);
1863                         }
1864                         codegen_add_branch_ref(cd, iptr->dst.block);
1865                         M_NOP;
1866                         break;
1867
1868                 case ICMD_IFLE:         /* ..., value ==> ...                         */
1869
1870                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1871                         if (iptr->sx.val.i == 0) {
1872                                 M_BLEZ(s1, 0);
1873                                 }
1874                         else {
1875                                 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1876                                         M_CMP_IMM(s1, iptr->sx.val.i);
1877                                         }
1878                                 else {
1879                                         ICONST(REG_ITMP2, iptr->sx.val.i);
1880                                         M_CMP(s1, REG_ITMP2);
1881                                 }
1882                                 M_BLE(0);
1883                         }
1884                         codegen_add_branch_ref(cd, iptr->dst.block);
1885                         M_NOP;
1886                         break;
1887
1888                 case ICMD_IFNE:         /* ..., value ==> ...                         */
1889
1890                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1891                         if (iptr->sx.val.i == 0) {
1892                                 M_BNEZ(s1, 0);
1893                                 }
1894                         else {
1895                                 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1896                                         M_CMP_IMM(s1, iptr->sx.val.i);
1897                                 }
1898                                 else {
1899                                         ICONST(REG_ITMP2, iptr->sx.val.i);
1900                                         M_CMP(s1, REG_ITMP2);
1901                                 }
1902                                 M_BNE(0);
1903                         }
1904                         codegen_add_branch_ref(cd, iptr->dst.block);
1905                         M_NOP;
1906                         break;
1907                                                 
1908                 case ICMD_IFGT:         /* ..., value ==> ...                         */
1909
1910                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1911                         if (iptr->sx.val.i == 0) {
1912                                 M_BGTZ(s1, 0);
1913                         } 
1914                         else {
1915                                 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1916                                         M_CMP_IMM(s1, iptr->sx.val.i);
1917                                 } else {
1918                                         ICONST(REG_ITMP2, iptr->sx.val.i);
1919                                         M_CMP(s1, REG_ITMP2);
1920                                 }
1921                                 M_BGT(0);
1922                         }
1923                         codegen_add_branch_ref(cd, iptr->dst.block);
1924                         M_NOP;
1925                         break;
1926
1927                 case ICMD_IFGE:         /* ..., value ==> ...                         */
1928
1929                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1930                         if (iptr->sx.val.i == 0) {
1931                                 M_BGEZ(s1, 0);
1932                                 }
1933                         else {
1934                                 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1935                                         M_CMP_IMM(s1, iptr->sx.val.i);
1936                                         }
1937                                 else {
1938                                         ICONST(REG_ITMP2, iptr->sx.val.i);
1939                                         M_CMP(s1, REG_ITMP2);
1940                                 }
1941                                 M_BGE(0);
1942                         }
1943                         codegen_add_branch_ref(cd, iptr->dst.block);
1944                         M_NOP;
1945                         break;
1946                         
1947                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
1948
1949                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1950                         if (iptr->sx.val.l == 0) {
1951                                 M_BEQZ(s1, 0);
1952                         }
1953                         else {
1954                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1955                                         M_CMP_IMM(s1, iptr->sx.val.l);
1956                                 }
1957                                 else {
1958                                         LCONST(REG_ITMP2, iptr->sx.val.l);
1959                                         M_CMP(s1, REG_ITMP2);
1960                                 }
1961                                 M_XBEQ(0);
1962                         }
1963                         codegen_add_branch_ref(cd, iptr->dst.block);
1964                         M_NOP;
1965                         break;
1966                         
1967                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
1968
1969                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1970                         if (iptr->sx.val.l == 0) {
1971                                 M_BLTZ(s1, 0);
1972                         } 
1973                         else {
1974                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1975                                         M_CMP_IMM(s1, iptr->sx.val.l);
1976                                 } 
1977                                 else {
1978                                         ICONST(REG_ITMP2, iptr->sx.val.l);
1979                                         M_CMP(s1, REG_ITMP2);
1980                                 }
1981                                 M_XBLT(0);
1982                         }
1983                         codegen_add_branch_ref(cd, iptr->dst.block);
1984                         M_NOP;
1985                         break;
1986
1987                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
1988
1989                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1990                         if (iptr->sx.val.l == 0) {
1991                                 M_BLEZ(s1, 0);
1992                                 }
1993                         else {
1994                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1995                                         M_CMP_IMM(s1, iptr->sx.val.l);
1996                                         }
1997                                 else {
1998                                         ICONST(REG_ITMP2, iptr->sx.val.l);
1999                                         M_CMP(s1, REG_ITMP2);
2000                                 }
2001                                 M_XBLE(0);
2002                         }
2003                         codegen_add_branch_ref(cd, iptr->dst.block);
2004                         M_NOP;
2005                         break;
2006                         
2007                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2008
2009                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2010                         if (iptr->sx.val.l == 0) {
2011                                 M_BNEZ(s1, 0);
2012                                 }
2013                         else {
2014                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2015                                         M_CMP_IMM(s1, iptr->sx.val.i);
2016                                 }
2017                                 else {
2018                                         ICONST(REG_ITMP2, iptr->sx.val.l);
2019                                         M_CMP(s1, REG_ITMP2);
2020                                 }
2021                                 M_XBNE(0);
2022                         }
2023                         codegen_add_branch_ref(cd, iptr->dst.block);
2024                         M_NOP;
2025                         break;
2026                                                 
2027                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2028
2029                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2030                         if (iptr->sx.val.l == 0) {
2031                                 M_BLTZ(s1, 0);
2032                         } else {
2033                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2034                                         M_CMP_IMM(s1, iptr->sx.val.l);
2035                                 } else {
2036                                         ICONST(REG_ITMP2, iptr->sx.val.l);
2037                                         M_CMP(s1, REG_ITMP2);
2038                                 }
2039                                 M_XBGT(0);
2040                         }
2041                         codegen_add_branch_ref(cd, iptr->dst.block);
2042                         M_NOP;
2043                         break;
2044
2045                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2046
2047                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2048                         if (iptr->sx.val.l == 0) {
2049                                 M_BLEZ(s1, 0);
2050                                 }
2051                         else {
2052                                 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2053                                         M_CMP_IMM(s1, iptr->sx.val.l);
2054                                         }
2055                                 else {
2056                                         ICONST(REG_ITMP2, iptr->sx.val.l);
2057                                         M_CMP(s1, REG_ITMP2);
2058                                 }
2059                                 M_XBGE(0);
2060                         }
2061                         codegen_add_branch_ref(cd, iptr->dst.block);
2062                         M_NOP;
2063                         break;                  
2064                         
2065
2066                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
2067                 case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
2068
2069                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2070                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2071                         M_CMP(s1, s2);
2072                         M_XBEQ(0);
2073                         codegen_add_branch_ref(cd, iptr->dst.block);
2074                         M_NOP;
2075                         break;
2076
2077                 case ICMD_IF_ICMPEQ:    /* 32-bit compare                             */
2078
2079                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2080                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2081                         M_CMP(s1, s2);
2082                         M_BEQ(0);
2083                         codegen_add_branch_ref(cd, iptr->dst.block);
2084                         M_NOP;
2085                         break;
2086
2087                 case ICMD_IF_ACMPNE:    /* ..., value, value ==> ...                  */
2088                 case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
2089
2090                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2091                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2092                         M_CMP(s1, s2);
2093                         M_XBNE(0);
2094                         codegen_add_branch_ref(cd, iptr->dst.block);
2095                         M_NOP;
2096                         break;
2097                         
2098                 case ICMD_IF_ICMPNE:    /* 32-bit compare                             */
2099
2100                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2101                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2102                         M_CMP(s1, s2);
2103                         M_BNE(0);
2104                         codegen_add_branch_ref(cd, iptr->dst.block);
2105                         M_NOP;
2106                         break;
2107
2108                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2109
2110                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2111                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2112                         M_CMP(s1, s2);
2113                         M_XBLT(0);
2114                         codegen_add_branch_ref(cd, iptr->dst.block);
2115                         M_NOP;
2116                         break;
2117                         
2118                 case ICMD_IF_ICMPLT:    /* 32-bit compare                             */
2119
2120                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2121                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2122                         M_CMP(s1, s2);
2123                         M_BLT(0);
2124                         codegen_add_branch_ref(cd, iptr->dst.block);
2125                         M_NOP;
2126                         break;
2127
2128                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2129
2130                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2131                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2132                         M_CMP(s1, s2);
2133                         M_XBGT(0);
2134                         codegen_add_branch_ref(cd, iptr->dst.block);
2135                         M_NOP;
2136                         break;
2137                         
2138                 case ICMD_IF_ICMPGT:    /* 32-bit compare                             */
2139
2140                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2141                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2142                         M_CMP(s1, s2);
2143                         M_BGT(0);
2144                         codegen_add_branch_ref(cd, iptr->dst.block);
2145                         M_NOP;
2146                         break;
2147
2148                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2149
2150                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2151                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2152                         M_CMP(s1, s2);
2153                         M_BLE(0);
2154                         codegen_add_branch_ref(cd, iptr->dst.block);
2155                         M_NOP;
2156                         break;
2157                         
2158                 case ICMD_IF_ICMPLE:    /* 32-bit compare                             */
2159
2160                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2161                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2162                         M_CMP(s1, s2);
2163                         M_BLE(0);
2164                         codegen_add_branch_ref(cd, iptr->dst.block);
2165                         M_NOP;
2166                         break;                  
2167         
2168
2169                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2170
2171                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2172                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2173                         M_CMP(s1, s2);
2174                         M_BGE(0);
2175                         codegen_add_branch_ref(cd, iptr->dst.block);
2176                         M_NOP;
2177                         break;
2178                         
2179                 case ICMD_IF_ICMPGE:    /* 32-bit compare                             */
2180
2181                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2182                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2183                         M_CMP(s1, s2);
2184                         M_BGE(0);
2185                         codegen_add_branch_ref(cd, iptr->dst.block);
2186                         M_NOP;
2187                         break;
2188
2189
2190                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2191                 case ICMD_LRETURN:
2192
2193                         s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2194                         M_INTMOVE(s1, REG_RESULT_CALLEE);
2195                         goto nowperformreturn;
2196
2197                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2198
2199                         s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2200                         M_INTMOVE(s1, REG_RESULT_CALLEE);
2201
2202 #ifdef ENABLE_VERIFIER
2203                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2204                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2205                                                                         iptr->sx.s23.s2.uc, 0);
2206
2207                                 if (opt_showdisassemble) {
2208                                         M_NOP; M_NOP;
2209                                 }
2210                         }
2211 #endif /* ENABLE_VERIFIER */
2212                         goto nowperformreturn;
2213
2214                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2215                 case ICMD_DRETURN:
2216
2217                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2218                         M_FLTMOVE(s1, REG_FRESULT);
2219                         goto nowperformreturn;
2220
2221                 case ICMD_RETURN:       /* ...  ==> ...                               */
2222
2223 nowperformreturn:
2224                         {
2225                         s4 i, p;
2226                         
2227                         p = cd->stackframesize;
2228
2229 #if !defined(NDEBUG)
2230                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2231                                 emit_verbosecall_exit(jd);
2232 #endif
2233
2234 #if defined(ENABLE_THREADS)
2235                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2236 /* XXX: REG_RESULT is save, but what about FRESULT? */
2237                                 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2238
2239                                 switch (iptr->opc) {
2240                                 case ICMD_FRETURN:
2241                                 case ICMD_DRETURN:
2242                                         M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2243                                         break;
2244                                 }
2245
2246                                 disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
2247                                 M_ALD(REG_ITMP3, REG_PV, disp);
2248                                 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2249
2250                                 switch (iptr->opc) {
2251                                 case ICMD_FRETURN:
2252                                 case ICMD_DRETURN:
2253                                         M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2254                                         break;
2255                                 }
2256                         }
2257 #endif
2258
2259
2260
2261                         M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2262                         M_NOP;
2263                         ALIGNCODENOP;
2264                         }
2265                         break;
2266
2267                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2268                         {
2269                         s4 i, l;
2270                         branch_target_t *table;
2271
2272                         table = iptr->dst.table;
2273
2274                         l = iptr->sx.s23.s2.tablelow;
2275                         i = iptr->sx.s23.s3.tablehigh;
2276                         
2277                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2278                         if (l == 0) {
2279                                 M_INTMOVE(s1, REG_ITMP1);
2280                         }
2281                         else if (l <= 4095) {
2282                                 M_ADD_IMM(s1, -l, REG_ITMP1);
2283                         }
2284                         else {
2285                                 ICONST(REG_ITMP2, l);
2286                                 /* XXX: do I need to truncate s1 to 32-bit ? */
2287                                 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2288                         }
2289                         i = i - l + 1;
2290
2291
2292                         /* range check */
2293                                         
2294                         if (i <= 4095) {
2295                                 M_CMP_IMM(REG_ITMP1, i);
2296                         }
2297                         else {
2298                                 ICONST(REG_ITMP2, i);
2299                                 M_CMP(REG_ITMP1, REG_ITMP2);
2300                         }               
2301                         M_XBULT(0);
2302                         codegen_add_branch_ref(cd, table[0].block); /* default target */
2303                         M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
2304
2305                         /* build jump table top down and use address of lowest entry */
2306
2307                         table += i;
2308
2309                         while (--i >= 0) {
2310                                 dseg_add_target(cd, table->block); 
2311                                 --table;
2312                                 }
2313                         }
2314
2315                         /* length of dataseg after last dseg_addtarget is used by load */
2316
2317                         M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2318                         M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2319                         M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2320                         M_NOP;
2321                         ALIGNCODENOP;
2322                         break;
2323                         
2324                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2325                         {
2326                         s4 i;
2327                         lookup_target_t *lookup;
2328
2329                         lookup = iptr->dst.lookup;
2330
2331                         i = iptr->sx.s23.s2.lookupcount;
2332                         
2333                         MCODECHECK((i<<2)+8);
2334                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2335
2336                         while (--i >= 0) {
2337                                 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2338                                         M_CMP_IMM(s1, lookup->value);
2339                                 } else {                                        
2340                                         ICONST(REG_ITMP2, lookup->value);
2341                                         M_CMP(s1, REG_ITMP2);
2342                                 }
2343                                 M_BEQ(0);
2344                                 codegen_add_branch_ref(cd, lookup->target.block); 
2345                                 M_NOP;
2346                                 ++lookup;
2347                         }
2348
2349                         M_BR(0);
2350                         codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2351                         M_NOP;
2352                         ALIGNCODENOP;
2353                         break;
2354                         }
2355
2356
2357                 case ICMD_BUILTIN:      /* ..., arg1, arg2, arg3 ==> ...              */
2358
2359                         bte = iptr->sx.s23.s3.bte;
2360                         md = bte->md;
2361                         
2362                         /* XXX: proper builtin calling and float args are so not implemented */
2363                         assert(md->paramcount <= 5 && md->argfltreguse < 1);
2364                         
2365                         goto gen_method;
2366
2367                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2368
2369                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2370                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2371                 case ICMD_INVOKEINTERFACE:
2372
2373                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2374                                 lm = NULL;
2375                                 um = iptr->sx.s23.s3.um;
2376                                 md = um->methodref->parseddesc.md;
2377                         }
2378                         else {
2379                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2380                                 um = NULL;
2381                                 md = lm->parseddesc;
2382                         }
2383
2384 gen_method:
2385                         s3 = md->paramcount;
2386
2387                         MCODECHECK((s3 << 1) + 64);
2388
2389                         /* copy arguments to registers or stack location                  */
2390
2391                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2392                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2393
2394                                 if (var->flags & PREALLOC)
2395                                         continue;
2396
2397                                 if (IS_INT_LNG_TYPE(var->type)) {
2398                                         if (!md->params[s3].inmemory) {
2399                                                 s1 = rd->argintregs[md->params[s3].regoff];
2400                                                 d = emit_load(jd, iptr, var, s1);
2401                                                 M_INTMOVE(d, s1);
2402                                         } 
2403                                         else {
2404                                                 d = emit_load(jd, iptr, var, REG_ITMP1);
2405                                                 M_STX(d, REG_SP, md->params[s3].regoff * 8);
2406                                         }
2407                                 }
2408                                 else {
2409                                         if (!md->params[s3].inmemory) {
2410                                                 s1 = rd->argfltregs[md->params[s3].regoff];
2411                                                 d = emit_load(jd, iptr, var, s1);
2412                                                 if (IS_2_WORD_TYPE(var->type))
2413                                                         M_DMOV(d, s1);
2414                                                 else
2415                                                         M_FMOV(d, s1);
2416                                         }
2417                                         else {
2418                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2419                                                 if (IS_2_WORD_TYPE(var->type))
2420                                                         M_DST(d, REG_SP, md->params[s3].regoff * 8);
2421                                                 else
2422                                                         M_FST(d, REG_SP, md->params[s3].regoff * 8);
2423                                         }
2424                                 }
2425                         }
2426
2427                         switch (iptr->opc) {
2428                         case ICMD_BUILTIN:
2429                                 disp = dseg_add_functionptr(cd, bte->fp);
2430
2431                                 M_ALD(REG_PV_CALLER, REG_PV, disp);  /* built-in-function pointer */
2432                                 s1 = REG_PV_CALLER;
2433
2434                                 /* c call, allocate parameter array */
2435                                 M_LDA(REG_SP, REG_SP, -(ABI_PARAMARRAY_SLOTS) * 8);
2436
2437                                 break;
2438
2439                         case ICMD_INVOKESPECIAL:
2440                                 M_BEQZ(REG_OUT0, 0);
2441                                 codegen_add_nullpointerexception_ref(cd);
2442                                 M_NOP;
2443                                 /* fall through */
2444
2445                         case ICMD_INVOKESTATIC:
2446                                 if (lm == NULL) {
2447                                         disp = dseg_add_unique_address(cd, NULL);
2448
2449                                         codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2450                                                                                 um, disp);
2451                                 }
2452                                 else
2453                                         disp = dseg_add_address(cd, lm->stubroutine);
2454
2455                                 M_ALD(REG_PV_CALLER, REG_PV, disp);          /* method pointer in pv */
2456                                 s1 = REG_PV_CALLER;
2457                                 break;
2458
2459                         case ICMD_INVOKEVIRTUAL:
2460                                 gen_nullptr_check(REG_OUT0);
2461
2462                                 if (lm == NULL) {
2463                                         codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2464
2465                                         s1 = 0;
2466                                 }
2467                                 else
2468                                         s1 = OFFSET(vftbl_t, table[0]) +
2469                                                 sizeof(methodptr) * lm->vftblindex;
2470
2471                                 M_ALD(REG_METHODPTR, REG_OUT0,
2472                                           OFFSET(java_objectheader, vftbl));
2473                                 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2474                                 s1 = REG_PV_CALLER;
2475                                 break;
2476
2477                         case ICMD_INVOKEINTERFACE:
2478                                 gen_nullptr_check(rd->argintregs[0]);
2479
2480                                 if (lm == NULL) {
2481                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2482
2483                                         if (opt_showdisassemble) {
2484                                                 M_NOP; M_NOP;
2485                                         }
2486
2487                                         s1 = 0;
2488                                         s2 = 0;
2489                                 } 
2490                                 else {
2491                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
2492                                                 sizeof(methodptr*) * lm->class->index;
2493
2494                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
2495                                 }
2496
2497                                 M_ALD(REG_METHODPTR, REG_OUT0,
2498                                           OFFSET(java_objectheader, vftbl));
2499                                 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2500                                 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2501                                 s1 = REG_PV_CALLER;
2502                                 break;
2503                         }
2504
2505                         /* generate the actual call */
2506
2507                         M_JMP(REG_RA_CALLER, s1, REG_ZERO);
2508                         M_NOP;
2509                         disp = (s4) (cd->mcodeptr - cd->mcodebase);
2510                         /* REG_RA holds the value of the jmp instruction, therefore +8 */
2511                         M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
2512
2513                         if (iptr->opc == ICMD_BUILTIN) {
2514                                 /* remove param slots */
2515                                 M_LDA(REG_SP, REG_SP, (ABI_PARAMARRAY_SLOTS) * 8);
2516                         }
2517
2518
2519                         /* actually only used for ICMD_BUILTIN */
2520
2521                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2522                                 M_BEQZ(REG_RESULT_CALLER, 0);
2523                                 codegen_add_fillinstacktrace_ref(cd);
2524                                 M_NOP;
2525                         }
2526
2527                         /* store return value */
2528
2529                         d = md->returntype.type;
2530
2531                         if (d != TYPE_VOID) {
2532                                 if (IS_INT_LNG_TYPE(d)) {
2533                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2534                                         M_INTMOVE(REG_RESULT_CALLER, s1);
2535                                 } 
2536                                 else {
2537                                         s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2538                                         if (IS_2_WORD_TYPE(d)) {
2539                                                 M_DBLMOVE(REG_FRESULT, s1);
2540                                         } else {
2541                                                 M_FLTMOVE(REG_FRESULT, s1);
2542                                         }
2543                                 }
2544                                 emit_store_dst(jd, iptr, s1);
2545                         }
2546                         break;
2547
2548
2549                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
2550                 /* XXX needs manual attention! */
2551                                       /* val.a: (classinfo*) superclass               */
2552
2553                         /*  superclass is an interface:
2554                          *
2555                          *  OK if ((sub == NULL) ||
2556                          *         (sub->vftbl->interfacetablelength > super->index) &&
2557                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
2558                          *
2559                          *  superclass is a class:
2560                          *
2561                          *  OK if ((sub == NULL) || (0
2562                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2563                          *         super->vftbl->diffvall));
2564                          */
2565
2566                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2567                                 classinfo *super;
2568                                 vftbl_t   *supervftbl;
2569                                 s4         superindex;
2570
2571                                 super = iptr->sx.s23.s3.c.cls;
2572
2573                                 if (super == NULL) {
2574                                         superindex = 0;
2575                                         supervftbl = NULL;
2576                                 }
2577                                 else {
2578                                         superindex = super->index;
2579                                         supervftbl = super->vftbl;
2580                                 }
2581
2582 #if defined(ENABLE_THREADS)
2583                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2584 #endif
2585
2586                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2587
2588                                 /* calculate interface checkcast code size */
2589
2590                                 s2 = 8;
2591                                 if (super == NULL)
2592                                         s2 += (opt_showdisassemble ? 2 : 0);
2593
2594                                 /* calculate class checkcast code size */
2595
2596                                 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
2597                                 if (super == NULL)
2598                                         s3 += (opt_showdisassemble ? 2 : 0);
2599
2600                                 /* if class is not resolved, check which code to call */
2601
2602                                 if (super == NULL) {
2603                                         M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2604                                         M_NOP;
2605
2606                                         disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
2607
2608                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2609                                                                                 iptr->sx.s23.s3.c.ref,
2610                                                                                 disp);
2611
2612                                         if (opt_showdisassemble) {
2613                                                 M_NOP; M_NOP;
2614                                         }
2615
2616                                         M_ILD(REG_ITMP2, REG_PV, disp);
2617                                         M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2618                                         M_BEQZ(REG_ITMP2, 1 + s2 + 2);
2619                                         M_NOP;
2620                                 }
2621
2622                                 /* interface checkcast code */
2623
2624                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2625                                         if (super == NULL) {
2626                                                 codegen_addpatchref(cd,
2627                                                                                         PATCHER_checkcast_instanceof_interface,
2628                                                                                         iptr->sx.s23.s3.c.ref,
2629                                                                                         0);
2630
2631                                                 if (opt_showdisassemble) {
2632                                                         M_NOP; M_NOP;
2633                                                 }
2634                                         }
2635                                         else {
2636                                                 M_BEQZ(s1, 1 + s2);
2637                                                 M_NOP;
2638                                         }
2639
2640                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2641                                         M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2642                                         M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2643                                         M_BLEZ(REG_ITMP3, 0);
2644                                         codegen_add_classcastexception_ref(cd, s1);
2645                                         M_NOP;
2646                                         M_ALD(REG_ITMP3, REG_ITMP2,
2647                                                   (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2648                                                                 superindex * sizeof(methodptr*)));
2649                                         M_BEQZ(REG_ITMP3, 0);
2650                                         codegen_add_classcastexception_ref(cd, s1);
2651                                         M_NOP;
2652
2653                                         if (super == NULL) {
2654                                                 M_BR(1 + s3);
2655                                                 M_NOP;
2656                                         }
2657                                 }
2658
2659                                 /* class checkcast code */
2660
2661                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2662                                         if (super == NULL) {
2663                                                 disp = dseg_add_unique_address(cd, NULL);
2664
2665                                                 codegen_addpatchref(cd,
2666                                                                                         PATCHER_checkcast_instanceof_class,
2667                                                                                         iptr->sx.s23.s3.c.ref,
2668                                                                                         disp);
2669
2670                                                 if (opt_showdisassemble) {
2671                                                         M_NOP; M_NOP;
2672                                                 }
2673                                         }
2674                                         else {
2675                                                 disp = dseg_add_address(cd, supervftbl);
2676
2677                                                 M_BEQZ(s1, 1 + s3);
2678                                                 M_NOP;
2679                                         }
2680
2681                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2682                                         M_ALD(REG_ITMP3, REG_PV, disp);
2683 #if defined(ENABLE_THREADS)
2684                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2685 #endif
2686                                         M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2687                                         /*                              if (s1 != REG_ITMP1) { */
2688                                         /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2689                                         /*                                      M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2690                                         /*  #if defined(ENABLE_THREADS) */
2691                                         /*                                      codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2692                                         /*  #endif */
2693                                         /*                                      M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2694
2695                                         /*                              } else { */
2696                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2697                                         M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2698                                         M_ALD(REG_ITMP3, REG_PV, disp);
2699                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2700 #if defined(ENABLE_THREADS)
2701                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2702 #endif
2703                                         /*                              } */
2704                                         M_CMP(REG_ITMP3, REG_ITMP2);
2705                                         M_BULT(0);                         /* branch if ITMP3 < ITMP2 */ 
2706                                         codegen_add_classcastexception_ref(cd, s1);
2707                                         M_NOP;
2708                                 }
2709
2710                                 d = codegen_reg_of_dst(jd, iptr, s1);
2711                         }
2712                         else {
2713                                 /* array type cast-check */
2714
2715                                 s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
2716                                 M_INTMOVE(s1, rd->argintregs[0]);
2717
2718                                 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2719
2720                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2721                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
2722                                                                                 iptr->sx.s23.s3.c.ref,
2723                                                                                 disp);
2724
2725                                         if (opt_showdisassemble) {
2726                                                 M_NOP; M_NOP;
2727                                         }
2728                                 }
2729
2730                                 M_ALD(rd->argintregs[1], REG_PV, disp);
2731                                 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2732                                 M_ALD(REG_ITMP3, REG_PV, disp);
2733                                 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2734                                 M_NOP;
2735
2736                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2737                                 M_BEQZ(REG_RESULT_CALLER, 0);
2738                                 codegen_add_classcastexception_ref(cd, s1);
2739                                 M_NOP;
2740
2741                                 d = codegen_reg_of_dst(jd, iptr, s1);
2742                         }
2743
2744                         M_INTMOVE(s1, d);
2745                         emit_store_dst(jd, iptr, d);
2746                         break;
2747
2748
2749
2750                 default:
2751                         *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
2752                         return false;
2753                         
2754         } /* switch */
2755                 
2756         } /* for instruction */
2757         
2758
2759                 
2760         } /* if (bptr -> flags >= BBREACHED) */
2761         } /* for basic block */
2762         
2763         dseg_createlinenumbertable(cd);
2764
2765         /* generate exception and patcher stubs */
2766
2767         emit_exception_stubs(jd);
2768         emit_patcher_stubs(jd);
2769         emit_replacement_stubs(jd);
2770
2771         codegen_finish(jd);
2772         
2773         /* everything's ok */
2774
2775         return true;    
2776 }
2777
2778
2779
2780
2781
2782 /* createcompilerstub **********************************************************
2783
2784    Creates a stub routine which calls the compiler.
2785         
2786 *******************************************************************************/
2787
2788 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
2789 #define COMPILERSTUB_CODESIZE    4 * 4
2790
2791 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2792
2793
2794 u1 *createcompilerstub(methodinfo *m)
2795 {
2796         u1     *s;                          /* memory to hold the stub            */
2797         ptrint      *d;
2798         codeinfo    *code;
2799         codegendata *cd;
2800         s4           dumpsize;
2801         
2802         s = CNEW(u1, COMPILERSTUB_SIZE);
2803
2804         /* set data pointer and code pointer */
2805
2806         d = (ptrint *) s;
2807         s = s + COMPILERSTUB_DATASIZE;
2808
2809         /* mark start of dump memory area */
2810
2811         dumpsize = dump_size();
2812
2813         cd = DNEW(codegendata);
2814         cd->mcodeptr = s;
2815         
2816         /* Store the codeinfo pointer in the same place as in the
2817            methodheader for compiled methods. */
2818
2819         code = code_codeinfo_new(m);
2820
2821         d[0] = (ptrint) asm_call_jit_compiler;
2822         d[1] = (ptrint) m;
2823         d[2] = (ptrint) code;
2824
2825         /* code for the stub */
2826         /* no window save yet, user caller's PV */
2827         M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
2828         M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
2829         M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO);  /* jump to the compiler, RA is wasted */
2830         M_NOP;
2831
2832 #if defined(ENABLE_STATISTICS)
2833         if (opt_stat)
2834                 count_cstub_len += COMPILERSTUB_SIZE;
2835 #endif
2836
2837         /* release dump area */
2838
2839         dump_release(dumpsize);
2840
2841         return s;
2842 }
2843
2844
2845
2846 /* createnativestub ************************************************************
2847
2848    Creates a stub routine which calls a native method.
2849
2850 *******************************************************************************/
2851
2852 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
2853 {
2854         methodinfo   *m;
2855         codeinfo     *code;
2856         codegendata  *cd;
2857         registerdata *rd;
2858         methoddesc   *md;
2859         s4            nativeparams;
2860         s4            i, j;                 /* count variables                    */
2861         s4            t;
2862         s4            s1, s2, disp;
2863         s4            funcdisp;             /* displacement of the function       */
2864
2865         /* get required compiler data */
2866
2867         m    = jd->m;
2868         code = jd->code;
2869         cd   = jd->cd;
2870         rd   = jd->rd;
2871
2872         /* rewrite registers and params */
2873         md_native_reg_setup(jd);
2874         md_native_param_alloc(nmd);
2875
2876         /* initialize variables */
2877
2878         md = m->parseddesc;
2879         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2880
2881         /* calculate stack frame size */
2882
2883         cd->stackframesize =
2884                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2885                 sizeof(localref_table) / SIZEOF_VOID_P +
2886                 md->paramcount +                /* for saving arguments over calls    */
2887                 nmd->memuse +  /* nmd knows about the native stackframe layout */
2888                 WINSAVE_CNT;
2889
2890         /* create method header */
2891
2892         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
2893         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
2894         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
2895         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
2896         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
2897         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
2898         (void) dseg_addlinenumbertablesize(cd);
2899         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
2900
2901         /* generate stub code */
2902
2903         M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe    */
2904
2905 #if !defined(NDEBUG)
2906         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2907                 emit_verbosecall_enter(jd);
2908 #endif
2909
2910         /* get function address (this must happen before the stackframeinfo) */
2911
2912         funcdisp = dseg_add_functionptr(cd, f);
2913
2914 #if !defined(WITH_STATIC_CLASSPATH)
2915         if (f == NULL) {
2916                 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
2917
2918                 if (opt_showdisassemble) {
2919                         M_NOP; M_NOP;
2920                 }
2921         }
2922 #endif
2923
2924         /* save float argument registers */
2925
2926         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
2927                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
2928                         M_DST(rd->argfltregs[i], REG_SP, j * 8);
2929                         j++;
2930                 }
2931         }
2932
2933         /* prepare data structures for native function call */
2934
2935         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
2936         M_MOV(REG_PV_CALLEE, REG_OUT1);
2937         M_MOV(REG_FP, REG_OUT2); /* java sp */
2938         M_MOV(REG_RA_CALLEE, REG_OUT3);
2939         disp = dseg_add_functionptr(cd, codegen_start_native_call);
2940         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
2941         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2942         M_NOP; /* XXX fill me! */
2943
2944         /* restore float argument registers */
2945
2946         for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
2947                 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
2948                         M_DLD(rd->argfltregs[i], REG_SP, j * 8);
2949                         j++;
2950                 }
2951         }
2952
2953         /* copy or spill arguments to new locations */
2954         int num_fltregargs = 0;
2955         int fltregarg_inswap[16];
2956         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
2957                 t = md->paramtypes[i].type;
2958
2959                 if (IS_INT_LNG_TYPE(t)) {
2960                         if (!md->params[i].inmemory) {
2961                                 s1 = rd->argintregs[md->params[i].regoff];
2962                                 /* s1 refers to the old window, transpose */
2963                                 s1 = REG_WINDOW_TRANSPOSE(s1);
2964
2965                                 if (!nmd->params[j].inmemory) {
2966                                         s2 = nat_argintregs[nmd->params[j].regoff];
2967                                         M_INTMOVE(s1, s2);
2968                                 } else {
2969                                         s2 = nmd->params[j].regoff;
2970                                         M_AST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
2971                                 }
2972
2973                         } else {
2974                                 s1 = md->params[i].regoff + cd->stackframesize;
2975                                 s2 = nmd->params[j].regoff;
2976                                 M_ALD(REG_ITMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
2977                                 M_AST(REG_ITMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
2978                         }
2979
2980                 } else {
2981                         if (!md->params[i].inmemory) {
2982                                 s1 = rd->argfltregs[md->params[i].regoff];
2983
2984                                 if (!nmd->params[j].inmemory) {
2985                                         /* no mapping to regs needed, native flt args use regoff */
2986                                         s2 = nmd->params[j].regoff;
2987                                         
2988                                         /* we cannot move flt regs to their native arg locations directly */
2989                                         M_DMOV(s1, s2 + 16);
2990                                         fltregarg_inswap[num_fltregargs] = s2;
2991                                         num_fltregargs++;
2992                                         printf("flt arg swap to %d\n", s2 + 16);
2993
2994                                 } else {
2995                                         s2 = nmd->params[j].regoff;
2996                                         if (IS_2_WORD_TYPE(t))
2997                                                 M_DST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
2998                                         else
2999                                                 M_FST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
3000                                 }
3001
3002                         } else {
3003                                 s1 = md->params[i].regoff + cd->stackframesize;
3004                                 s2 = nmd->params[j].regoff;
3005                                 if (IS_2_WORD_TYPE(t)) {
3006                                         M_DLD(REG_FTMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
3007                                         M_DST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
3008                                 } else {
3009                                         M_FLD(REG_FTMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
3010                                         M_FST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
3011                                 }
3012                         }
3013                 }
3014         }
3015         
3016         /* move swapped float args to target regs */
3017         for (i = 0; i < num_fltregargs; i++) {
3018                 s1 = fltregarg_inswap[i];
3019                 M_DMOV(s1 + 16, s1);
3020                 printf("float arg to target reg: %d ==> %d\n", s1+16, s1);
3021         }
3022
3023
3024         /* put class into second argument register */
3025
3026         if (m->flags & ACC_STATIC) {
3027                 disp = dseg_add_address(cd, m->class);
3028                 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3029         }
3030
3031         /* put env into first argument register */
3032
3033         disp = dseg_add_address(cd, _Jv_env);
3034         M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3035
3036         /* do the native function call */
3037
3038         M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method       */
3039         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method                 */
3040         M_NOP;                              /* delay slot                         */
3041
3042         /* save return value */
3043
3044         if (md->returntype.type != TYPE_VOID) {
3045                 if (IS_INT_LNG_TYPE(md->returntype.type))
3046                         M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3047                 else
3048                         M_DST(REG_FRESULT, REG_SP, USESTACK_PARAMS);
3049         }
3050         
3051         /* Note: native functions return float values in %f0 (see ABI) */
3052         /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3053
3054 #if !defined(NDEBUG)
3055         /* But for the trace function we need to put a flt result into %f1 */
3056         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3057                 if (!IS_2_WORD_TYPE(md->returntype.type))
3058                         M_FLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
3059                 emit_verbosecall_exit(jd);
3060         }
3061 #endif
3062
3063         /* remove native stackframe info */
3064
3065         M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3066         disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3067         M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3068         M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3069         M_NOP; /* XXX fill me! */
3070         M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3071
3072         /* restore float return value, int return value already in our return reg */
3073
3074         if (md->returntype.type != TYPE_VOID) {
3075                 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3076                         if (IS_2_WORD_TYPE(md->returntype.type))
3077                                 M_DLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
3078                         else
3079                                 M_FLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
3080                 }
3081         }
3082
3083         /* check for exception */
3084
3085         M_BNEZ(REG_ITMP2_XPTR, 4);          /* if no exception then return        */
3086         M_RESTORE(REG_ZERO, 0, REG_ZERO);   /* restore callers window (DELAY)     */
3087
3088         M_RET(REG_RA_CALLER, 8);            /* return to caller                   */
3089         M_NOP;                              /* DELAY SLOT                         */
3090
3091         /* handle exception */
3092         
3093         disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3094         M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
3095         M_JMP(REG_ZERO, REG_ITMP3, REG_ZERO);/* jump to asm exception handler     */
3096         M_MOV(REG_RA_CALLER, REG_ITMP3_XPC); /* get exception address (DELAY)    */
3097
3098         /* generate patcher stubs */
3099
3100         emit_patcher_stubs(jd);
3101
3102         codegen_finish(jd);
3103
3104         return code->entrypoint;
3105 }
3106
3107 /*
3108  * These are local overrides for various environment variables in Emacs.
3109  * Please do not remove this and leave it at the end of the file, where
3110  * Emacs will automagically detect them.
3111  * ---------------------------------------------------------------------
3112  * Local variables:
3113  * mode: c
3114  * indent-tabs-mode: t
3115  * c-basic-offset: 4
3116  * tab-width: 4
3117  * End:
3118  * vim:noexpandtab:sw=4:ts=4:
3119  */