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