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