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