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