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