a15b6d9575918dc8717b6ce18629546b80c9252c
[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 7601 2007-03-28 23:02:50Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <stdio.h>
34
35 #include "vm/types.h"
36
37 #include "vm/jit/i386/md-abi.h"
38
39 #include "vm/jit/i386/codegen.h"
40 #include "vm/jit/i386/emit.h"
41
42 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/native.h"
45
46 #if defined(ENABLE_THREADS)
47 # include "threads/native/lock.h"
48 #endif
49
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/global.h"
53 #include "vm/stringlocal.h"
54 #include "vm/vm.h"
55
56 #include "vm/jit/abi.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/parse.h"
63 #include "vm/jit/patcher.h"
64 #include "vm/jit/reg.h"
65 #include "vm/jit/replace.h"
66 #include "vm/jit/stacktrace.h"
67
68 #if defined(ENABLE_SSA)
69 # include "vm/jit/optimizing/lsra.h"
70 # include "vm/jit/optimizing/ssa.h"
71 #elif defined(ENABLE_LSRA)
72 # include "vm/jit/allocator/lsra.h"
73 #endif
74
75 #include "vmcore/loader.h"
76 #include "vmcore/options.h"
77 #include "vmcore/utf8.h"
78
79
80 /* codegen_emit ****************************************************************
81
82    Generates machine code.
83
84 *******************************************************************************/
85
86 #if defined(ENABLE_SSA)
87 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
88                          s4 dst_regoff, s4 dst_flags);
89 void codegen_insert_phi_moves(jitdata *jd, basicblock *bptr);
90 #endif
91
92 bool codegen_emit(jitdata *jd)
93 {
94         methodinfo         *m;
95         codeinfo           *code;
96         codegendata        *cd;
97         registerdata       *rd;
98         s4                  len, s1, s2, s3, d, disp;
99         varinfo            *var, *var1;
100         basicblock         *bptr;
101         instruction        *iptr;
102         exception_entry    *ex;
103         u2                  currentline;
104         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
105         builtintable_entry *bte;
106         methoddesc         *md;
107         fieldinfo          *fi;
108         unresolved_field   *uf;
109         s4                  fieldtype;
110         s4                  varindex;
111 #if defined(ENABLE_SSA)
112         lsradata *ls;
113         bool last_cmd_was_goto;
114
115         last_cmd_was_goto = false;
116         ls = jd->ls;
117 #endif
118
119         /* get required compiler data */
120
121         m    = jd->m;
122         code = jd->code;
123         cd   = jd->cd;
124         rd   = jd->rd;
125
126         /* prevent compiler warnings */
127
128         s1          = 0;
129         s2          = 0;
130         d           = 0;
131         currentline = 0;
132         lm          = NULL;
133         bte         = NULL;
134
135         {
136         s4 i, p, t, l;
137         s4 savedregs_num = 0;
138         s4 stack_off = 0;
139
140         /* space to save used callee saved registers */
141
142         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
143
144         /* float register are saved on 2 4-byte stackslots */
145         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
146
147         cd->stackframesize = rd->memuse + savedregs_num;
148
149            
150 #if defined(ENABLE_THREADS)
151         /* space to save argument of monitor_enter */
152
153         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
154                 /* reserve 2 slots for long/double return values for monitorexit */
155
156                 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
157                         cd->stackframesize += 2;
158                 else
159                         cd->stackframesize++;
160         }
161 #endif
162
163         /* create method header */
164
165     /* Keep stack of non-leaf functions 16-byte aligned. */
166
167         if (!jd->isleafmethod)
168                 cd->stackframesize |= 0x3;
169
170         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
171         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
172
173 #if defined(ENABLE_THREADS)
174         /* IsSync contains the offset relative to the stack pointer for the
175            argument of monitor_exit used in the exception handler. Since the
176            offset could be zero and give a wrong meaning of the flag it is
177            offset by one.
178         */
179
180         if (checksync && (m->flags & ACC_SYNCHRONIZED))
181                 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4); /* IsSync        */
182         else
183 #endif
184                 (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
185                                                
186         (void) dseg_add_unique_s4(cd, jd->isleafmethod);       /* IsLeaf          */
187         (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
188         (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
189
190         /* adds a reference for the length of the line number counter. We don't
191            know the size yet, since we evaluate the information during code
192            generation, to save one additional iteration over the whole
193            instructions. During code optimization the position could have changed
194            to the information gotten from the class file */
195         (void) dseg_addlinenumbertablesize(cd);
196
197         (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
198         
199         /* create exception table */
200
201         for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
202                 dseg_add_target(cd, ex->start);
203                 dseg_add_target(cd, ex->end);
204                 dseg_add_target(cd, ex->handler);
205                 (void) dseg_add_unique_address(cd, ex->catchtype.any);
206         }
207
208 #if defined(ENABLE_PROFILING)
209         /* generate method profiling code */
210
211         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
212                 /* count frequency */
213
214                 M_MOV_IMM(code, REG_ITMP3);
215                 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
216         }
217 #endif
218
219         /* create stack frame (if necessary) */
220
221         if (cd->stackframesize)
222                 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
223
224         /* save return address and used callee saved registers */
225
226         p = cd->stackframesize;
227         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
228                 p--; M_AST(rd->savintregs[i], REG_SP, p * 4);
229         }
230         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
231                 p-=2; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 4);
232         }
233
234         /* take arguments out of register or stack frame */
235
236         md = m->parseddesc;
237
238         stack_off = 0;
239         for (p = 0, l = 0; p < md->paramcount; p++) {
240                 t = md->paramtypes[p].type;
241
242 #if defined(ENABLE_SSA)
243                 if ( ls != NULL ) {
244                         l = ls->local_0[p];
245                 }
246 #endif
247                 varindex = jd->local_map[l * 5 + t];
248                 l++;
249                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
250                         l++;
251
252                 if (varindex == UNUSED)
253                         continue;
254
255                 var = VAR(varindex);
256                 
257                 s1 = md->params[p].regoff;
258
259                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
260                         if (!md->params[p].inmemory) {           /* register arguments    */
261                                 log_text("integer register argument");
262                                 assert(0);
263                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
264                                         /* rd->argintregs[md->params[p].regoff -> var->vv.regoff     */
265                                 } 
266                                 else {                               /* reg arg -> spilled    */
267                                         /* rd->argintregs[md->params[p].regoff -> var->vv.regoff * 4 */
268                                 }
269                         } 
270                         else {                                   /* stack arguments       */
271                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
272                                         emit_mov_membase_reg(           /* + 4 for return address */
273                                            cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, var->vv.regoff);
274                                                                         /* + 4 for return address */
275                                 } 
276                                 else {                               /* stack arg -> spilled  */
277                                         if (!IS_2_WORD_TYPE(t)) {
278 #if defined(ENABLE_SSA)
279                                                 /* no copy avoiding by now possible with SSA */
280                                                 if (ls != NULL) {
281                                                         emit_mov_membase_reg(   /* + 4 for return address */
282                                                                  cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
283                                                                  REG_ITMP1);    
284                                                         emit_mov_reg_membase(
285                                                                  cd, REG_ITMP1, REG_SP, var->vv.regoff * 4);
286                                                 }
287                                                 else 
288 #endif /*defined(ENABLE_SSA)*/
289                                                                   /* reuse Stackslotand avoid copying */
290                                                         var->vv.regoff = cd->stackframesize + s1 + 1;
291
292                                         } 
293                                         else {
294 #if defined(ENABLE_SSA)
295                                                 /* no copy avoiding by now possible with SSA */
296                                                 if (ls != NULL) {
297                                                         emit_mov_membase_reg(  /* + 4 for return address */
298                                                                  cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
299                                                                  REG_ITMP1);
300                                                         emit_mov_reg_membase(
301                                                                  cd, REG_ITMP1, REG_SP, var->vv.regoff * 4);
302                                                         emit_mov_membase_reg(   /* + 4 for return address */
303                                                                   cd, REG_SP, (cd->stackframesize + s1) * 4 + 4 + 4,
304                                                                   REG_ITMP1);             
305                                                         emit_mov_reg_membase(
306                                                                  cd, REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
307                                                 }
308                                                 else
309 #endif /*defined(ENABLE_SSA)*/
310                                                                   /* reuse Stackslotand avoid copying */
311                                                         var->vv.regoff = cd->stackframesize + s1 + 1;
312                                         }
313                                 }
314                         }
315                 }
316                 else {                                       /* floating args         */
317                         if (!md->params[p].inmemory) {           /* register arguments    */
318                                 log_text("There are no float argument registers!");
319                                 assert(0);
320                                 if (!(var->flags & INMEMORY)) {  /* reg arg -> register   */
321                                         /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff     */
322                                 } else {                                     /* reg arg -> spilled    */
323                                         /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff * 4 */
324                                 }
325
326                         } 
327                         else {                                   /* stack arguments       */
328                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
329                                         if (t == TYPE_FLT) {
330                                                 emit_flds_membase(
331                             cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
332                                                 assert(0);
333 /*                                              emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
334
335                                         } 
336                                         else {
337                                                 emit_fldl_membase(
338                             cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
339                                                 assert(0);
340 /*                                              emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
341                                         }
342
343                                 } else {                             /* stack-arg -> spilled  */
344 #if defined(ENABLE_SSA)
345                                         /* no copy avoiding by now possible with SSA */
346                                         if (ls != NULL) {
347                                                 emit_mov_membase_reg(
348                                                  cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, REG_ITMP1);
349                                                 emit_mov_reg_membase(
350                                                                          cd, REG_ITMP1, REG_SP, var->vv.regoff * 4);
351                                                 if (t == TYPE_FLT) {
352                                                         emit_flds_membase(
353                                                                   cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
354                                                         emit_fstps_membase(cd, REG_SP, var->vv.regoff * 4);
355                                                 } 
356                                                 else {
357                                                         emit_fldl_membase(
358                                                                   cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
359                                                         emit_fstpl_membase(cd, REG_SP, var->vv.regoff * 4);
360                                                 }
361                                         }
362                                         else
363 #endif /*defined(ENABLE_SSA)*/
364                                                                   /* reuse Stackslotand avoid copying */
365                                                 var->vv.regoff = cd->stackframesize + s1 + 1;
366                                 }
367                         }
368                 }
369         }  /* end for */
370
371         /* call monitorenter function */
372
373 #if defined(ENABLE_THREADS)
374         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
375                 s1 = rd->memuse;
376
377                 if (m->flags & ACC_STATIC) {
378                         M_MOV_IMM(&m->class->object.header, REG_ITMP1);
379                 }
380                 else {
381                         M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 4 + 4);
382                         M_TEST(REG_ITMP1);
383                         M_BNE(6);
384                         M_ALD_MEM(REG_ITMP1, EXCEPTION_HARDWARE_NULLPOINTER);
385                 }
386
387                 M_AST(REG_ITMP1, REG_SP, s1 * 4);
388                 M_AST(REG_ITMP1, REG_SP, 0 * 4);
389                 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
390                 M_CALL(REG_ITMP3);
391         }                       
392 #endif
393
394 #if !defined(NDEBUG)
395         emit_verbosecall_enter(jd);
396 #endif
397
398         } 
399
400 #if defined(ENABLE_SSA)
401         /* with SSA Header is Basic Block 0 - insert phi Moves if necessary */
402         if ( ls != NULL)
403                 codegen_insert_phi_moves(jd, ls->basicblocks[0]);
404 #endif
405
406         /* end of header generation */
407
408         /* create replacement points */
409
410         REPLACEMENT_POINTS_INIT(cd, jd);
411
412         /* walk through all basic blocks */
413
414         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
415
416                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
417
418                 if (bptr->flags >= BBREACHED) {
419                 /* branch resolving */
420
421                 codegen_resolve_branchrefs(cd, bptr);
422
423                 /* handle replacement points */
424
425                 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
426
427 #if defined(ENABLE_REPLACEMENT)
428                 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
429                         if (cd->replacementpoint[-1].flags & RPLPOINT_FLAG_COUNTDOWN) {
430                                 MCODECHECK(32);
431                                 disp = (s4) &(m->hitcountdown);
432                                 M_ISUB_IMM_MEMABS(1, disp);
433                                 M_BS(0);
434                         }
435                 }
436 #endif
437
438                 /* copy interface registers to their destination */
439
440                 len = bptr->indepth;
441                 MCODECHECK(512);
442
443 #if defined(ENABLE_PROFILING)
444                 /* generate basic block profiling code */
445
446                 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
447                         /* count frequency */
448
449                         M_MOV_IMM(code->bbfrequency, REG_ITMP3);
450                         M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
451                 }
452 #endif
453
454 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
455 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
456                 if (opt_lsra) {
457 # endif
458 # if defined(ENABLE_SSA)
459                 if (ls != NULL) {
460                         last_cmd_was_goto = false;
461 # endif
462                         if (len > 0) {
463                                 len--;
464                                 var = VAR(bptr->invars[len]);
465                                 if (bptr->type != BBTYPE_STD) {
466                                         if (!IS_2_WORD_TYPE(var->type)) {
467                                                 if (bptr->type == BBTYPE_EXH) {
468                                                         d = codegen_reg_of_var(0, var, REG_ITMP1);
469                                                         M_INTMOVE(REG_ITMP1, d);
470                                                         emit_store(jd, NULL, var, d);
471                                                 }
472                                         } 
473                                         else {
474                                                 log_text("copy interface registers(EXH, SBR): longs \
475                                   have to be in memory (begin 1)");
476                                                 assert(0);
477                                         }
478                                 }
479                         }
480
481                 } 
482                 else
483 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
484                 {
485                 while (len) {
486                         len--;
487                         var = VAR(bptr->invars[len]);
488                         if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
489                                 if (!IS_2_WORD_TYPE(var->type)) {
490                                         if (bptr->type == BBTYPE_EXH) {
491                                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
492                                                 M_INTMOVE(REG_ITMP1, d);
493                                                 emit_store(jd, NULL, var, d);
494                                         }
495                                 } 
496                                 else {
497                                         log_text("copy interface registers: longs have to be in \
498                                memory (begin 1)");
499                                         assert(0);
500                                 }
501
502                         } 
503                         else {
504                                 assert((var->flags & INOUT));
505                         }
506                 } /* while (len) */
507                 } /* */
508
509                 /* walk through all instructions */
510                 
511                 len = bptr->icount;
512                 currentline = 0;
513
514                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
515                         if (iptr->line != currentline) {
516                                 dseg_addlinenumber(cd, iptr->line);
517                                 currentline = iptr->line;
518                         }
519
520                         MCODECHECK(1024);                         /* 1kB should be enough */
521
522                 switch (iptr->opc) {
523                 case ICMD_NOP:        /* ...  ==> ...                                 */
524                 case ICMD_POP:        /* ..., value  ==> ...                          */
525                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
526                         break;
527
528                 case ICMD_INLINE_START:
529
530                         REPLACEMENT_POINT_INLINE_START(cd, iptr);
531                         break;
532
533                 case ICMD_INLINE_BODY:
534
535                         REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
536                         dseg_addlinenumber_inline_start(cd, iptr);
537                         dseg_addlinenumber(cd, iptr->line);
538                         break;
539
540                 case ICMD_INLINE_END:
541
542                         dseg_addlinenumber_inline_end(cd, iptr);
543                         dseg_addlinenumber(cd, iptr->line);
544                         break;
545
546                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
547
548                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
549                         emit_nullpointer_check(cd, iptr, s1);
550                         break;
551
552                 /* constant operations ************************************************/
553
554                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
555
556                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
557                         ICONST(d, iptr->sx.val.i);
558                         emit_store_dst(jd, iptr, d);
559                         break;
560
561                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
562
563                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
564                         LCONST(d, iptr->sx.val.l);
565                         emit_store_dst(jd, iptr, d);
566                         break;
567
568                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
569
570                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
571                         if (iptr->sx.val.f == 0.0) {
572                                 emit_fldz(cd);
573
574                                 /* -0.0 */
575                                 if (iptr->sx.val.i == 0x80000000) {
576                                         emit_fchs(cd);
577                                 }
578
579                         } else if (iptr->sx.val.f == 1.0) {
580                                 emit_fld1(cd);
581
582                         } else if (iptr->sx.val.f == 2.0) {
583                                 emit_fld1(cd);
584                                 emit_fld1(cd);
585                                 emit_faddp(cd);
586
587                         } else {
588                                 disp = dseg_add_float(cd, iptr->sx.val.f);
589                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
590                                 dseg_adddata(cd);
591                                 emit_flds_membase(cd, REG_ITMP1, disp);
592                         }
593                         emit_store_dst(jd, iptr, d);
594                         break;
595                 
596                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
597
598                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
599                         if (iptr->sx.val.d == 0.0) {
600                                 emit_fldz(cd);
601
602                                 /* -0.0 */
603                                 if (iptr->sx.val.l == 0x8000000000000000LL) {
604                                         emit_fchs(cd);
605                                 }
606
607                         } else if (iptr->sx.val.d == 1.0) {
608                                 emit_fld1(cd);
609
610                         } else if (iptr->sx.val.d == 2.0) {
611                                 emit_fld1(cd);
612                                 emit_fld1(cd);
613                                 emit_faddp(cd);
614
615                         } else {
616                                 disp = dseg_add_double(cd, iptr->sx.val.d);
617                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
618                                 dseg_adddata(cd);
619                                 emit_fldl_membase(cd, REG_ITMP1, disp);
620                         }
621                         emit_store_dst(jd, iptr, d);
622                         break;
623
624                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
625
626                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
627
628                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
629                                 codegen_addpatchref(cd, PATCHER_aconst,
630                                                                         iptr->sx.val.c.ref, 0);
631
632                                 M_MOV_IMM(NULL, d);
633
634                         } else {
635                                 if (iptr->sx.val.anyptr == NULL)
636                                         M_CLR(d);
637                                 else
638                                         M_MOV_IMM(iptr->sx.val.anyptr, d);
639                         }
640                         emit_store_dst(jd, iptr, d);
641                         break;
642
643
644                 /* load/store/copy/move operations ************************************/
645
646                 case ICMD_ILOAD:
647                 case ICMD_ALOAD:
648                 case ICMD_LLOAD:
649                 case ICMD_FLOAD:
650                 case ICMD_DLOAD:
651                 case ICMD_ISTORE:
652                 case ICMD_LSTORE:
653                 case ICMD_FSTORE:
654                 case ICMD_DSTORE:
655                 case ICMD_COPY:
656                 case ICMD_MOVE:
657
658                         emit_copy(jd, iptr, 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                         /* implicit null-pointer check */
1923                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
1924                         emit_store_dst(jd, iptr, d);
1925                         break;
1926
1927                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
1928
1929                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1930                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1931                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1932                         /* implicit null-pointer check */
1933                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1934                         emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), 
1935                                                                          s1, s2, 0, d);
1936                         emit_store_dst(jd, iptr, d);
1937                         break;
1938
1939                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
1940
1941                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1942                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1943                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1944                         /* implicit null-pointer check */
1945                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1946                         emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), 
1947                                                                          s1, s2, 1, d);
1948                         emit_store_dst(jd, iptr, d);
1949                         break;                  
1950
1951                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
1952
1953                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1954                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1955                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1956                         /* implicit null-pointer check */
1957                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1958                         emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), 
1959                                                                          s1, s2, 1, d);
1960                         emit_store_dst(jd, iptr, d);
1961                         break;
1962
1963                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
1964
1965                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1966                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1967                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1968                         /* implicit null-pointer check */
1969                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1970                         emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), 
1971                                                                   s1, s2, 2, d);
1972                         emit_store_dst(jd, iptr, d);
1973                         break;
1974
1975                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
1976
1977                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1978                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1979                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1980                         /* implicit null-pointer check */
1981                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1982
1983                         var = VAROP(iptr->dst);
1984
1985                         assert(var->flags & INMEMORY);
1986                         emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), 
1987                                                                   s1, s2, 3, REG_ITMP3);
1988                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff * 4);
1989                         emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, 
1990                                                                   s1, s2, 3, REG_ITMP3);
1991                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff * 4 + 4);
1992                         break;
1993
1994                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
1995
1996                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1997                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1998                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1999                         /* implicit null-pointer check */
2000                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2001                         emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2002                         emit_store_dst(jd, iptr, d);
2003                         break;
2004
2005                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
2006
2007                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2008                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2009                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2010                         /* implicit null-pointer check */
2011                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2012                         emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2,3);
2013                         emit_store_dst(jd, iptr, d);
2014                         break;
2015
2016                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
2017
2018                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2019                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2020                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2021                         /* implicit null-pointer check */
2022                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2023                         emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]),
2024                                                                   s1, s2, 2, d);
2025                         emit_store_dst(jd, iptr, d);
2026                         break;
2027
2028
2029                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
2030
2031                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2032                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2033                         /* implicit null-pointer check */
2034                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2035                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2036                         if (s3 >= EBP) { 
2037                                 /* because EBP, ESI, EDI have no xH and xL nibbles */
2038                                 M_INTMOVE(s3, REG_ITMP3);
2039                                 s3 = REG_ITMP3;
2040                         }
2041                         emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]),
2042                                                                    s1, s2, 0);
2043                         break;
2044
2045                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
2046
2047                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2048                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2049                         /* implicit null-pointer check */
2050                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2051                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2052                         emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]),
2053                                                                    s1, s2, 1);
2054                         break;
2055
2056                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
2057
2058                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2059                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2060                         /* implicit null-pointer check */
2061                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2062                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2063                         emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]),
2064                                                                    s1, s2, 1);
2065                         break;
2066
2067                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
2068
2069                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2070                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2071                         /* implicit null-pointer check */
2072                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2073                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2074                         emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]),
2075                                                                   s1, s2, 2);
2076                         break;
2077
2078                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
2079
2080                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2081                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2082                         /* implicit null-pointer check */
2083                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2084
2085                         var = VAROP(iptr->sx.s23.s3);
2086
2087                         assert(var->flags & INMEMORY);
2088                         emit_mov_membase_reg(cd, REG_SP, var->vv.regoff * 4, REG_ITMP3);
2089                         emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0])
2090                                                                   , s1, s2, 3);
2091                         emit_mov_membase_reg(cd, REG_SP, var->vv.regoff * 4 + 4, REG_ITMP3);
2092                         emit_mov_reg_memindex(cd, REG_ITMP3,
2093                                                             OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2094                         break;
2095
2096                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
2097
2098                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2099                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2100                         /* implicit null-pointer check */
2101                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2102                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2103                         emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2,2);
2104                         break;
2105
2106                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
2107
2108                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2109                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2110                         /* implicit null-pointer check */
2111                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2112                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2113                         emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]),
2114                                                                 s1, s2, 3);
2115                         break;
2116
2117                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
2118
2119                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2120                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2121                         /* implicit null-pointer check */
2122                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2123                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2124
2125                         M_AST(s1, REG_SP, 0 * 4);
2126                         M_AST(s3, REG_SP, 1 * 4);
2127                         M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2128                         M_CALL(REG_ITMP1);
2129                         emit_exception_check(cd, iptr);
2130
2131                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2132                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2133                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2134                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]),
2135                                                                   s1, s2, 2);
2136                         break;
2137
2138                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
2139
2140                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2141                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2142                         /* implicit null-pointer check */
2143                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2144                         emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
2145                                                                    OFFSET(java_bytearray, data[0]), s1, s2, 0);
2146                         break;
2147
2148                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
2149
2150                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2151                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2152                         /* implicit null-pointer check */
2153                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2154                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2155                                                                    OFFSET(java_chararray, data[0]), s1, s2, 1);
2156                         break;
2157
2158                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
2159
2160                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2161                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2162                         /* implicit null-pointer check */
2163                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2164                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2165                                                                    OFFSET(java_shortarray, data[0]), s1, s2, 1);
2166                         break;
2167
2168                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
2169
2170                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2171                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2172                         /* implicit null-pointer check */
2173                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2174                         emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
2175                                                                   OFFSET(java_intarray, data[0]), s1, s2, 2);
2176                         break;
2177
2178                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
2179
2180                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2181                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2182                         /* implicit null-pointer check */
2183                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2184                         emit_mov_imm_memindex(cd, 
2185                                                    (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
2186                                                    OFFSET(java_longarray, data[0]), s1, s2, 3);
2187                         emit_mov_imm_memindex(cd, 
2188                                                         ((s4)iptr->sx.s23.s3.constval) >> 31, 
2189                                                         OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2190                         break;
2191
2192                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
2193
2194                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2195                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2196                         /* implicit null-pointer check */
2197                         emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2198                         emit_mov_imm_memindex(cd, 0, 
2199                                                                   OFFSET(java_objectarray, data[0]), s1, s2, 2);
2200                         break;
2201
2202
2203                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
2204
2205                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2206                                 uf        = iptr->sx.s23.s3.uf;
2207                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2208                                 disp      = 0;
2209
2210                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
2211
2212                         }
2213                         else {
2214                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2215                                 fieldtype = fi->type;
2216                                 disp      = (ptrint) &(fi->value);
2217
2218                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2219                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2220                         }
2221
2222                         M_MOV_IMM(disp, REG_ITMP1);
2223                         switch (fieldtype) {
2224                         case TYPE_INT:
2225                         case TYPE_ADR:
2226                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2227                                 M_ILD(d, REG_ITMP1, 0);
2228                                 break;
2229                         case TYPE_LNG:
2230                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2231                                 M_LLD(d, REG_ITMP1, 0);
2232                                 break;
2233                         case TYPE_FLT:
2234                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2235                                 M_FLD(d, REG_ITMP1, 0);
2236                                 break;
2237                         case TYPE_DBL:                          
2238                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2239                                 M_DLD(d, REG_ITMP1, 0);
2240                                 break;
2241                         }
2242                         emit_store_dst(jd, iptr, d);
2243                         break;
2244
2245                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2246
2247                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2248                                 uf        = iptr->sx.s23.s3.uf;
2249                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2250                                 disp      = 0;
2251
2252                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
2253                         }
2254                         else {
2255                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2256                                 fieldtype = fi->type;
2257                                 disp      = (ptrint) &(fi->value);
2258
2259                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2260                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2261                         }
2262
2263                         M_MOV_IMM(disp, REG_ITMP1);
2264                         switch (fieldtype) {
2265                         case TYPE_INT:
2266                         case TYPE_ADR:
2267                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2268                                 M_IST(s1, REG_ITMP1, 0);
2269                                 break;
2270                         case TYPE_LNG:
2271                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2272                                 M_LST(s1, REG_ITMP1, 0);
2273                                 break;
2274                         case TYPE_FLT:
2275                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2276                                 emit_fstps_membase(cd, REG_ITMP1, 0);
2277                                 break;
2278                         case TYPE_DBL:
2279                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2280                                 emit_fstpl_membase(cd, REG_ITMP1, 0);
2281                                 break;
2282                         }
2283                         break;
2284
2285                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2286                                           /* val = value (in current instruction)     */
2287                                           /* following NOP)                           */
2288
2289                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2290                                 uf        = iptr->sx.s23.s3.uf;
2291                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2292                                 disp      = 0;
2293
2294                                 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
2295                         }
2296                         else {
2297                                 fi        = iptr->sx.s23.s3.fmiref->p.field;
2298                                 fieldtype = fi->type;
2299                                 disp      = (ptrint) &(fi->value);
2300
2301                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2302                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2303                         }
2304
2305                         M_MOV_IMM(disp, REG_ITMP1);
2306                         switch (fieldtype) {
2307                         case TYPE_INT:
2308                         case TYPE_ADR:
2309                                 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2310                                 break;
2311                         case TYPE_LNG:
2312                                 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
2313                                 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
2314                                 break;
2315                         default:
2316                                 assert(0);
2317                         }
2318                         break;
2319
2320                 case ICMD_GETFIELD:   /* .., objectref.  ==> ..., value               */
2321
2322                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2323                         emit_nullpointer_check(cd, iptr, s1);
2324
2325                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2326                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2327
2328                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2329
2330                                 codegen_addpatchref(cd, PATCHER_getfield,
2331                                                                         iptr->sx.s23.s3.uf, 0);
2332
2333                                 disp = 0;
2334
2335                         }
2336                         else {
2337                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2338                                 
2339                                 fieldtype = fi->type;
2340                                 disp = fi->offset;
2341                         }
2342
2343                         switch (fieldtype) {
2344                         case TYPE_INT:
2345                         case TYPE_ADR:
2346                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2347                                 M_ILD32(d, s1, disp);
2348                                 break;
2349                         case TYPE_LNG:
2350                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2351                                 M_LLD32(d, s1, disp);
2352                                 break;
2353                         case TYPE_FLT:
2354                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2355                                 M_FLD32(d, s1, disp);
2356                                 break;
2357                         case TYPE_DBL:                          
2358                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2359                                 M_DLD32(d, s1, disp);
2360                                 break;
2361                         }
2362                         emit_store_dst(jd, iptr, d);
2363                         break;
2364
2365                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2366
2367                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2368                         emit_nullpointer_check(cd, iptr, s1);
2369
2370                         /* must be done here because of code patching */
2371
2372                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2373                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2374
2375                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2376                         }
2377                         else {
2378                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2379
2380                                 fieldtype = fi->type;
2381                         }
2382
2383                         if (!IS_FLT_DBL_TYPE(fieldtype)) {
2384                                 if (IS_2_WORD_TYPE(fieldtype))
2385                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2386                                 else
2387                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2388                         }
2389                         else
2390                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2391
2392                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2393                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2394
2395                                 codegen_addpatchref(cd, PATCHER_putfield, uf, 0);
2396
2397                                 disp = 0;
2398
2399                         }
2400                         else {
2401                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2402
2403                                 disp = fi->offset;
2404                         }
2405
2406                         switch (fieldtype) {
2407                         case TYPE_INT:
2408                         case TYPE_ADR:
2409                                 M_IST32(s2, s1, disp);
2410                                 break;
2411                         case TYPE_LNG:
2412                                 M_LST32(s2, s1, disp);
2413                                 break;
2414                         case TYPE_FLT:
2415                                 emit_fstps_membase32(cd, s1, disp);
2416                                 break;
2417                         case TYPE_DBL:
2418                                 emit_fstpl_membase32(cd, s1, disp);
2419                                 break;
2420                         }
2421                         break;
2422
2423                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2424                                           /* val = value (in current instruction)     */
2425                                           /* following NOP)                           */
2426
2427                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2428                         emit_nullpointer_check(cd, iptr, s1);
2429
2430                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2431                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2432
2433                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2434
2435                                 codegen_addpatchref(cd, PATCHER_putfieldconst,
2436                                                                         uf, 0);
2437
2438                                 disp = 0;
2439
2440                         }
2441                         else
2442                         {
2443                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2444
2445                                 fieldtype = fi->type;
2446                                 disp = fi->offset;
2447                         }
2448
2449
2450                         switch (fieldtype) {
2451                         case TYPE_INT:
2452                         case TYPE_ADR:
2453                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2454                                 break;
2455                         case TYPE_LNG:
2456                                 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2457                                 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2458                                 break;
2459                         default:
2460                                 assert(0);
2461                         }
2462                         break;
2463
2464
2465                 /* branch operations **************************************************/
2466
2467                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2468
2469                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2470                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2471
2472 #ifdef ENABLE_VERIFIER
2473                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2474                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2475                                                                         iptr->sx.s23.s2.uc, 0);
2476                         }
2477 #endif /* ENABLE_VERIFIER */
2478
2479                         M_CALL_IMM(0);                            /* passing exception pc */
2480                         M_POP(REG_ITMP2_XPC);
2481
2482                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2483                         M_JMP(REG_ITMP3);
2484                         break;
2485
2486                 case ICMD_GOTO:         /* ... ==> ...                                */
2487                 case ICMD_RET:          /* ... ==> ...                                */
2488
2489 #if defined(ENABLE_SSA)
2490                         if ( ls != NULL ) {
2491                                 last_cmd_was_goto = true;
2492                                 /* In case of a Goto phimoves have to be inserted before the */
2493                                 /* jump */
2494                                 codegen_insert_phi_moves(jd, bptr);
2495                         }
2496 #endif
2497                         emit_br(cd, iptr->dst.block);
2498                         ALIGNCODENOP;
2499                         break;
2500
2501                 case ICMD_JSR:          /* ... ==> ...                                */
2502
2503                         emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2504                         ALIGNCODENOP;
2505                         break;
2506                         
2507                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2508                 case ICMD_IFNONNULL:
2509
2510                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2511                         M_TEST(s1);
2512                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2513                         break;
2514
2515                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2516                 case ICMD_IFLT:
2517                 case ICMD_IFLE:
2518                 case ICMD_IFNE:
2519                 case ICMD_IFGT:
2520                 case ICMD_IFGE:
2521
2522                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2523                         M_CMP_IMM(iptr->sx.val.i, s1);
2524                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2525                         break;
2526
2527                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2528
2529                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2530                         if (iptr->sx.val.l == 0) {
2531                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2532                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2533                         }
2534                         else {
2535                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2536                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2537                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2538                                 M_OR(REG_ITMP2, REG_ITMP1);
2539                         }
2540                         emit_beq(cd, iptr->dst.block);
2541                         break;
2542
2543                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2544
2545                         if (iptr->sx.val.l == 0) {
2546                                 /* If high 32-bit are less than zero, then the 64-bits
2547                                    are too. */
2548                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2549                                 M_CMP_IMM(0, s1);
2550                                 emit_blt(cd, iptr->dst.block);
2551                         }
2552                         else {
2553                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2554                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2555                                 emit_blt(cd, iptr->dst.block);
2556                                 M_BGT(6 + 6);
2557                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2558                                 emit_bult(cd, iptr->dst.block);
2559                         }                       
2560                         break;
2561
2562                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2563
2564                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2565                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2566                         emit_blt(cd, iptr->dst.block);
2567                         M_BGT(6 + 6);
2568                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2569                         emit_bule(cd, iptr->dst.block);
2570                         break;
2571
2572                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2573
2574                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2575                         if (iptr->sx.val.l == 0) {
2576                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2577                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2578                         }
2579                         else {
2580                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2581                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2582                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2583                                 M_OR(REG_ITMP2, REG_ITMP1);
2584                         }
2585                         emit_bne(cd, iptr->dst.block);
2586                         break;
2587
2588                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2589
2590                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2591                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2592                         emit_bgt(cd, iptr->dst.block);
2593                         M_BLT(6 + 6);
2594                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2595                         emit_bugt(cd, iptr->dst.block);
2596                         break;
2597
2598                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2599
2600                         if (iptr->sx.val.l == 0) {
2601                                 /* If high 32-bit are greater equal zero, then the
2602                                    64-bits are too. */
2603                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2604                                 M_CMP_IMM(0, s1);
2605                                 emit_bge(cd, iptr->dst.block);
2606                         }
2607                         else {
2608                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2609                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2610                                 emit_bgt(cd, iptr->dst.block);
2611                                 M_BLT(6 + 6);
2612                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2613                                 emit_buge(cd, iptr->dst.block);
2614                         }
2615                         break;
2616
2617                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
2618                 case ICMD_IF_ICMPNE:
2619                 case ICMD_IF_ICMPLT:
2620                 case ICMD_IF_ICMPGT:
2621                 case ICMD_IF_ICMPGE:
2622                 case ICMD_IF_ICMPLE:
2623
2624                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2625                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2626                         M_CMP(s2, s1);
2627                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2628                         break;
2629
2630                 case ICMD_IF_ACMPEQ:    /* ..., value, value ==> ...                  */
2631                 case ICMD_IF_ACMPNE:
2632
2633                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2634                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2635                         M_CMP(s2, s1);
2636                         emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2637                         break;
2638
2639                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
2640
2641                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2642                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2643                         M_INTMOVE(s1, REG_ITMP1);
2644                         M_XOR(s2, REG_ITMP1);
2645                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2646                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2647                         M_INTMOVE(s1, REG_ITMP2);
2648                         M_XOR(s2, REG_ITMP2);
2649                         M_OR(REG_ITMP1, REG_ITMP2);
2650                         emit_beq(cd, iptr->dst.block);
2651                         break;
2652
2653                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
2654
2655                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2656                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2657                         M_INTMOVE(s1, REG_ITMP1);
2658                         M_XOR(s2, REG_ITMP1);
2659                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2660                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2661                         M_INTMOVE(s1, REG_ITMP2);
2662                         M_XOR(s2, REG_ITMP2);
2663                         M_OR(REG_ITMP1, REG_ITMP2);
2664                         emit_bne(cd, iptr->dst.block);
2665                         break;
2666
2667                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
2668
2669                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2670                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2671                         M_CMP(s2, s1);
2672                         emit_blt(cd, iptr->dst.block);
2673                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2674                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2675                         M_BGT(2 + 6);
2676                         M_CMP(s2, s1);
2677                         emit_bult(cd, iptr->dst.block);
2678                         break;
2679
2680                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
2681
2682                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2683                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2684                         M_CMP(s2, s1);
2685                         emit_bgt(cd, iptr->dst.block);
2686                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2687                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2688                         M_BLT(2 + 6);
2689                         M_CMP(s2, s1);
2690                         emit_bugt(cd, iptr->dst.block);
2691                         break;
2692
2693                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
2694
2695                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2696                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2697                         M_CMP(s2, s1);
2698                         emit_blt(cd, iptr->dst.block);
2699                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2700                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2701                         M_BGT(2 + 6);
2702                         M_CMP(s2, s1);
2703                         emit_bule(cd, iptr->dst.block);
2704                         break;
2705
2706                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
2707
2708                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2709                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2710                         M_CMP(s2, s1);
2711                         emit_bgt(cd, iptr->dst.block);
2712                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2713                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2714                         M_BLT(2 + 6);
2715                         M_CMP(s2, s1);
2716                         emit_buge(cd, iptr->dst.block);
2717                         break;
2718
2719
2720                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
2721
2722                         REPLACEMENT_POINT_RETURN(cd, iptr);
2723                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2724                         M_INTMOVE(s1, REG_RESULT);
2725                         goto nowperformreturn;
2726
2727                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
2728
2729                         REPLACEMENT_POINT_RETURN(cd, iptr);
2730                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2731                         M_LNGMOVE(s1, REG_RESULT_PACKED);
2732                         goto nowperformreturn;
2733
2734                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
2735
2736                         REPLACEMENT_POINT_RETURN(cd, iptr);
2737                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
2738                         M_INTMOVE(s1, REG_RESULT);
2739
2740 #ifdef ENABLE_VERIFIER
2741                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2742                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2743                                                                         iptr->sx.s23.s2.uc, 0);
2744                         }
2745 #endif /* ENABLE_VERIFIER */
2746                         goto nowperformreturn;
2747
2748                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
2749                 case ICMD_DRETURN:
2750
2751                         REPLACEMENT_POINT_RETURN(cd, iptr);
2752                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2753                         goto nowperformreturn;
2754
2755                 case ICMD_RETURN:      /* ...  ==> ...                                */
2756
2757                         REPLACEMENT_POINT_RETURN(cd, iptr);
2758
2759 nowperformreturn:
2760                         {
2761                         s4 i, p;
2762                         
2763                         p = cd->stackframesize;
2764                         
2765 #if !defined(NDEBUG)
2766                         emit_verbosecall_exit(jd);
2767 #endif
2768
2769 #if defined(ENABLE_THREADS)
2770                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2771                                 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
2772
2773                                 /* we need to save the proper return value */
2774                                 switch (iptr->opc) {
2775                                 case ICMD_IRETURN:
2776                                 case ICMD_ARETURN:
2777                                         M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
2778                                         break;
2779
2780                                 case ICMD_LRETURN:
2781                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
2782                                         break;
2783
2784                                 case ICMD_FRETURN:
2785                                         emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
2786                                         break;
2787
2788                                 case ICMD_DRETURN:
2789                                         emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
2790                                         break;
2791                                 }
2792
2793                                 M_AST(REG_ITMP2, REG_SP, 0);
2794                                 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
2795                                 M_CALL(REG_ITMP3);
2796
2797                                 /* and now restore the proper return value */
2798                                 switch (iptr->opc) {
2799                                 case ICMD_IRETURN:
2800                                 case ICMD_ARETURN:
2801                                         M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
2802                                         break;
2803
2804                                 case ICMD_LRETURN:
2805                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
2806                                         break;
2807
2808                                 case ICMD_FRETURN:
2809                                         emit_flds_membase(cd, REG_SP, rd->memuse * 4);
2810                                         break;
2811
2812                                 case ICMD_DRETURN:
2813                                         emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
2814                                         break;
2815                                 }
2816                         }
2817 #endif
2818
2819                         /* restore saved registers */
2820
2821                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2822                                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
2823                         }
2824
2825                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2826                                 p--;
2827                                 emit_fldl_membase(cd, REG_SP, p * 4);
2828                                 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
2829                                         assert(0);
2830 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
2831                                 } else {
2832                                         assert(0);
2833 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
2834                                 }
2835                         }
2836
2837                         /* deallocate stack */
2838
2839                         if (cd->stackframesize)
2840                                 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
2841
2842                         emit_ret(cd);
2843                         }
2844                         break;
2845
2846
2847                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
2848                         {
2849                                 s4 i, l;
2850                                 branch_target_t *table;
2851
2852                                 table = iptr->dst.table;
2853
2854                                 l = iptr->sx.s23.s2.tablelow;
2855                                 i = iptr->sx.s23.s3.tablehigh;
2856
2857                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2858                                 M_INTMOVE(s1, REG_ITMP1);
2859
2860                                 if (l != 0)
2861                                         M_ISUB_IMM(l, REG_ITMP1);
2862
2863                                 i = i - l + 1;
2864
2865                 /* range check */
2866
2867                                 M_CMP_IMM(i - 1, REG_ITMP1);
2868                                 emit_bugt(cd, table[0].block);
2869
2870                                 /* build jump table top down and use address of lowest entry */
2871
2872                                 table += i;
2873
2874                                 while (--i >= 0) {
2875                                         dseg_add_target(cd, table->block); 
2876                                         --table;
2877                                 }
2878
2879                                 /* length of dataseg after last dseg_addtarget is used
2880                                    by load */
2881
2882                                 M_MOV_IMM(0, REG_ITMP2);
2883                                 dseg_adddata(cd);
2884                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
2885                                 M_JMP(REG_ITMP1);
2886                         }
2887                         break;
2888
2889
2890                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
2891                         {
2892                                 s4 i;
2893                                 lookup_target_t *lookup;
2894
2895                                 lookup = iptr->dst.lookup;
2896
2897                                 i = iptr->sx.s23.s2.lookupcount;
2898                         
2899                                 MCODECHECK((i<<2)+8);
2900                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2901
2902                                 while (--i >= 0) {
2903                                         M_CMP_IMM(lookup->value, s1);
2904                                         emit_beq(cd, lookup->target.block);
2905                                         lookup++;
2906                                 }
2907
2908                                 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2909                                 ALIGNCODENOP;
2910                         }
2911                         break;
2912
2913                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
2914
2915                         bte = iptr->sx.s23.s3.bte;
2916                         md = bte->md;
2917                         goto gen_method;
2918
2919                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
2920
2921                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2922                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
2923                 case ICMD_INVOKEINTERFACE:
2924
2925                         REPLACEMENT_POINT_INVOKE(cd, iptr);
2926
2927                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2928                                 md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
2929                                 lm = NULL;
2930                         }
2931                         else {
2932                                 lm = iptr->sx.s23.s3.fmiref->p.method;
2933                                 md = lm->parseddesc;
2934                         }
2935
2936 gen_method:
2937                         s3 = md->paramcount;
2938
2939                         MCODECHECK((s3 << 1) + 64);
2940
2941                         /* copy arguments to registers or stack location                  */
2942
2943                         for (s3 = s3 - 1; s3 >= 0; s3--) {
2944                                 var = VAR(iptr->sx.s23.s2.args[s3]);
2945           
2946                                 /* Already Preallocated (ARGVAR) ? */
2947                                 if (var->flags & PREALLOC)
2948                                         continue;
2949                                 if (IS_INT_LNG_TYPE(var->type)) {
2950                                         if (!md->params[s3].inmemory) {
2951                                                 log_text("No integer argument registers available!");
2952                                                 assert(0);
2953
2954                                         } else {
2955                                                 if (IS_2_WORD_TYPE(var->type)) {
2956                                                         d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2957                                                         M_LST(d, REG_SP, md->params[s3].regoff * 4);
2958                                                 } else {
2959                                                         d = emit_load(jd, iptr, var, REG_ITMP1);
2960                                                         M_IST(d, REG_SP, md->params[s3].regoff * 4);
2961                                                 }
2962                                         }
2963
2964                                 } else {
2965                                         if (!md->params[s3].inmemory) {
2966                                                 s1 = rd->argfltregs[md->params[s3].regoff];
2967                                                 d = emit_load(jd, iptr, var, s1);
2968                                                 M_FLTMOVE(d, s1);
2969
2970                                         } else {
2971                                                 d = emit_load(jd, iptr, var, REG_FTMP1);
2972                                                 if (IS_2_WORD_TYPE(var->type))
2973                                                         M_DST(d, REG_SP, md->params[s3].regoff * 4);
2974                                                 else
2975                                                         M_FST(d, REG_SP, md->params[s3].regoff * 4);
2976                                         }
2977                                 }
2978                         } /* end of for */
2979
2980                         switch (iptr->opc) {
2981                         case ICMD_BUILTIN:
2982                                 disp = (ptrint) bte->fp;
2983                                 d = md->returntype.type;
2984
2985                                 M_MOV_IMM(disp, REG_ITMP1);
2986                                 M_CALL(REG_ITMP1);
2987
2988                                 emit_exception_check(cd, iptr);
2989                                 break;
2990
2991                         case ICMD_INVOKESPECIAL:
2992                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
2993                                 emit_nullpointer_check(cd, iptr, REG_ITMP1);
2994                                 /* fall through */
2995
2996                         case ICMD_INVOKESTATIC:
2997                                 if (lm == NULL) {
2998                                         unresolved_method *um = iptr->sx.s23.s3.um;
2999
3000                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
3001                                                                                 um, 0);
3002
3003                                         disp = 0;
3004                                         d = md->returntype.type;
3005                                 }
3006                                 else {
3007                                         disp = (ptrint) lm->stubroutine;
3008                                         d = lm->parseddesc->returntype.type;
3009                                 }
3010
3011                                 M_MOV_IMM(disp, REG_ITMP2);
3012                                 M_CALL(REG_ITMP2);
3013                                 break;
3014
3015                         case ICMD_INVOKEVIRTUAL:
3016                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3017                                 emit_nullpointer_check(cd, iptr, s1);
3018
3019                                 if (lm == NULL) {
3020                                         unresolved_method *um = iptr->sx.s23.s3.um;
3021
3022                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3023
3024                                         s1 = 0;
3025                                         d = md->returntype.type;
3026                                 }
3027                                 else {
3028                                         s1 = OFFSET(vftbl_t, table[0]) +
3029                                                 sizeof(methodptr) * lm->vftblindex;
3030                                         d = md->returntype.type;
3031                                 }
3032
3033                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3034                                           OFFSET(java_objectheader, vftbl));
3035                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3036                                 M_CALL(REG_ITMP3);
3037                                 break;
3038
3039                         case ICMD_INVOKEINTERFACE:
3040                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3041                                 emit_nullpointer_check(cd, iptr, s1);
3042
3043                                 if (lm == NULL) {
3044                                         unresolved_method *um = iptr->sx.s23.s3.um;
3045
3046                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3047
3048                                         s1 = 0;
3049                                         s2 = 0;
3050                                         d = md->returntype.type;
3051                                 }
3052                                 else {
3053                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3054                                                 sizeof(methodptr) * lm->class->index;
3055
3056                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3057
3058                                         d = md->returntype.type;
3059                                 }
3060
3061                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3062                                           OFFSET(java_objectheader, vftbl));
3063                                 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3064                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3065                                 M_CALL(REG_ITMP3);
3066                                 break;
3067                         }
3068
3069                         /* store size of call code in replacement point */
3070
3071                         REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3072
3073                         /* d contains return type */
3074
3075                         if (d != TYPE_VOID) {
3076 #if defined(ENABLE_SSA)
3077                                 if ((ls == NULL) || (!IS_TEMPVAR_INDEX(iptr->dst.varindex)) ||
3078                                         (ls->lifetime[-iptr->dst.varindex-1].type != -1)) 
3079                                         /* a "living" stackslot */
3080 #endif
3081                                 {
3082                                         if (IS_INT_LNG_TYPE(d)) {
3083                                                 if (IS_2_WORD_TYPE(d)) {
3084                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3085                                                         M_LNGMOVE(REG_RESULT_PACKED, s1);
3086                                                 }
3087                                                 else {
3088                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3089                                                         M_INTMOVE(REG_RESULT, s1);
3090                                                 }
3091                                         }
3092                                         else {
3093                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
3094                                         }
3095                                         emit_store_dst(jd, iptr, s1);
3096                                 }
3097                         }
3098                         break;
3099
3100
3101                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3102                                       /* val.a: (classinfo*) superclass               */
3103
3104                         /*  superclass is an interface:
3105                          *
3106                          *  OK if ((sub == NULL) ||
3107                          *         (sub->vftbl->interfacetablelength > super->index) &&
3108                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
3109                          *
3110                          *  superclass is a class:
3111                          *
3112                          *  OK if ((sub == NULL) || (0
3113                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3114                          *         super->vftbl->diffval));
3115                          */
3116
3117                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3118                                 /* object type cast-check */
3119
3120                                 classinfo *super;
3121                                 vftbl_t   *supervftbl;
3122                                 s4         superindex;
3123
3124                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3125                                         super = NULL;
3126                                         superindex = 0;
3127                                         supervftbl = NULL;
3128                                 }
3129                                 else {
3130                                         super = iptr->sx.s23.s3.c.cls;
3131                                         superindex = super->index;
3132                                         supervftbl = super->vftbl;
3133                                 }
3134                         
3135 #if defined(ENABLE_THREADS)
3136                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3137 #endif
3138                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3139
3140                                 /* if class is not resolved, check which code to call */
3141
3142                                 if (super == NULL) {
3143                                         M_TEST(s1);
3144                                         emit_label_beq(cd, BRANCH_LABEL_1);
3145
3146                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3147                                                                                 iptr->sx.s23.s3.c.ref, 0);
3148
3149                                         M_MOV_IMM(0, REG_ITMP2);                  /* super->flags */
3150                                         M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3151                                         emit_label_beq(cd, BRANCH_LABEL_2);
3152                                 }
3153
3154                                 /* interface checkcast code */
3155
3156                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3157                                         if (super != NULL) {
3158                                                 M_TEST(s1);
3159                                                 emit_label_beq(cd, BRANCH_LABEL_3);
3160                                         }
3161
3162                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3163
3164                                         if (super == NULL) {
3165                                                 codegen_addpatchref(cd, PATCHER_checkcast_interface,
3166                                                                                         iptr->sx.s23.s3.c.ref,
3167                                                                                         0);
3168                                         }
3169
3170                                         M_ILD32(REG_ITMP3,
3171                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3172                                         M_ISUB_IMM32(superindex, REG_ITMP3);
3173                                         /* XXX do we need this one? */
3174                                         M_TEST(REG_ITMP3);
3175                                         emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
3176
3177                                         M_ALD32(REG_ITMP3, REG_ITMP2,
3178                                                         OFFSET(vftbl_t, interfacetable[0]) -
3179                                                         superindex * sizeof(methodptr*));
3180                                         M_TEST(REG_ITMP3);
3181                                         emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
3182
3183                                         if (super == NULL)
3184                                                 emit_label_br(cd, BRANCH_LABEL_4);
3185                                         else
3186                                                 emit_label(cd, BRANCH_LABEL_3);
3187                                 }
3188
3189                                 /* class checkcast code */
3190
3191                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3192                                         if (super == NULL) {
3193                                                 emit_label(cd, BRANCH_LABEL_2);
3194                                         }
3195                                         else {
3196                                                 M_TEST(s1);
3197                                                 emit_label_beq(cd, BRANCH_LABEL_5);
3198                                         }
3199
3200                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3201
3202                                         if (super == NULL) {
3203                                                 codegen_addpatchref(cd, PATCHER_checkcast_class,
3204                                                                                         iptr->sx.s23.s3.c.ref,
3205                                                                                         0);
3206                                         }
3207
3208                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3209 #if defined(ENABLE_THREADS)
3210                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3211 #endif
3212                                         M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3213
3214                                         /*                              if (s1 != REG_ITMP1) { */
3215                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3216                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3217                                         /* #if defined(ENABLE_THREADS) */
3218                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3219                                         /* #endif */
3220                                         /*                                      emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3221
3222                                         /*                              } else { */
3223                                         M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3224                                         M_ISUB(REG_ITMP3, REG_ITMP2);
3225                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3226                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3227 #if defined(ENABLE_THREADS)
3228                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3229 #endif
3230                                         /*                              } */
3231
3232                                         M_CMP(REG_ITMP3, REG_ITMP2);
3233                                         emit_classcast_check(cd, iptr, BRANCH_ULE, REG_ITMP3, s1);
3234
3235                                         if (super != NULL)
3236                                                 emit_label(cd, BRANCH_LABEL_5);
3237                                 }
3238
3239                                 if (super == NULL) {
3240                                         emit_label(cd, BRANCH_LABEL_1);
3241                                         emit_label(cd, BRANCH_LABEL_4);
3242                                 }
3243
3244                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3245                         }
3246                         else {
3247                                 /* array type cast-check */
3248
3249                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3250                                 M_AST(s1, REG_SP, 0 * 4);
3251
3252                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3253                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3254                                                                                 iptr->sx.s23.s3.c.ref, 0);
3255                                 }
3256
3257                                 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
3258                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3259                                 M_CALL(REG_ITMP3);
3260
3261                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3262                                 M_TEST(REG_RESULT);
3263                                 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
3264
3265                                 d = codegen_reg_of_dst(jd, iptr, s1);
3266                         }
3267
3268                         M_INTMOVE(s1, d);
3269                         emit_store_dst(jd, iptr, d);
3270                         break;
3271
3272                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3273                                       /* val.a: (classinfo*) superclass               */
3274
3275                         /*  superclass is an interface:
3276                          *
3277                          *  return (sub != NULL) &&
3278                          *         (sub->vftbl->interfacetablelength > super->index) &&
3279                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3280                          *
3281                          *  superclass is a class:
3282                          *
3283                          *  return ((sub != NULL) && (0
3284                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3285                          *          super->vftbl->diffvall));
3286                          */
3287
3288                         {
3289                         classinfo *super;
3290                         vftbl_t   *supervftbl;
3291                         s4         superindex;
3292
3293                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3294                                 super = NULL;
3295                                 superindex = 0;
3296                                 supervftbl = NULL;
3297
3298                         } else {
3299                                 super = iptr->sx.s23.s3.c.cls;
3300                                 superindex = super->index;
3301                                 supervftbl = super->vftbl;
3302                         }
3303                         
3304 #if defined(ENABLE_THREADS)
3305                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3306 #endif
3307
3308                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3309                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3310
3311                         if (s1 == d) {
3312                                 M_INTMOVE(s1, REG_ITMP1);
3313                                 s1 = REG_ITMP1;
3314                         }
3315
3316                         M_CLR(d);
3317
3318                         /* if class is not resolved, check which code to call */
3319
3320                         if (super == NULL) {
3321                                 M_TEST(s1);
3322                                 emit_label_beq(cd, BRANCH_LABEL_1);
3323
3324                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3325                                                                         iptr->sx.s23.s3.c.ref, 0);
3326
3327                                 M_MOV_IMM(0, REG_ITMP3);                      /* super->flags */
3328                                 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3329                                 emit_label_beq(cd, BRANCH_LABEL_2);
3330                         }
3331
3332                         /* interface instanceof code */
3333
3334                         if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3335                                 if (super != NULL) {
3336                                         M_TEST(s1);
3337                                         emit_label_beq(cd, BRANCH_LABEL_3);
3338                                 }
3339
3340                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3341
3342                                 if (super == NULL) {
3343                                         codegen_addpatchref(cd, PATCHER_instanceof_interface,
3344                                                                                 iptr->sx.s23.s3.c.ref, 0);
3345                                 }
3346
3347                                 M_ILD32(REG_ITMP3,
3348                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3349                                 M_ISUB_IMM32(superindex, REG_ITMP3);
3350                                 M_TEST(REG_ITMP3);
3351
3352                                 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3353                                                 6 /* jcc */ + 5 /* mov_imm_reg */);
3354
3355                                 M_BLE(disp);
3356                                 M_ALD32(REG_ITMP1, REG_ITMP1,
3357                                                 OFFSET(vftbl_t, interfacetable[0]) -
3358                                                 superindex * sizeof(methodptr*));
3359                                 M_TEST(REG_ITMP1);
3360 /*                                      emit_setcc_reg(cd, CC_A, d); */
3361 /*                                      emit_jcc(cd, CC_BE, 5); */
3362                                 M_BEQ(5);
3363                                 M_MOV_IMM(1, d);
3364
3365                                 if (super == NULL)
3366                                         emit_label_br(cd, BRANCH_LABEL_4);
3367                                 else
3368                                         emit_label(cd, BRANCH_LABEL_3);
3369                         }
3370
3371                         /* class instanceof code */
3372
3373                         if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3374                                 if (super == NULL) {
3375                                         emit_label(cd, BRANCH_LABEL_2);
3376                                 }
3377                                 else {
3378                                         M_TEST(s1);
3379                                         emit_label_beq(cd, BRANCH_LABEL_5);
3380                                 }
3381
3382                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3383
3384                                 if (super == NULL) {
3385                                         codegen_addpatchref(cd, PATCHER_instanceof_class,
3386                                                                                 iptr->sx.s23.s3.c.ref, 0);
3387                                 }
3388
3389                                 M_MOV_IMM(supervftbl, REG_ITMP2);
3390 #if defined(ENABLE_THREADS)
3391                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3392 #endif
3393                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3394                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3395                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3396 #if defined(ENABLE_THREADS)
3397                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3398 #endif
3399                                 M_ISUB(REG_ITMP2, REG_ITMP1);
3400                                 M_CLR(d);                                 /* may be REG_ITMP2 */
3401                                 M_CMP(REG_ITMP3, REG_ITMP1);
3402                                 M_BA(5);
3403                                 M_MOV_IMM(1, d);
3404
3405                                 if (super != NULL)
3406                                         emit_label(cd, BRANCH_LABEL_5);
3407                         }
3408
3409                         if (super == NULL) {
3410                                 emit_label(cd, BRANCH_LABEL_1);
3411                                 emit_label(cd, BRANCH_LABEL_4);
3412                         }
3413
3414                         emit_store_dst(jd, iptr, d);
3415                         }
3416                         break;
3417
3418                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3419
3420                         /* check for negative sizes and copy sizes to stack if necessary  */
3421
3422                         MCODECHECK((iptr->s1.argcount << 1) + 64);
3423
3424                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3425                                 /* copy SAVEDVAR sizes to stack */
3426                                 var = VAR(iptr->sx.s23.s2.args[s1]);
3427
3428                                 /* Already Preallocated? */
3429                                 if (!(var->flags & PREALLOC)) {
3430                                         if (var->flags & INMEMORY) {
3431                                                 M_ILD(REG_ITMP1, REG_SP, var->vv.regoff * 4);
3432                                                 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
3433                                         }
3434                                         else
3435                                                 M_IST(var->vv.regoff, REG_SP, (s1 + 3) * 4);
3436                                 }
3437                         }
3438
3439                         /* is a patcher function set? */
3440
3441                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3442                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3443                                                                         iptr->sx.s23.s3.c.ref, 0);
3444
3445                                 disp = 0;
3446
3447                         }
3448                         else
3449                                 disp = (ptrint) iptr->sx.s23.s3.c.cls;
3450
3451                         /* a0 = dimension count */
3452
3453                         M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
3454
3455                         /* a1 = arraydescriptor */
3456
3457                         M_IST_IMM(disp, REG_SP, 1 * 4);
3458
3459                         /* a2 = pointer to dimensions = stack pointer */
3460
3461                         M_MOV(REG_SP, REG_ITMP1);
3462                         M_AADD_IMM(3 * 4, REG_ITMP1);
3463                         M_AST(REG_ITMP1, REG_SP, 2 * 4);
3464
3465                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3466                         M_CALL(REG_ITMP1);
3467
3468                         /* check for exception before result assignment */
3469
3470                         emit_exception_check(cd, iptr);
3471
3472                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3473                         M_INTMOVE(REG_RESULT, s1);
3474                         emit_store_dst(jd, iptr, s1);
3475                         break;
3476
3477                 default:
3478                         exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3479                                                                                    iptr->opc);
3480                         return false;
3481         } /* switch */
3482                 
3483         } /* for instruction */
3484                 
3485         MCODECHECK(64);
3486
3487 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
3488         if (!opt_lsra)
3489 #endif
3490 #if defined(ENABLE_SSA)
3491         if ( ls != NULL ) {
3492                 /* by edge splitting, in Blocks with phi moves there can only */
3493                 /* be a goto as last command, no other Jump/Branch Command    */
3494                 if (!last_cmd_was_goto)
3495                         codegen_insert_phi_moves(jd, bptr);
3496         }
3497
3498 #endif
3499
3500         /* At the end of a basic block we may have to append some nops,
3501            because the patcher stub calling code might be longer than the
3502            actual instruction. So codepatching does not change the
3503            following block unintentionally. */
3504
3505         if (cd->mcodeptr < cd->lastmcodeptr) {
3506                 while (cd->mcodeptr < cd->lastmcodeptr) {
3507                         M_NOP;
3508                 }
3509         }
3510
3511         } /* if (bptr -> flags >= BBREACHED) */
3512         } /* for basic block */
3513
3514         dseg_createlinenumbertable(cd);
3515
3516         /* generate stubs */
3517
3518         emit_patcher_stubs(jd);
3519         REPLACEMENT_EMIT_STUBS(jd);
3520
3521         /* everything's ok */
3522
3523         return true;
3524 }
3525
3526 #if defined(ENABLE_SSA)
3527 void codegen_insert_phi_moves(jitdata *jd, basicblock *bptr) {
3528         /* look for phi moves */
3529         int t_a,s_a,i, type;
3530         int t_lt, s_lt; /* lifetime indices of phi_moves */
3531         s4 t_regoff, s_regoff, s_flags, t_flags;
3532         codegendata *cd;
3533         lsradata *ls;
3534
3535         MCODECHECK(512);
3536
3537         ls = jd->ls;
3538         cd = jd->cd;
3539         
3540         /* Moves from phi functions with highest indices have to be */
3541         /* inserted first, since this is the order as is used for   */
3542         /* conflict resolution */
3543         for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
3544                 t_a = ls->phi_moves[bptr->nr][i][0];
3545                 s_a = ls->phi_moves[bptr->nr][i][1];
3546 #if defined(SSA_DEBUG_VERBOSE)
3547                 if (compileverbose)
3548                         printf("BB %3i Move %3i <- %3i ", bptr->nr, t_a, s_a);
3549 #endif
3550                 if (t_a >= 0) {
3551                         /* local var lifetimes */
3552                         t_lt = ls->maxlifetimes + t_a;
3553                         type = ls->lifetime[t_lt].type;
3554                 }
3555                 else {
3556                         t_lt = -t_a-1;
3557                         type = ls->lifetime[t_lt].local_ss->s->type;
3558                         /* stackslot lifetime */
3559                 }
3560
3561                 if (type == -1) {
3562 #if defined(SSA_DEBUG_VERBOSE)
3563                         if (compileverbose)
3564                                 printf("...returning - phi lifetimes where joined\n");
3565 #endif
3566                         return;
3567                 }
3568
3569                 if (s_a >= 0) {
3570                         /* local var lifetimes */
3571                         s_lt = ls->maxlifetimes + s_a;
3572                         type = ls->lifetime[s_lt].type;
3573                 }
3574                 else {
3575                         s_lt = -s_a-1;
3576                         type = ls->lifetime[s_lt].type;
3577                         /* stackslot lifetime */
3578                 }
3579
3580                 if (type == -1) {
3581 #if defined(SSA_DEBUG_VERBOSE)
3582                         if (compileverbose)
3583                                 printf("...returning - phi lifetimes where joined\n");
3584 #endif
3585                         return;
3586                 }
3587
3588                 if (t_a >= 0) {
3589                         t_flags = VAR(t_a)->flags;
3590                         t_regoff = VAR(t_a)->vv.regoff;
3591                         
3592                 }
3593                 else {
3594                         t_flags = ls->lifetime[t_lt].local_ss->s->flags;
3595                         t_regoff = ls->lifetime[t_lt].local_ss->s->regoff;
3596                 }
3597
3598                 if (s_a >= 0) {
3599                         /* local var move */
3600                         s_flags = VAR(s_a)->flags;
3601                         s_regoff = VAR(s_a)->vv.regoff;
3602                 } else {
3603                         /* stackslot lifetime */
3604                         s_flags = ls->lifetime[s_lt].local_ss->s->flags;
3605                         s_regoff = ls->lifetime[s_lt].local_ss->s->regoff;
3606                 }
3607
3608                 if (type == -1) {
3609 #if defined(SSA_DEBUG_VERBOSE)
3610                         if (compileverbose)
3611                                 printf("...returning - phi lifetimes where joined\n");
3612 #endif
3613                         return;
3614                 }
3615
3616                 cg_move(cd, type, s_regoff, s_flags, t_regoff, t_flags);
3617
3618 #if defined(SSA_DEBUG_VERBOSE)
3619                 if (compileverbose) {
3620                         if (IS_INMEMORY(t_flags) && IS_INMEMORY(s_flags)) {
3621                                 /* mem -> mem */
3622                                 printf("M%3i <- M%3i",t_regoff,s_regoff);
3623                         }
3624                         else    if (IS_INMEMORY(s_flags)) {
3625                                 /* mem -> reg */
3626                                 printf("R%3i <- M%3i",t_regoff,s_regoff);
3627                         }
3628                         else if (IS_INMEMORY(t_flags)) {
3629                                 /* reg -> mem */
3630                                 printf("M%3i <- R%3i",t_regoff,s_regoff);
3631                         }
3632                         else {
3633                                 /* reg -> reg */
3634                                 printf("R%3i <- R%3i",t_regoff,s_regoff);
3635                         }
3636                         printf("\n");
3637                 }
3638 #endif /* defined(SSA_DEBUG_VERBOSE) */
3639         }
3640 }
3641
3642 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
3643                          s4 dst_regoff, s4 dst_flags) {
3644         if ((IS_INMEMORY(dst_flags)) && (IS_INMEMORY(src_flags))) {
3645                 /* mem -> mem */
3646                 if (dst_regoff != src_regoff) {
3647                         if (!IS_2_WORD_TYPE(type)) {
3648                                 if (IS_FLT_DBL_TYPE(type)) {
3649                                         emit_flds_membase(cd, REG_SP, src_regoff * 4);
3650                                         emit_fstps_membase(cd, REG_SP, dst_regoff * 4);
3651                                 } else{
3652                                         emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
3653                                                         REG_ITMP1);
3654                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
3655                                 }
3656                         } else { /* LONG OR DOUBLE */
3657                                 if (IS_FLT_DBL_TYPE(type)) {
3658                                         emit_fldl_membase( cd, REG_SP, src_regoff * 4);
3659                                         emit_fstpl_membase(cd, REG_SP, dst_regoff * 4);
3660                                 } else {
3661                                         emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
3662                                                         REG_ITMP1);
3663                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
3664                                         emit_mov_membase_reg(cd, REG_SP, src_regoff * 4 + 4,
3665                             REG_ITMP1);             
3666                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, 
3667                                                         dst_regoff * 4 + 4);
3668                                 }
3669                         }
3670                 }
3671         } else {
3672                 if (IS_FLT_DBL_TYPE(type)) {
3673                         log_text("cg_move: flt/dbl type have to be in memory\n");
3674 /*                      assert(0); */
3675                 }
3676                 if (IS_2_WORD_TYPE(type)) {
3677                         log_text("cg_move: longs have to be in memory\n");
3678 /*                      assert(0); */
3679                 }
3680                 if (IS_INMEMORY(src_flags)) {
3681                         /* mem -> reg */
3682                         emit_mov_membase_reg(cd, REG_SP, src_regoff * 4, dst_regoff);
3683                 } else if (IS_INMEMORY(dst_flags)) {
3684                         /* reg -> mem */
3685                         emit_mov_reg_membase(cd, src_regoff, REG_SP, dst_regoff * 4);
3686                 } else {
3687                         /* reg -> reg */
3688                         /* only ints can be in regs on i386 */
3689                         M_INTMOVE(src_regoff,dst_regoff);
3690                 }
3691         }
3692 }
3693 #endif /* defined(ENABLE_SSA) */
3694
3695 /* createcompilerstub **********************************************************
3696
3697    Creates a stub routine which calls the compiler.
3698         
3699 *******************************************************************************/
3700
3701 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
3702 #define COMPILERSTUB_CODESIZE    12
3703
3704 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3705
3706
3707 u1 *createcompilerstub(methodinfo *m)
3708 {
3709         u1          *s;                     /* memory to hold the stub            */
3710         ptrint      *d;
3711         codegendata *cd;
3712         s4           dumpsize;
3713
3714         s = CNEW(u1, COMPILERSTUB_SIZE);
3715
3716         /* set data pointer and code pointer */
3717
3718         d = (ptrint *) s;
3719         s = s + COMPILERSTUB_DATASIZE;
3720
3721         /* mark start of dump memory area */
3722
3723         dumpsize = dump_size();
3724
3725         cd = DNEW(codegendata);
3726         cd->mcodeptr = s;
3727
3728         /* The codeinfo pointer is actually a pointer to the
3729            methodinfo. This fakes a codeinfo structure. */
3730
3731         d[0] = (ptrint) asm_call_jit_compiler;
3732         d[1] = (ptrint) m;
3733         d[2] = (ptrint) &d[1];                                    /* fake code->m */
3734
3735         /* code for the stub */
3736
3737         M_MOV_IMM(m, REG_ITMP1);            /* method info                        */
3738         M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
3739         M_JMP(REG_ITMP3);
3740
3741 #if defined(ENABLE_STATISTICS)
3742         if (opt_stat)
3743                 count_cstub_len += COMPILERSTUB_SIZE;
3744 #endif
3745
3746         /* release dump area */
3747
3748         dump_release(dumpsize);
3749         
3750         return s;
3751 }
3752
3753
3754 /* createnativestub ************************************************************
3755
3756    Creates a stub routine which calls a native method.
3757
3758 *******************************************************************************/
3759
3760 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3761 {
3762         methodinfo   *m;
3763         codeinfo     *code;
3764         codegendata  *cd;
3765         registerdata *rd;
3766         methoddesc   *md;
3767         s4            nativeparams;
3768         s4            i, j;                 /* count variables                    */
3769         s4            t;
3770         s4            s1, s2;
3771
3772         /* get required compiler data */
3773
3774         m    = jd->m;
3775         code = jd->code;
3776         cd   = jd->cd;
3777         rd   = jd->rd;
3778
3779         /* set some variables */
3780
3781         md = m->parseddesc;
3782         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3783
3784         /* calculate stackframe size */
3785
3786         cd->stackframesize =
3787                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3788                 sizeof(localref_table) / SIZEOF_VOID_P +
3789                 1 +                             /* function pointer                   */
3790                 4 * 4 +                         /* 4 arguments (start_native_call)    */
3791                 nmd->memuse;
3792
3793     /* keep stack 16-byte aligned */
3794
3795         cd->stackframesize |= 0x3;
3796
3797         /* create method header */
3798
3799         (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
3800         (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
3801         (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
3802         (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
3803         (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
3804         (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
3805         (void) dseg_addlinenumbertablesize(cd);
3806         (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
3807
3808 #if defined(ENABLE_PROFILING)
3809         /* generate native method profiling code */
3810
3811         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3812                 /* count frequency */
3813
3814                 M_MOV_IMM(code, REG_ITMP1);
3815                 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
3816         }
3817 #endif
3818
3819         /* calculate stackframe size for native function */
3820
3821         M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
3822
3823 #if !defined(NDEBUG)
3824         emit_verbosecall_enter(jd);
3825 #endif
3826
3827         /* get function address (this must happen before the stackframeinfo) */
3828
3829 #if !defined(WITH_STATIC_CLASSPATH)
3830         if (f == NULL)
3831                 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
3832 #endif
3833
3834         M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
3835
3836         /* Mark the whole fpu stack as free for native functions (only for saved  */
3837         /* register count == 0).                                                  */
3838
3839         emit_ffree_reg(cd, 0);
3840         emit_ffree_reg(cd, 1);
3841         emit_ffree_reg(cd, 2);
3842         emit_ffree_reg(cd, 3);
3843         emit_ffree_reg(cd, 4);
3844         emit_ffree_reg(cd, 5);
3845         emit_ffree_reg(cd, 6);
3846         emit_ffree_reg(cd, 7);
3847
3848 #if defined(ENABLE_GC_CACAO)
3849         /* remember callee saved int registers in stackframeinfo (GC may need to  */
3850         /* recover them during a collection).                                     */
3851
3852         j = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3853                         OFFSET(stackframeinfo, intregs);
3854         for (i=0; i<INT_REG_CNT; ++i) {
3855                 if (nregdescint[i] == REG_SAV) {
3856                         M_AST(i, REG_SP, j);
3857                         j += SIZEOF_VOID_P;
3858                 }
3859         }
3860 #endif
3861
3862         /* prepare data structures for native function call */
3863
3864         M_MOV(REG_SP, REG_ITMP1);
3865         M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
3866
3867         M_AST(REG_ITMP1, REG_SP, 0 * 4);
3868         M_IST_IMM(0, REG_SP, 1 * 4);
3869         dseg_adddata(cd);
3870
3871         M_MOV(REG_SP, REG_ITMP2);
3872         M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
3873
3874         M_AST(REG_ITMP2, REG_SP, 2 * 4);
3875         M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 4);
3876         M_AST(REG_ITMP3, REG_SP, 3 * 4);
3877         M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3878         M_CALL(REG_ITMP1);
3879
3880         M_ALD(REG_ITMP3, REG_SP, 4 * 4);
3881
3882         /* copy arguments into new stackframe */
3883
3884         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3885                 t = md->paramtypes[i].type;
3886
3887                 if (!md->params[i].inmemory) {
3888                         /* no integer argument registers */
3889                 } else {       /* float/double in memory can be copied like int/longs */
3890                         s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
3891                         s2 = nmd->params[j].regoff * 4;
3892
3893                         M_ILD(REG_ITMP1, REG_SP, s1);
3894                         M_IST(REG_ITMP1, REG_SP, s2);
3895                         if (IS_2_WORD_TYPE(t)) {
3896                                 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
3897                                 M_IST(REG_ITMP1, REG_SP, s2 + 4);
3898                         }
3899                 }
3900         }
3901
3902         /* if function is static, put class into second argument */
3903
3904         if (m->flags & ACC_STATIC)
3905                 M_AST_IMM(m->class, REG_SP, 1 * 4);
3906
3907         /* put env into first argument */
3908
3909         M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
3910
3911         /* call the native function */
3912
3913         M_CALL(REG_ITMP3);
3914
3915         /* save return value */
3916
3917         if (md->returntype.type != TYPE_VOID) {
3918                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3919                         if (IS_2_WORD_TYPE(md->returntype.type))
3920                                 M_IST(REG_RESULT2, REG_SP, 2 * 4);
3921                         M_IST(REG_RESULT, REG_SP, 1 * 4);
3922                 }
3923                 else {
3924                         if (IS_2_WORD_TYPE(md->returntype.type))
3925                                 emit_fstl_membase(cd, REG_SP, 1 * 4);
3926                         else
3927                                 emit_fsts_membase(cd, REG_SP, 1 * 4);
3928                 }
3929         }
3930
3931 #if !defined(NDEBUG)
3932         emit_verbosecall_exit(jd);
3933 #endif
3934
3935         /* remove native stackframe info */
3936
3937         M_MOV(REG_SP, REG_ITMP1);
3938         M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
3939
3940         M_AST(REG_ITMP1, REG_SP, 0 * 4);
3941         M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3942         M_CALL(REG_ITMP1);
3943         M_MOV(REG_RESULT, REG_ITMP2);                 /* REG_ITMP3 == REG_RESULT2 */
3944
3945         /* restore return value */
3946
3947         if (md->returntype.type != TYPE_VOID) {
3948                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3949                         if (IS_2_WORD_TYPE(md->returntype.type))
3950                                 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
3951                         M_ILD(REG_RESULT, REG_SP, 1 * 4);
3952                 }
3953                 else {
3954                         if (IS_2_WORD_TYPE(md->returntype.type))
3955                                 emit_fldl_membase(cd, REG_SP, 1 * 4);
3956                         else
3957                                 emit_flds_membase(cd, REG_SP, 1 * 4);
3958                 }
3959         }
3960
3961 #if defined(ENABLE_GC_CACAO)
3962         /* restore callee saved int registers from stackframeinfo (GC might have  */
3963         /* modified them during a collection).                                    */
3964
3965         j = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3966                 OFFSET(stackframeinfo, intregs);
3967         for (i=0; i<INT_REG_CNT; ++i) {
3968                 if (nregdescint[i] == REG_SAV) {
3969                         M_ALD(i, REG_SP, j);
3970                         j += SIZEOF_VOID_P;
3971                 }
3972         }
3973 #endif
3974
3975         M_AADD_IMM(cd->stackframesize * 4, REG_SP);
3976
3977         /* check for exception */
3978
3979         M_TEST(REG_ITMP2);
3980         M_BNE(1);
3981
3982         M_RET;
3983
3984         /* handle exception */
3985
3986         M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
3987         M_ALD(REG_ITMP2_XPC, REG_SP, 0);
3988         M_ASUB_IMM(2, REG_ITMP2_XPC);
3989
3990         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3991         M_JMP(REG_ITMP3);
3992
3993
3994         /* generate patcher stubs */
3995
3996         emit_patcher_stubs(jd);
3997
3998         codegen_finish(jd);
3999
4000         return code->entrypoint;
4001 }
4002
4003
4004 /*
4005  * These are local overrides for various environment variables in Emacs.
4006  * Please do not remove this and leave it at the end of the file, where
4007  * Emacs will automagically detect them.
4008  * ---------------------------------------------------------------------
4009  * Local variables:
4010  * mode: c
4011  * indent-tabs-mode: t
4012  * c-basic-offset: 4
4013  * tab-width: 4
4014  * End:
4015  * vim:noexpandtab:sw=4:ts=4:
4016  */