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