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