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