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