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