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