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