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