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