* src/vm/jit/jit.h (jitdata): Removed isleafmethod.
[cacao.git] / src / vm / jit / i386 / codegen.c
1 /* src/vm/jit/i386/codegen.c - machine code generator for i386
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 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31 #include <stdint.h>
32 #include <stdio.h>
33
34 #include "vm/types.h"
35
36 #include "vm/jit/i386/md-abi.h"
37
38 #include "vm/jit/i386/codegen.h"
39 #include "vm/jit/i386/emit.h"
40
41 #include "mm/memory.h"
42 #include "native/jni.h"
43 #include "native/localref.h"
44 #include "native/native.h"
45
46 #include "threads/lock-common.h"
47
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "vm/global.h"
51 #include "vm/stringlocal.h"
52 #include "vm/vm.h"
53
54 #include "vm/jit/abi.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/codegen-common.h"
57 #include "vm/jit/dseg.h"
58 #include "vm/jit/emit-common.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/parse.h"
61 #include "vm/jit/patcher-common.h"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/replace.h"
64 #include "vm/jit/stacktrace.h"
65
66 #if defined(ENABLE_SSA)
67 # include "vm/jit/optimizing/lsra.h"
68 # include "vm/jit/optimizing/ssa.h"
69 #elif defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
71 #endif
72
73 #include "vmcore/loader.h"
74 #include "vmcore/options.h"
75 #include "vmcore/utf8.h"
76
77
78 /* codegen_emit ****************************************************************
79
80    Generates machine code.
81
82 *******************************************************************************/
83
84 bool codegen_emit(jitdata *jd)
85 {
86         methodinfo         *m;
87         codeinfo           *code;
88         codegendata        *cd;
89         registerdata       *rd;
90         s4                  len, s1, s2, s3, d, disp;
91         varinfo            *var, *var1;
92         basicblock         *bptr;
93         instruction        *iptr;
94         exception_entry    *ex;
95         u2                  currentline;
96         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
97         builtintable_entry *bte;
98         methoddesc         *md;
99         fieldinfo          *fi;
100         unresolved_field   *uf;
101         s4                  fieldtype;
102         s4                  varindex;
103 #if defined(ENABLE_SSA)
104         lsradata *ls;
105         bool last_cmd_was_goto;
106
107         last_cmd_was_goto = false;
108         ls = jd->ls;
109 #endif
110
111         /* get required compiler data */
112
113         m    = jd->m;
114         code = jd->code;
115         cd   = jd->cd;
116         rd   = jd->rd;
117
118         /* prevent compiler warnings */
119
120         s1          = 0;
121         s2          = 0;
122         d           = 0;
123         currentline = 0;
124         lm          = NULL;
125         bte         = NULL;
126
127         {
128         s4 i, p, t, l;
129         s4 savedregs_num = 0;
130         s4 stack_off = 0;
131
132         /* space to save used callee saved registers */
133
134         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
135         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
136
137         cd->stackframesize = rd->memuse + savedregs_num;
138
139            
140 #if defined(ENABLE_THREADS)
141         /* space to save argument of monitor_enter */
142
143         if (checksync && (m->flags & ACC_SYNCHRONIZED))
144                 cd->stackframesize++;
145 #endif
146
147         /* create method header */
148
149     /* Keep stack of non-leaf functions 16-byte aligned. */
150
151         if (!code_is_leafmethod(code)) {
152                 ALIGN_ODD(cd->stackframesize);    /* XXX this is wrong, +4 is missing */
153         }
154
155         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
156         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
157
158 #if defined(ENABLE_THREADS)
159         /* IsSync contains the offset relative to the stack pointer for the
160            argument of monitor_exit used in the exception handler. Since the
161            offset could be zero and give a wrong meaning of the flag it is
162            offset by one.
163         */
164
165         if (checksync && (m->flags & ACC_SYNCHRONIZED))
166                 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync        */
167         else
168 #endif
169                 (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
170                                                
171         if (code_is_leafmethod(code))
172                 (void) dseg_add_unique_s4(cd, 1);                  /* IsLeaf          */
173         else
174                 (void) dseg_add_unique_s4(cd, 0);                  /* IsLeaf          */
175
176         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
177         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
178
179         /* adds a reference for the length of the line number counter. We don't
180            know the size yet, since we evaluate the information during code
181            generation, to save one additional iteration over the whole
182            instructions. During code optimization the position could have changed
183            to the information gotten from the class file */
184         (void) dseg_addlinenumbertablesize(cd);
185
186         (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
187         
188         /* create exception table */
189
190         for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
191                 dseg_add_target(cd, ex->start);
192                 dseg_add_target(cd, ex->end);
193                 dseg_add_target(cd, ex->handler);
194                 (void) dseg_add_unique_address(cd, ex->catchtype.any);
195         }
196
197 #if defined(ENABLE_PROFILING)
198         /* generate method profiling code */
199
200         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
201                 /* count frequency */
202
203                 M_MOV_IMM(code, REG_ITMP3);
204                 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
205         }
206 #endif
207
208         /* create stack frame (if necessary) */
209
210         if (cd->stackframesize)
211                 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
212
213         /* save return address and used callee saved registers */
214
215         p = cd->stackframesize;
216         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
217                 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
218         }
219         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
220                 p--; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 8);
221         }
222
223         /* take arguments out of register or stack frame */
224
225         md = m->parseddesc;
226
227         stack_off = 0;
228         for (p = 0, l = 0; p < md->paramcount; p++) {
229                 t = md->paramtypes[p].type;
230
231                 varindex = jd->local_map[l * 5 + t];
232 #if defined(ENABLE_SSA)
233                 if ( ls != NULL ) {
234                         if (varindex != UNUSED)
235                                 varindex = ls->var_0[varindex];
236                         if ((varindex != UNUSED) && (ls->lifetime[varindex].type == UNUSED))
237                                 varindex = UNUSED;
238                 }
239 #endif
240                 l++;
241                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
242                         l++;
243
244                 if (varindex == UNUSED)
245                         continue;
246
247                 var = VAR(varindex);
248                 s1  = md->params[p].regoff;
249                 d   = var->vv.regoff;
250
251                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
252                         if (!md->params[p].inmemory) {           /* register arguments    */
253                                 log_text("integer register argument");
254                                 assert(0);
255                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
256                                         /* rd->argintregs[md->params[p].regoff -> var->vv.regoff     */
257                                 } 
258                                 else {                               /* reg arg -> spilled    */
259                                         /* rd->argintregs[md->params[p].regoff -> var->vv.regoff * 4 */
260                                 }
261                         } 
262                         else {
263                                 if (!(var->flags & INMEMORY)) {
264                                         M_ILD(d, REG_SP, cd->stackframesize * 8 + 4 + s1);
265                                 } 
266                                 else {
267                                         if (!IS_2_WORD_TYPE(t)) {
268 #if defined(ENABLE_SSA)
269                                                 /* no copy avoiding by now possible with SSA */
270                                                 if (ls != NULL) {
271                                                         emit_mov_membase_reg(   /* + 4 for return address */
272                                                                  cd, REG_SP, cd->stackframesize * 8 + s1 + 4,
273                                                                  REG_ITMP1);    
274                                                         emit_mov_reg_membase(
275                                                                  cd, REG_ITMP1, REG_SP, var->vv.regoff);
276                                                 }
277                                                 else 
278 #endif /*defined(ENABLE_SSA)*/
279                                                         /* reuse stackslot */
280                                                         var->vv.regoff = cd->stackframesize * 8 + 4 + s1;
281
282                                         } 
283                                         else {
284 #if defined(ENABLE_SSA)
285                                                 /* no copy avoiding by now possible with SSA */
286                                                 if (ls != NULL) {
287                                                         emit_mov_membase_reg(  /* + 4 for return address */
288                                                                  cd, REG_SP, cd->stackframesize * 8 + s1 + 4,
289                                                                  REG_ITMP1);
290                                                         emit_mov_reg_membase(
291                                                                  cd, REG_ITMP1, REG_SP, var->vv.regoff);
292                                                         emit_mov_membase_reg(   /* + 4 for return address */
293                                                                   cd, REG_SP, cd->stackframesize * 8 + s1 + 4 + 4,
294                                                                   REG_ITMP1);             
295                                                         emit_mov_reg_membase(
296                                                                  cd, REG_ITMP1, REG_SP, var->vv.regoff + 4);
297                                                 }
298                                                 else
299 #endif /*defined(ENABLE_SSA)*/
300                                                         /* reuse stackslot */
301                                                         var->vv.regoff = cd->stackframesize * 8 + 4 + s1;
302                                         }
303                                 }
304                         }
305                 }
306                 else {                                       /* floating args         */
307                         if (!md->params[p].inmemory) {           /* register arguments    */
308                                 log_text("There are no float argument registers!");
309                                 assert(0);
310                                 if (!(var->flags & INMEMORY)) {  /* reg arg -> register   */
311                                         /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff     */
312                                 } else {                                     /* reg arg -> spilled    */
313                                         /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff * 8 */
314                                 }
315
316                         } 
317                         else {                                   /* stack arguments       */
318                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
319                                         if (t == TYPE_FLT) {
320                                                 emit_flds_membase(
321                             cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
322                                                 assert(0);
323 /*                                              emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
324
325                                         } 
326                                         else {
327                                                 emit_fldl_membase(
328                             cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
329                                                 assert(0);
330 /*                                              emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
331                                         }
332
333                                 } else {                             /* stack-arg -> spilled  */
334 #if defined(ENABLE_SSA)
335                                         /* no copy avoiding by now possible with SSA */
336                                         if (ls != NULL) {
337                                                 emit_mov_membase_reg(
338                                                  cd, REG_SP, cd->stackframesize * 8 + s1 + 4, REG_ITMP1);
339                                                 emit_mov_reg_membase(
340                                                                          cd, REG_ITMP1, REG_SP, var->vv.regoff);
341                                                 if (t == TYPE_FLT) {
342                                                         emit_flds_membase(
343                                                                   cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
344                                                         emit_fstps_membase(cd, REG_SP, var->vv.regoff);
345                                                 } 
346                                                 else {
347                                                         emit_fldl_membase(
348                                                                   cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
349                                                         emit_fstpl_membase(cd, REG_SP, var->vv.regoff);
350                                                 }
351                                         }
352                                         else
353 #endif /*defined(ENABLE_SSA)*/
354                                                 /* reuse stackslot */
355                                                 var->vv.regoff = cd->stackframesize * 8 + 4 + s1;
356                                 }
357                         }
358                 }
359         }
360
361         /* call monitorenter function */
362
363 #if defined(ENABLE_THREADS)
364         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
365                 s1 = rd->memuse;
366
367                 if (m->flags & ACC_STATIC) {
368                         M_MOV_IMM(&m->class->object.header, REG_ITMP1);
369                 }
370                 else {
371                         M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + 4);
372                         M_TEST(REG_ITMP1);
373                         M_BNE(6);
374                         M_ALD_MEM(REG_ITMP1, EXCEPTION_HARDWARE_NULLPOINTER);
375                 }
376
377                 M_AST(REG_ITMP1, REG_SP, s1 * 8);
378                 M_AST(REG_ITMP1, REG_SP, 0 * 4);
379                 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
380                 M_CALL(REG_ITMP3);
381         }                       
382 #endif
383
384 #if !defined(NDEBUG)
385         emit_verbosecall_enter(jd);
386 #endif
387
388         } 
389
390 #if defined(ENABLE_SSA)
391         /* with SSA the Header is Basic Block 0 - insert phi Moves if necessary */
392         if ( ls != NULL)
393                 codegen_emit_phi_moves(jd, ls->basicblocks[0]);
394 #endif
395
396         /* end of header generation */
397
398         /* create replacement points */
399
400         REPLACEMENT_POINTS_INIT(cd, jd);
401
402         /* walk through all basic blocks */
403
404         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
405
406                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
407
408                 if (bptr->flags >= BBREACHED) {
409                 /* branch resolving */
410
411                 codegen_resolve_branchrefs(cd, bptr);
412
413                 /* handle replacement points */
414
415                 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
416
417 #if defined(ENABLE_REPLACEMENT)
418                 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
419                         if (cd->replacementpoint[-1].flags & RPLPOINT_FLAG_COUNTDOWN) {
420                                 MCODECHECK(32);
421                                 disp = (s4) &(m->hitcountdown);
422                                 M_ISUB_IMM_MEMABS(1, disp);
423                                 M_BS(0);
424                         }
425                 }
426 #endif
427
428                 /* copy interface registers to their destination */
429
430                 len = bptr->indepth;
431                 MCODECHECK(512);
432
433 #if defined(ENABLE_PROFILING)
434                 /* generate basic block profiling code */
435
436                 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
437                         /* count frequency */
438
439                         M_MOV_IMM(code->bbfrequency, REG_ITMP3);
440                         M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
441                 }
442 #endif
443
444 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
445 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
446                 if (opt_lsra) {
447 # endif
448 # if defined(ENABLE_SSA)
449                 if (ls != NULL) {
450                         last_cmd_was_goto = false;
451 # endif
452                         if (len > 0) {
453                                 len--;
454                                 var = VAR(bptr->invars[len]);
455                                 if (bptr->type != BBTYPE_STD) {
456                                         if (!IS_2_WORD_TYPE(var->type)) {
457                                                 if (bptr->type == BBTYPE_EXH) {
458                                                         d = codegen_reg_of_var(0, var, REG_ITMP1);
459                                                         M_INTMOVE(REG_ITMP1, d);
460                                                         emit_store(jd, NULL, var, d);
461                                                 }
462                                         } 
463                                         else {
464                                                 log_text("copy interface registers(EXH, SBR): longs \
465                                   have to be in memory (begin 1)");
466                                                 assert(0);
467                                         }
468                                 }
469                         }
470
471                 } 
472                 else
473 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
474                 {
475                 while (len) {
476                         len--;
477                         var = VAR(bptr->invars[len]);
478                         if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
479                                 if (!IS_2_WORD_TYPE(var->type)) {
480                                         if (bptr->type == BBTYPE_EXH) {
481                                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
482                                                 M_INTMOVE(REG_ITMP1, d);
483                                                 emit_store(jd, NULL, var, d);
484                                         }
485                                 } 
486                                 else {
487                                         log_text("copy interface registers: longs have to be in \
488                                memory (begin 1)");
489                                         assert(0);
490                                 }
491
492                         } 
493                         else {
494                                 assert((var->flags & INOUT));
495                         }
496                 } /* while (len) */
497                 } /* */
498
499                 /* walk through all instructions */
500                 
501                 len = bptr->icount;
502                 currentline = 0;
503
504                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
505                         if (iptr->line != currentline) {
506                                 dseg_addlinenumber(cd, iptr->line);
507                                 currentline = iptr->line;
508                         }
509
510                         MCODECHECK(1024);                         /* 1kB should be enough */
511
512                 switch (iptr->opc) {
513                 case ICMD_NOP:        /* ...  ==> ...                                 */
514                 case ICMD_POP:        /* ..., value  ==> ...                          */
515                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
516                         break;
517
518                 case ICMD_INLINE_START:
519
520                         REPLACEMENT_POINT_INLINE_START(cd, iptr);
521                         break;
522
523                 case ICMD_INLINE_BODY:
524
525                         REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
526                         dseg_addlinenumber_inline_start(cd, iptr);
527                         dseg_addlinenumber(cd, iptr->line);
528                         break;
529
530                 case ICMD_INLINE_END:
531
532                         dseg_addlinenumber_inline_end(cd, iptr);
533                         dseg_addlinenumber(cd, iptr->line);
534                         break;
535
536                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
537
538                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
539                         emit_nullpointer_check(cd, iptr, s1);
540                         break;
541
542                 /* constant operations ************************************************/
543
544                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
545
546                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
547                         ICONST(d, iptr->sx.val.i);
548                         emit_store_dst(jd, iptr, d);
549                         break;
550
551                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
552
553                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
554                         LCONST(d, iptr->sx.val.l);
555                         emit_store_dst(jd, iptr, d);
556                         break;
557
558                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
559
560                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
561                         if (iptr->sx.val.f == 0.0) {
562                                 emit_fldz(cd);
563
564                                 /* -0.0 */
565                                 if (iptr->sx.val.i == 0x80000000) {
566                                         emit_fchs(cd);
567                                 }
568
569                         } else if (iptr->sx.val.f == 1.0) {
570                                 emit_fld1(cd);
571
572                         } else if (iptr->sx.val.f == 2.0) {
573                                 emit_fld1(cd);
574                                 emit_fld1(cd);
575                                 emit_faddp(cd);
576
577                         } else {
578                                 disp = dseg_add_float(cd, iptr->sx.val.f);
579                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
580                                 dseg_adddata(cd);
581                                 emit_flds_membase(cd, REG_ITMP1, disp);
582                         }
583                         emit_store_dst(jd, iptr, d);
584                         break;
585                 
586                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
587
588                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
589                         if (iptr->sx.val.d == 0.0) {
590                                 emit_fldz(cd);
591
592                                 /* -0.0 */
593                                 if (iptr->sx.val.l == 0x8000000000000000LL) {
594                                         emit_fchs(cd);
595                                 }
596
597                         } else if (iptr->sx.val.d == 1.0) {
598                                 emit_fld1(cd);
599
600                         } else if (iptr->sx.val.d == 2.0) {
601                                 emit_fld1(cd);
602                                 emit_fld1(cd);
603                                 emit_faddp(cd);
604
605                         } else {
606                                 disp = dseg_add_double(cd, iptr->sx.val.d);
607                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
608                                 dseg_adddata(cd);
609                                 emit_fldl_membase(cd, REG_ITMP1, disp);
610                         }
611                         emit_store_dst(jd, iptr, d);
612                         break;
613
614                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
615
616                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
617
618                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
619                                 patcher_add_patch_ref(jd, PATCHER_aconst,
620                                                                         iptr->sx.val.c.ref, 0);
621
622                                 M_MOV_IMM(NULL, d);
623
624                         } else {
625                                 if (iptr->sx.val.anyptr == NULL)
626                                         M_CLR(d);
627                                 else
628                                         M_MOV_IMM(iptr->sx.val.anyptr, d);
629                         }
630                         emit_store_dst(jd, iptr, d);
631                         break;
632
633
634                 /* load/store/copy/move operations ************************************/
635
636                 case ICMD_ILOAD:
637                 case ICMD_ALOAD:
638                 case ICMD_LLOAD:
639                 case ICMD_FLOAD:
640                 case ICMD_DLOAD:
641                 case ICMD_ISTORE:
642                 case ICMD_LSTORE:
643                 case ICMD_FSTORE:
644                 case ICMD_DSTORE:
645                 case ICMD_COPY:
646                 case ICMD_MOVE:
647
648                         emit_copy(jd, iptr);
649                         break;
650
651                 case ICMD_ASTORE:
652                         if (!(iptr->flags.bits & INS_FLAG_RETADDR))
653                                 emit_copy(jd, iptr);
654                         break;
655
656
657                 /* integer operations *************************************************/
658
659                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
660
661                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
662                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
663                         M_INTMOVE(s1, d);
664                         M_NEG(d);
665                         emit_store_dst(jd, iptr, d);
666                         break;
667
668                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
669
670                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
671                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
672                         M_LNGMOVE(s1, d);
673                         M_NEG(GET_LOW_REG(d));
674                         M_IADDC_IMM(0, GET_HIGH_REG(d));
675                         M_NEG(GET_HIGH_REG(d));
676                         emit_store_dst(jd, iptr, d);
677                         break;
678
679                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
680
681                         s1 = emit_load_s1(jd, iptr, EAX);
682                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
683                         M_INTMOVE(s1, EAX);
684                         M_CLTD;
685                         M_LNGMOVE(EAX_EDX_PACKED, d);
686                         emit_store_dst(jd, iptr, d);
687                         break;
688
689                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
690
691                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
692                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
693                         M_INTMOVE(s1, d);
694                         emit_store_dst(jd, iptr, d);
695                         break;
696
697                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
698
699                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
701                         M_INTMOVE(s1, d);
702                         M_SLL_IMM(24, d);
703                         M_SRA_IMM(24, d);
704                         emit_store_dst(jd, iptr, d);
705                         break;
706
707                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
708
709                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
710                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
711                         M_CZEXT(s1, d);
712                         emit_store_dst(jd, iptr, d);
713                         break;
714
715                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
716
717                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
719                         M_SSEXT(s1, d);
720                         emit_store_dst(jd, iptr, d);
721                         break;
722
723
724                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
725
726                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
727                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
728                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
729                         if (s2 == d)
730                                 M_IADD(s1, d);
731                         else {
732                                 M_INTMOVE(s1, d);
733                                 M_IADD(s2, d);
734                         }
735                         emit_store_dst(jd, iptr, d);
736                         break;
737
738                 case ICMD_IINC:
739                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
740                                       /* sx.val.i = constant                          */
741
742                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
743                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
744                                 
745                         /* `inc reg' is slower on p4's (regarding to ia32
746                            optimization reference manual and benchmarks) and as
747                            fast on athlon's. */
748
749                         M_INTMOVE(s1, d);
750                         M_IADD_IMM(iptr->sx.val.i, d);
751                         emit_store_dst(jd, iptr, d);
752                         break;
753
754                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
755
756                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
757                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
758                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
759                         M_INTMOVE(s1, GET_LOW_REG(d));
760                         M_IADD(s2, GET_LOW_REG(d));
761                         /* don't use REG_ITMP1 */
762                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
763                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
764                         M_INTMOVE(s1, GET_HIGH_REG(d));
765                         M_IADDC(s2, GET_HIGH_REG(d));
766                         emit_store_dst(jd, iptr, d);
767                         break;
768
769                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
770                                       /* sx.val.l = constant                          */
771
772                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
773                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
774                         M_LNGMOVE(s1, d);
775                         M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
776                         M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
777                         emit_store_dst(jd, iptr, d);
778                         break;
779
780                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
781
782                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
783                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
784                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
785                         if (s2 == d) {
786                                 M_INTMOVE(s1, REG_ITMP1);
787                                 M_ISUB(s2, REG_ITMP1);
788                                 M_INTMOVE(REG_ITMP1, d);
789                         }
790                         else {
791                                 M_INTMOVE(s1, d);
792                                 M_ISUB(s2, d);
793                         }
794                         emit_store_dst(jd, iptr, d);
795                         break;
796
797                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
798                                       /* sx.val.i = constant                             */
799
800                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
802                         M_INTMOVE(s1, d);
803                         M_ISUB_IMM(iptr->sx.val.i, d);
804                         emit_store_dst(jd, iptr, d);
805                         break;
806
807                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
808
809                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
810                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
811                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
812                         if (s2 == GET_LOW_REG(d)) {
813                                 M_INTMOVE(s1, REG_ITMP1);
814                                 M_ISUB(s2, REG_ITMP1);
815                                 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
816                         }
817                         else {
818                                 M_INTMOVE(s1, GET_LOW_REG(d));
819                                 M_ISUB(s2, GET_LOW_REG(d));
820                         }
821                         /* don't use REG_ITMP1 */
822                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
823                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
824                         if (s2 == GET_HIGH_REG(d)) {
825                                 M_INTMOVE(s1, REG_ITMP2);
826                                 M_ISUBB(s2, REG_ITMP2);
827                                 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
828                         }
829                         else {
830                                 M_INTMOVE(s1, GET_HIGH_REG(d));
831                                 M_ISUBB(s2, GET_HIGH_REG(d));
832                         }
833                         emit_store_dst(jd, iptr, d);
834                         break;
835
836                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
837                                       /* sx.val.l = constant                          */
838
839                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
840                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
841                         M_LNGMOVE(s1, d);
842                         M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
843                         M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
844                         emit_store_dst(jd, iptr, d);
845                         break;
846
847                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
848
849                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
850                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
851                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
852                         if (s2 == d)
853                                 M_IMUL(s1, d);
854                         else {
855                                 M_INTMOVE(s1, d);
856                                 M_IMUL(s2, d);
857                         }
858                         emit_store_dst(jd, iptr, d);
859                         break;
860
861                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
862                                       /* sx.val.i = constant                          */
863
864                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
865                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
866                         M_IMUL_IMM(s1, iptr->sx.val.i, d);
867                         emit_store_dst(jd, iptr, d);
868                         break;
869
870                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
871
872                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
873                         s2 = emit_load_s2_low(jd, iptr, EDX);
874                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
875
876                         M_INTMOVE(s1, REG_ITMP2);
877                         M_IMUL(s2, REG_ITMP2);
878
879                         s1 = emit_load_s1_low(jd, iptr, EAX);
880                         s2 = emit_load_s2_high(jd, iptr, EDX);
881                         M_INTMOVE(s2, EDX);
882                         M_IMUL(s1, EDX);
883                         M_IADD(EDX, REG_ITMP2);
884
885                         s1 = emit_load_s1_low(jd, iptr, EAX);
886                         s2 = emit_load_s2_low(jd, iptr, EDX);
887                         M_INTMOVE(s1, EAX);
888                         M_MUL(s2);
889                         M_INTMOVE(EAX, GET_LOW_REG(d));
890                         M_IADD(REG_ITMP2, GET_HIGH_REG(d));
891
892                         emit_store_dst(jd, iptr, d);
893                         break;
894
895                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
896                                       /* sx.val.l = constant                          */
897
898                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
899                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
900                         ICONST(EAX, iptr->sx.val.l);
901                         M_MUL(s1);
902                         M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
903                         M_IADD(REG_ITMP2, EDX);
904                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
905                         M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
906                         M_IADD(REG_ITMP2, EDX);
907                         M_LNGMOVE(EAX_EDX_PACKED, d);
908                         emit_store_dst(jd, iptr, d);
909                         break;
910
911                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
912
913                         s1 = emit_load_s1(jd, iptr, EAX);
914                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
915                         d = codegen_reg_of_dst(jd, iptr, EAX);
916                         emit_arithmetic_check(cd, iptr, s2);
917
918                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
919
920                         /* check as described in jvm spec */
921
922                         M_CMP_IMM(0x80000000, EAX);
923                         M_BNE(3 + 6);
924                         M_CMP_IMM(-1, s2);
925                         M_BEQ(1 + 2);
926                         M_CLTD;
927                         M_IDIV(s2);
928
929                         M_INTMOVE(EAX, d);           /* if INMEMORY then d is already EAX */
930                         emit_store_dst(jd, iptr, d);
931                         break;
932
933                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
934
935                         s1 = emit_load_s1(jd, iptr, EAX);
936                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
937                         d = codegen_reg_of_dst(jd, iptr, EDX);
938                         emit_arithmetic_check(cd, iptr, s2);
939
940                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
941
942                         /* check as described in jvm spec */
943
944                         M_CMP_IMM(0x80000000, EAX);
945                         M_BNE(2 + 3 + 6);
946                         M_CLR(EDX);
947                         M_CMP_IMM(-1, s2);
948                         M_BEQ(1 + 2);
949                         M_CLTD;
950                         M_IDIV(s2);
951
952                         M_INTMOVE(EDX, d);           /* if INMEMORY then d is already EDX */
953                         emit_store_dst(jd, iptr, d);
954                         break;
955
956                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
957                                       /* sx.val.i = constant                          */
958
959                         /* TODO: optimize for `/ 2' */
960                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
961                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
962                         M_INTMOVE(s1, d);
963                         M_TEST(d);
964                         M_BNS(6);
965                         M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d);/* 32-bit for jump off */
966                         M_SRA_IMM(iptr->sx.val.i, d);
967                         emit_store_dst(jd, iptr, d);
968                         break;
969
970                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
971                                       /* sx.val.i = constant                          */
972
973                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
974                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
975                         if (s1 == d) {
976                                 M_MOV(s1, REG_ITMP1);
977                                 s1 = REG_ITMP1;
978                         } 
979                         M_INTMOVE(s1, d);
980                         M_AND_IMM(iptr->sx.val.i, d);
981                         M_TEST(s1);
982                         M_BGE(2 + 2 + 6 + 2);
983                         M_MOV(s1, d);  /* don't use M_INTMOVE, so we know the jump offset */
984                         M_NEG(d);
985                         M_AND_IMM32(iptr->sx.val.i, d);     /* use 32-bit for jump offset */
986                         M_NEG(d);
987                         emit_store_dst(jd, iptr, d);
988                         break;
989
990                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
991                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
992
993                         s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
994                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
995
996                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
997                         M_OR(GET_HIGH_REG(s2), REG_ITMP3);
998                         /* XXX could be optimized */
999                         emit_arithmetic_check(cd, iptr, REG_ITMP3);
1000
1001                         bte = iptr->sx.s23.s3.bte;
1002                         md = bte->md;
1003
1004                         M_LST(s2, REG_SP, 2 * 4);
1005
1006                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1007                         M_LST(s1, REG_SP, 0 * 4);
1008
1009                         M_MOV_IMM(bte->fp, REG_ITMP3);
1010                         M_CALL(REG_ITMP3);
1011                         emit_store_dst(jd, iptr, d);
1012                         break;
1013
1014                 case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
1015                                       /* sx.val.i = constant                          */
1016
1017                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1018                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1019                         M_LNGMOVE(s1, d);
1020                         M_TEST(GET_HIGH_REG(d));
1021                         M_BNS(6 + 3);
1022                         M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
1023                         M_IADDC_IMM(0, GET_HIGH_REG(d));
1024                         M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
1025                         M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
1026                         emit_store_dst(jd, iptr, d);
1027                         break;
1028
1029 #if 0
1030                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1031                                       /* sx.val.l = constant                          */
1032
1033                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1034                         if (iptr->dst.var->flags & INMEMORY) {
1035                                 if (iptr->s1.var->flags & INMEMORY) {
1036                                         /* Alpha algorithm */
1037                                         disp = 3;
1038                                         CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 8);
1039                                         disp += 3;
1040                                         CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 8 + 4);
1041
1042                                         disp += 2;
1043                                         disp += 3;
1044                                         disp += 2;
1045
1046                                         /* TODO: hmm, don't know if this is always correct */
1047                                         disp += 2;
1048                                         CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
1049                                         disp += 2;
1050                                         CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
1051
1052                                         disp += 2;
1053                                         disp += 3;
1054                                         disp += 2;
1055
1056                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8, REG_ITMP1);
1057                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8 + 4, REG_ITMP2);
1058                                         
1059                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1060                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1061                                         emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->vv.regoff * 8 + 4);
1062                                         emit_jcc(cd, CC_GE, disp);
1063
1064                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8, REG_ITMP1);
1065                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8 + 4, REG_ITMP2);
1066                                         
1067                                         emit_neg_reg(cd, REG_ITMP1);
1068                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1069                                         emit_neg_reg(cd, REG_ITMP2);
1070                                         
1071                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1072                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1073                                         
1074                                         emit_neg_reg(cd, REG_ITMP1);
1075                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1076                                         emit_neg_reg(cd, REG_ITMP2);
1077
1078                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->vv.regoff * 8);
1079                                         emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->vv.regoff * 8 + 4);
1080                                 }
1081                         }
1082
1083                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1084                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1085                         M_LNGMOVE(s1, d);
1086                         M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));      
1087                         M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1088                         M_TEST(GET_LOW_REG(s1));
1089                         M_BGE(0);
1090                         M_LNGMOVE(s1, d);
1091                 break;
1092 #endif
1093
1094                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1095
1096                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1097                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1098                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1099                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
1100                         M_INTMOVE(s1, d);
1101                         M_SLL(d);
1102                         emit_store_dst(jd, iptr, d);
1103                         break;
1104
1105                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1106                                       /* sx.val.i = constant                          */
1107
1108                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1109                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1110                         M_INTMOVE(s1, d);
1111                         M_SLL_IMM(iptr->sx.val.i, d);
1112                         emit_store_dst(jd, iptr, d);
1113                         break;
1114
1115                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1116
1117                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1118                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1119                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1120                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
1121                         M_INTMOVE(s1, d);
1122                         M_SRA(d);
1123                         emit_store_dst(jd, iptr, d);
1124                         break;
1125
1126                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1127                                       /* sx.val.i = constant                          */
1128
1129                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1130                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1131                         M_INTMOVE(s1, d);
1132                         M_SRA_IMM(iptr->sx.val.i, d);
1133                         emit_store_dst(jd, iptr, d);
1134                         break;
1135
1136                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1137
1138                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1139                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1140                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1141                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
1142                         M_INTMOVE(s1, d);
1143                         M_SRL(d);
1144                         emit_store_dst(jd, iptr, d);
1145                         break;
1146
1147                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1148                                       /* sx.val.i = constant                          */
1149
1150                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1152                         M_INTMOVE(s1, d);
1153                         M_SRL_IMM(iptr->sx.val.i, d);
1154                         emit_store_dst(jd, iptr, d);
1155                         break;
1156
1157                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1158
1159                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1160                         s2 = emit_load_s2(jd, iptr, ECX);
1161                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1162                         M_LNGMOVE(s1, d);
1163                         M_INTMOVE(s2, ECX);
1164                         M_TEST_IMM(32, ECX);
1165                         M_BEQ(2 + 2);
1166                         M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1167                         M_CLR(GET_LOW_REG(d));
1168                         M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
1169                         M_SLL(GET_LOW_REG(d));
1170                         emit_store_dst(jd, iptr, d);
1171                         break;
1172
1173         case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1174                                           /* sx.val.i = constant                          */
1175
1176                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1177                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1178                         M_LNGMOVE(s1, d);
1179                         if (iptr->sx.val.i & 0x20) {
1180                                 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1181                                 M_CLR(GET_LOW_REG(d));
1182                                 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), 
1183                                                    GET_HIGH_REG(d));
1184                         }
1185                         else {
1186                                 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
1187                                                    GET_HIGH_REG(d));
1188                                 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
1189                         }
1190                         emit_store_dst(jd, iptr, d);
1191                         break;
1192
1193                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1194
1195                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1196                         s2 = emit_load_s2(jd, iptr, ECX);
1197                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1198                         M_LNGMOVE(s1, d);
1199                         M_INTMOVE(s2, ECX);
1200                         M_TEST_IMM(32, ECX);
1201                         M_BEQ(2 + 3);
1202                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1203                         M_SRA_IMM(31, GET_HIGH_REG(d));
1204                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1205                         M_SRA(GET_HIGH_REG(d));
1206                         emit_store_dst(jd, iptr, d);
1207                         break;
1208
1209                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1210                                       /* sx.val.i = constant                          */
1211
1212                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1213                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1214                         M_LNGMOVE(s1, d);
1215                         if (iptr->sx.val.i & 0x20) {
1216                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1217                                 M_SRA_IMM(31, GET_HIGH_REG(d));
1218                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
1219                                                    GET_LOW_REG(d));
1220                         }
1221                         else {
1222                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
1223                                                    GET_LOW_REG(d));
1224                                 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1225                         }
1226                         emit_store_dst(jd, iptr, d);
1227                         break;
1228
1229                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1230
1231                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1232                         s2 = emit_load_s2(jd, iptr, ECX);
1233                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1234                         M_LNGMOVE(s1, d);
1235                         M_INTMOVE(s2, ECX);
1236                         M_TEST_IMM(32, ECX);
1237                         M_BEQ(2 + 2);
1238                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1239                         M_CLR(GET_HIGH_REG(d));
1240                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1241                         M_SRL(GET_HIGH_REG(d));
1242                         emit_store_dst(jd, iptr, d);
1243                         break;
1244
1245                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1246                                       /* sx.val.l = constant                          */
1247
1248                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1249                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1250                         M_LNGMOVE(s1, d);
1251                         if (iptr->sx.val.i & 0x20) {
1252                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1253                                 M_CLR(GET_HIGH_REG(d));
1254                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
1255                                                    GET_LOW_REG(d));
1256                         }
1257                         else {
1258                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
1259                                                    GET_LOW_REG(d));
1260                                 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1261                         }
1262                         emit_store_dst(jd, iptr, d);
1263                         break;
1264
1265                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1266
1267                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1268                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1269                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1270                         if (s2 == d)
1271                                 M_AND(s1, d);
1272                         else {
1273                                 M_INTMOVE(s1, d);
1274                                 M_AND(s2, d);
1275                         }
1276                         emit_store_dst(jd, iptr, d);
1277                         break;
1278
1279                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1280                                       /* sx.val.i = constant                          */
1281
1282                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1283                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1284                         M_INTMOVE(s1, d);
1285                         M_AND_IMM(iptr->sx.val.i, d);
1286                         emit_store_dst(jd, iptr, d);
1287                         break;
1288
1289                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1290
1291                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1292                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1293                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1294                         if (s2 == GET_LOW_REG(d))
1295                                 M_AND(s1, GET_LOW_REG(d));
1296                         else {
1297                                 M_INTMOVE(s1, GET_LOW_REG(d));
1298                                 M_AND(s2, GET_LOW_REG(d));
1299                         }
1300                         /* REG_ITMP1 probably contains low 32-bit of destination */
1301                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1302                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1303                         if (s2 == GET_HIGH_REG(d))
1304                                 M_AND(s1, GET_HIGH_REG(d));
1305                         else {
1306                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1307                                 M_AND(s2, GET_HIGH_REG(d));
1308                         }
1309                         emit_store_dst(jd, iptr, d);
1310                         break;
1311
1312                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1313                                       /* sx.val.l = constant                          */
1314
1315                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1316                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1317                         M_LNGMOVE(s1, d);
1318                         M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1319                         M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1320                         emit_store_dst(jd, iptr, d);
1321                         break;
1322
1323                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1324
1325                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1326                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1327                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1328                         if (s2 == d)
1329                                 M_OR(s1, d);
1330                         else {
1331                                 M_INTMOVE(s1, d);
1332                                 M_OR(s2, d);
1333                         }
1334                         emit_store_dst(jd, iptr, d);
1335                         break;
1336
1337                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1338                                       /* sx.val.i = constant                          */
1339
1340                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1341                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1342                         M_INTMOVE(s1, d);
1343                         M_OR_IMM(iptr->sx.val.i, d);
1344                         emit_store_dst(jd, iptr, d);
1345                         break;
1346
1347                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1348
1349                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1350                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1351                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1352                         if (s2 == GET_LOW_REG(d))
1353                                 M_OR(s1, GET_LOW_REG(d));
1354                         else {
1355                                 M_INTMOVE(s1, GET_LOW_REG(d));
1356                                 M_OR(s2, GET_LOW_REG(d));
1357                         }
1358                         /* REG_ITMP1 probably contains low 32-bit of destination */
1359                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1360                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1361                         if (s2 == GET_HIGH_REG(d))
1362                                 M_OR(s1, GET_HIGH_REG(d));
1363                         else {
1364                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1365                                 M_OR(s2, GET_HIGH_REG(d));
1366                         }
1367                         emit_store_dst(jd, iptr, d);
1368                         break;
1369
1370                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1371                                       /* sx.val.l = constant                          */
1372
1373                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1374                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1375                         M_LNGMOVE(s1, d);
1376                         M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1377                         M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1378                         emit_store_dst(jd, iptr, d);
1379                         break;
1380
1381                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1382
1383                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1384                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1385                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1386                         if (s2 == d)
1387                                 M_XOR(s1, d);
1388                         else {
1389                                 M_INTMOVE(s1, d);
1390                                 M_XOR(s2, d);
1391                         }
1392                         emit_store_dst(jd, iptr, d);
1393                         break;
1394
1395                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1396                                       /* sx.val.i = constant                          */
1397
1398                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1399                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1400                         M_INTMOVE(s1, d);
1401                         M_XOR_IMM(iptr->sx.val.i, d);
1402                         emit_store_dst(jd, iptr, d);
1403                         break;
1404
1405                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1406
1407                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1408                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1409                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1410                         if (s2 == GET_LOW_REG(d))
1411                                 M_XOR(s1, GET_LOW_REG(d));
1412                         else {
1413                                 M_INTMOVE(s1, GET_LOW_REG(d));
1414                                 M_XOR(s2, GET_LOW_REG(d));
1415                         }
1416                         /* REG_ITMP1 probably contains low 32-bit of destination */
1417                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1418                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1419                         if (s2 == GET_HIGH_REG(d))
1420                                 M_XOR(s1, GET_HIGH_REG(d));
1421                         else {
1422                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1423                                 M_XOR(s2, GET_HIGH_REG(d));
1424                         }
1425                         emit_store_dst(jd, iptr, d);
1426                         break;
1427
1428                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1429                                       /* sx.val.l = constant                          */
1430
1431                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1432                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1433                         M_LNGMOVE(s1, d);
1434                         M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1435                         M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1436                         emit_store_dst(jd, iptr, d);
1437                         break;
1438
1439
1440                 /* floating operations ************************************************/
1441
1442                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1443
1444                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1445                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1446                         emit_fchs(cd);
1447                         emit_store_dst(jd, iptr, d);
1448                         break;
1449
1450                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1451
1452                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1453                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1454                         emit_fchs(cd);
1455                         emit_store_dst(jd, iptr, d);
1456                         break;
1457
1458                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1459
1460                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1461                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1462                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1463                         emit_faddp(cd);
1464                         emit_store_dst(jd, iptr, d);
1465                         break;
1466
1467                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1468
1469                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1470                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1471                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1472                         emit_faddp(cd);
1473                         emit_store_dst(jd, iptr, d);
1474                         break;
1475
1476                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1477
1478                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1479                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1480                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1481                         emit_fsubp(cd);
1482                         emit_store_dst(jd, iptr, d);
1483                         break;
1484
1485                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1486
1487                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1488                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1489                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1490                         emit_fsubp(cd);
1491                         emit_store_dst(jd, iptr, d);
1492                         break;
1493
1494                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1495
1496                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1497                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1498                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1499                         emit_fmulp(cd);
1500                         emit_store_dst(jd, iptr, d);
1501                         break;
1502
1503                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1504
1505                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1506                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1507                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1508                         emit_fmulp(cd);
1509                         emit_store_dst(jd, iptr, d);
1510                         break;
1511
1512                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1513
1514                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1515                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1516                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1517                         emit_fdivp(cd);
1518                         emit_store_dst(jd, iptr, d);
1519                         break;
1520
1521                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1522
1523                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1524                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1525                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1526                         emit_fdivp(cd);
1527                         emit_store_dst(jd, iptr, d);
1528                         break;
1529
1530                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1531
1532                         /* exchanged to skip fxch */
1533                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1534                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1535                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1536 /*                      emit_fxch(cd); */
1537                         emit_fprem(cd);
1538                         emit_wait(cd);
1539                         emit_fnstsw(cd);
1540                         emit_sahf(cd);
1541                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1542                         emit_store_dst(jd, iptr, d);
1543                         emit_ffree_reg(cd, 0);
1544                         emit_fincstp(cd);
1545                         break;
1546
1547                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1548
1549                         /* exchanged to skip fxch */
1550                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1551                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1552                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1553 /*                      emit_fxch(cd); */
1554                         emit_fprem(cd);
1555                         emit_wait(cd);
1556                         emit_fnstsw(cd);
1557                         emit_sahf(cd);
1558                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1559                         emit_store_dst(jd, iptr, d);
1560                         emit_ffree_reg(cd, 0);
1561                         emit_fincstp(cd);
1562                         break;
1563
1564                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1565                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1566
1567                         var = VAROP(iptr->s1);
1568                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1569
1570                         if (var->flags & INMEMORY) {
1571                                 emit_fildl_membase(cd, REG_SP, var->vv.regoff);
1572                         } else {
1573                                 /* XXX not thread safe! */
1574                                 disp = dseg_add_unique_s4(cd, 0);
1575                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1576                                 dseg_adddata(cd);
1577                                 emit_mov_reg_membase(cd, var->vv.regoff, REG_ITMP1, disp);
1578                                 emit_fildl_membase(cd, REG_ITMP1, disp);
1579                         }
1580
1581                         emit_store_dst(jd, iptr, d);
1582                         break;
1583
1584                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
1585                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
1586
1587                         var = VAROP(iptr->s1);
1588                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1589                         if (var->flags & INMEMORY) {
1590                                 emit_fildll_membase(cd, REG_SP, var->vv.regoff);
1591
1592                         } else {
1593                                 log_text("L2F: longs have to be in memory");
1594                                 assert(0);
1595                         }
1596                         emit_store_dst(jd, iptr, d);
1597                         break;
1598                         
1599                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1600
1601                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1602                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1603
1604                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1605                         dseg_adddata(cd);
1606
1607                         /* Round to zero, 53-bit mode, exception masked */
1608                         disp = dseg_add_s4(cd, 0x0e7f);
1609                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1610
1611                         var = VAROP(iptr->dst);
1612                         var1 = VAROP(iptr->s1);
1613
1614                         if (var->flags & INMEMORY) {
1615                                 emit_fistpl_membase(cd, REG_SP, var->vv.regoff);
1616
1617                                 /* Round to nearest, 53-bit mode, exceptions masked */
1618                                 disp = dseg_add_s4(cd, 0x027f);
1619                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1620
1621                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1622                                                                          REG_SP, var->vv.regoff);
1623
1624                                 disp = 3;
1625                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1626                                 disp += 5 + 2 + 3;
1627                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1628
1629                         } else {
1630                                 /* XXX not thread safe! */
1631                                 disp = dseg_add_unique_s4(cd, 0);
1632                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
1633                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1634
1635                                 /* Round to nearest, 53-bit mode, exceptions masked */
1636                                 disp = dseg_add_s4(cd, 0x027f);
1637                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1638
1639                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1640
1641                                 disp = 3;
1642                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1643                                 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1644                         }
1645
1646                         emit_jcc(cd, CC_NE, disp);
1647
1648                         /* XXX: change this when we use registers */
1649                         emit_flds_membase(cd, REG_SP, var1->vv.regoff);
1650                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
1651                         emit_call_reg(cd, REG_ITMP1);
1652
1653                         if (var->flags & INMEMORY) {
1654                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1655
1656                         } else {
1657                                 M_INTMOVE(REG_RESULT, var->vv.regoff);
1658                         }
1659                         break;
1660
1661                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
1662
1663                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1664                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1665
1666                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1667                         dseg_adddata(cd);
1668
1669                         /* Round to zero, 53-bit mode, exception masked */
1670                         disp = dseg_add_s4(cd, 0x0e7f);
1671                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1672
1673                         var  = VAROP(iptr->dst);
1674                         var1 = VAROP(iptr->s1);
1675
1676                         if (var->flags & INMEMORY) {
1677                                 emit_fistpl_membase(cd, REG_SP, var->vv.regoff);
1678
1679                                 /* Round to nearest, 53-bit mode, exceptions masked */
1680                                 disp = dseg_add_s4(cd, 0x027f);
1681                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1682
1683                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1684                                                                          REG_SP, var->vv.regoff);
1685
1686                                 disp = 3;
1687                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1688                                 disp += 5 + 2 + 3;
1689                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1690
1691                         } else {
1692                                 /* XXX not thread safe! */
1693                                 disp = dseg_add_unique_s4(cd, 0);
1694                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
1695                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1696
1697                                 /* Round to nearest, 53-bit mode, exceptions masked */
1698                                 disp = dseg_add_s4(cd, 0x027f);
1699                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1700
1701                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1702
1703                                 disp = 3;
1704                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1705                                 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1706                         }
1707
1708                         emit_jcc(cd, CC_NE, disp);
1709
1710                         /* XXX: change this when we use registers */
1711                         emit_fldl_membase(cd, REG_SP, var1->vv.regoff);
1712                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
1713                         emit_call_reg(cd, REG_ITMP1);
1714
1715                         if (var->flags & INMEMORY) {
1716                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1717                         } else {
1718                                 M_INTMOVE(REG_RESULT, var->vv.regoff);
1719                         }
1720                         break;
1721
1722                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
1723
1724                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1725                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1726
1727                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1728                         dseg_adddata(cd);
1729
1730                         /* Round to zero, 53-bit mode, exception masked */
1731                         disp = dseg_add_s4(cd, 0x0e7f);
1732                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1733
1734                         var  = VAROP(iptr->dst);
1735                         var1 = VAROP(iptr->s1);
1736
1737                         if (var->flags & INMEMORY) {
1738                                 emit_fistpll_membase(cd, REG_SP, var->vv.regoff);
1739
1740                                 /* Round to nearest, 53-bit mode, exceptions masked */
1741                                 disp = dseg_add_s4(cd, 0x027f);
1742                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1743
1744                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1745                                                                          REG_SP, var->vv.regoff + 4);
1746
1747                                 disp = 6 + 4;
1748                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1749                                 disp += 3;
1750                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1751                                 disp += 5 + 2;
1752                                 disp += 3;
1753                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1754                                 disp += 3;
1755                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff + 4);
1756
1757                                 emit_jcc(cd, CC_NE, disp);
1758
1759                                 emit_alu_imm_membase(cd, ALU_CMP, 0, 
1760                                                                          REG_SP, var->vv.regoff);
1761
1762                                 disp = 3;
1763                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1764                                 disp += 5 + 2 + 3;
1765                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1766
1767                                 emit_jcc(cd, CC_NE, disp);
1768
1769                                 /* XXX: change this when we use registers */
1770                                 emit_flds_membase(cd, REG_SP, var1->vv.regoff);
1771                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
1772                                 emit_call_reg(cd, REG_ITMP1);
1773                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1774                                 emit_mov_reg_membase(cd, REG_RESULT2, 
1775                                                                          REG_SP, var->vv.regoff + 4);
1776
1777                         } else {
1778                                 log_text("F2L: longs have to be in memory");
1779                                 assert(0);
1780                         }
1781                         break;
1782
1783                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
1784
1785                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1786                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1787
1788                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1789                         dseg_adddata(cd);
1790
1791                         /* Round to zero, 53-bit mode, exception masked */
1792                         disp = dseg_add_s4(cd, 0x0e7f);
1793                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1794
1795                         var  = VAROP(iptr->dst);
1796                         var1 = VAROP(iptr->s1);
1797
1798                         if (var->flags & INMEMORY) {
1799                                 emit_fistpll_membase(cd, REG_SP, var->vv.regoff);
1800
1801                                 /* Round to nearest, 53-bit mode, exceptions masked */
1802                                 disp = dseg_add_s4(cd, 0x027f);
1803                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1804
1805                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1806                                                                          REG_SP, var->vv.regoff + 4);
1807
1808                                 disp = 6 + 4;
1809                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1810                                 disp += 3;
1811                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1812                                 disp += 5 + 2;
1813                                 disp += 3;
1814                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1815                                 disp += 3;
1816                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff + 4);
1817
1818                                 emit_jcc(cd, CC_NE, disp);
1819
1820                                 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, var->vv.regoff);
1821
1822                                 disp = 3;
1823                                 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1824                                 disp += 5 + 2 + 3;
1825                                 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1826
1827                                 emit_jcc(cd, CC_NE, disp);
1828
1829                                 /* XXX: change this when we use registers */
1830                                 emit_fldl_membase(cd, REG_SP, var1->vv.regoff);
1831                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
1832                                 emit_call_reg(cd, REG_ITMP1);
1833                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1834                                 emit_mov_reg_membase(cd, REG_RESULT2, 
1835                                                                          REG_SP, var->vv.regoff + 4);
1836
1837                         } else {
1838                                 log_text("D2L: longs have to be in memory");
1839                                 assert(0);
1840                         }
1841                         break;
1842
1843                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
1844
1845                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1846                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1847                         /* nothing to do */
1848                         emit_store_dst(jd, iptr, d);
1849                         break;
1850
1851                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
1852
1853                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1854                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1855                         /* nothing to do */
1856                         emit_store_dst(jd, iptr, d);
1857                         break;
1858
1859                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
1860                 case ICMD_DCMPL:
1861
1862                         /* exchanged to skip fxch */
1863                         s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1864                         s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1865                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1866 /*                      emit_fxch(cd); */
1867                         emit_fucompp(cd);
1868                         emit_fnstsw(cd);
1869                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as GT */
1870                         emit_jcc(cd, CC_E, 6);
1871                         emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
1872                         emit_sahf(cd);
1873                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
1874                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1875                         emit_jcc(cd, CC_B, 3 + 5);
1876                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1877                         emit_jmp_imm(cd, 3);
1878                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1879                         emit_store_dst(jd, iptr, d);
1880                         break;
1881
1882                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
1883                 case ICMD_DCMPG:
1884
1885                         /* exchanged to skip fxch */
1886                         s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1887                         s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1888                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1889 /*                      emit_fxch(cd); */
1890                         emit_fucompp(cd);
1891                         emit_fnstsw(cd);
1892                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as LT */
1893                         emit_jcc(cd, CC_E, 3);
1894                         emit_movb_imm_reg(cd, 1, REG_AH);
1895                         emit_sahf(cd);
1896                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
1897                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1898                         emit_jcc(cd, CC_B, 3 + 5);
1899                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1900                         emit_jmp_imm(cd, 3);
1901                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1902                         emit_store_dst(jd, iptr, d);
1903                         break;
1904
1905
1906                 /* memory operations **************************************************/
1907
1908                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
1909
1910                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1911                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1912                         /* implicit null-pointer check */
1913                         M_ILD(d, s1, OFFSET(java_array_t, size));
1914                         emit_store_dst(jd, iptr, d);
1915                         break;
1916
1917                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1918
1919                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1920                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1921                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1922                         /* implicit null-pointer check */
1923                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1924                         emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), 
1925                                                                          s1, s2, 0, d);
1926                         emit_store_dst(jd, iptr, d);
1927                         break;
1928
1929                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1930
1931                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1932                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1933                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1934                         /* implicit null-pointer check */
1935                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1936                         emit_movzwl_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), 
1937                                                                          s1, s2, 1, d);
1938                         emit_store_dst(jd, iptr, d);
1939                         break;                  
1940
1941                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1942
1943                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1944                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1945                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1946                         /* implicit null-pointer check */
1947                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1948                         emit_movswl_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), 
1949                                                                          s1, s2, 1, d);
1950                         emit_store_dst(jd, iptr, d);
1951                         break;
1952
1953                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1954
1955                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1956                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1957                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1958                         /* implicit null-pointer check */
1959                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1960                         emit_mov_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), 
1961                                                                   s1, s2, 2, d);
1962                         emit_store_dst(jd, iptr, d);
1963                         break;
1964
1965                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1966
1967                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1968                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1969                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1970                         /* implicit null-pointer check */
1971                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1972
1973                         var = VAROP(iptr->dst);
1974
1975                         assert(var->flags & INMEMORY);
1976                         emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), 
1977                                                                   s1, s2, 3, REG_ITMP3);
1978                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff);
1979                         emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]) + 4, 
1980                                                                   s1, s2, 3, REG_ITMP3);
1981                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff + 4);
1982                         break;
1983
1984                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1985
1986                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1988                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1989                         /* implicit null-pointer check */
1990                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1991                         emit_flds_memindex(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1992                         emit_store_dst(jd, iptr, d);
1993                         break;
1994
1995                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
1996
1997                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1998                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1999                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2000                         /* implicit null-pointer check */
2001                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2002                         emit_fldl_memindex(cd, OFFSET(java_doublearray_t, data[0]), s1, s2,3);
2003                         emit_store_dst(jd, iptr, d);
2004                         break;
2005
2006                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
2007
2008                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2009                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2010                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2011                         /* implicit null-pointer check */
2012                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2013                         emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]),
2014                                                                   s1, s2, 2, d);
2015                         emit_store_dst(jd, iptr, d);
2016                         break;
2017
2018
2019                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
2020
2021                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2022                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2023                         /* implicit null-pointer check */
2024                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2025                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2026                         if (s3 >= EBP) { 
2027                                 /* because EBP, ESI, EDI have no xH and xL nibbles */
2028                                 M_INTMOVE(s3, REG_ITMP3);
2029                                 s3 = REG_ITMP3;
2030                         }
2031                         emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]),
2032                                                                    s1, s2, 0);
2033                         break;
2034
2035                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
2036
2037                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2038                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2039                         /* implicit null-pointer check */
2040                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2041                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2042                         emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]),
2043                                                                    s1, s2, 1);
2044                         break;
2045
2046                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
2047
2048                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2049                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2050                         /* implicit null-pointer check */
2051                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2052                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2053                         emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]),
2054                                                                    s1, s2, 1);
2055                         break;
2056
2057                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
2058
2059                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2060                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2061                         /* implicit null-pointer check */
2062                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2063                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2064                         emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]),
2065                                                                   s1, s2, 2);
2066                         break;
2067
2068                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
2069
2070                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2071                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2072                         /* implicit null-pointer check */
2073                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2074
2075                         var = VAROP(iptr->sx.s23.s3);
2076
2077                         assert(var->flags & INMEMORY);
2078                         emit_mov_membase_reg(cd, REG_SP, var->vv.regoff, REG_ITMP3);
2079                         emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray_t, data[0])
2080                                                                   , s1, s2, 3);
2081                         emit_mov_membase_reg(cd, REG_SP, var->vv.regoff + 4, REG_ITMP3);
2082                         emit_mov_reg_memindex(cd, REG_ITMP3,
2083                                                             OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
2084                         break;
2085
2086                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
2087
2088                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2089                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2090                         /* implicit null-pointer check */
2091                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2092                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2093                         emit_fstps_memindex(cd, OFFSET(java_floatarray_t, data[0]), s1, s2,2);
2094                         break;
2095
2096                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
2097
2098                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2099                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2100                         /* implicit null-pointer check */
2101                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2102                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2103                         emit_fstpl_memindex(cd, OFFSET(java_doublearray_t, data[0]),
2104                                                                 s1, s2, 3);
2105                         break;
2106
2107                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
2108
2109                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2111                         /* implicit null-pointer check */
2112                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2113                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2114
2115                         M_AST(s1, REG_SP, 0 * 4);
2116                         M_AST(s3, REG_SP, 1 * 4);
2117                         M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
2118                         M_CALL(REG_ITMP1);
2119                         emit_arraystore_check(cd, iptr);
2120
2121                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2122                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2123                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2124                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]),
2125                                                                   s1, s2, 2);
2126                         break;
2127
2128                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
2129
2130                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2131                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2132                         /* implicit null-pointer check */
2133                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2134                         emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
2135                                                                    OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
2136                         break;
2137
2138                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
2139
2140                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2141                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2142                         /* implicit null-pointer check */
2143                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2144                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2145                                                                    OFFSET(java_chararray_t, data[0]), s1, s2, 1);
2146                         break;
2147
2148                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
2149
2150                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2151                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2152                         /* implicit null-pointer check */
2153                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2154                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2155                                                                    OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
2156                         break;
2157
2158                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
2159
2160                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2161                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2162                         /* implicit null-pointer check */
2163                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2164                         emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
2165                                                                   OFFSET(java_intarray_t, data[0]), s1, s2, 2);
2166                         break;
2167
2168                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
2169
2170                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2171                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2172                         /* implicit null-pointer check */
2173                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2174                         emit_mov_imm_memindex(cd, 
2175                                                    (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
2176                                                    OFFSET(java_longarray_t, data[0]), s1, s2, 3);
2177                         emit_mov_imm_memindex(cd, 
2178                                                         ((s4)iptr->sx.s23.s3.constval) >> 31, 
2179                                                         OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
2180                         break;
2181
2182                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
2183
2184                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2185                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2186                         /* implicit null-pointer check */
2187                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2188                         emit_mov_imm_memindex(cd, 0, 
2189                                                                   OFFSET(java_objectarray_t, data[0]), s1, s2, 2);
2190                         break;
2191
2192
2193                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
2194
2195                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2196                                 uf        = iptr->sx.s23.s3.uf;
2197                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2198                                 disp      = 0;
2199
2200                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
2201
2202                         }
2203                         else {
2204                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2205                                 fieldtype = fi->type;
2206                                 disp      = (intptr_t) fi->value;
2207
2208                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2209                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
2210                         }
2211
2212                         M_MOV_IMM(disp, REG_ITMP1);
2213                         switch (fieldtype) {
2214                         case TYPE_INT:
2215                         case TYPE_ADR:
2216                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2217                                 M_ILD(d, REG_ITMP1, 0);
2218                                 break;
2219                         case TYPE_LNG:
2220                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2221                                 M_LLD(d, REG_ITMP1, 0);
2222                                 break;
2223                         case TYPE_FLT:
2224                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2225                                 M_FLD(d, REG_ITMP1, 0);
2226                                 break;
2227                         case TYPE_DBL:                          
2228                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2229                                 M_DLD(d, REG_ITMP1, 0);
2230                                 break;
2231                         }
2232                         emit_store_dst(jd, iptr, d);
2233                         break;
2234
2235                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2236
2237                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2238                                 uf        = iptr->sx.s23.s3.uf;
2239                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2240                                 disp      = 0;
2241
2242                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
2243                         }
2244                         else {
2245                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2246                                 fieldtype = fi->type;
2247                                 disp      = (intptr_t) fi->value;
2248
2249                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2250                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
2251                         }
2252
2253                         M_MOV_IMM(disp, REG_ITMP1);
2254                         switch (fieldtype) {
2255                         case TYPE_INT:
2256                         case TYPE_ADR:
2257                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2258                                 M_IST(s1, REG_ITMP1, 0);
2259                                 break;
2260                         case TYPE_LNG:
2261                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2262                                 M_LST(s1, REG_ITMP1, 0);
2263                                 break;
2264                         case TYPE_FLT:
2265                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2266                                 emit_fstps_membase(cd, REG_ITMP1, 0);
2267                                 break;
2268                         case TYPE_DBL:
2269                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2270                                 emit_fstpl_membase(cd, REG_ITMP1, 0);
2271                                 break;
2272                         }
2273                         break;
2274
2275                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2276                                           /* val = value (in current instruction)     */
2277                                           /* following NOP)                           */
2278
2279                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2280                                 uf        = iptr->sx.s23.s3.uf;
2281                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2282                                 disp      = 0;
2283
2284                                 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
2285                         }
2286                         else {
2287                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2288                                 fieldtype = fi->type;
2289                                 disp      = (intptr_t) fi->value;
2290
2291                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2292                                         patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
2293                         }
2294
2295                         M_MOV_IMM(disp, REG_ITMP1);
2296                         switch (fieldtype) {
2297                         case TYPE_INT:
2298                         case TYPE_ADR:
2299                                 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2300                                 break;
2301                         case TYPE_LNG:
2302                                 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
2303                                 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
2304                                 break;
2305                         default:
2306                                 assert(0);
2307                         }
2308                         break;
2309
2310                 case ICMD_GETFIELD:   /* .., objectref.  ==> ..., value               */
2311
2312                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2313                         emit_nullpointer_check(cd, iptr, s1);
2314
2315                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2316                                 uf        = iptr->sx.s23.s3.uf;
2317                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2318                                 disp      = 0;
2319
2320                                 patcher_add_patch_ref(jd, PATCHER_getfield,
2321                                                                         iptr->sx.s23.s3.uf, 0);
2322                         }
2323                         else {
2324                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2325                                 fieldtype = fi->type;
2326                                 disp      = fi->offset;
2327                         }
2328
2329                         switch (fieldtype) {
2330                         case TYPE_INT:
2331                         case TYPE_ADR:
2332                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2333                                 M_ILD32(d, s1, disp);
2334                                 break;
2335                         case TYPE_LNG:
2336                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2337                                 M_LLD32(d, s1, disp);
2338                                 break;
2339                         case TYPE_FLT:
2340                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2341                                 M_FLD32(d, s1, disp);
2342                                 break;
2343                         case TYPE_DBL:                          
2344                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2345                                 M_DLD32(d, s1, disp);
2346                                 break;
2347                         }
2348                         emit_store_dst(jd, iptr, d);
2349                         break;
2350
2351                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2352
2353                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2354                         emit_nullpointer_check(cd, iptr, s1);
2355
2356                         /* must be done here because of code patching */
2357
2358                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2359                                 uf        = iptr->sx.s23.s3.uf;
2360                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2361                         }
2362                         else {
2363                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2364                                 fieldtype = fi->type;
2365                         }
2366
2367                         if (!IS_FLT_DBL_TYPE(fieldtype)) {
2368                                 if (IS_2_WORD_TYPE(fieldtype))
2369                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2370                                 else
2371                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2372                         }
2373                         else
2374                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2375
2376                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2377                                 /* XXX */
2378                                 uf   = iptr->sx.s23.s3.uf;
2379                                 disp = 0;
2380
2381                                 patcher_add_patch_ref(jd, PATCHER_putfield, uf, 0);
2382                         }
2383                         else {
2384                                 /* XXX */
2385                                 fi   = iptr->sx.s23.s3.fmiref->p.field;
2386                                 disp = fi->offset;
2387                         }
2388
2389                         switch (fieldtype) {
2390                         case TYPE_INT:
2391                         case TYPE_ADR:
2392                                 M_IST32(s2, s1, disp);
2393                                 break;
2394                         case TYPE_LNG:
2395                                 M_LST32(s2, s1, disp);
2396                                 break;
2397                         case TYPE_FLT:
2398                                 emit_fstps_membase32(cd, s1, disp);
2399                                 break;
2400                         case TYPE_DBL:
2401                                 emit_fstpl_membase32(cd, s1, disp);
2402                                 break;
2403                         }
2404                         break;
2405
2406                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2407                                           /* val = value (in current instruction)     */
2408                                           /* following NOP)                           */
2409
2410                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2411                         emit_nullpointer_check(cd, iptr, s1);
2412
2413                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2414                                 uf        = iptr->sx.s23.s3.uf;
2415                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2416                                 disp      = 0;
2417
2418                                 patcher_add_patch_ref(jd, PATCHER_putfieldconst,
2419                                                                         uf, 0);
2420                         }
2421                         else {
2422                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2423                                 fieldtype = fi->type;
2424                                 disp      = fi->offset;
2425                         }
2426
2427                         switch (fieldtype) {
2428                         case TYPE_INT:
2429                         case TYPE_ADR:
2430                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2431                                 break;
2432                         case TYPE_LNG:
2433                                 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2434                                 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2435                                 break;
2436                         default:
2437                                 assert(0);
2438                         }
2439                         break;
2440
2441
2442                 /* branch operations **************************************************/
2443
2444                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2445
2446                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2447                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2448
2449 #ifdef ENABLE_VERIFIER
2450                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2451                                 patcher_add_patch_ref(jd, PATCHER_resolve_class,
2452                                                                         iptr->sx.s23.s2.uc, 0);
2453                         }
2454 #endif /* ENABLE_VERIFIER */
2455
2456                         M_CALL_IMM(0);                            /* passing exception pc */
2457                         M_POP(REG_ITMP2_XPC);
2458
2459                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2460                         M_JMP(REG_ITMP3);
2461                         break;
2462
2463                 case ICMD_GOTO:         /* ... ==> ...                                */
2464                 case ICMD_RET:          /* ... ==> ...                                */
2465
2466 #if defined(ENABLE_SSA)
2467                         if ( ls != NULL ) {
2468                                 last_cmd_was_goto = true;
2469
2470                                 /* In case of a Goto phimoves have to be inserted before the */
2471                                 /* jump */
2472
2473                                 codegen_emit_phi_moves(jd, bptr);
2474                         }
2475 #endif
2476                         emit_br(cd, iptr->dst.block);
2477                         ALIGNCODENOP;
2478                         break;
2479
2480                 case ICMD_JSR:          /* ... ==> ...                                */
2481
2482                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2483                         ALIGNCODENOP;
2484                         break;
2485                         
2486                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2487                 case ICMD_IFNONNULL:
2488
2489                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2490                         M_TEST(s1);
2491                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2492                         break;
2493
2494                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2495                 case ICMD_IFLT:
2496                 case ICMD_IFLE:
2497                 case ICMD_IFNE:
2498                 case ICMD_IFGT:
2499                 case ICMD_IFGE:
2500
2501                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2502                         M_CMP_IMM(iptr->sx.val.i, s1);
2503                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2504                         break;
2505
2506                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2507
2508                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2509                         if (iptr->sx.val.l == 0) {
2510                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2511                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2512                         }
2513                         else {
2514                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2515                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2516                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2517                                 M_OR(REG_ITMP2, REG_ITMP1);
2518                         }
2519                         emit_beq(cd, iptr->dst.block);
2520                         break;
2521
2522                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2523
2524                         if (iptr->sx.val.l == 0) {
2525                                 /* If high 32-bit are less than zero, then the 64-bits
2526                                    are too. */
2527                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2528                                 M_CMP_IMM(0, s1);
2529                                 emit_blt(cd, iptr->dst.block);
2530                         }
2531                         else {
2532                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2533                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2534                                 emit_blt(cd, iptr->dst.block);
2535                                 M_BGT(6 + 6);
2536                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2537                                 emit_bult(cd, iptr->dst.block);
2538                         }                       
2539                         break;
2540
2541                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2542
2543                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2544                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2545                         emit_blt(cd, iptr->dst.block);
2546                         M_BGT(6 + 6);
2547                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2548                         emit_bule(cd, iptr->dst.block);
2549                         break;
2550
2551                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2552
2553                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2554                         if (iptr->sx.val.l == 0) {
2555                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2556                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2557                         }
2558                         else {
2559                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2560                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2561                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2562                                 M_OR(REG_ITMP2, REG_ITMP1);
2563                         }
2564                         emit_bne(cd, iptr->dst.block);
2565                         break;
2566
2567                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2568
2569                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2570                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2571                         emit_bgt(cd, iptr->dst.block);
2572                         M_BLT(6 + 6);
2573                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2574                         emit_bugt(cd, iptr->dst.block);
2575                         break;
2576
2577                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2578
2579                         if (iptr->sx.val.l == 0) {
2580                                 /* If high 32-bit are greater equal zero, then the
2581                                    64-bits are too. */
2582                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2583                                 M_CMP_IMM(0, s1);
2584                                 emit_bge(cd, iptr->dst.block);
2585                         }
2586                         else {
2587                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2588                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2589                                 emit_bgt(cd, iptr->dst.block);
2590                                 M_BLT(6 + 6);
2591                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2592                                 emit_buge(cd, iptr->dst.block);
2593                         }
2594                         break;
2595
2596                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2597                 case ICMD_IF_ICMPNE:
2598                 case ICMD_IF_ICMPLT:
2599                 case ICMD_IF_ICMPGT:
2600                 case ICMD_IF_ICMPGE:
2601                 case ICMD_IF_ICMPLE:
2602
2603                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2604                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2605                         M_CMP(s2, s1);
2606                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2607                         break;
2608
2609                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
2610                 case ICMD_IF_ACMPNE:
2611
2612                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2613                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2614                         M_CMP(s2, s1);
2615                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2616                         break;
2617
2618                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2619
2620                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2621                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2622                         M_INTMOVE(s1, REG_ITMP1);
2623                         M_XOR(s2, REG_ITMP1);
2624                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2625                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2626                         M_INTMOVE(s1, REG_ITMP2);
2627                         M_XOR(s2, REG_ITMP2);
2628                         M_OR(REG_ITMP1, REG_ITMP2);
2629                         emit_beq(cd, iptr->dst.block);
2630                         break;
2631
2632                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
2633
2634                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2635                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2636                         M_INTMOVE(s1, REG_ITMP1);
2637                         M_XOR(s2, REG_ITMP1);
2638                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2639                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2640                         M_INTMOVE(s1, REG_ITMP2);
2641                         M_XOR(s2, REG_ITMP2);
2642                         M_OR(REG_ITMP1, REG_ITMP2);
2643                         emit_bne(cd, iptr->dst.block);
2644                         break;
2645
2646                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2647
2648                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2649                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2650                         M_CMP(s2, s1);
2651                         emit_blt(cd, iptr->dst.block);
2652                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2653                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2654                         M_BGT(2 + 6);
2655                         M_CMP(s2, s1);
2656                         emit_bult(cd, iptr->dst.block);
2657                         break;
2658
2659                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2660
2661                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2662                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2663                         M_CMP(s2, s1);
2664                         emit_bgt(cd, iptr->dst.block);
2665                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2666                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2667                         M_BLT(2 + 6);
2668                         M_CMP(s2, s1);
2669                         emit_bugt(cd, iptr->dst.block);
2670                         break;
2671
2672                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2673
2674                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2675                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2676                         M_CMP(s2, s1);
2677                         emit_blt(cd, iptr->dst.block);
2678                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2679                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2680                         M_BGT(2 + 6);
2681                         M_CMP(s2, s1);
2682                         emit_bule(cd, iptr->dst.block);
2683                         break;
2684
2685                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2686
2687                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2688                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2689                         M_CMP(s2, s1);
2690                         emit_bgt(cd, iptr->dst.block);
2691                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2692                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2693                         M_BLT(2 + 6);
2694                         M_CMP(s2, s1);
2695                         emit_buge(cd, iptr->dst.block);
2696                         break;
2697
2698
2699                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2700
2701                         REPLACEMENT_POINT_RETURN(cd, iptr);
2702                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2703                         M_INTMOVE(s1, REG_RESULT);
2704                         goto nowperformreturn;
2705
2706                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2707
2708                         REPLACEMENT_POINT_RETURN(cd, iptr);
2709                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2710                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2711                         goto nowperformreturn;
2712
2713                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2714
2715                         REPLACEMENT_POINT_RETURN(cd, iptr);
2716                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2717                         M_INTMOVE(s1, REG_RESULT);
2718
2719 #ifdef ENABLE_VERIFIER
2720                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2721                                 patcher_add_patch_ref(jd, PATCHER_resolve_class,
2722                                                                         iptr->sx.s23.s2.uc, 0);
2723                         }
2724 #endif /* ENABLE_VERIFIER */
2725                         goto nowperformreturn;
2726
2727                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2728                 case ICMD_DRETURN:
2729
2730                         REPLACEMENT_POINT_RETURN(cd, iptr);
2731                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2732                         goto nowperformreturn;
2733
2734                 case ICMD_RETURN:      /* ...  ==> ...                                */
2735
2736                         REPLACEMENT_POINT_RETURN(cd, iptr);
2737
2738 nowperformreturn:
2739                         {
2740                         s4 i, p;
2741                         
2742                         p = cd->stackframesize;
2743                         
2744 #if !defined(NDEBUG)
2745                         emit_verbosecall_exit(jd);
2746 #endif
2747
2748 #if defined(ENABLE_THREADS)
2749                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2750                                 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 8);
2751
2752                                 /* we need to save the proper return value */
2753                                 switch (iptr->opc) {
2754                                 case ICMD_IRETURN:
2755                                 case ICMD_ARETURN:
2756                                         M_IST(REG_RESULT, REG_SP, rd->memuse * 8);
2757                                         break;
2758
2759                                 case ICMD_LRETURN:
2760                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2761                                         break;
2762
2763                                 case ICMD_FRETURN:
2764                                         emit_fstps_membase(cd, REG_SP, rd->memuse * 8);
2765                                         break;
2766
2767                                 case ICMD_DRETURN:
2768                                         emit_fstpl_membase(cd, REG_SP, rd->memuse * 8);
2769                                         break;
2770                                 }
2771
2772                                 M_AST(REG_ITMP2, REG_SP, 0);
2773                                 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
2774                                 M_CALL(REG_ITMP3);
2775
2776                                 /* and now restore the proper return value */
2777                                 switch (iptr->opc) {
2778                                 case ICMD_IRETURN:
2779                                 case ICMD_ARETURN:
2780                                         M_ILD(REG_RESULT, REG_SP, rd->memuse * 8);
2781                                         break;
2782
2783                                 case ICMD_LRETURN:
2784                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2785                                         break;
2786
2787                                 case ICMD_FRETURN:
2788                                         emit_flds_membase(cd, REG_SP, rd->memuse * 8);
2789                                         break;
2790
2791                                 case ICMD_DRETURN:
2792                                         emit_fldl_membase(cd, REG_SP, rd->memuse * 8);
2793                                         break;
2794                                 }
2795                         }
2796 #endif
2797
2798                         /* restore saved registers */
2799
2800                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2801                                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2802                         }
2803
2804                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2805                                 p--;
2806                                 emit_fldl_membase(cd, REG_SP, p * 8);
2807                                 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
2808                                         assert(0);
2809 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
2810                                 } else {
2811                                         assert(0);
2812 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
2813                                 }
2814                         }
2815
2816                         /* deallocate stack */
2817
2818                         if (cd->stackframesize)
2819                                 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2820
2821                         M_RET;
2822                         }
2823                         break;
2824
2825
2826                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2827                         {
2828                                 s4 i, l;
2829                                 branch_target_t *table;
2830
2831                                 table = iptr->dst.table;
2832
2833                                 l = iptr->sx.s23.s2.tablelow;
2834                                 i = iptr->sx.s23.s3.tablehigh;
2835
2836                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2837                                 M_INTMOVE(s1, REG_ITMP1);
2838
2839                                 if (l != 0)
2840                                         M_ISUB_IMM(l, REG_ITMP1);
2841
2842                                 i = i - l + 1;
2843
2844                 /* range check */
2845
2846                                 M_CMP_IMM(i - 1, REG_ITMP1);
2847                                 emit_bugt(cd, table[0].block);
2848
2849                                 /* build jump table top down and use address of lowest entry */
2850
2851                                 table += i;
2852
2853                                 while (--i >= 0) {
2854                                         dseg_add_target(cd, table->block); 
2855                                         --table;
2856                                 }
2857
2858                                 /* length of dataseg after last dseg_addtarget is used
2859                                    by load */
2860
2861                                 M_MOV_IMM(0, REG_ITMP2);
2862                                 dseg_adddata(cd);
2863                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
2864                                 M_JMP(REG_ITMP1);
2865                         }
2866                         break;
2867
2868
2869                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2870                         {
2871                                 s4 i;
2872                                 lookup_target_t *lookup;
2873
2874                                 lookup = iptr->dst.lookup;
2875
2876                                 i = iptr->sx.s23.s2.lookupcount;
2877                         
2878                                 MCODECHECK((i<<2)+8);
2879                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2880
2881                                 while (--i >= 0) {
2882                                         M_CMP_IMM(lookup->value, s1);
2883                                         emit_beq(cd, lookup->target.block);
2884                                         lookup++;
2885                                 }
2886
2887                                 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2888                                 ALIGNCODENOP;
2889                         }
2890                         break;
2891
2892                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
2893
2894                         REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2895
2896                         bte = iptr->sx.s23.s3.bte;
2897                         md = bte->md;
2898                         goto gen_method;
2899
2900                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2901
2902                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2903                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2904                 case ICMD_INVOKEINTERFACE:
2905
2906                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2907
2908                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2909                                 md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
2910                                 lm = NULL;
2911                         }
2912                         else {
2913                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2914                                 md = lm->parseddesc;
2915                         }
2916
2917 gen_method:
2918                         s3 = md->paramcount;
2919
2920                         MCODECHECK((s3 << 1) + 64);
2921
2922                         /* copy arguments to registers or stack location                  */
2923
2924                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2925                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2926           
2927                                 /* Already Preallocated (ARGVAR) ? */
2928                                 if (var->flags & PREALLOC)
2929                                         continue;
2930                                 if (IS_INT_LNG_TYPE(var->type)) {
2931                                         if (!md->params[s3].inmemory) {
2932                                                 log_text("No integer argument registers available!");
2933                                                 assert(0);
2934
2935                                         } else {
2936                                                 if (IS_2_WORD_TYPE(var->type)) {
2937                                                         d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2938                                                         M_LST(d, REG_SP, md->params[s3].regoff);
2939                                                 } else {
2940                                                         d = emit_load(jd, iptr, var, REG_ITMP1);
2941                                                         M_IST(d, REG_SP, md->params[s3].regoff);
2942                                                 }
2943                                         }
2944
2945                                 } else {
2946                                         if (!md->params[s3].inmemory) {
2947                                                 s1 = md->params[s3].regoff;
2948                                                 d = emit_load(jd, iptr, var, s1);
2949                                                 M_FLTMOVE(d, s1);
2950
2951                                         } else {
2952                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2953                                                 if (IS_2_WORD_TYPE(var->type))
2954                                                         M_DST(d, REG_SP, md->params[s3].regoff);
2955                                                 else
2956                                                         M_FST(d, REG_SP, md->params[s3].regoff);
2957                                         }
2958                                 }
2959                         } /* end of for */
2960
2961                         switch (iptr->opc) {
2962                         case ICMD_BUILTIN:
2963                                 d = md->returntype.type;
2964
2965                                 if (bte->stub == NULL) {
2966                                         M_MOV_IMM(bte->fp, REG_ITMP1);
2967                                 }
2968                                 else {
2969                                         M_MOV_IMM(bte->stub, REG_ITMP1);
2970                                 }
2971                                 M_CALL(REG_ITMP1);
2972                                 break;
2973
2974                         case ICMD_INVOKESPECIAL:
2975                                 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
2976                                 emit_nullpointer_check(cd, iptr, REG_ITMP1);
2977                                 /* fall through */
2978
2979                         case ICMD_INVOKESTATIC:
2980                                 if (lm == NULL) {
2981                                         unresolved_method *um = iptr->sx.s23.s3.um;
2982
2983                                         patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2984                                                                                 um, 0);
2985
2986                                         disp = 0;
2987                                         d = md->returntype.type;
2988                                 }
2989                                 else {
2990                                         disp = (ptrint) lm->stubroutine;
2991                                         d = lm->parseddesc->returntype.type;
2992                                 }
2993
2994                                 M_MOV_IMM(disp, REG_ITMP2);
2995                                 M_CALL(REG_ITMP2);
2996                                 break;
2997
2998                         case ICMD_INVOKEVIRTUAL:
2999                                 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
3000                                 emit_nullpointer_check(cd, iptr, s1);
3001
3002                                 if (lm == NULL) {
3003                                         unresolved_method *um = iptr->sx.s23.s3.um;
3004
3005                                         patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3006
3007                                         s1 = 0;
3008                                         d = md->returntype.type;
3009                                 }
3010                                 else {
3011                                         s1 = OFFSET(vftbl_t, table[0]) +
3012                                                 sizeof(methodptr) * lm->vftblindex;
3013                                         d = md->returntype.type;
3014                                 }
3015
3016                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3017                                           OFFSET(java_object_t, vftbl));
3018                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3019                                 M_CALL(REG_ITMP3);
3020                                 break;
3021
3022                         case ICMD_INVOKEINTERFACE:
3023                                 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
3024                                 emit_nullpointer_check(cd, iptr, s1);
3025
3026                                 if (lm == NULL) {
3027                                         unresolved_method *um = iptr->sx.s23.s3.um;
3028
3029                                         patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3030
3031                                         s1 = 0;
3032                                         s2 = 0;
3033                                         d = md->returntype.type;
3034                                 }
3035                                 else {
3036                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3037                                                 sizeof(methodptr) * lm->class->index;
3038
3039                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3040
3041                                         d = md->returntype.type;
3042                                 }
3043
3044                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3045                                           OFFSET(java_object_t, vftbl));
3046                                 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3047                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3048                                 M_CALL(REG_ITMP3);
3049                                 break;
3050                         }
3051
3052                         /* store size of call code in replacement point */
3053
3054                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3055                         REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
3056
3057                         /* d contains return type */
3058
3059                         if (d != TYPE_VOID) {
3060 #if defined(ENABLE_SSA)
3061                                 if ((ls == NULL) /* || (!IS_TEMPVAR_INDEX(iptr->dst.varindex)) */ ||
3062                                         (ls->lifetime[iptr->dst.varindex].type != UNUSED)) 
3063                                         /* a "living" stackslot */
3064 #endif
3065                                 {
3066                                         if (IS_INT_LNG_TYPE(d)) {
3067                                                 if (IS_2_WORD_TYPE(d)) {
3068                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3069                                                         M_LNGMOVE(REG_RESULT_PACKED, s1);
3070                                                 }
3071                                                 else {
3072                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3073                                                         M_INTMOVE(REG_RESULT, s1);
3074                                                 }
3075                                         }
3076                                         else {
3077                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
3078                                         }
3079                                         emit_store_dst(jd, iptr, s1);
3080                                 }
3081                         }
3082                         break;
3083
3084
3085                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3086
3087                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3088                                 /* object type cast-check */
3089
3090                                 classinfo *super;
3091                                 vftbl_t   *supervftbl;
3092                                 s4         superindex;
3093
3094                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3095                                         super = NULL;
3096                                         superindex = 0;
3097                                         supervftbl = NULL;
3098                                 }
3099                                 else {
3100                                         super = iptr->sx.s23.s3.c.cls;
3101                                         superindex = super->index;
3102                                         supervftbl = super->vftbl;
3103                                 }
3104                         
3105                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3106                                         CODEGEN_CRITICAL_SECTION_NEW;
3107
3108                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3109
3110                                 /* if class is not resolved, check which code to call */
3111
3112                                 if (super == NULL) {
3113                                         M_TEST(s1);
3114                                         emit_label_beq(cd, BRANCH_LABEL_1);
3115
3116                                         patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
3117                                                                                 iptr->sx.s23.s3.c.ref, 0);
3118
3119                                         M_MOV_IMM(0, REG_ITMP2);                  /* super->flags */
3120                                         M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3121                                         emit_label_beq(cd, BRANCH_LABEL_2);
3122                                 }
3123
3124                                 /* interface checkcast code */
3125
3126                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3127                                         if (super != NULL) {
3128                                                 M_TEST(s1);
3129                                                 emit_label_beq(cd, BRANCH_LABEL_3);
3130                                         }
3131
3132                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3133
3134                                         if (super == NULL) {
3135                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3136                                                                                         iptr->sx.s23.s3.c.ref,
3137                                                                                         0);
3138                                         }
3139
3140                                         M_ILD32(REG_ITMP3,
3141                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3142                                         M_ISUB_IMM32(superindex, REG_ITMP3);
3143                                         /* XXX do we need this one? */
3144                                         M_TEST(REG_ITMP3);
3145                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
3146
3147                                         M_ALD32(REG_ITMP3, REG_ITMP2,
3148                                                         OFFSET(vftbl_t, interfacetable[0]) -
3149                                                         superindex * sizeof(methodptr*));
3150                                         M_TEST(REG_ITMP3);
3151                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
3152
3153                                         if (super == NULL)
3154                                                 emit_label_br(cd, BRANCH_LABEL_4);
3155                                         else
3156                                                 emit_label(cd, BRANCH_LABEL_3);
3157                                 }
3158
3159                                 /* class checkcast code */
3160
3161                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3162                                         if (super == NULL) {
3163                                                 emit_label(cd, BRANCH_LABEL_2);
3164                                         }
3165                                         else {
3166                                                 M_TEST(s1);
3167                                                 emit_label_beq(cd, BRANCH_LABEL_5);
3168                                         }
3169
3170                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3171
3172                                         if (super == NULL) {
3173                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_class,
3174                                                                                         iptr->sx.s23.s3.c.ref,
3175                                                                                         0);
3176                                         }
3177
3178                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3179
3180                                         CODEGEN_CRITICAL_SECTION_START;
3181
3182                                         M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3183
3184                                         /*                              if (s1 != REG_ITMP1) { */
3185                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3186                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3187                                         /* #if defined(ENABLE_THREADS) */
3188                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3189                                         /* #endif */
3190                                         /*                                      emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3191
3192                                         /*                              } else { */
3193                                         M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3194                                         M_ISUB(REG_ITMP3, REG_ITMP2);
3195                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3196                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3197
3198                                         CODEGEN_CRITICAL_SECTION_END;
3199
3200                                         /*                              } */
3201
3202                                         M_CMP(REG_ITMP3, REG_ITMP2);
3203                                         emit_classcast_check(cd, iptr, BRANCH_ULE, REG_ITMP3, s1);
3204
3205                                         if (super != NULL)
3206                                                 emit_label(cd, BRANCH_LABEL_5);
3207                                 }
3208
3209                                 if (super == NULL) {
3210                                         emit_label(cd, BRANCH_LABEL_1);
3211                                         emit_label(cd, BRANCH_LABEL_4);
3212                                 }
3213
3214                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3215                         }
3216                         else {
3217                                 /* array type cast-check */
3218
3219                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3220                                 M_AST(s1, REG_SP, 0 * 4);
3221
3222                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3223                                         patcher_add_patch_ref(jd, PATCHER_builtin_arraycheckcast,
3224                                                                                 iptr->sx.s23.s3.c.ref, 0);
3225                                 }
3226
3227                                 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
3228                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3229                                 M_CALL(REG_ITMP3);
3230
3231                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3232                                 M_TEST(REG_RESULT);
3233                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
3234
3235                                 d = codegen_reg_of_dst(jd, iptr, s1);
3236                         }
3237
3238                         M_INTMOVE(s1, d);
3239                         emit_store_dst(jd, iptr, d);
3240                         break;
3241
3242                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3243
3244                         {
3245                         classinfo *super;
3246                         vftbl_t   *supervftbl;
3247                         s4         superindex;
3248
3249                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3250                                 super = NULL;
3251                                 superindex = 0;
3252                                 supervftbl = NULL;
3253
3254                         } else {
3255                                 super = iptr->sx.s23.s3.c.cls;
3256                                 superindex = super->index;
3257                                 supervftbl = super->vftbl;
3258                         }
3259                         
3260                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3261                                 CODEGEN_CRITICAL_SECTION_NEW;
3262
3263                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3264                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3265
3266                         if (s1 == d) {
3267                                 M_INTMOVE(s1, REG_ITMP1);
3268                                 s1 = REG_ITMP1;
3269                         }
3270
3271                         M_CLR(d);
3272
3273                         /* if class is not resolved, check which code to call */
3274
3275                         if (super == NULL) {
3276                                 M_TEST(s1);
3277                                 emit_label_beq(cd, BRANCH_LABEL_1);
3278
3279                                 patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
3280                                                                         iptr->sx.s23.s3.c.ref, 0);
3281
3282                                 M_MOV_IMM(0, REG_ITMP3);                      /* super->flags */
3283                                 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3284                                 emit_label_beq(cd, BRANCH_LABEL_2);
3285                         }
3286
3287                         /* interface instanceof code */
3288
3289                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3290                                 if (super != NULL) {
3291                                         M_TEST(s1);
3292                                         emit_label_beq(cd, BRANCH_LABEL_3);
3293                                 }
3294
3295                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3296
3297                                 if (super == NULL) {
3298                                         patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3299                                                                                 iptr->sx.s23.s3.c.ref, 0);
3300                                 }
3301
3302                                 M_ILD32(REG_ITMP3,
3303                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3304                                 M_ISUB_IMM32(superindex, REG_ITMP3);
3305                                 M_TEST(REG_ITMP3);
3306
3307                                 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3308                                                 6 /* jcc */ + 5 /* mov_imm_reg */);
3309
3310                                 M_BLE(disp);
3311                                 M_ALD32(REG_ITMP1, REG_ITMP1,
3312                                                 OFFSET(vftbl_t, interfacetable[0]) -
3313                                                 superindex * sizeof(methodptr*));
3314                                 M_TEST(REG_ITMP1);
3315 /*                                      emit_setcc_reg(cd, CC_A, d); */
3316 /*                                      emit_jcc(cd, CC_BE, 5); */
3317                                 M_BEQ(5);
3318                                 M_MOV_IMM(1, d);
3319
3320                                 if (super == NULL)
3321                                         emit_label_br(cd, BRANCH_LABEL_4);
3322                                 else
3323                                         emit_label(cd, BRANCH_LABEL_3);
3324                         }
3325
3326                         /* class instanceof code */
3327
3328                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3329                                 if (super == NULL) {
3330                                         emit_label(cd, BRANCH_LABEL_2);
3331                                 }
3332                                 else {
3333                                         M_TEST(s1);
3334                                         emit_label_beq(cd, BRANCH_LABEL_5);
3335                                 }
3336
3337                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3338
3339                                 if (super == NULL) {
3340                                         patcher_add_patch_ref(jd, PATCHER_instanceof_class,
3341                                                                                 iptr->sx.s23.s3.c.ref, 0);
3342                                 }
3343
3344                                 M_MOV_IMM(supervftbl, REG_ITMP2);
3345
3346                                 CODEGEN_CRITICAL_SECTION_START;
3347
3348                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3349                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3350                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3351
3352                                 CODEGEN_CRITICAL_SECTION_END;
3353
3354                                 M_ISUB(REG_ITMP2, REG_ITMP1);
3355                                 M_CLR(d);                                 /* may be REG_ITMP2 */
3356                                 M_CMP(REG_ITMP3, REG_ITMP1);
3357                                 M_BA(5);
3358                                 M_MOV_IMM(1, d);
3359
3360                                 if (super != NULL)
3361                                         emit_label(cd, BRANCH_LABEL_5);
3362                         }
3363
3364                         if (super == NULL) {
3365                                 emit_label(cd, BRANCH_LABEL_1);
3366                                 emit_label(cd, BRANCH_LABEL_4);
3367                         }
3368
3369                         emit_store_dst(jd, iptr, d);
3370                         }
3371                         break;
3372
3373                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3374
3375                         /* check for negative sizes and copy sizes to stack if necessary  */
3376
3377                         MCODECHECK((iptr->s1.argcount << 1) + 64);
3378
3379                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3380                                 /* copy SAVEDVAR sizes to stack */
3381                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3382
3383                                 /* Already Preallocated? */
3384                                 if (!(var->flags & PREALLOC)) {
3385                                         if (var->flags & INMEMORY) {
3386                                                 M_ILD(REG_ITMP1, REG_SP, var->vv.regoff);
3387                                                 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
3388                                         }
3389                                         else
3390                                                 M_IST(var->vv.regoff, REG_SP, (s1 + 3) * 4);
3391                                 }
3392                         }
3393
3394                         /* is a patcher function set? */
3395
3396                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3397                                 patcher_add_patch_ref(jd, PATCHER_builtin_multianewarray,
3398                                                                         iptr->sx.s23.s3.c.ref, 0);
3399
3400                                 disp = 0;
3401
3402                         }
3403                         else
3404                                 disp = (ptrint) iptr->sx.s23.s3.c.cls;
3405
3406                         /* a0 = dimension count */
3407
3408                         M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
3409
3410                         /* a1 = arraydescriptor */
3411
3412                         M_IST_IMM(disp, REG_SP, 1 * 4);
3413
3414                         /* a2 = pointer to dimensions = stack pointer */
3415
3416                         M_MOV(REG_SP, REG_ITMP1);
3417                         M_AADD_IMM(3 * 4, REG_ITMP1);
3418                         M_AST(REG_ITMP1, REG_SP, 2 * 4);
3419
3420                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3421                         M_CALL(REG_ITMP1);
3422
3423                         /* check for exception before result assignment */
3424
3425                         emit_exception_check(cd, iptr);
3426
3427                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3428                         M_INTMOVE(REG_RESULT, s1);
3429                         emit_store_dst(jd, iptr, s1);
3430                         break;
3431
3432                 default:
3433                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3434                                                                                    iptr->opc);
3435                         return false;
3436         } /* switch */
3437                 
3438         } /* for instruction */
3439                 
3440         MCODECHECK(64);
3441
3442 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
3443         if (!opt_lsra)
3444 #endif
3445 #if defined(ENABLE_SSA)
3446         if ( ls != NULL ) {
3447
3448                 /* by edge splitting, in Blocks with phi moves there can only */
3449                 /* be a goto as last command, no other Jump/Branch Command    */
3450
3451                 if (!last_cmd_was_goto)
3452                         codegen_emit_phi_moves(jd, bptr);
3453         }
3454
3455 #endif
3456
3457         /* At the end of a basic block we may have to append some nops,
3458            because the patcher stub calling code might be longer than the
3459            actual instruction. So codepatching does not change the
3460            following block unintentionally. */
3461
3462         if (cd->mcodeptr < cd->lastmcodeptr) {
3463                 while (cd->mcodeptr < cd->lastmcodeptr) {
3464                         M_NOP;
3465                 }
3466         }
3467
3468         } /* if (bptr -> flags >= BBREACHED) */
3469         } /* for basic block */
3470
3471         dseg_createlinenumbertable(cd);
3472
3473         /* generate stubs */
3474
3475         emit_patcher_traps(jd);
3476
3477         /* everything's ok */
3478
3479         return true;
3480 }
3481
3482
3483 /* codegen_emit_stub_native ****************************************************
3484
3485    Emits a stub routine which calls a native method.
3486
3487 *******************************************************************************/
3488
3489 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3490 {
3491         methodinfo  *m;
3492         codeinfo    *code;
3493         codegendata *cd;
3494         methoddesc  *md;
3495         int          i, j;                 /* count variables                    */
3496         int          s1, s2;
3497         int          funcdisp;
3498 #if defined(ENABLE_GC_CACAO)
3499         int          disp;
3500 #endif
3501
3502         /* get required compiler data */
3503
3504         m    = jd->m;
3505         code = jd->code;
3506         cd   = jd->cd;
3507
3508         /* set some variables */
3509
3510         md = m->parseddesc;
3511
3512         /* calculate stackframe size */
3513
3514         cd->stackframesize =
3515                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3516                 sizeof(localref_table) / SIZEOF_VOID_P +
3517                 4 +                             /* 4 arguments (start_native_call)    */
3518                 nmd->memuse;
3519
3520     /* keep stack 16-byte aligned */
3521
3522         ALIGN_ODD(cd->stackframesize);        /* XXX this is wrong, +4 is missing */
3523
3524         /* create method header */
3525
3526         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3527         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
3528         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
3529         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3530         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3531         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3532         (void) dseg_addlinenumbertablesize(cd);
3533         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
3534
3535 #if defined(ENABLE_PROFILING)
3536         /* generate native method profiling code */
3537
3538         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3539                 /* count frequency */
3540
3541                 M_MOV_IMM(code, REG_ITMP1);
3542                 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
3543         }
3544 #endif
3545
3546         /* calculate stackframe size for native function */
3547
3548         M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3549
3550         /* get function address (this must happen before the stackframeinfo) */
3551
3552         funcdisp = dseg_add_functionptr(cd, f);
3553
3554         if (f == NULL)
3555                 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3556
3557         /* Mark the whole fpu stack as free for native functions (only for saved  */
3558         /* register count == 0).                                                  */
3559
3560         emit_ffree_reg(cd, 0);
3561         emit_ffree_reg(cd, 1);
3562         emit_ffree_reg(cd, 2);
3563         emit_ffree_reg(cd, 3);
3564         emit_ffree_reg(cd, 4);
3565         emit_ffree_reg(cd, 5);
3566         emit_ffree_reg(cd, 6);
3567         emit_ffree_reg(cd, 7);
3568
3569 #if defined(ENABLE_GC_CACAO)
3570         /* remember callee saved int registers in stackframeinfo (GC may need to  */
3571         /* recover them during a collection).                                     */
3572
3573         disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3574                 OFFSET(stackframeinfo, intregs);
3575
3576         for (i = 0; i < INT_SAV_CNT; i++)
3577                 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3578 #endif
3579
3580         /* prepare data structures for native function call */
3581
3582         M_MOV(REG_SP, REG_ITMP1);
3583         M_AST(REG_ITMP1, REG_SP, 0 * 4);
3584         M_IST_IMM(0, REG_SP, 1 * 4);
3585         dseg_adddata(cd);
3586
3587         M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3588         M_CALL(REG_ITMP1);
3589
3590         /* remember class argument */
3591
3592         if (m->flags & ACC_STATIC)
3593                 M_MOV(REG_RESULT, REG_ITMP3);
3594
3595         /* Copy or spill arguments to new locations. */
3596
3597         for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3598                 if (!md->params[i].inmemory)
3599                         assert(0);
3600
3601                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
3602                 s2 = nmd->params[j].regoff;
3603
3604                 /* float/double in memory can be copied like int/longs */
3605
3606                 switch (md->paramtypes[i].type) {
3607                 case TYPE_INT:
3608                 case TYPE_FLT:
3609                 case TYPE_ADR:
3610                         M_ILD(REG_ITMP1, REG_SP, s1);
3611                         M_IST(REG_ITMP1, REG_SP, s2);
3612                         break;
3613                 case TYPE_LNG:
3614                 case TYPE_DBL:
3615                         M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3616                         M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3617                         break;
3618                 }
3619         }
3620
3621         /* Handle native Java methods. */
3622
3623         if (m->flags & ACC_NATIVE) {
3624                 /* if function is static, put class into second argument */
3625
3626                 if (m->flags & ACC_STATIC)
3627                         M_AST(REG_ITMP3, REG_SP, 1 * 4);
3628
3629                 /* put env into first argument */
3630
3631                 M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
3632         }
3633
3634         /* call the native function */
3635
3636         emit_mov_imm_reg(cd, 0, REG_ITMP3);
3637         dseg_adddata(cd);
3638         M_ALD(REG_ITMP1, REG_ITMP3, funcdisp);
3639         M_CALL(REG_ITMP1);
3640
3641         /* save return value */
3642
3643         switch (md->returntype.type) {
3644         case TYPE_INT:
3645         case TYPE_ADR:
3646                 M_IST(REG_RESULT, REG_SP, 1 * 8);
3647                 break;
3648         case TYPE_LNG:
3649                 M_LST(REG_RESULT_PACKED, REG_SP, 1 * 8);
3650                 break;
3651         case TYPE_FLT:
3652                 emit_fsts_membase(cd, REG_SP, 1 * 8);
3653                 break;
3654         case TYPE_DBL:
3655                 emit_fstl_membase(cd, REG_SP, 1 * 8);
3656                 break;
3657         case TYPE_VOID:
3658                 break;
3659         }
3660
3661         /* remove native stackframe info */
3662
3663         M_MOV(REG_SP, REG_ITMP1);
3664         M_AST(REG_ITMP1, REG_SP, 0 * 4);
3665         M_IST_IMM(0, REG_SP, 1 * 4);
3666         dseg_adddata(cd);
3667
3668         M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3669         M_CALL(REG_ITMP1);
3670         M_MOV(REG_RESULT, REG_ITMP2);                 /* REG_ITMP3 == REG_RESULT2 */
3671
3672         /* restore return value */
3673
3674         switch (md->returntype.type) {
3675         case TYPE_INT:
3676         case TYPE_ADR:
3677                 M_ILD(REG_RESULT, REG_SP, 1 * 8);
3678                 break;
3679         case TYPE_LNG:
3680                 M_LLD(REG_RESULT_PACKED, REG_SP, 1 * 8);
3681                 break;
3682         case TYPE_FLT:
3683                 emit_flds_membase(cd, REG_SP, 1 * 8);
3684                 break;
3685         case TYPE_DBL:
3686                 emit_fldl_membase(cd, REG_SP, 1 * 8);
3687                 break;
3688         case TYPE_VOID:
3689                 break;
3690         }
3691
3692 #if defined(ENABLE_GC_CACAO)
3693         /* restore callee saved int registers from stackframeinfo (GC might have  */
3694         /* modified them during a collection).                                    */
3695
3696         disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3697                 OFFSET(stackframeinfo, intregs);
3698
3699         for (i = 0; i < INT_SAV_CNT; i++)
3700                 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3701 #endif
3702
3703         M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3704
3705         /* check for exception */
3706
3707         M_TEST(REG_ITMP2);
3708         M_BNE(1);
3709
3710         M_RET;
3711
3712         /* handle exception */
3713
3714         M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
3715         M_ALD(REG_ITMP2_XPC, REG_SP, 0);
3716         M_ASUB_IMM(2, REG_ITMP2_XPC);
3717
3718         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3719         M_JMP(REG_ITMP3);
3720
3721         /* generate patcher stubs */
3722
3723         emit_patcher_traps(jd);
3724 }
3725
3726
3727 /*
3728  * These are local overrides for various environment variables in Emacs.
3729  * Please do not remove this and leave it at the end of the file, where
3730  * Emacs will automagically detect them.
3731  * ---------------------------------------------------------------------
3732  * Local variables:
3733  * mode: c
3734  * indent-tabs-mode: t
3735  * c-basic-offset: 4
3736  * tab-width: 4
3737  * End:
3738  * vim:noexpandtab:sw=4:ts=4:
3739  */