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