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