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