* src/vm/jit/i386/codegen.c (codegen_emit): Commented out escape checks.
[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 defined(ENABLE_ESCAPE_CHECK)
2307                         /*emit_escape_check(cd, s1);*/
2308 #endif
2309
2310                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2311                                 uf        = iptr->sx.s23.s3.uf;
2312                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2313                                 disp      = 0;
2314
2315                                 patcher_add_patch_ref(jd, PATCHER_getfield,
2316                                                                         iptr->sx.s23.s3.uf, 0);
2317                         }
2318                         else {
2319                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2320                                 fieldtype = fi->type;
2321                                 disp      = fi->offset;
2322                         }
2323
2324                         switch (fieldtype) {
2325                         case TYPE_INT:
2326                         case TYPE_ADR:
2327                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2328                                 M_ILD32(d, s1, disp);
2329                                 break;
2330                         case TYPE_LNG:
2331                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2332                                 M_LLD32(d, s1, disp);
2333                                 break;
2334                         case TYPE_FLT:
2335                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2336                                 M_FLD32(d, s1, disp);
2337                                 break;
2338                         case TYPE_DBL:                          
2339                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2340                                 M_DLD32(d, s1, disp);
2341                                 break;
2342                         }
2343                         emit_store_dst(jd, iptr, d);
2344                         break;
2345
2346                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2347
2348                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2349                         emit_nullpointer_check(cd, iptr, s1);
2350
2351                         /* must be done here because of code patching */
2352
2353                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2354                                 uf        = iptr->sx.s23.s3.uf;
2355                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2356                         }
2357                         else {
2358                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2359                                 fieldtype = fi->type;
2360                         }
2361
2362                         if (!IS_FLT_DBL_TYPE(fieldtype)) {
2363                                 if (IS_2_WORD_TYPE(fieldtype))
2364                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2365                                 else
2366                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2367                         }
2368                         else
2369                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2370
2371                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2372                                 /* XXX */
2373                                 uf   = iptr->sx.s23.s3.uf;
2374                                 disp = 0;
2375
2376                                 patcher_add_patch_ref(jd, PATCHER_putfield, uf, 0);
2377                         }
2378                         else {
2379                                 /* XXX */
2380                                 fi   = iptr->sx.s23.s3.fmiref->p.field;
2381                                 disp = fi->offset;
2382                         }
2383
2384                         switch (fieldtype) {
2385                         case TYPE_INT:
2386                         case TYPE_ADR:
2387                                 M_IST32(s2, s1, disp);
2388                                 break;
2389                         case TYPE_LNG:
2390                                 M_LST32(s2, s1, disp);
2391                                 break;
2392                         case TYPE_FLT:
2393                                 emit_fstps_membase32(cd, s1, disp);
2394                                 break;
2395                         case TYPE_DBL:
2396                                 emit_fstpl_membase32(cd, s1, disp);
2397                                 break;
2398                         }
2399                         break;
2400
2401                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2402                                           /* val = value (in current instruction)     */
2403                                           /* following NOP)                           */
2404
2405                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2406                         emit_nullpointer_check(cd, iptr, s1);
2407
2408                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2409                                 uf        = iptr->sx.s23.s3.uf;
2410                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2411                                 disp      = 0;
2412
2413                                 patcher_add_patch_ref(jd, PATCHER_putfieldconst,
2414                                                                         uf, 0);
2415                         }
2416                         else {
2417                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2418                                 fieldtype = fi->type;
2419                                 disp      = fi->offset;
2420                         }
2421
2422                         switch (fieldtype) {
2423                         case TYPE_INT:
2424                         case TYPE_ADR:
2425                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2426                                 break;
2427                         case TYPE_LNG:
2428                                 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2429                                 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2430                                 break;
2431                         default:
2432                                 assert(0);
2433                         }
2434                         break;
2435
2436
2437                 /* branch operations **************************************************/
2438
2439                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2440
2441                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2442                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2443
2444 #ifdef ENABLE_VERIFIER
2445                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2446                                 patcher_add_patch_ref(jd, PATCHER_resolve_class,
2447                                                                         iptr->sx.s23.s2.uc, 0);
2448                         }
2449 #endif /* ENABLE_VERIFIER */
2450
2451                         M_CALL_IMM(0);                            /* passing exception pc */
2452                         M_POP(REG_ITMP2_XPC);
2453
2454                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2455                         M_JMP(REG_ITMP3);
2456                         break;
2457
2458                 case ICMD_GOTO:         /* ... ==> ...                                */
2459                 case ICMD_RET:          /* ... ==> ...                                */
2460
2461 #if defined(ENABLE_SSA)
2462                         if ( ls != NULL ) {
2463                                 last_cmd_was_goto = true;
2464
2465                                 /* In case of a Goto phimoves have to be inserted before the */
2466                                 /* jump */
2467
2468                                 codegen_emit_phi_moves(jd, bptr);
2469                         }
2470 #endif
2471                         emit_br(cd, iptr->dst.block);
2472                         ALIGNCODENOP;
2473                         break;
2474
2475                 case ICMD_JSR:          /* ... ==> ...                                */
2476
2477                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2478                         ALIGNCODENOP;
2479                         break;
2480                         
2481                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2482                 case ICMD_IFNONNULL:
2483
2484                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2485                         M_TEST(s1);
2486                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2487                         break;
2488
2489                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2490                 case ICMD_IFLT:
2491                 case ICMD_IFLE:
2492                 case ICMD_IFNE:
2493                 case ICMD_IFGT:
2494                 case ICMD_IFGE:
2495
2496                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2497                         M_CMP_IMM(iptr->sx.val.i, s1);
2498                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2499                         break;
2500
2501                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2502
2503                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2504                         if (iptr->sx.val.l == 0) {
2505                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2506                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2507                         }
2508                         else {
2509                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2510                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2511                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2512                                 M_OR(REG_ITMP2, REG_ITMP1);
2513                         }
2514                         emit_beq(cd, iptr->dst.block);
2515                         break;
2516
2517                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2518
2519                         if (iptr->sx.val.l == 0) {
2520                                 /* If high 32-bit are less than zero, then the 64-bits
2521                                    are too. */
2522                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2523                                 M_CMP_IMM(0, s1);
2524                                 emit_blt(cd, iptr->dst.block);
2525                         }
2526                         else {
2527                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2528                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2529                                 emit_blt(cd, iptr->dst.block);
2530                                 M_BGT(6 + 6);
2531                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2532                                 emit_bult(cd, iptr->dst.block);
2533                         }                       
2534                         break;
2535
2536                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2537
2538                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2539                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2540                         emit_blt(cd, iptr->dst.block);
2541                         M_BGT(6 + 6);
2542                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2543                         emit_bule(cd, iptr->dst.block);
2544                         break;
2545
2546                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2547
2548                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2549                         if (iptr->sx.val.l == 0) {
2550                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2551                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2552                         }
2553                         else {
2554                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2555                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2556                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2557                                 M_OR(REG_ITMP2, REG_ITMP1);
2558                         }
2559                         emit_bne(cd, iptr->dst.block);
2560                         break;
2561
2562                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2563
2564                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2565                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2566                         emit_bgt(cd, iptr->dst.block);
2567                         M_BLT(6 + 6);
2568                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2569                         emit_bugt(cd, iptr->dst.block);
2570                         break;
2571
2572                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2573
2574                         if (iptr->sx.val.l == 0) {
2575                                 /* If high 32-bit are greater equal zero, then the
2576                                    64-bits are too. */
2577                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2578                                 M_CMP_IMM(0, s1);
2579                                 emit_bge(cd, iptr->dst.block);
2580                         }
2581                         else {
2582                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2583                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2584                                 emit_bgt(cd, iptr->dst.block);
2585                                 M_BLT(6 + 6);
2586                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2587                                 emit_buge(cd, iptr->dst.block);
2588                         }
2589                         break;
2590
2591                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2592                 case ICMD_IF_ICMPNE:
2593                 case ICMD_IF_ICMPLT:
2594                 case ICMD_IF_ICMPGT:
2595                 case ICMD_IF_ICMPGE:
2596                 case ICMD_IF_ICMPLE:
2597
2598                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2599                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2600                         M_CMP(s2, s1);
2601                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2602                         break;
2603
2604                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
2605                 case ICMD_IF_ACMPNE:
2606
2607                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2608                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2609                         M_CMP(s2, s1);
2610                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2611                         break;
2612
2613                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2614
2615                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2616                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2617                         M_INTMOVE(s1, REG_ITMP1);
2618                         M_XOR(s2, REG_ITMP1);
2619                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2620                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2621                         M_INTMOVE(s1, REG_ITMP2);
2622                         M_XOR(s2, REG_ITMP2);
2623                         M_OR(REG_ITMP1, REG_ITMP2);
2624                         emit_beq(cd, iptr->dst.block);
2625                         break;
2626
2627                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
2628
2629                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2630                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2631                         M_INTMOVE(s1, REG_ITMP1);
2632                         M_XOR(s2, REG_ITMP1);
2633                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2634                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2635                         M_INTMOVE(s1, REG_ITMP2);
2636                         M_XOR(s2, REG_ITMP2);
2637                         M_OR(REG_ITMP1, REG_ITMP2);
2638                         emit_bne(cd, iptr->dst.block);
2639                         break;
2640
2641                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2642
2643                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2644                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2645                         M_CMP(s2, s1);
2646                         emit_blt(cd, iptr->dst.block);
2647                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2648                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2649                         M_BGT(2 + 6);
2650                         M_CMP(s2, s1);
2651                         emit_bult(cd, iptr->dst.block);
2652                         break;
2653
2654                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2655
2656                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2657                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2658                         M_CMP(s2, s1);
2659                         emit_bgt(cd, iptr->dst.block);
2660                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2661                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2662                         M_BLT(2 + 6);
2663                         M_CMP(s2, s1);
2664                         emit_bugt(cd, iptr->dst.block);
2665                         break;
2666
2667                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2668
2669                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2670                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2671                         M_CMP(s2, s1);
2672                         emit_blt(cd, iptr->dst.block);
2673                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2674                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2675                         M_BGT(2 + 6);
2676                         M_CMP(s2, s1);
2677                         emit_bule(cd, iptr->dst.block);
2678                         break;
2679
2680                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2681
2682                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2683                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2684                         M_CMP(s2, s1);
2685                         emit_bgt(cd, iptr->dst.block);
2686                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2687                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2688                         M_BLT(2 + 6);
2689                         M_CMP(s2, s1);
2690                         emit_buge(cd, iptr->dst.block);
2691                         break;
2692
2693
2694                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2695
2696                         REPLACEMENT_POINT_RETURN(cd, iptr);
2697                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2698                         M_INTMOVE(s1, REG_RESULT);
2699                         goto nowperformreturn;
2700
2701                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2702
2703                         REPLACEMENT_POINT_RETURN(cd, iptr);
2704                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2705                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2706                         goto nowperformreturn;
2707
2708                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2709
2710                         REPLACEMENT_POINT_RETURN(cd, iptr);
2711                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2712                         M_INTMOVE(s1, REG_RESULT);
2713
2714 #ifdef ENABLE_VERIFIER
2715                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2716                                 patcher_add_patch_ref(jd, PATCHER_resolve_class,
2717                                                                         iptr->sx.s23.s2.uc, 0);
2718                         }
2719 #endif /* ENABLE_VERIFIER */
2720                         goto nowperformreturn;
2721
2722                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2723                 case ICMD_DRETURN:
2724
2725                         REPLACEMENT_POINT_RETURN(cd, iptr);
2726                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2727                         goto nowperformreturn;
2728
2729                 case ICMD_RETURN:      /* ...  ==> ...                                */
2730
2731                         REPLACEMENT_POINT_RETURN(cd, iptr);
2732
2733 nowperformreturn:
2734                         {
2735                         s4 i, p;
2736                         
2737                         p = cd->stackframesize;
2738                         
2739 #if !defined(NDEBUG)
2740                         emit_verbosecall_exit(jd);
2741 #endif
2742
2743 #if defined(ENABLE_THREADS)
2744                         if (checksync && code_is_synchronized(code)) {
2745                                 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 8);
2746
2747                                 /* we need to save the proper return value */
2748                                 switch (iptr->opc) {
2749                                 case ICMD_IRETURN:
2750                                 case ICMD_ARETURN:
2751                                         M_IST(REG_RESULT, REG_SP, rd->memuse * 8);
2752                                         break;
2753
2754                                 case ICMD_LRETURN:
2755                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2756                                         break;
2757
2758                                 case ICMD_FRETURN:
2759                                         emit_fstps_membase(cd, REG_SP, rd->memuse * 8);
2760                                         break;
2761
2762                                 case ICMD_DRETURN:
2763                                         emit_fstpl_membase(cd, REG_SP, rd->memuse * 8);
2764                                         break;
2765                                 }
2766
2767                                 M_AST(REG_ITMP2, REG_SP, 0);
2768                                 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
2769                                 M_CALL(REG_ITMP3);
2770
2771                                 /* and now restore the proper return value */
2772                                 switch (iptr->opc) {
2773                                 case ICMD_IRETURN:
2774                                 case ICMD_ARETURN:
2775                                         M_ILD(REG_RESULT, REG_SP, rd->memuse * 8);
2776                                         break;
2777
2778                                 case ICMD_LRETURN:
2779                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2780                                         break;
2781
2782                                 case ICMD_FRETURN:
2783                                         emit_flds_membase(cd, REG_SP, rd->memuse * 8);
2784                                         break;
2785
2786                                 case ICMD_DRETURN:
2787                                         emit_fldl_membase(cd, REG_SP, rd->memuse * 8);
2788                                         break;
2789                                 }
2790                         }
2791 #endif
2792
2793                         /* restore saved registers */
2794
2795                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2796                                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2797                         }
2798
2799                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2800                                 p--;
2801                                 emit_fldl_membase(cd, REG_SP, p * 8);
2802                                 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
2803                                         assert(0);
2804 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
2805                                 } else {
2806                                         assert(0);
2807 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
2808                                 }
2809                         }
2810
2811                         /* deallocate stack */
2812
2813                         if (cd->stackframesize)
2814                                 M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP);
2815
2816                         M_RET;
2817                         }
2818                         break;
2819
2820
2821                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2822                         {
2823                                 s4 i, l;
2824                                 branch_target_t *table;
2825
2826                                 table = iptr->dst.table;
2827
2828                                 l = iptr->sx.s23.s2.tablelow;
2829                                 i = iptr->sx.s23.s3.tablehigh;
2830
2831                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2832                                 M_INTMOVE(s1, REG_ITMP1);
2833
2834                                 if (l != 0)
2835                                         M_ISUB_IMM(l, REG_ITMP1);
2836
2837                                 i = i - l + 1;
2838
2839                 /* range check */
2840
2841                                 M_CMP_IMM(i - 1, REG_ITMP1);
2842                                 emit_bugt(cd, table[0].block);
2843
2844                                 /* build jump table top down and use address of lowest entry */
2845
2846                                 table += i;
2847
2848                                 while (--i >= 0) {
2849                                         dseg_add_target(cd, table->block); 
2850                                         --table;
2851                                 }
2852
2853                                 /* length of dataseg after last dseg_addtarget is used
2854                                    by load */
2855
2856                                 M_MOV_IMM(0, REG_ITMP2);
2857                                 dseg_adddata(cd);
2858                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
2859                                 M_JMP(REG_ITMP1);
2860                         }
2861                         break;
2862
2863
2864                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2865                         {
2866                                 s4 i;
2867                                 lookup_target_t *lookup;
2868
2869                                 lookup = iptr->dst.lookup;
2870
2871                                 i = iptr->sx.s23.s2.lookupcount;
2872                         
2873                                 MCODECHECK((i<<2)+8);
2874                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2875
2876                                 while (--i >= 0) {
2877                                         M_CMP_IMM(lookup->value, s1);
2878                                         emit_beq(cd, lookup->target.block);
2879                                         lookup++;
2880                                 }
2881
2882                                 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2883                                 ALIGNCODENOP;
2884                         }
2885                         break;
2886
2887                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
2888
2889                         REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2890
2891                         bte = iptr->sx.s23.s3.bte;
2892                         md = bte->md;
2893                         goto gen_method;
2894
2895                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2896
2897                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2898                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2899                 case ICMD_INVOKEINTERFACE:
2900
2901                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2902
2903                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2904                                 md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
2905                                 lm = NULL;
2906                         }
2907                         else {
2908                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2909                                 md = lm->parseddesc;
2910                         }
2911
2912 gen_method:
2913                         s3 = md->paramcount;
2914
2915                         MCODECHECK((s3 << 1) + 64);
2916
2917                         /* copy arguments to registers or stack location                  */
2918
2919                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2920                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2921           
2922                                 /* Already Preallocated (ARGVAR) ? */
2923                                 if (var->flags & PREALLOC)
2924                                         continue;
2925                                 if (IS_INT_LNG_TYPE(var->type)) {
2926                                         if (!md->params[s3].inmemory) {
2927                                                 log_text("No integer argument registers available!");
2928                                                 assert(0);
2929
2930                                         } else {
2931                                                 if (IS_2_WORD_TYPE(var->type)) {
2932                                                         d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2933                                                         M_LST(d, REG_SP, md->params[s3].regoff);
2934                                                 } else {
2935                                                         d = emit_load(jd, iptr, var, REG_ITMP1);
2936                                                         M_IST(d, REG_SP, md->params[s3].regoff);
2937                                                 }
2938                                         }
2939
2940                                 } else {
2941                                         if (!md->params[s3].inmemory) {
2942                                                 s1 = md->params[s3].regoff;
2943                                                 d = emit_load(jd, iptr, var, s1);
2944                                                 M_FLTMOVE(d, s1);
2945
2946                                         } else {
2947                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2948                                                 if (IS_2_WORD_TYPE(var->type))
2949                                                         M_DST(d, REG_SP, md->params[s3].regoff);
2950                                                 else
2951                                                         M_FST(d, REG_SP, md->params[s3].regoff);
2952                                         }
2953                                 }
2954                         } /* end of for */
2955
2956                         switch (iptr->opc) {
2957                         case ICMD_BUILTIN:
2958                                 d = md->returntype.type;
2959
2960                                 if (bte->stub == NULL) {
2961                                         M_MOV_IMM(bte->fp, REG_ITMP1);
2962                                 }
2963                                 else {
2964                                         M_MOV_IMM(bte->stub, REG_ITMP1);
2965                                 }
2966                                 M_CALL(REG_ITMP1);
2967
2968 #if defined(ENABLE_ESCAPE_CHECK)
2969                                 if (bte->opcode == ICMD_NEW || bte->opcode == ICMD_NEWARRAY) {
2970                                         /*emit_escape_annotate_object(cd, m);*/
2971                                 }
2972 #endif
2973                                 break;
2974
2975                         case ICMD_INVOKESPECIAL:
2976                                 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
2977                                 emit_nullpointer_check(cd, iptr, REG_ITMP1);
2978                                 /* fall through */
2979
2980                         case ICMD_INVOKESTATIC:
2981                                 if (lm == NULL) {
2982                                         unresolved_method *um = iptr->sx.s23.s3.um;
2983
2984                                         patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2985                                                                                 um, 0);
2986
2987                                         disp = 0;
2988                                         d = md->returntype.type;
2989                                 }
2990                                 else {
2991                                         disp = (ptrint) lm->stubroutine;
2992                                         d = lm->parseddesc->returntype.type;
2993                                 }
2994
2995                                 M_MOV_IMM(disp, REG_ITMP2);
2996                                 M_CALL(REG_ITMP2);
2997                                 break;
2998
2999                         case ICMD_INVOKEVIRTUAL:
3000                                 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
3001                                 emit_nullpointer_check(cd, iptr, s1);
3002
3003                                 if (lm == NULL) {
3004                                         unresolved_method *um = iptr->sx.s23.s3.um;
3005
3006                                         patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3007
3008                                         s1 = 0;
3009                                         d = md->returntype.type;
3010                                 }
3011                                 else {
3012                                         s1 = OFFSET(vftbl_t, table[0]) +
3013                                                 sizeof(methodptr) * lm->vftblindex;
3014                                         d = md->returntype.type;
3015                                 }
3016
3017                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3018                                           OFFSET(java_object_t, vftbl));
3019                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3020                                 M_CALL(REG_ITMP3);
3021                                 break;
3022
3023                         case ICMD_INVOKEINTERFACE:
3024                                 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
3025                                 emit_nullpointer_check(cd, iptr, s1);
3026
3027                                 if (lm == NULL) {
3028                                         unresolved_method *um = iptr->sx.s23.s3.um;
3029
3030                                         patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3031
3032                                         s1 = 0;
3033                                         s2 = 0;
3034                                         d = md->returntype.type;
3035                                 }
3036                                 else {
3037                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3038                                                 sizeof(methodptr) * lm->clazz->index;
3039
3040                                         s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
3041
3042                                         d = md->returntype.type;
3043                                 }
3044
3045                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3046                                           OFFSET(java_object_t, vftbl));
3047                                 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3048                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3049                                 M_CALL(REG_ITMP3);
3050                                 break;
3051                         }
3052
3053                         /* store size of call code in replacement point */
3054
3055                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3056                         REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
3057
3058                         /* d contains return type */
3059
3060                         if (d != TYPE_VOID) {
3061 #if defined(ENABLE_SSA)
3062                                 if ((ls == NULL) /* || (!IS_TEMPVAR_INDEX(iptr->dst.varindex)) */ ||
3063                                         (ls->lifetime[iptr->dst.varindex].type != UNUSED)) 
3064                                         /* a "living" stackslot */
3065 #endif
3066                                 {
3067                                         if (IS_INT_LNG_TYPE(d)) {
3068                                                 if (IS_2_WORD_TYPE(d)) {
3069                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3070                                                         M_LNGMOVE(REG_RESULT_PACKED, s1);
3071                                                 }
3072                                                 else {
3073                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3074                                                         M_INTMOVE(REG_RESULT, s1);
3075                                                 }
3076                                         }
3077                                         else {
3078                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
3079                                         }
3080                                         emit_store_dst(jd, iptr, s1);
3081                                 }
3082                         }
3083                         break;
3084
3085
3086                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3087
3088                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3089                                 /* object type cast-check */
3090
3091                                 classinfo *super;
3092                                 vftbl_t   *supervftbl;
3093                                 s4         superindex;
3094
3095                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3096                                         super = NULL;
3097                                         superindex = 0;
3098                                         supervftbl = NULL;
3099                                 }
3100                                 else {
3101                                         super = iptr->sx.s23.s3.c.cls;
3102                                         superindex = super->index;
3103                                         supervftbl = super->vftbl;
3104                                 }
3105                         
3106                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3107                                         CODEGEN_CRITICAL_SECTION_NEW;
3108
3109                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3110
3111                                 /* if class is not resolved, check which code to call */
3112
3113                                 if (super == NULL) {
3114                                         M_TEST(s1);
3115                                         emit_label_beq(cd, BRANCH_LABEL_1);
3116
3117                                         patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
3118                                                                                 iptr->sx.s23.s3.c.ref, 0);
3119
3120                                         M_MOV_IMM(0, REG_ITMP2);                  /* super->flags */
3121                                         M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3122                                         emit_label_beq(cd, BRANCH_LABEL_2);
3123                                 }
3124
3125                                 /* interface checkcast code */
3126
3127                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3128                                         if (super != NULL) {
3129                                                 M_TEST(s1);
3130                                                 emit_label_beq(cd, BRANCH_LABEL_3);
3131                                         }
3132
3133                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3134
3135                                         if (super == NULL) {
3136                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3137                                                                                         iptr->sx.s23.s3.c.ref,
3138                                                                                         0);
3139                                         }
3140
3141                                         M_ILD32(REG_ITMP3,
3142                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3143                                         M_ISUB_IMM32(superindex, REG_ITMP3);
3144                                         /* XXX do we need this one? */
3145                                         M_TEST(REG_ITMP3);
3146                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
3147
3148                                         M_ALD32(REG_ITMP3, REG_ITMP2,
3149                                                         OFFSET(vftbl_t, interfacetable[0]) -
3150                                                         superindex * sizeof(methodptr*));
3151                                         M_TEST(REG_ITMP3);
3152                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
3153
3154                                         if (super == NULL)
3155                                                 emit_label_br(cd, BRANCH_LABEL_4);
3156                                         else
3157                                                 emit_label(cd, BRANCH_LABEL_3);
3158                                 }
3159
3160                                 /* class checkcast code */
3161
3162                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3163                                         if (super == NULL) {
3164                                                 emit_label(cd, BRANCH_LABEL_2);
3165                                         }
3166                                         else {
3167                                                 M_TEST(s1);
3168                                                 emit_label_beq(cd, BRANCH_LABEL_5);
3169                                         }
3170
3171                                         M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3172
3173                                         if (super == NULL) {
3174                                                 patcher_add_patch_ref(jd, PATCHER_checkcast_class,
3175                                                                                         iptr->sx.s23.s3.c.ref,
3176                                                                                         0);
3177                                         }
3178
3179                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3180
3181                                         CODEGEN_CRITICAL_SECTION_START;
3182
3183                                         M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3184
3185                                         /*                              if (s1 != REG_ITMP1) { */
3186                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3187                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3188                                         /* #if defined(ENABLE_THREADS) */
3189                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3190                                         /* #endif */
3191                                         /*                                      emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3192
3193                                         /*                              } else { */
3194                                         M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3195                                         M_ISUB(REG_ITMP3, REG_ITMP2);
3196                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3197                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3198
3199                                         CODEGEN_CRITICAL_SECTION_END;
3200
3201                                         /*                              } */
3202
3203                                         M_CMP(REG_ITMP3, REG_ITMP2);
3204                                         emit_classcast_check(cd, iptr, BRANCH_ULE, REG_ITMP3, s1);
3205
3206                                         if (super != NULL)
3207                                                 emit_label(cd, BRANCH_LABEL_5);
3208                                 }
3209
3210                                 if (super == NULL) {
3211                                         emit_label(cd, BRANCH_LABEL_1);
3212                                         emit_label(cd, BRANCH_LABEL_4);
3213                                 }
3214
3215                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3216                         }
3217                         else {
3218                                 /* array type cast-check */
3219
3220                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3221                                 M_AST(s1, REG_SP, 0 * 4);
3222
3223                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3224                                         patcher_add_patch_ref(jd, PATCHER_builtin_arraycheckcast,
3225                                                                                 iptr->sx.s23.s3.c.ref, 0);
3226                                 }
3227
3228                                 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
3229                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3230                                 M_CALL(REG_ITMP3);
3231
3232                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3233                                 M_TEST(REG_RESULT);
3234                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
3235
3236                                 d = codegen_reg_of_dst(jd, iptr, s1);
3237                         }
3238
3239                         M_INTMOVE(s1, d);
3240                         emit_store_dst(jd, iptr, d);
3241                         break;
3242
3243                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3244
3245                         {
3246                         classinfo *super;
3247                         vftbl_t   *supervftbl;
3248                         s4         superindex;
3249
3250                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3251                                 super = NULL;
3252                                 superindex = 0;
3253                                 supervftbl = NULL;
3254
3255                         } else {
3256                                 super = iptr->sx.s23.s3.c.cls;
3257                                 superindex = super->index;
3258                                 supervftbl = super->vftbl;
3259                         }
3260                         
3261                         if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3262                                 CODEGEN_CRITICAL_SECTION_NEW;
3263
3264                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3265                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3266
3267                         if (s1 == d) {
3268                                 M_INTMOVE(s1, REG_ITMP1);
3269                                 s1 = REG_ITMP1;
3270                         }
3271
3272                         M_CLR(d);
3273
3274                         /* if class is not resolved, check which code to call */
3275
3276                         if (super == NULL) {
3277                                 M_TEST(s1);
3278                                 emit_label_beq(cd, BRANCH_LABEL_1);
3279
3280                                 patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
3281                                                                         iptr->sx.s23.s3.c.ref, 0);
3282
3283                                 M_MOV_IMM(0, REG_ITMP3);                      /* super->flags */
3284                                 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3285                                 emit_label_beq(cd, BRANCH_LABEL_2);
3286                         }
3287
3288                         /* interface instanceof code */
3289
3290                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3291                                 if (super != NULL) {
3292                                         M_TEST(s1);
3293                                         emit_label_beq(cd, BRANCH_LABEL_3);
3294                                 }
3295
3296                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3297
3298                                 if (super == NULL) {
3299                                         patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3300                                                                                 iptr->sx.s23.s3.c.ref, 0);
3301                                 }
3302
3303                                 M_ILD32(REG_ITMP3,
3304                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3305                                 M_ISUB_IMM32(superindex, REG_ITMP3);
3306                                 M_TEST(REG_ITMP3);
3307
3308                                 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3309                                                 6 /* jcc */ + 5 /* mov_imm_reg */);
3310
3311                                 M_BLE(disp);
3312                                 M_ALD32(REG_ITMP1, REG_ITMP1,
3313                                                 OFFSET(vftbl_t, interfacetable[0]) -
3314                                                 superindex * sizeof(methodptr*));
3315                                 M_TEST(REG_ITMP1);
3316 /*                                      emit_setcc_reg(cd, CC_A, d); */
3317 /*                                      emit_jcc(cd, CC_BE, 5); */
3318                                 M_BEQ(5);
3319                                 M_MOV_IMM(1, d);
3320
3321                                 if (super == NULL)
3322                                         emit_label_br(cd, BRANCH_LABEL_4);
3323                                 else
3324                                         emit_label(cd, BRANCH_LABEL_3);
3325                         }
3326
3327                         /* class instanceof code */
3328
3329                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3330                                 if (super == NULL) {
3331                                         emit_label(cd, BRANCH_LABEL_2);
3332                                 }
3333                                 else {
3334                                         M_TEST(s1);
3335                                         emit_label_beq(cd, BRANCH_LABEL_5);
3336                                 }
3337
3338                                 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3339
3340                                 if (super == NULL) {
3341                                         patcher_add_patch_ref(jd, PATCHER_instanceof_class,
3342                                                                                 iptr->sx.s23.s3.c.ref, 0);
3343                                 }
3344
3345                                 M_MOV_IMM(supervftbl, REG_ITMP2);
3346
3347                                 CODEGEN_CRITICAL_SECTION_START;
3348
3349                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3350                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3351                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3352
3353                                 CODEGEN_CRITICAL_SECTION_END;
3354
3355                                 M_ISUB(REG_ITMP2, REG_ITMP1);
3356                                 M_CLR(d);                                 /* may be REG_ITMP2 */
3357                                 M_CMP(REG_ITMP3, REG_ITMP1);
3358                                 M_BA(5);
3359                                 M_MOV_IMM(1, d);
3360
3361                                 if (super != NULL)
3362                                         emit_label(cd, BRANCH_LABEL_5);
3363                         }
3364
3365                         if (super == NULL) {
3366                                 emit_label(cd, BRANCH_LABEL_1);
3367                                 emit_label(cd, BRANCH_LABEL_4);
3368                         }
3369
3370                         emit_store_dst(jd, iptr, d);
3371                         }
3372                         break;
3373
3374                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3375
3376                         /* check for negative sizes and copy sizes to stack if necessary  */
3377
3378                         MCODECHECK((iptr->s1.argcount << 1) + 64);
3379
3380                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3381                                 /* copy SAVEDVAR sizes to stack */
3382                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3383
3384                                 /* Already Preallocated? */
3385                                 if (!(var->flags & PREALLOC)) {
3386                                         if (var->flags & INMEMORY) {
3387                                                 M_ILD(REG_ITMP1, REG_SP, var->vv.regoff);
3388                                                 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
3389                                         }
3390                                         else
3391                                                 M_IST(var->vv.regoff, REG_SP, (s1 + 3) * 4);
3392                                 }
3393                         }
3394
3395                         /* is a patcher function set? */
3396
3397                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3398                                 patcher_add_patch_ref(jd, PATCHER_builtin_multianewarray,
3399                                                                         iptr->sx.s23.s3.c.ref, 0);
3400
3401                                 disp = 0;
3402
3403                         }
3404                         else
3405                                 disp = (ptrint) iptr->sx.s23.s3.c.cls;
3406
3407                         /* a0 = dimension count */
3408
3409                         M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
3410
3411                         /* a1 = arraydescriptor */
3412
3413                         M_IST_IMM(disp, REG_SP, 1 * 4);
3414
3415                         /* a2 = pointer to dimensions = stack pointer */
3416
3417                         M_MOV(REG_SP, REG_ITMP1);
3418                         M_AADD_IMM(3 * 4, REG_ITMP1);
3419                         M_AST(REG_ITMP1, REG_SP, 2 * 4);
3420
3421                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3422                         M_CALL(REG_ITMP1);
3423
3424                         /* check for exception before result assignment */
3425
3426                         emit_exception_check(cd, iptr);
3427
3428                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3429                         M_INTMOVE(REG_RESULT, s1);
3430                         emit_store_dst(jd, iptr, s1);
3431                         break;
3432
3433 #if defined(ENABLE_SSA)
3434                 case ICMD_GETEXCEPTION:
3435                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
3436                         M_INTMOVE(REG_ITMP1, d);
3437                         emit_store_dst(jd, iptr, d);
3438                         break;
3439 #endif
3440                 default:
3441                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3442                                                                                    iptr->opc);
3443                         return false;
3444         } /* switch */
3445                 
3446         } /* for instruction */
3447                 
3448         MCODECHECK(64);
3449
3450 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
3451         if (!opt_lsra)
3452 #endif
3453 #if defined(ENABLE_SSA)
3454         if ( ls != NULL ) {
3455
3456                 /* by edge splitting, in Blocks with phi moves there can only */
3457                 /* be a goto as last command, no other Jump/Branch Command    */
3458
3459                 if (!last_cmd_was_goto)
3460                         codegen_emit_phi_moves(jd, bptr);
3461         }
3462
3463 #endif
3464
3465         /* At the end of a basic block we may have to append some nops,
3466            because the patcher stub calling code might be longer than the
3467            actual instruction. So codepatching does not change the
3468            following block unintentionally. */
3469
3470         if (cd->mcodeptr < cd->lastmcodeptr) {
3471                 while (cd->mcodeptr < cd->lastmcodeptr) {
3472                         M_NOP;
3473                 }
3474         }
3475
3476         } /* if (bptr -> flags >= BBREACHED) */
3477         } /* for basic block */
3478
3479         /* generate stubs */
3480
3481         emit_patcher_traps(jd);
3482
3483         /* everything's ok */
3484
3485         return true;
3486 }
3487
3488
3489 /* codegen_emit_stub_native ****************************************************
3490
3491    Emits a stub routine which calls a native method.
3492
3493 *******************************************************************************/
3494
3495 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3496 {
3497         methodinfo  *m;
3498         codeinfo    *code;
3499         codegendata *cd;
3500         methoddesc  *md;
3501         int          i, j;                 /* count variables                    */
3502         int          s1, s2;
3503         int          disp;
3504
3505         /* get required compiler data */
3506
3507         m    = jd->m;
3508         code = jd->code;
3509         cd   = jd->cd;
3510
3511         /* set some variables */
3512
3513         md = m->parseddesc;
3514
3515         /* calculate stackframe size */
3516
3517         cd->stackframesize =
3518                 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3519                 sizeof(localref_table) / SIZEOF_VOID_P +
3520                 4 +                             /* 4 arguments (start_native_call)    */
3521                 nmd->memuse;
3522
3523     /* keep stack 16-byte aligned */
3524
3525         ALIGN_ODD(cd->stackframesize);
3526
3527         /* create method header */
3528
3529         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3530         (void) dseg_add_unique_s4(cd, cd->stackframesize * 8 + 4); /* FrameSize       */
3531         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3532         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3533         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3534
3535 #if defined(ENABLE_PROFILING)
3536         /* generate native method profiling code */
3537
3538         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3539                 /* count frequency */
3540
3541                 M_MOV_IMM(code, REG_ITMP1);
3542                 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
3543         }
3544 #endif
3545
3546         /* calculate stackframe size for native function */
3547
3548         M_ASUB_IMM(cd->stackframesize * 8 + 4, REG_SP);
3549
3550         /* Mark the whole fpu stack as free for native functions (only for saved  */
3551         /* register count == 0).                                                  */
3552
3553         emit_ffree_reg(cd, 0);
3554         emit_ffree_reg(cd, 1);
3555         emit_ffree_reg(cd, 2);
3556         emit_ffree_reg(cd, 3);
3557         emit_ffree_reg(cd, 4);
3558         emit_ffree_reg(cd, 5);
3559         emit_ffree_reg(cd, 6);
3560         emit_ffree_reg(cd, 7);
3561
3562 #if defined(ENABLE_GC_CACAO)
3563         /* remember callee saved int registers in stackframeinfo (GC may need to  */
3564         /* recover them during a collection).                                     */
3565
3566         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3567                 OFFSET(stackframeinfo_t, intregs);
3568
3569         for (i = 0; i < INT_SAV_CNT; i++)
3570                 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3571 #endif
3572
3573         /* prepare data structures for native function call */
3574
3575         M_MOV(REG_SP, REG_ITMP1);
3576         M_AST(REG_ITMP1, REG_SP, 0 * 4);
3577         M_IST_IMM(0, REG_SP, 1 * 4);
3578         dseg_adddata(cd);
3579
3580         M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3581         M_CALL(REG_ITMP1);
3582
3583         /* remember class argument */
3584
3585         if (m->flags & ACC_STATIC)
3586                 M_MOV(REG_RESULT, REG_ITMP3);
3587
3588         /* Copy or spill arguments to new locations. */
3589
3590         for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3591                 if (!md->params[i].inmemory)
3592                         assert(0);
3593
3594                 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;
3595                 s2 = nmd->params[j].regoff;
3596
3597                 /* float/double in memory can be copied like int/longs */
3598
3599                 switch (md->paramtypes[i].type) {
3600                 case TYPE_INT:
3601                 case TYPE_FLT:
3602                 case TYPE_ADR:
3603                         M_ILD(REG_ITMP1, REG_SP, s1);
3604                         M_IST(REG_ITMP1, REG_SP, s2);
3605                         break;
3606                 case TYPE_LNG:
3607                 case TYPE_DBL:
3608                         M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3609                         M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3610                         break;
3611                 }
3612         }
3613
3614         /* Handle native Java methods. */
3615
3616         if (m->flags & ACC_NATIVE) {
3617                 /* if function is static, put class into second argument */
3618
3619                 if (m->flags & ACC_STATIC)
3620                         M_AST(REG_ITMP3, REG_SP, 1 * 4);
3621
3622                 /* put env into first argument */
3623
3624                 M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
3625         }
3626
3627         /* Call the native function. */
3628
3629         disp = dseg_add_functionptr(cd, f);
3630         emit_mov_imm_reg(cd, 0, REG_ITMP3);
3631         dseg_adddata(cd);
3632         M_ALD(REG_ITMP1, REG_ITMP3, disp);
3633         M_CALL(REG_ITMP1);
3634
3635         /* save return value */
3636
3637         switch (md->returntype.type) {
3638         case TYPE_INT:
3639         case TYPE_ADR:
3640                 M_IST(REG_RESULT, REG_SP, 1 * 8);
3641                 break;
3642         case TYPE_LNG:
3643                 M_LST(REG_RESULT_PACKED, REG_SP, 1 * 8);
3644                 break;
3645         case TYPE_FLT:
3646                 emit_fsts_membase(cd, REG_SP, 1 * 8);
3647                 break;
3648         case TYPE_DBL:
3649                 emit_fstl_membase(cd, REG_SP, 1 * 8);
3650                 break;
3651         case TYPE_VOID:
3652                 break;
3653         }
3654
3655         /* remove native stackframe info */
3656
3657         M_MOV(REG_SP, REG_ITMP1);
3658         M_AST(REG_ITMP1, REG_SP, 0 * 4);
3659         M_IST_IMM(0, REG_SP, 1 * 4);
3660         dseg_adddata(cd);
3661
3662         M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3663         M_CALL(REG_ITMP1);
3664         M_MOV(REG_RESULT, REG_ITMP2);                 /* REG_ITMP3 == REG_RESULT2 */
3665
3666         /* restore return value */
3667
3668         switch (md->returntype.type) {
3669         case TYPE_INT:
3670         case TYPE_ADR:
3671                 M_ILD(REG_RESULT, REG_SP, 1 * 8);
3672                 break;
3673         case TYPE_LNG:
3674                 M_LLD(REG_RESULT_PACKED, REG_SP, 1 * 8);
3675                 break;
3676         case TYPE_FLT:
3677                 emit_flds_membase(cd, REG_SP, 1 * 8);
3678                 break;
3679         case TYPE_DBL:
3680                 emit_fldl_membase(cd, REG_SP, 1 * 8);
3681                 break;
3682         case TYPE_VOID:
3683                 break;
3684         }
3685
3686 #if defined(ENABLE_GC_CACAO)
3687         /* restore callee saved int registers from stackframeinfo (GC might have  */
3688         /* modified them during a collection).                                    */
3689
3690         disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3691                 OFFSET(stackframeinfo_t, intregs);
3692
3693         for (i = 0; i < INT_SAV_CNT; i++)
3694                 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3695 #endif
3696
3697         M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP);
3698
3699         /* check for exception */
3700
3701         M_TEST(REG_ITMP2);
3702         M_BNE(1);
3703
3704         M_RET;
3705
3706         /* handle exception */
3707
3708         M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
3709         M_ALD(REG_ITMP2_XPC, REG_SP, 0);
3710         M_ASUB_IMM(2, REG_ITMP2_XPC);
3711
3712         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3713         M_JMP(REG_ITMP3);
3714 }
3715
3716
3717 /*
3718  * These are local overrides for various environment variables in Emacs.
3719  * Please do not remove this and leave it at the end of the file, where
3720  * Emacs will automagically detect them.
3721  * ---------------------------------------------------------------------
3722  * Local variables:
3723  * mode: c
3724  * indent-tabs-mode: t
3725  * c-basic-offset: 4
3726  * tab-width: 4
3727  * End:
3728  * vim:noexpandtab:sw=4:ts=4:
3729  */