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