Unified variables changes for common/i386.
[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 5404 2006-09-07 13:29:05Z christian $
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/md-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.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_LSRA) && !defined(ENABLE_SSA)
78 # include "vm/jit/allocator/lsra.h"
79 #endif
80 #if defined(ENABLE_SSA)
81 # include "vm/jit/optimizing/lsra.h"
82 # include "vm/jit/optimizing/ssa.h"
83 #endif
84
85
86 /* codegen *********************************************************************
87
88    Generates machine code.
89
90 *******************************************************************************/
91
92 #if defined(ENABLE_SSA)
93 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
94                          s4 dst_regoff, s4 dst_flags);
95 void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls,
96                                                           basicblock *bptr);
97 #endif
98
99 #if defined(NEW_VAR)
100 bool codegen(jitdata *jd)
101 {
102         methodinfo         *m;
103         codeinfo           *code;
104         codegendata        *cd;
105         registerdata       *rd;
106         s4                  len, s1, s2, s3, d, disp;
107         varinfo            *var, *var1;
108         basicblock         *bptr;
109         instruction        *iptr;
110         exceptiontable     *ex;
111         u2                  currentline;
112         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
113         builtintable_entry *bte;
114         methoddesc         *md;
115         rplpoint           *replacementpoint;
116         s4                 fieldtype;
117         s4                 varindex;
118 #if defined(ENABLE_SSA)
119         lsradata *ls;
120         bool last_cmd_was_goto;
121
122         last_cmd_was_goto = false;
123         ls = jd->ls;
124 #endif
125
126         /* get required compiler data */
127
128         m    = jd->m;
129         code = jd->code;
130         cd   = jd->cd;
131         rd   = jd->rd;
132
133         /* prevent compiler warnings */
134
135         d = 0;
136         currentline = 0;
137         lm = NULL;
138         bte = NULL;
139         s2 = 0;
140
141         {
142         s4 i, p, t, l;
143         s4 savedregs_num = 0;
144         s4 stack_off = 0;
145
146         /* space to save used callee saved registers */
147
148         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
149
150         /* float register are saved on 2 4-byte stackslots */
151         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
152
153         cd->stackframesize = rd->memuse + savedregs_num;
154
155            
156 #if defined(ENABLE_THREADS)
157         /* space to save argument of monitor_enter */
158
159         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
160                 /* reserve 2 slots for long/double return values for monitorexit */
161
162                 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
163                         cd->stackframesize += 2;
164                 else
165                         cd->stackframesize++;
166         }
167 #endif
168
169         /* create method header */
170
171     /* Keep stack of non-leaf functions 16-byte aligned. */
172
173         if (!jd->isleafmethod)
174                 cd->stackframesize |= 0x3;
175
176         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
177         (void) dseg_adds4(cd, cd->stackframesize * 4);         /* FrameSize       */
178
179 #if defined(ENABLE_THREADS)
180         /* IsSync contains the offset relative to the stack pointer for the
181            argument of monitor_exit used in the exception handler. Since the
182            offset could be zero and give a wrong meaning of the flag it is
183            offset by one.
184         */
185
186         if (checksync && (m->flags & ACC_SYNCHRONIZED))
187                 (void) dseg_adds4(cd, (rd->memuse + 1) * 4);       /* IsSync          */
188         else
189 #endif
190                 (void) dseg_adds4(cd, 0);                          /* IsSync          */
191                                                
192         (void) dseg_adds4(cd, jd->isleafmethod);               /* IsLeaf          */
193         (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave         */
194         (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave         */
195
196         /* adds a reference for the length of the line number counter. We don't
197            know the size yet, since we evaluate the information during code
198            generation, to save one additional iteration over the whole
199            instructions. During code optimization the position could have changed
200            to the information gotten from the class file */
201         (void) dseg_addlinenumbertablesize(cd);
202
203         (void) dseg_adds4(cd, cd->exceptiontablelength);       /* ExTableSize     */
204         
205         /* create exception table */
206
207         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
208                 dseg_addtarget(cd, ex->start);
209                 dseg_addtarget(cd, ex->end);
210                 dseg_addtarget(cd, ex->handler);
211                 (void) dseg_addaddress(cd, ex->catchtype.cls);
212         }
213         
214         /* generate method profiling code */
215
216         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
217                 /* count frequency */
218
219                 M_MOV_IMM(code, REG_ITMP3);
220                 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
221         }
222
223         /* create stack frame (if necessary) */
224
225         if (cd->stackframesize)
226                 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
227
228         /* save return address and used callee saved registers */
229
230         p = cd->stackframesize;
231         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
232                 p--; M_AST(rd->savintregs[i], REG_SP, p * 4);
233         }
234         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
235                 p-=2; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 4);
236         }
237
238         /* take arguments out of register or stack frame */
239
240         md = m->parseddesc;
241
242         stack_off = 0;
243         for (p = 0, l = 0; p < md->paramcount; p++) {
244                 t = md->paramtypes[p].type;
245 #if defined(ENABLE_SSA)
246                 if ( ls != NULL ) {
247                         l = ls->local_0[p];
248                 }
249 #endif
250                 var = &(jd->var[jd->local_map[l * 5 + t]]);
251                 l++;
252                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
253                         l++;
254                 if (var->type < 0)
255                         continue;
256                 s1 = md->params[p].regoff;
257
258                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
259                         if (!md->params[p].inmemory) {           /* register arguments    */
260                                 log_text("integer register argument");
261                                 assert(0);
262                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
263                                         /* rd->argintregs[md->params[p].regoff -> var->regoff     */
264                                 } 
265                                 else {                               /* reg arg -> spilled    */
266                                         /* rd->argintregs[md->params[p].regoff -> var->regoff * 4 */
267                                 }
268                         } 
269                         else {                                   /* stack arguments       */
270                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
271                                         emit_mov_membase_reg(           /* + 4 for return address */
272                                            cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, var->regoff);
273                                                                         /* + 4 for return address */
274                                 } 
275                                 else {                               /* stack arg -> spilled  */
276                                         if (!IS_2_WORD_TYPE(t)) {
277 #if defined(ENABLE_SSA)
278                                                 /* no copy avoiding by now possible with SSA */
279                                                 if (ls != NULL) {
280                                                         emit_mov_membase_reg(   /* + 4 for return address */
281                                                                  cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
282                                                                  REG_ITMP1);    
283                                                         emit_mov_reg_membase(
284                                                                  cd, REG_ITMP1, REG_SP, var->regoff * 4);
285                                                 }
286                                                 else 
287 #endif /*defined(ENABLE_SSA)*/
288                                                                   /* reuse Stackslotand avoid copying */
289                                                         var->regoff = cd->stackframesize + s1 + 1;
290
291                                         } 
292                                         else {
293 #if defined(ENABLE_SSA)
294                                                 /* no copy avoiding by now possible with SSA */
295                                                 if (ls != NULL) {
296                                                         emit_mov_membase_reg(  /* + 4 for return address */
297                                                                  cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
298                                                                  REG_ITMP1);
299                                                         emit_mov_reg_membase(
300                                                                  cd, REG_ITMP1, REG_SP, var->regoff * 4);
301                                                         emit_mov_membase_reg(   /* + 4 for return address */
302                                                                   cd, REG_SP, (cd->stackframesize + s1) * 4 + 4 + 4,
303                                                                   REG_ITMP1);             
304                                                         emit_mov_reg_membase(
305                                                                  cd, REG_ITMP1, REG_SP, var->regoff * 4 + 4);
306                                                 }
307                                                 else
308 #endif /*defined(ENABLE_SSA)*/
309                                                                   /* reuse Stackslotand avoid copying */
310                                                         var->regoff = cd->stackframesize + s1 + 1;
311                                         }
312                                 }
313                         }
314                 }
315                 else {                                       /* floating args         */
316                         if (!md->params[p].inmemory) {           /* register arguments    */
317                                 log_text("There are no float argument registers!");
318                                 assert(0);
319                                 if (!(var->flags & INMEMORY)) {  /* reg arg -> register   */
320                                         /* rd->argfltregs[md->params[p].regoff -> var->regoff     */
321                                 } else {                                     /* reg arg -> spilled    */
322                                         /* rd->argfltregs[md->params[p].regoff -> var->regoff * 4 */
323                                 }
324
325                         } 
326                         else {                                   /* stack arguments       */
327                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
328                                         if (t == TYPE_FLT) {
329                                                 emit_flds_membase(
330                             cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
331                                                 assert(0);
332 /*                                              emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
333
334                                         } 
335                                         else {
336                                                 emit_fldl_membase(
337                             cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
338                                                 assert(0);
339 /*                                              emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
340                                         }
341
342                                 } else {                             /* stack-arg -> spilled  */
343 #if defined(ENABLE_SSA)
344                                         /* no copy avoiding by now possible with SSA */
345                                         if (ls != NULL) {
346                                                 emit_mov_membase_reg(
347                                                  cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, REG_ITMP1);
348                                                 emit_mov_reg_membase(
349                                                                          cd, REG_ITMP1, REG_SP, var->regoff * 4);
350                                                 if (t == TYPE_FLT) {
351                                                         emit_flds_membase(
352                                                                   cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
353                                                         emit_fstps_membase(cd, REG_SP, var->regoff * 4);
354                                                 } 
355                                                 else {
356                                                         emit_fldl_membase(
357                                                                   cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
358                                                         emit_fstpl_membase(cd, REG_SP, var->regoff * 4);
359                                                 }
360                                         }
361                                         else
362 #endif /*defined(ENABLE_SSA)*/
363                                                                   /* reuse Stackslotand avoid copying */
364                                                 var->regoff = cd->stackframesize + s1 + 1;
365                                 }
366                         }
367                 }
368         }  /* end for */
369
370         /* call monitorenter function */
371
372 #if defined(ENABLE_THREADS)
373         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
374                 s1 = rd->memuse;
375
376                 if (m->flags & ACC_STATIC) {
377                         M_MOV_IMM(&m->class->object.header, REG_ITMP1);
378                 }
379                 else {
380                         M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 4 + 4);
381                         M_TEST(REG_ITMP1);
382                         M_BEQ(0);
383                         codegen_add_nullpointerexception_ref(cd);
384                 }
385
386                 M_AST(REG_ITMP1, REG_SP, s1 * 4);
387                 M_AST(REG_ITMP1, REG_SP, 0 * 4);
388                 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
389                 M_CALL(REG_ITMP3);
390         }                       
391 #endif
392
393 #if !defined(NDEBUG)
394         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
395                 emit_verbosecall_enter(jd);
396 #endif
397
398         } 
399
400 #if defined(ENABLE_SSA)
401         /* with SSA Header is Basic Block 0 - insert phi Moves if necessary */
402         if ( ls != NULL)
403                         codegen_insert_phi_moves(cd, rd, ls, ls->basicblocks[0]);
404 #endif
405
406         /* end of header generation */
407
408         replacementpoint = jd->code->rplpoints;
409
410         /* walk through all basic blocks */
411         for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
412
413                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
414
415                 if (bptr->flags >= BBREACHED) {
416
417                 /* branch resolving */
418
419                 branchref *brefs;
420                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
421                         gen_resolvebranch(cd->mcodebase + brefs->branchpos, 
422                                           brefs->branchpos,
423                                                           bptr->mpc);
424                 }
425
426 #if 0
427                 /* handle replacement points */
428
429                 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
430                         replacementpoint->pc = (u1*)bptr->mpc; /* will be resolved later */
431                         
432                         replacementpoint++;
433
434                         assert(cd->lastmcodeptr <= cd->mcodeptr);
435                         cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
436                 }
437 #endif
438
439                 /* copy interface registers to their destination */
440
441                 len = bptr->indepth;
442                 MCODECHECK(512);
443
444 #if 0
445                 /* generate basic block profiling code */
446
447                 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
448                         /* count frequency */
449
450                         M_MOV_IMM(code->bbfrequency, REG_ITMP3);
451                         M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
452                 }
453 #endif
454
455 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
456 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
457                 if (opt_lsra) {
458 # endif
459 # if defined(ENABLE_SSA)
460                 if (ls != NULL) {
461                         last_cmd_was_goto = false;
462 # endif
463                         if (len > 0) {
464                                 len--;
465                                 src = bptr->invars[len];
466                                 if (bptr->type != BBTYPE_STD) {
467                                         if (!IS_2_WORD_TYPE(src->type)) {
468                                                 if (bptr->type == BBTYPE_SBR) {
469                                                         if (!(src->flags & INMEMORY))
470                                                                 d = src->regoff;
471                                                         else
472                                                                 d = REG_ITMP1;
473                                                         emit_pop_reg(cd, d);
474                                                         emit_store(jd, NULL, src, d);
475                                                 } else if (bptr->type == BBTYPE_EXH) {
476                                                         if (!(src->flags & INMEMORY))
477                                                                 d = src->regoff;
478                                                         else
479                                                                 d = REG_ITMP1;
480                                                         M_INTMOVE(REG_ITMP1, d);
481                                                         emit_store(jd, NULL, src, d);
482                                                 }
483
484                                         } else {
485                                                 log_text("copy interface registers(EXH, SBR): longs have to be in memory (begin 1)");
486                                                 assert(0);
487                                         }
488                                 }
489                         }
490
491                 } else
492 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
493                 {
494                 while (len) {
495                         len--;
496                         varindex = bptr->invars[len];
497                         var = &(jd->var[varindex]);
498                         if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
499                                 if (!IS_2_WORD_TYPE(var->type)) {
500                                         if (bptr->type == BBTYPE_SBR) {
501                                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
502                                                 emit_pop_reg(cd, d);
503                                                 emit_store(jd, NULL, var, d);
504
505                                         } else if (bptr->type == BBTYPE_EXH) {
506                                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
507                                                 M_INTMOVE(REG_ITMP1, d);
508                                                 emit_store(jd, NULL, var, d);
509                                         }
510                                 } else {
511                                         log_text("copy interface registers: longs have to be in \
512                                memory (begin 1)");
513                                         assert(0);
514                                 }
515
516                         } else {
517                                 printf("block %i var %i\n",bptr->nr, varindex);
518                                 assert((var->flags & OUTVAR));
519                                 /* will be done directly in simplereg lateron          */ 
520                                 /* for now codegen_reg_of_var has to be called here to */
521                                 /* set the regoff and flags for all bptr->invars[]     */
522                                 d = codegen_reg_of_var(0, var, REG_ITMP1);
523
524                         }
525                 }
526                 }
527
528                 /* walk through all instructions */
529                 
530                 len = bptr->icount;
531                 currentline = 0;
532
533                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
534                         if (iptr->line != currentline) {
535                                 dseg_addlinenumber(cd, iptr->line);
536                                 currentline = iptr->line;
537                         }
538
539                         MCODECHECK(1024);                         /* 1kB should be enough */
540
541                 switch (iptr->opc) {
542                 case ICMD_INLINE_START:
543 #if 0
544                         {
545                                 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
546 #if defined(ENABLE_THREADS)
547                                 if (insinfo->synchronize) {
548                                         /* add monitor enter code */
549                                         if (insinfo->method->flags & ACC_STATIC) {
550                                                 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
551                                                 M_AST(REG_ITMP1, REG_SP, 0 * 4);
552                                         } 
553                                         else {
554                                                 /* nullpointer check must have been performed before */
555                                                 /* (XXX not done, yet) */
556                                                 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
557                                                 if (var->flags & INMEMORY) {
558                                                         emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP1);
559                                                         M_AST(REG_ITMP1, REG_SP, 0 * 4);
560                                                 } 
561                                                 else {
562                                                         M_AST(var->regoff, REG_SP, 0 * 4);
563                                                 }
564                                         }
565
566                                         M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
567                                         M_CALL(REG_ITMP3);
568                                 }
569 #endif
570                                 dseg_addlinenumber_inline_start(cd, iptr);
571                         }
572 #endif
573                         break;
574
575                 case ICMD_INLINE_END:
576 #if 0
577                         {
578                                 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
579
580                                 dseg_addlinenumber_inline_end(cd, iptr);
581                                 dseg_addlinenumber(cd, iptr->line);
582
583 #if defined(ENABLE_THREADS)
584                                 if (insinfo->synchronize) {
585                                         /* add monitor exit code */
586                                         if (insinfo->method->flags & ACC_STATIC) {
587                                                 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
588                                                 M_AST(REG_ITMP1, REG_SP, 0 * 4);
589                                         } 
590                                         else {
591                                                 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
592                                                 if (var->flags & INMEMORY) {
593                                                         M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
594                                                         M_AST(REG_ITMP1, REG_SP, 0 * 4);
595                                                 } 
596                                                 else {
597                                                         M_AST(var->regoff, REG_SP, 0 * 4);
598                                                 }
599                                         }
600
601                                         M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
602                                         M_CALL(REG_ITMP3);
603                                 }
604 #endif
605                         }
606 #endif
607                         break;
608
609                 case ICMD_NOP:        /* ...  ==> ...                                 */
610                         break;
611
612                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
613
614                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
615                         M_TEST(s1);
616                         M_BEQ(0);
617                         codegen_add_nullpointerexception_ref(cd);
618                         break;
619
620                 /* constant operations ************************************************/
621
622                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
623
624                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
625                         ICONST(d, iptr->sx.val.i);
626                         emit_store_dst(jd, iptr, d);
627                         break;
628
629                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
630
631                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
632                         LCONST(d, iptr->sx.val.l);
633                         emit_store_dst(jd, iptr, d);
634                         break;
635
636                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
637
638                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
639                         if (iptr->sx.val.f == 0.0) {
640                                 emit_fldz(cd);
641
642                                 /* -0.0 */
643                                 if (iptr->sx.val.i == 0x80000000) {
644                                         emit_fchs(cd);
645                                 }
646
647                         } else if (iptr->sx.val.f == 1.0) {
648                                 emit_fld1(cd);
649
650                         } else if (iptr->sx.val.f == 2.0) {
651                                 emit_fld1(cd);
652                                 emit_fld1(cd);
653                                 emit_faddp(cd);
654
655                         } else {
656                                 disp = dseg_addfloat(cd, iptr->sx.val.f);
657                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
658                                 dseg_adddata(cd);
659                                 emit_flds_membase(cd, REG_ITMP1, disp);
660                         }
661                         emit_store_dst(jd, iptr, d);
662                         break;
663                 
664                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
665
666                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
667                         if (iptr->sx.val.d == 0.0) {
668                                 emit_fldz(cd);
669
670                                 /* -0.0 */
671                                 if (iptr->sx.val.l == 0x8000000000000000LL) {
672                                         emit_fchs(cd);
673                                 }
674
675                         } else if (iptr->sx.val.d == 1.0) {
676                                 emit_fld1(cd);
677
678                         } else if (iptr->sx.val.d == 2.0) {
679                                 emit_fld1(cd);
680                                 emit_fld1(cd);
681                                 emit_faddp(cd);
682
683                         } else {
684                                 disp = dseg_adddouble(cd, iptr->sx.val.d);
685                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
686                                 dseg_adddata(cd);
687                                 emit_fldl_membase(cd, REG_ITMP1, disp);
688                         }
689                         emit_store_dst(jd, iptr, d);
690                         break;
691
692                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
693
694                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
695
696                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
697                                 codegen_addpatchref(cd, PATCHER_aconst,
698                                                                         iptr->sx.val.c.ref, 0);
699
700                                 if (opt_showdisassemble) {
701                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
702                                 }
703
704                                 M_MOV_IMM(NULL, d);
705
706                         } else {
707                                 if (iptr->sx.val.anyptr == NULL)
708                                         M_CLR(d);
709                                 else
710                                         M_MOV_IMM(iptr->sx.val.anyptr, d);
711                         }
712                         emit_store_dst(jd, iptr, d);
713                         break;
714
715
716                 /* load/store operations **********************************************/
717
718                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
719                 case ICMD_ALOAD:      /* op1 = local variable                         */
720
721                         if ( iptr->dst.varindex == iptr->s1.varindex)
722                                 break;
723
724                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
725
726                         s1 = emit_load_s1(jd, iptr, d);
727                         M_INTMOVE(s1, d);
728                         emit_store_dst(jd, iptr, d);
729
730                         break;
731
732                 case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
733                                       /* s1.localindex = local variable                         */
734   
735                         if ( iptr->dst.varindex == iptr->s1.varindex)
736                                 break;
737
738                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
739
740                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
741                         M_INTMOVE(s1, d);
742                         emit_store_dst(jd, iptr, d);
743
744                         break;
745
746                 case ICMD_FLOAD:      
747                 case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
748                                       /* s1.localindex = local variable               */
749
750                         if ( iptr->dst.varindex == iptr->s1.varindex)
751                                 break;
752                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
753
754                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
755                         M_FLTMOVE(s1, d);
756                         emit_store_dst(jd, iptr, d);
757
758                         break;
759
760
761                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
762                 case ICMD_ASTORE:     /* op1 = local variable                         */
763
764                         if ( iptr->s1.varindex == iptr->dst.varindex)
765                                 break;
766                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
767
768                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
769
770                         M_INTMOVE(s1,d);
771                         emit_store_dst(jd, iptr, d);
772
773                         break;
774
775                 case ICMD_LSTORE:     /* ..., value  ==> ...                          */
776                                       /* dst.localindex = local variable              */
777
778                         if ( iptr->dst.varindex == iptr->dst.varindex)
779                                 break;
780
781                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
782
783                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
784                         M_INTMOVE(s1,d);
785                         emit_store_dst(jd, iptr, d);
786
787                         break;
788
789                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
790                                       /* dst.localindex = local variable              */
791
792                         if ( iptr->dst.varindex == iptr->s1.varindex)
793                                 break;
794                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
795
796                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
797                         M_FLTMOVE(s1, d);
798                         emit_store_dst(jd, iptr, d);
799
800                         break;
801
802                 case ICMD_DSTORE:     /* ..., value  ==> ...                          */
803                                       /* dst.localindex = local variable              */
804
805                         if ( iptr->dst.varindex == iptr->s1.varindex)
806                                 break;
807                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
808
809                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
810                         M_FLTMOVE(s1, d);
811                         emit_store_dst(jd, iptr, d);
812
813                         break;
814
815
816                 /* pop/dup/swap operations ********************************************/
817
818                 /* attention: double and longs are only one entry in CACAO ICMDs      */
819
820                 case ICMD_POP:        /* ..., value  ==> ...                          */
821                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
822                         break;
823
824                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
825
826                         M_COPY(iptr->s1.varindex, iptr->dst.varindex);
827                         break;
828
829                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
830
831                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+2]);
832                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+1]);
833                         M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
834                         break;
835
836                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
837
838                         M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[3+3]);
839                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[3+2]);
840                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[3+1]);
841                         M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
842                         break;
843
844                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
845
846                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+1]);
847                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+0]);
848                         break;
849
850                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
851
852                         M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[3+4]);
853                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[3+3]);
854                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[3+2]);
855                         M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
856                         M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
857                         break;
858
859                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
860
861                         M_COPY(iptr->dst.dupslots[  3], iptr->dst.dupslots[4+5]);
862                         M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[4+4]);
863                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[4+3]);
864                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[4+2]);
865                         M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
866                         M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
867                         break;
868
869                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
870
871                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+0]);
872                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+1]);
873                         break;
874
875
876 #if 0
877                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
878
879                         M_COPY(src,       iptr->dst);
880                         M_COPY(src->prev, iptr->dst->prev);
881 #if defined(ENABLE_SSA)
882                         if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
883                                 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
884 #endif
885                                 M_COPY(iptr->dst, iptr->dst->prev->prev);
886 #if defined(ENABLE_SSA)
887                         } else {
888                                 M_COPY(src, iptr->dst->prev->prev);
889                         }
890 #endif
891                         break;
892
893                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
894
895                         M_COPY(src,             iptr->dst);
896                         M_COPY(src->prev,       iptr->dst->prev);
897                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
898 #if defined(ENABLE_SSA)
899                         if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
900                                 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
901 #endif
902                                 M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
903 #if defined(ENABLE_SSA)
904                         } else {
905                                 M_COPY(src, iptr->dst->prev->prev->prev);
906                         }
907 #endif
908                         break;
909 #endif
910
911                 /* integer operations *************************************************/
912
913                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
914
915                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
916                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
917                         M_INTMOVE(s1, d);
918                         M_NEG(d);
919                         emit_store_dst(jd, iptr, d);
920                         break;
921
922                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
923
924                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
925                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
926                         M_LNGMOVE(s1, d);
927                         M_NEG(GET_LOW_REG(d));
928                         M_IADDC_IMM(0, GET_HIGH_REG(d));
929                         M_NEG(GET_HIGH_REG(d));
930                         emit_store_dst(jd, iptr, d);
931                         break;
932
933                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
934
935                         s1 = emit_load_s1(jd, iptr, EAX);
936                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
937                         M_INTMOVE(s1, EAX);
938                         M_CLTD;
939                         M_LNGMOVE(EAX_EDX_PACKED, d);
940                         emit_store_dst(jd, iptr, d);
941                         break;
942
943                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
944
945                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
946                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
947                         M_INTMOVE(s1, d);
948                         emit_store_dst(jd, iptr, d);
949                         break;
950
951                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
952
953                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
954                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
955                         M_INTMOVE(s1, d);
956                         M_SLL_IMM(24, d);
957                         M_SRA_IMM(24, d);
958                         emit_store_dst(jd, iptr, d);
959                         break;
960
961                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
962
963                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
964                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
965                         M_CZEXT(s1, d);
966                         emit_store_dst(jd, iptr, d);
967                         break;
968
969                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
970
971                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
972                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
973                         M_SSEXT(s1, d);
974                         emit_store_dst(jd, iptr, d);
975                         break;
976
977
978                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
979
980                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
981                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
982                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
983                         if (s2 == d)
984                                 M_IADD(s1, d);
985                         else {
986                                 M_INTMOVE(s1, d);
987                                 M_IADD(s2, d);
988                         }
989                         emit_store_dst(jd, iptr, d);
990                         break;
991
992                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
993                                       /* sx.val.i = constant                          */
994
995                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
996                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
997                         M_INTMOVE(s1, d);
998                         M_IADD_IMM(iptr->sx.val.i, d);
999                         emit_store_dst(jd, iptr, d);
1000                         break;
1001
1002                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1003
1004                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1005                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1006                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1007                         M_INTMOVE(s1, GET_LOW_REG(d));
1008                         M_IADD(s2, GET_LOW_REG(d));
1009                         /* don't use REG_ITMP1 */
1010                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1011                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1012                         M_INTMOVE(s1, GET_HIGH_REG(d));
1013                         M_IADDC(s2, GET_HIGH_REG(d));
1014                         emit_store_dst(jd, iptr, d);
1015                         break;
1016
1017                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
1018                                       /* sx.val.l = constant                          */
1019
1020                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1021                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1022                         M_LNGMOVE(s1, d);
1023                         M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1024                         M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1025                         emit_store_dst(jd, iptr, d);
1026                         break;
1027
1028                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1029
1030                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1031                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1032                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1033                         if (s2 == d) {
1034                                 M_INTMOVE(s1, REG_ITMP1);
1035                                 M_ISUB(s2, REG_ITMP1);
1036                                 M_INTMOVE(REG_ITMP1, d);
1037                         }
1038                         else {
1039                                 M_INTMOVE(s1, d);
1040                                 M_ISUB(s2, d);
1041                         }
1042                         emit_store_dst(jd, iptr, d);
1043                         break;
1044
1045                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
1046                                       /* sx.val.i = constant                             */
1047
1048                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1050                         M_INTMOVE(s1, d);
1051                         M_ISUB_IMM(iptr->sx.val.i, d);
1052                         emit_store_dst(jd, iptr, d);
1053                         break;
1054
1055                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1056
1057                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1058                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1059                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1060                         if (s2 == GET_LOW_REG(d)) {
1061                                 M_INTMOVE(s1, REG_ITMP1);
1062                                 M_ISUB(s2, REG_ITMP1);
1063                                 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
1064                         }
1065                         else {
1066                                 M_INTMOVE(s1, GET_LOW_REG(d));
1067                                 M_ISUB(s2, GET_LOW_REG(d));
1068                         }
1069                         /* don't use REG_ITMP1 */
1070                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1071                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1072                         if (s2 == GET_HIGH_REG(d)) {
1073                                 M_INTMOVE(s1, REG_ITMP2);
1074                                 M_ISUBB(s2, REG_ITMP2);
1075                                 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
1076                         }
1077                         else {
1078                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1079                                 M_ISUBB(s2, GET_HIGH_REG(d));
1080                         }
1081                         emit_store_dst(jd, iptr, d);
1082                         break;
1083
1084                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
1085                                       /* sx.val.l = constant                          */
1086
1087                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1088                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1089                         M_LNGMOVE(s1, d);
1090                         M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1091                         M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1092                         emit_store_dst(jd, iptr, d);
1093                         break;
1094
1095                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1096
1097                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1098                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1099                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1100                         if (s2 == d)
1101                                 M_IMUL(s1, d);
1102                         else {
1103                                 M_INTMOVE(s1, d);
1104                                 M_IMUL(s2, d);
1105                         }
1106                         emit_store_dst(jd, iptr, d);
1107                         break;
1108
1109                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
1110                                       /* sx.val.i = constant                          */
1111
1112                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1113                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1114                         M_IMUL_IMM(s1, iptr->sx.val.i, d);
1115                         emit_store_dst(jd, iptr, d);
1116                         break;
1117
1118                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1119
1120                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1121                         s2 = emit_load_s2_low(jd, iptr, EDX);
1122                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
1123
1124                         M_INTMOVE(s1, REG_ITMP2);
1125                         M_IMUL(s2, REG_ITMP2);
1126
1127                         s1 = emit_load_s1_low(jd, iptr, EAX);
1128                         s2 = emit_load_s2_high(jd, iptr, EDX);
1129                         M_INTMOVE(s2, EDX);
1130                         M_IMUL(s1, EDX);
1131                         M_IADD(EDX, REG_ITMP2);
1132
1133                         s1 = emit_load_s1_low(jd, iptr, EAX);
1134                         s2 = emit_load_s2_low(jd, iptr, EDX);
1135                         M_INTMOVE(s1, EAX);
1136                         M_MUL(s2);
1137                         M_INTMOVE(EAX, GET_LOW_REG(d));
1138                         M_IADD(REG_ITMP2, GET_HIGH_REG(d));
1139
1140                         emit_store_dst(jd, iptr, d);
1141                         break;
1142
1143                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
1144                                       /* sx.val.l = constant                          */
1145
1146                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1147                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
1148                         ICONST(EAX, iptr->sx.val.l);
1149                         M_MUL(s1);
1150                         M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
1151                         M_IADD(REG_ITMP2, EDX);
1152                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1153                         M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
1154                         M_IADD(REG_ITMP2, EDX);
1155                         M_LNGMOVE(EAX_EDX_PACKED, d);
1156                         emit_store_dst(jd, iptr, d);
1157                         break;
1158
1159                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1160
1161                         s1 = emit_load_s1(jd, iptr, EAX);
1162                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1163                         d = codegen_reg_of_dst(jd, iptr, EAX);
1164
1165                         if (checknull) {
1166                                 M_TEST(s2);
1167                                 M_BEQ(0);
1168                                 codegen_add_arithmeticexception_ref(cd);
1169                         }
1170
1171                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
1172
1173                         /* check as described in jvm spec */
1174
1175                         M_CMP_IMM(0x80000000, EAX);
1176                         M_BNE(3 + 6);
1177                         M_CMP_IMM(-1, s2);
1178                         M_BEQ(1 + 2);
1179                         M_CLTD;
1180                         M_IDIV(s2);
1181
1182                         M_INTMOVE(EAX, d);           /* if INMEMORY then d is already EAX */
1183                         emit_store_dst(jd, iptr, d);
1184                         break;
1185
1186                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1187
1188                         s1 = emit_load_s1(jd, iptr, EAX);
1189                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1190                         d = codegen_reg_of_dst(jd, iptr, EDX);
1191
1192                         if (checknull) {
1193                                 M_TEST(s2);
1194                                 M_BEQ(0);
1195                                 codegen_add_arithmeticexception_ref(cd);
1196                         }
1197
1198                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
1199
1200                         /* check as described in jvm spec */
1201
1202                         M_CMP_IMM(0x80000000, EAX);
1203                         M_BNE(2 + 3 + 6);
1204                         M_CLR(EDX);
1205                         M_CMP_IMM(-1, s2);
1206                         M_BEQ(1 + 2);
1207                         M_CLTD;
1208                         M_IDIV(s2);
1209
1210                         M_INTMOVE(EDX, d);           /* if INMEMORY then d is already EDX */
1211                         emit_store_dst(jd, iptr, d);
1212                         break;
1213
1214                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
1215                                       /* sx.val.i = constant                          */
1216
1217                         /* TODO: optimize for `/ 2' */
1218                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1219                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1220                         M_INTMOVE(s1, d);
1221                         M_TEST(d);
1222                         M_BNS(6);
1223                         M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d);/* 32-bit for jump off */
1224                         M_SRA_IMM(iptr->sx.val.i, d);
1225                         emit_store_dst(jd, iptr, d);
1226                         break;
1227
1228                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1229                                       /* sx.val.i = constant                          */
1230
1231                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1232                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1233                         if (s1 == d) {
1234                                 M_MOV(s1, REG_ITMP1);
1235                                 s1 = REG_ITMP1;
1236                         } 
1237                         M_INTMOVE(s1, d);
1238                         M_AND_IMM(iptr->sx.val.i, d);
1239                         M_TEST(s1);
1240                         M_BGE(2 + 2 + 6 + 2);
1241                         M_MOV(s1, d);  /* don't use M_INTMOVE, so we know the jump offset */
1242                         M_NEG(d);
1243                         M_AND_IMM32(iptr->sx.val.i, d);     /* use 32-bit for jump offset */
1244                         M_NEG(d);
1245                         emit_store_dst(jd, iptr, d);
1246                         break;
1247
1248                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1249                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1250
1251                         s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
1252                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1253
1254                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
1255                         M_OR(GET_HIGH_REG(s2), REG_ITMP3);
1256                         M_BEQ(0);
1257                         codegen_add_arithmeticexception_ref(cd);
1258
1259                         bte = iptr->sx.s23.s3.bte;
1260                         md = bte->md;
1261
1262                         M_LST(s2, REG_SP, 2 * 4);
1263
1264                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1265                         M_LST(s1, REG_SP, 0 * 4);
1266
1267                         M_MOV_IMM(bte->fp, REG_ITMP3);
1268                         M_CALL(REG_ITMP3);
1269                         emit_store_dst(jd, iptr, d);
1270                         break;
1271
1272                 case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
1273                                       /* sx.val.i = constant                          */
1274
1275                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1276                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1277                         M_LNGMOVE(s1, d);
1278                         M_TEST(GET_HIGH_REG(d));
1279                         M_BNS(6 + 3);
1280                         M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
1281                         M_IADDC_IMM(0, GET_HIGH_REG(d));
1282                         M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
1283                         M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
1284                         emit_store_dst(jd, iptr, d);
1285                         break;
1286
1287 #if 0
1288                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1289                                       /* sx.val.l = constant                          */
1290
1291                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1292                         if (iptr->dst.var->flags & INMEMORY) {
1293                                 if (iptr->s1.var->flags & INMEMORY) {
1294                                         /* Alpha algorithm */
1295                                         disp = 3;
1296                                         CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
1297                                         disp += 3;
1298                                         CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4 + 4);
1299
1300                                         disp += 2;
1301                                         disp += 3;
1302                                         disp += 2;
1303
1304                                         /* TODO: hmm, don't know if this is always correct */
1305                                         disp += 2;
1306                                         CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
1307                                         disp += 2;
1308                                         CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
1309
1310                                         disp += 2;
1311                                         disp += 3;
1312                                         disp += 2;
1313
1314                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
1315                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
1316                                         
1317                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1318                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1319                                         emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->regoff * 4 + 4);
1320                                         emit_jcc(cd, CC_GE, disp);
1321
1322                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
1323                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
1324                                         
1325                                         emit_neg_reg(cd, REG_ITMP1);
1326                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1327                                         emit_neg_reg(cd, REG_ITMP2);
1328                                         
1329                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1330                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1331                                         
1332                                         emit_neg_reg(cd, REG_ITMP1);
1333                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1334                                         emit_neg_reg(cd, REG_ITMP2);
1335
1336                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->regoff * 4);
1337                                         emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->regoff * 4 + 4);
1338                                 }
1339                         }
1340
1341                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1342                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1343                         M_LNGMOVE(s1, d);
1344                         M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));      
1345                         M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1346                         M_TEST(GET_LOW_REG(s1));
1347                         M_BGE(0);
1348                         M_LNGMOVE(s1, d);
1349                 break;
1350 #endif
1351
1352                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1353
1354                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1355                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1356                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1357                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
1358                         M_INTMOVE(s1, d);
1359                         M_SLL(d);
1360                         emit_store_dst(jd, iptr, d);
1361                         break;
1362
1363                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1364                                       /* sx.val.i = constant                          */
1365
1366                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1367                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1368                         M_INTMOVE(s1, d);
1369                         M_SLL_IMM(iptr->sx.val.i, d);
1370                         emit_store_dst(jd, iptr, d);
1371                         break;
1372
1373                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1374
1375                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1376                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1377                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1378                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
1379                         M_INTMOVE(s1, d);
1380                         M_SRA(d);
1381                         emit_store_dst(jd, iptr, d);
1382                         break;
1383
1384                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1385                                       /* sx.val.i = constant                          */
1386
1387                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1388                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1389                         M_INTMOVE(s1, d);
1390                         M_SRA_IMM(iptr->sx.val.i, d);
1391                         emit_store_dst(jd, iptr, d);
1392                         break;
1393
1394                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1395
1396                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1397                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1398                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1399                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
1400                         M_INTMOVE(s1, d);
1401                         M_SRL(d);
1402                         emit_store_dst(jd, iptr, d);
1403                         break;
1404
1405                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1406                                       /* sx.val.i = constant                          */
1407
1408                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1409                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1410                         M_INTMOVE(s1, d);
1411                         M_SRL_IMM(iptr->sx.val.i, d);
1412                         emit_store_dst(jd, iptr, d);
1413                         break;
1414
1415                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1416
1417                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1418                         s2 = emit_load_s2(jd, iptr, ECX);
1419                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1420                         M_LNGMOVE(s1, d);
1421                         M_INTMOVE(s2, ECX);
1422                         M_TEST_IMM(32, ECX);
1423                         M_BEQ(2 + 2);
1424                         M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1425                         M_CLR(GET_LOW_REG(d));
1426                         M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
1427                         M_SLL(GET_LOW_REG(d));
1428                         emit_store_dst(jd, iptr, d);
1429                         break;
1430
1431         case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1432                                           /* sx.val.i = constant                          */
1433
1434                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1435                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1436                         M_LNGMOVE(s1, d);
1437                         if (iptr->sx.val.i & 0x20) {
1438                                 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1439                                 M_CLR(GET_LOW_REG(d));
1440                                 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), 
1441                                                    GET_HIGH_REG(d));
1442                         }
1443                         else {
1444                                 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
1445                                                    GET_HIGH_REG(d));
1446                                 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
1447                         }
1448                         emit_store_dst(jd, iptr, d);
1449                         break;
1450
1451                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1452
1453                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1454                         s2 = emit_load_s2(jd, iptr, ECX);
1455                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1456                         M_LNGMOVE(s1, d);
1457                         M_INTMOVE(s2, ECX);
1458                         M_TEST_IMM(32, ECX);
1459                         M_BEQ(2 + 3);
1460                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1461                         M_SRA_IMM(31, GET_HIGH_REG(d));
1462                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1463                         M_SRA(GET_HIGH_REG(d));
1464                         emit_store_dst(jd, iptr, d);
1465                         break;
1466
1467                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1468                                       /* sx.val.i = constant                          */
1469
1470                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1471                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1472                         M_LNGMOVE(s1, d);
1473                         if (iptr->sx.val.i & 0x20) {
1474                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1475                                 M_SRA_IMM(31, GET_HIGH_REG(d));
1476                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
1477                                                    GET_LOW_REG(d));
1478                         }
1479                         else {
1480                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
1481                                                    GET_LOW_REG(d));
1482                                 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1483                         }
1484                         emit_store_dst(jd, iptr, d);
1485                         break;
1486
1487                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1488
1489                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1490                         s2 = emit_load_s2(jd, iptr, ECX);
1491                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1492                         M_LNGMOVE(s1, d);
1493                         M_INTMOVE(s2, ECX);
1494                         M_TEST_IMM(32, ECX);
1495                         M_BEQ(2 + 2);
1496                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1497                         M_CLR(GET_HIGH_REG(d));
1498                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1499                         M_SRL(GET_HIGH_REG(d));
1500                         emit_store_dst(jd, iptr, d);
1501                         break;
1502
1503                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1504                                       /* sx.val.l = constant                          */
1505
1506                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1507                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1508                         M_LNGMOVE(s1, d);
1509                         if (iptr->sx.val.i & 0x20) {
1510                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1511                                 M_CLR(GET_HIGH_REG(d));
1512                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
1513                                                    GET_LOW_REG(d));
1514                         }
1515                         else {
1516                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
1517                                                    GET_LOW_REG(d));
1518                                 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1519                         }
1520                         emit_store_dst(jd, iptr, d);
1521                         break;
1522
1523                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1524
1525                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1526                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1527                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1528                         if (s2 == d)
1529                                 M_AND(s1, d);
1530                         else {
1531                                 M_INTMOVE(s1, d);
1532                                 M_AND(s2, d);
1533                         }
1534                         emit_store_dst(jd, iptr, d);
1535                         break;
1536
1537                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1538                                       /* sx.val.i = constant                          */
1539
1540                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1541                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1542                         M_INTMOVE(s1, d);
1543                         M_AND_IMM(iptr->sx.val.i, d);
1544                         emit_store_dst(jd, iptr, d);
1545                         break;
1546
1547                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1548
1549                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1550                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1551                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1552                         if (s2 == GET_LOW_REG(d))
1553                                 M_AND(s1, GET_LOW_REG(d));
1554                         else {
1555                                 M_INTMOVE(s1, GET_LOW_REG(d));
1556                                 M_AND(s2, GET_LOW_REG(d));
1557                         }
1558                         /* REG_ITMP1 probably contains low 32-bit of destination */
1559                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1560                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1561                         if (s2 == GET_HIGH_REG(d))
1562                                 M_AND(s1, GET_HIGH_REG(d));
1563                         else {
1564                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1565                                 M_AND(s2, GET_HIGH_REG(d));
1566                         }
1567                         emit_store_dst(jd, iptr, d);
1568                         break;
1569
1570                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1571                                       /* sx.val.l = constant                          */
1572
1573                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1574                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1575                         M_LNGMOVE(s1, d);
1576                         M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1577                         M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1578                         emit_store_dst(jd, iptr, d);
1579                         break;
1580
1581                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1582
1583                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1584                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1585                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1586                         if (s2 == d)
1587                                 M_OR(s1, d);
1588                         else {
1589                                 M_INTMOVE(s1, d);
1590                                 M_OR(s2, d);
1591                         }
1592                         emit_store_dst(jd, iptr, d);
1593                         break;
1594
1595                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1596                                       /* sx.val.i = constant                          */
1597
1598                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1599                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1600                         M_INTMOVE(s1, d);
1601                         M_OR_IMM(iptr->sx.val.i, d);
1602                         emit_store_dst(jd, iptr, d);
1603                         break;
1604
1605                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1606
1607                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1608                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1609                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1610                         if (s2 == GET_LOW_REG(d))
1611                                 M_OR(s1, GET_LOW_REG(d));
1612                         else {
1613                                 M_INTMOVE(s1, GET_LOW_REG(d));
1614                                 M_OR(s2, GET_LOW_REG(d));
1615                         }
1616                         /* REG_ITMP1 probably contains low 32-bit of destination */
1617                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1618                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1619                         if (s2 == GET_HIGH_REG(d))
1620                                 M_OR(s1, GET_HIGH_REG(d));
1621                         else {
1622                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1623                                 M_OR(s2, GET_HIGH_REG(d));
1624                         }
1625                         emit_store_dst(jd, iptr, d);
1626                         break;
1627
1628                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1629                                       /* sx.val.l = constant                          */
1630
1631                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1632                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1633                         M_LNGMOVE(s1, d);
1634                         M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1635                         M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1636                         emit_store_dst(jd, iptr, d);
1637                         break;
1638
1639                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1640
1641                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1642                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1643                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1644                         if (s2 == d)
1645                                 M_XOR(s1, d);
1646                         else {
1647                                 M_INTMOVE(s1, d);
1648                                 M_XOR(s2, d);
1649                         }
1650                         emit_store_dst(jd, iptr, d);
1651                         break;
1652
1653                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1654                                       /* sx.val.i = constant                          */
1655
1656                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1657                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1658                         M_INTMOVE(s1, d);
1659                         M_XOR_IMM(iptr->sx.val.i, d);
1660                         emit_store_dst(jd, iptr, d);
1661                         break;
1662
1663                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1664
1665                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1666                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1667                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1668                         if (s2 == GET_LOW_REG(d))
1669                                 M_XOR(s1, GET_LOW_REG(d));
1670                         else {
1671                                 M_INTMOVE(s1, GET_LOW_REG(d));
1672                                 M_XOR(s2, GET_LOW_REG(d));
1673                         }
1674                         /* REG_ITMP1 probably contains low 32-bit of destination */
1675                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1676                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1677                         if (s2 == GET_HIGH_REG(d))
1678                                 M_XOR(s1, GET_HIGH_REG(d));
1679                         else {
1680                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1681                                 M_XOR(s2, GET_HIGH_REG(d));
1682                         }
1683                         emit_store_dst(jd, iptr, d);
1684                         break;
1685
1686                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1687                                       /* sx.val.l = constant                          */
1688
1689                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1690                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1691                         M_LNGMOVE(s1, d);
1692                         M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1693                         M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1694                         emit_store_dst(jd, iptr, d);
1695                         break;
1696
1697                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
1698                                       /* s1.localindex = variable, sx.val.i = constant*/
1699
1700                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1701                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1702                                 
1703                         /* `inc reg' is slower on p4's (regarding to ia32
1704                            optimization reference manual and benchmarks) and as
1705                            fast on athlon's. */
1706
1707                         M_INTMOVE(s1, d);
1708                         M_IADD_IMM(iptr->sx.val.i, d);
1709
1710                         emit_store_dst(jd, iptr, d);
1711
1712                         break;
1713
1714
1715                 /* floating operations ************************************************/
1716
1717                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1718
1719                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1720                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1721                         emit_fchs(cd);
1722                         emit_store_dst(jd, iptr, d);
1723                         break;
1724
1725                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1726
1727                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1728                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1729                         emit_fchs(cd);
1730                         emit_store_dst(jd, iptr, d);
1731                         break;
1732
1733                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1734
1735                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1736                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1737                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1738                         emit_faddp(cd);
1739                         emit_store_dst(jd, iptr, d);
1740                         break;
1741
1742                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1743
1744                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1745                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1746                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1747                         emit_faddp(cd);
1748                         emit_store_dst(jd, iptr, d);
1749                         break;
1750
1751                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1752
1753                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1754                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1755                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1756                         emit_fsubp(cd);
1757                         emit_store_dst(jd, iptr, d);
1758                         break;
1759
1760                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1761
1762                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1763                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1764                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1765                         emit_fsubp(cd);
1766                         emit_store_dst(jd, iptr, d);
1767                         break;
1768
1769                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1770
1771                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1772                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1773                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1774                         emit_fmulp(cd);
1775                         emit_store_dst(jd, iptr, d);
1776                         break;
1777
1778                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1779
1780                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1781                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1782                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1783                         emit_fmulp(cd);
1784                         emit_store_dst(jd, iptr, d);
1785                         break;
1786
1787                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1788
1789                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1790                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1791                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1792                         emit_fdivp(cd);
1793                         emit_store_dst(jd, iptr, d);
1794                         break;
1795
1796                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1797
1798                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1799                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1800                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1801                         emit_fdivp(cd);
1802                         emit_store_dst(jd, iptr, d);
1803                         break;
1804
1805                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1806
1807                         /* exchanged to skip fxch */
1808                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1809                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1810                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1811 /*                      emit_fxch(cd); */
1812                         emit_fprem(cd);
1813                         emit_wait(cd);
1814                         emit_fnstsw(cd);
1815                         emit_sahf(cd);
1816                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1817                         emit_store_dst(jd, iptr, d);
1818                         emit_ffree_reg(cd, 0);
1819                         emit_fincstp(cd);
1820                         break;
1821
1822                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1823
1824                         /* exchanged to skip fxch */
1825                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1826                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1827                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1828 /*                      emit_fxch(cd); */
1829                         emit_fprem(cd);
1830                         emit_wait(cd);
1831                         emit_fnstsw(cd);
1832                         emit_sahf(cd);
1833                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1834                         emit_store_dst(jd, iptr, d);
1835                         emit_ffree_reg(cd, 0);
1836                         emit_fincstp(cd);
1837                         break;
1838
1839                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1840                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1841
1842                         var = &(jd->var[iptr->s1.varindex]);
1843                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1844
1845                         if (var->flags & INMEMORY) {
1846                                 emit_fildl_membase(cd, REG_SP, var->regoff * 4);
1847                         } else {
1848                                 disp = dseg_adds4(cd, 0);
1849                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1850                                 dseg_adddata(cd);
1851                                 emit_mov_reg_membase(cd, var->regoff, REG_ITMP1, disp);
1852                                 emit_fildl_membase(cd, REG_ITMP1, disp);
1853                         }
1854
1855                         emit_store_dst(jd, iptr, d);
1856                         break;
1857
1858                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
1859                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
1860
1861                         var = &(jd->var[iptr->s1.varindex]);
1862                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1863                         if (var->flags & INMEMORY) {
1864                                 emit_fildll_membase(cd, REG_SP, var->regoff * 4);
1865
1866                         } else {
1867                                 log_text("L2F: longs have to be in memory");
1868                                 assert(0);
1869                         }
1870                         emit_store_dst(jd, iptr, d);
1871                         break;
1872                         
1873                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1874
1875                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1876                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1877
1878                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1879                         dseg_adddata(cd);
1880
1881                         /* Round to zero, 53-bit mode, exception masked */
1882                         disp = dseg_adds4(cd, 0x0e7f);
1883                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1884
1885                         var = &(jd->var[iptr->dst.varindex]);
1886                         var1 = &(jd->var[iptr->s1.varindex]);
1887
1888                         if (var->flags & INMEMORY) {
1889                                 emit_fistpl_membase(cd, REG_SP, var->regoff * 4);
1890
1891                                 /* Round to nearest, 53-bit mode, exceptions masked */
1892                                 disp = dseg_adds4(cd, 0x027f);
1893                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1894
1895                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1896                                                                          REG_SP, var->regoff * 4);
1897
1898                                 disp = 3;
1899                                 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
1900                                 disp += 5 + 2 + 3;
1901                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
1902
1903                         } else {
1904                                 disp = dseg_adds4(cd, 0);
1905                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
1906                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->regoff);
1907
1908                                 /* Round to nearest, 53-bit mode, exceptions masked */
1909                                 disp = dseg_adds4(cd, 0x027f);
1910                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1911
1912                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->regoff);
1913
1914                                 disp = 3;
1915                                 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
1916                                 disp += 5 + 2 + ((REG_RESULT == var->regoff) ? 0 : 2);
1917                         }
1918
1919                         emit_jcc(cd, CC_NE, disp);
1920
1921                         /* XXX: change this when we use registers */
1922                         emit_flds_membase(cd, REG_SP, var1->regoff * 4);
1923                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
1924                         emit_call_reg(cd, REG_ITMP1);
1925
1926                         if (var->flags & INMEMORY) {
1927                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
1928
1929                         } else {
1930                                 M_INTMOVE(REG_RESULT, var->regoff);
1931                         }
1932                         break;
1933
1934                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
1935
1936                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1937                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1938
1939                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1940                         dseg_adddata(cd);
1941
1942                         /* Round to zero, 53-bit mode, exception masked */
1943                         disp = dseg_adds4(cd, 0x0e7f);
1944                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1945
1946                         var  = &(jd->var[iptr->dst.varindex]);
1947                         var1 = &(jd->var[iptr->s1.varindex]);
1948
1949                         if (var->flags & INMEMORY) {
1950                                 emit_fistpl_membase(cd, REG_SP, var->regoff * 4);
1951
1952                                 /* Round to nearest, 53-bit mode, exceptions masked */
1953                                 disp = dseg_adds4(cd, 0x027f);
1954                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1955
1956                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
1957                                                                          REG_SP, var->regoff * 4);
1958
1959                                 disp = 3;
1960                                 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
1961                                 disp += 5 + 2 + 3;
1962                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
1963
1964                         } else {
1965                                 disp = dseg_adds4(cd, 0);
1966                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
1967                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->regoff);
1968
1969                                 /* Round to nearest, 53-bit mode, exceptions masked */
1970                                 disp = dseg_adds4(cd, 0x027f);
1971                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1972
1973                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->regoff);
1974
1975                                 disp = 3;
1976                                 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
1977                                 disp += 5 + 2 + ((REG_RESULT == var->regoff) ? 0 : 2);
1978                         }
1979
1980                         emit_jcc(cd, CC_NE, disp);
1981
1982                         /* XXX: change this when we use registers */
1983                         emit_fldl_membase(cd, REG_SP, var1->regoff * 4);
1984                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
1985                         emit_call_reg(cd, REG_ITMP1);
1986
1987                         if (var->flags & INMEMORY) {
1988                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
1989                         } else {
1990                                 M_INTMOVE(REG_RESULT, var->regoff);
1991                         }
1992                         break;
1993
1994                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
1995
1996                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1997                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1998
1999                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
2000                         dseg_adddata(cd);
2001
2002                         /* Round to zero, 53-bit mode, exception masked */
2003                         disp = dseg_adds4(cd, 0x0e7f);
2004                         emit_fldcw_membase(cd, REG_ITMP1, disp);
2005
2006                         var  = &(jd->var[iptr->dst.varindex]);
2007                         var1 = &(jd->var[iptr->s1.varindex]);
2008
2009                         if (var->flags & INMEMORY) {
2010                                 emit_fistpll_membase(cd, REG_SP, var->regoff * 4);
2011
2012                                 /* Round to nearest, 53-bit mode, exceptions masked */
2013                                 disp = dseg_adds4(cd, 0x027f);
2014                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
2015
2016                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
2017                                                                          REG_SP, var->regoff * 4 + 4);
2018
2019                                 disp = 6 + 4;
2020                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2021                                 disp += 3;
2022                                 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
2023                                 disp += 5 + 2;
2024                                 disp += 3;
2025                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2026                                 disp += 3;
2027                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4 + 4);
2028
2029                                 emit_jcc(cd, CC_NE, disp);
2030
2031                                 emit_alu_imm_membase(cd, ALU_CMP, 0, 
2032                                                                          REG_SP, var->regoff * 4);
2033
2034                                 disp = 3;
2035                                 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
2036                                 disp += 5 + 2 + 3;
2037                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2038
2039                                 emit_jcc(cd, CC_NE, disp);
2040
2041                                 /* XXX: change this when we use registers */
2042                                 emit_flds_membase(cd, REG_SP, var1->regoff * 4);
2043                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
2044                                 emit_call_reg(cd, REG_ITMP1);
2045                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
2046                                 emit_mov_reg_membase(cd, REG_RESULT2, 
2047                                                                          REG_SP, var->regoff * 4 + 4);
2048
2049                         } else {
2050                                 log_text("F2L: longs have to be in memory");
2051                                 assert(0);
2052                         }
2053                         break;
2054
2055                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
2056
2057                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2058                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
2059
2060                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
2061                         dseg_adddata(cd);
2062
2063                         /* Round to zero, 53-bit mode, exception masked */
2064                         disp = dseg_adds4(cd, 0x0e7f);
2065                         emit_fldcw_membase(cd, REG_ITMP1, disp);
2066
2067                         var  = &(jd->var[iptr->dst.varindex]);
2068                         var1 = &(jd->var[iptr->s1.varindex]);
2069
2070                         if (var->flags & INMEMORY) {
2071                                 emit_fistpll_membase(cd, REG_SP, var->regoff * 4);
2072
2073                                 /* Round to nearest, 53-bit mode, exceptions masked */
2074                                 disp = dseg_adds4(cd, 0x027f);
2075                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
2076
2077                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
2078                                                                          REG_SP, var->regoff * 4 + 4);
2079
2080                                 disp = 6 + 4;
2081                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2082                                 disp += 3;
2083                                 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
2084                                 disp += 5 + 2;
2085                                 disp += 3;
2086                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2087                                 disp += 3;
2088                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4 + 4);
2089
2090                                 emit_jcc(cd, CC_NE, disp);
2091
2092                                 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, var->regoff * 4);
2093
2094                                 disp = 3;
2095                                 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
2096                                 disp += 5 + 2 + 3;
2097                                 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2098
2099                                 emit_jcc(cd, CC_NE, disp);
2100
2101                                 /* XXX: change this when we use registers */
2102                                 emit_fldl_membase(cd, REG_SP, var1->regoff * 4);
2103                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
2104                                 emit_call_reg(cd, REG_ITMP1);
2105                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
2106                                 emit_mov_reg_membase(cd, REG_RESULT2, 
2107                                                                          REG_SP, var->regoff * 4 + 4);
2108
2109                         } else {
2110                                 log_text("D2L: longs have to be in memory");
2111                                 assert(0);
2112                         }
2113                         break;
2114
2115                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
2116
2117                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2118                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2119                         /* nothing to do */
2120                         emit_store_dst(jd, iptr, d);
2121                         break;
2122
2123                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
2124
2125                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2126                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2127                         /* nothing to do */
2128                         emit_store_dst(jd, iptr, d);
2129                         break;
2130
2131                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
2132                 case ICMD_DCMPL:
2133
2134                         /* exchanged to skip fxch */
2135                         s2 = emit_load_s1(jd, iptr, REG_FTMP1);
2136                         s1 = emit_load_s2(jd, iptr, REG_FTMP2);
2137                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2138 /*                      emit_fxch(cd); */
2139                         emit_fucompp(cd);
2140                         emit_fnstsw(cd);
2141                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as GT */
2142                         emit_jcc(cd, CC_E, 6);
2143                         emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
2144                         emit_sahf(cd);
2145                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
2146                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2147                         emit_jcc(cd, CC_B, 3 + 5);
2148                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2149                         emit_jmp_imm(cd, 3);
2150                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2151                         emit_store_dst(jd, iptr, d);
2152                         break;
2153
2154                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
2155                 case ICMD_DCMPG:
2156
2157                         /* exchanged to skip fxch */
2158                         s2 = emit_load_s1(jd, iptr, REG_FTMP1);
2159                         s1 = emit_load_s2(jd, iptr, REG_FTMP2);
2160                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2161 /*                      emit_fxch(cd); */
2162                         emit_fucompp(cd);
2163                         emit_fnstsw(cd);
2164                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as LT */
2165                         emit_jcc(cd, CC_E, 3);
2166                         emit_movb_imm_reg(cd, 1, REG_AH);
2167                         emit_sahf(cd);
2168                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
2169                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2170                         emit_jcc(cd, CC_B, 3 + 5);
2171                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2172                         emit_jmp_imm(cd, 3);
2173                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2174                         emit_store_dst(jd, iptr, d);
2175                         break;
2176
2177
2178                 /* memory operations **************************************************/
2179
2180                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
2181
2182                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2183                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2184                         gen_nullptr_check(s1);
2185                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
2186                         emit_store_dst(jd, iptr, d);
2187                         break;
2188
2189                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
2190
2191                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2192                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2193                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2194                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2195                                 gen_nullptr_check(s1);
2196                                 gen_bound_check;
2197                         }
2198                         emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), 
2199                                                                          s1, s2, 0, d);
2200                         emit_store_dst(jd, iptr, d);
2201                         break;
2202
2203                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
2204
2205                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2206                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2207                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2208                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2209                                 gen_nullptr_check(s1);
2210                                 gen_bound_check;
2211                         }
2212                         emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), 
2213                                                                          s1, s2, 1, d);
2214                         emit_store_dst(jd, iptr, d);
2215                         break;                  
2216
2217                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
2218
2219                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2220                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2221                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2222                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2223                                 gen_nullptr_check(s1);
2224                                 gen_bound_check;
2225                         }
2226                         emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), 
2227                                                                          s1, s2, 1, d);
2228                         emit_store_dst(jd, iptr, d);
2229                         break;
2230
2231                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
2232
2233                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2234                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2235                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2236                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2237                                 gen_nullptr_check(s1);
2238                                 gen_bound_check;
2239                         }
2240                         emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), 
2241                                                                   s1, s2, 2, d);
2242                         emit_store_dst(jd, iptr, d);
2243                         break;
2244
2245                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
2246
2247                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2248                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2249                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2250                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2251                                 gen_nullptr_check(s1);
2252                                 gen_bound_check;
2253                         }
2254
2255                         var  = &(jd->var[iptr->dst.varindex]);
2256
2257                         assert(var->flags & INMEMORY);
2258                         emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), 
2259                                                                   s1, s2, 3, REG_ITMP3);
2260                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->regoff * 4);
2261                         emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, 
2262                                                                   s1, s2, 3, REG_ITMP3);
2263                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->regoff * 4 + 4);
2264                         break;
2265
2266                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
2267
2268                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2269                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2270                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2271                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2272                                 gen_nullptr_check(s1);
2273                                 gen_bound_check;
2274                         }
2275                         emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2276                         emit_store_dst(jd, iptr, d);
2277                         break;
2278
2279                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
2280
2281                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2282                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2283                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2284                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2285                                 gen_nullptr_check(s1);
2286                                 gen_bound_check;
2287                         }
2288                         emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2,3);
2289                         emit_store_dst(jd, iptr, d);
2290                         break;
2291
2292                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
2293
2294                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2295                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2296                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2297                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2298                                 gen_nullptr_check(s1);
2299                                 gen_bound_check;
2300                         }
2301                         emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]),
2302                                                                   s1, s2, 2, d);
2303                         emit_store_dst(jd, iptr, d);
2304                         break;
2305
2306
2307                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
2308
2309                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2310                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2311                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2312                                 gen_nullptr_check(s1);
2313                                 gen_bound_check;
2314                         }
2315                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2316                         if (s3 >= EBP) { 
2317                                 /* because EBP, ESI, EDI have no xH and xL nibbles */
2318                                 M_INTMOVE(s3, REG_ITMP3);
2319                                 s3 = REG_ITMP3;
2320                         }
2321                         emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]),
2322                                                                    s1, s2, 0);
2323                         break;
2324
2325                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
2326
2327                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2328                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2329                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2330                                 gen_nullptr_check(s1);
2331                                 gen_bound_check;
2332                         }
2333                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2334                         emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]),
2335                                                                    s1, s2, 1);
2336                         break;
2337
2338                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
2339
2340                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2341                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2342                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2343                                 gen_nullptr_check(s1);
2344                                 gen_bound_check;
2345                         }
2346                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2347                         emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]),
2348                                                                    s1, s2, 1);
2349                         break;
2350
2351                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
2352
2353                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2354                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2355                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2356                                 gen_nullptr_check(s1);
2357                                 gen_bound_check;
2358                         }
2359                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2360                         emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]),
2361                                                                   s1, s2, 2);
2362                         break;
2363
2364                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
2365
2366                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2367                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2368                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2369                                 gen_nullptr_check(s1);
2370                                 gen_bound_check;
2371                         }
2372
2373                         var  = &(jd->var[iptr->sx.s23.s3.varindex]);
2374
2375                         assert(var->flags & INMEMORY);
2376                         emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP3);
2377                         emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0])
2378                                                                   , s1, s2, 3);
2379                         emit_mov_membase_reg(cd, REG_SP, var->regoff * 4 + 4, REG_ITMP3);
2380                         emit_mov_reg_memindex(cd, REG_ITMP3,
2381                                                             OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2382                         break;
2383
2384                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
2385
2386                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2387                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2388                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2389                                 gen_nullptr_check(s1);
2390                                 gen_bound_check;
2391                         }
2392                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2393                         emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2,2);
2394                         break;
2395
2396                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
2397
2398                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2399                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2400                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2401                                 gen_nullptr_check(s1);
2402                                 gen_bound_check;
2403                         }
2404                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2405                         emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]),
2406                                                                 s1, s2, 3);
2407                         break;
2408
2409                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
2410
2411                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2412                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2413                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2414                                 gen_nullptr_check(s1);
2415                                 gen_bound_check;
2416                         }
2417                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2418
2419                         M_AST(s1, REG_SP, 0 * 4);
2420                         M_AST(s3, REG_SP, 1 * 4);
2421                         M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2422                         M_CALL(REG_ITMP1);
2423                         M_TEST(REG_RESULT);
2424                         M_BEQ(0);
2425                         codegen_add_arraystoreexception_ref(cd);
2426
2427                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2428                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2429                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2430                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]),
2431                                                                   s1, s2, 2);
2432                         break;
2433
2434                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
2435
2436                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2437                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2438                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2439                                 gen_nullptr_check(s1);
2440                                 gen_bound_check;
2441                         }
2442                         emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
2443                                                                    OFFSET(java_bytearray, data[0]), s1, s2, 0);
2444                         break;
2445
2446                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
2447
2448                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2449                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2450                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2451                                 gen_nullptr_check(s1);
2452                                 gen_bound_check;
2453                         }
2454                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2455                                                                    OFFSET(java_chararray, data[0]), s1, s2, 1);
2456                         break;
2457
2458                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
2459
2460                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2461                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2462                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2463                                 gen_nullptr_check(s1);
2464                                 gen_bound_check;
2465                         }
2466                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2467                                                                    OFFSET(java_shortarray, data[0]), s1, s2, 1);
2468                         break;
2469
2470                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
2471
2472                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2473                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2474                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2475                                 gen_nullptr_check(s1);
2476                                 gen_bound_check;
2477                         }
2478                         emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
2479                                                                   OFFSET(java_intarray, data[0]), s1, s2, 2);
2480                         break;
2481
2482                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
2483
2484                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2485                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2486                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2487                                 gen_nullptr_check(s1);
2488                                 gen_bound_check;
2489                         }
2490                         emit_mov_imm_memindex(cd, 
2491                                                    (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
2492                                                    OFFSET(java_longarray, data[0]), s1, s2, 3);
2493                         emit_mov_imm_memindex(cd, 
2494                                                         ((s4)iptr->sx.s23.s3.constval) >> 31, 
2495                                                         OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2496                         break;
2497
2498                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
2499
2500                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2501                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2502                         if (INSTRUCTION_MUST_CHECK(iptr)) {
2503                                 gen_nullptr_check(s1);
2504                                 gen_bound_check;
2505                         }
2506                         emit_mov_imm_memindex(cd, 0, 
2507                                                                   OFFSET(java_objectarray, data[0]), s1, s2, 2);
2508                         break;
2509
2510
2511                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
2512
2513                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2514                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2515
2516                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2517
2518                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
2519                                                                         iptr->sx.s23.s3.uf, 0);
2520
2521                                 if (opt_showdisassemble) {
2522                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2523                                 }
2524
2525                                 disp = 0;
2526
2527                         }
2528                         else {
2529                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2530
2531                                 fieldtype = fi->type;
2532
2533                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2534                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2535
2536                                         if (opt_showdisassemble) {
2537                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2538                                         }
2539                                 }
2540
2541                                 disp = (ptrint) &(fi->value);
2542                         }
2543
2544                         M_MOV_IMM(disp, REG_ITMP1);
2545                         switch (fieldtype) {
2546                         case TYPE_INT:
2547                         case TYPE_ADR:
2548                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2549                                 M_ILD(d, REG_ITMP1, 0);
2550                                 break;
2551                         case TYPE_LNG:
2552                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2553                                 M_LLD(d, REG_ITMP1, 0);
2554                                 break;
2555                         case TYPE_FLT:
2556                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2557                                 M_FLD(d, REG_ITMP1, 0);
2558                                 break;
2559                         case TYPE_DBL:                          
2560                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2561                                 M_DLD(d, REG_ITMP1, 0);
2562                                 break;
2563                         }
2564                         emit_store_dst(jd, iptr, d);
2565                         break;
2566
2567                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2568
2569                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2570                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2571
2572                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2573
2574                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
2575                                                                         iptr->sx.s23.s3.uf, 0);
2576
2577                                 if (opt_showdisassemble) {
2578                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2579                                 }
2580
2581                                 disp = 0;
2582
2583                         }
2584                         else {
2585                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2586                                 
2587                                 fieldtype = fi->type;
2588
2589                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2590                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2591
2592                                         if (opt_showdisassemble) {
2593                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2594                                         }
2595                                 }
2596
2597                                 disp = (ptrint) &(fi->value);
2598                         }
2599
2600                         M_MOV_IMM(disp, REG_ITMP1);
2601                         switch (fieldtype) {
2602                         case TYPE_INT:
2603                         case TYPE_ADR:
2604                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2605                                 M_IST(s1, REG_ITMP1, 0);
2606                                 break;
2607                         case TYPE_LNG:
2608                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2609                                 M_LST(s1, REG_ITMP1, 0);
2610                                 break;
2611                         case TYPE_FLT:
2612                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2613                                 emit_fstps_membase(cd, REG_ITMP1, 0);
2614                                 break;
2615                         case TYPE_DBL:
2616                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2617                                 emit_fstpl_membase(cd, REG_ITMP1, 0);
2618                                 break;
2619                         }
2620                         break;
2621
2622                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2623                                           /* val = value (in current instruction)     */
2624                                           /* following NOP)                           */
2625
2626                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2627                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2628
2629                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2630
2631                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
2632                                                                         uf, 0);
2633
2634                                 if (opt_showdisassemble) {
2635                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2636                                 }
2637
2638                                 disp = 0;
2639
2640                         }
2641                         else {
2642                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2643
2644                                 fieldtype = fi->type;
2645
2646                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2647                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2648
2649                                         if (opt_showdisassemble) {
2650                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2651                                         }
2652                                 }
2653
2654                                 disp = (ptrint) &(fi->value);
2655                         }
2656
2657                         M_MOV_IMM(disp, REG_ITMP1);
2658                         switch (fieldtype) {
2659                         case TYPE_INT:
2660                         case TYPE_ADR:
2661                                 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2662                                 break;
2663                         case TYPE_LNG:
2664                                 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
2665                                 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
2666                                 break;
2667                         default:
2668                                 assert(0);
2669                         }
2670                         break;
2671
2672                 case ICMD_GETFIELD:   /* .., objectref.  ==> ..., value               */
2673
2674                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2675                         gen_nullptr_check(s1);
2676
2677                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2678                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2679
2680                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2681
2682                                 codegen_addpatchref(cd, PATCHER_getfield,
2683                                                                         iptr->sx.s23.s3.uf, 0);
2684
2685                                 if (opt_showdisassemble) {
2686                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2687                                 }
2688
2689                                 disp = 0;
2690
2691                         }
2692                         else {
2693                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2694                                 
2695                                 fieldtype = fi->type;
2696                                 disp = fi->offset;
2697                         }
2698
2699                         switch (fieldtype) {
2700                         case TYPE_INT:
2701                         case TYPE_ADR:
2702                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2703                                 M_ILD32(d, s1, disp);
2704                                 break;
2705                         case TYPE_LNG:
2706                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2707                                 M_LLD32(d, s1, disp);
2708                                 break;
2709                         case TYPE_FLT:
2710                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2711                                 M_FLD32(d, s1, disp);
2712                                 break;
2713                         case TYPE_DBL:                          
2714                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2715                                 M_DLD32(d, s1, disp);
2716                                 break;
2717                         }
2718                         emit_store_dst(jd, iptr, d);
2719                         break;
2720
2721                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2722
2723                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2724                         gen_nullptr_check(s1);
2725
2726                         /* must be done here because of code patching */
2727
2728                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2729                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2730
2731                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2732                         }
2733                         else {
2734                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2735
2736                                 fieldtype = fi->type;
2737                         }
2738
2739                         if (!IS_FLT_DBL_TYPE(fieldtype)) {
2740                                 if (IS_2_WORD_TYPE(fieldtype))
2741                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2742                                 else
2743                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2744                         }
2745                         else
2746                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2747
2748                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2749                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2750
2751                                 codegen_addpatchref(cd, PATCHER_putfield, uf, 0);
2752
2753                                 if (opt_showdisassemble) {
2754                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2755                                 }
2756
2757                                 disp = 0;
2758
2759                         }
2760                         else {
2761                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2762
2763                                 disp = fi->offset;
2764                         }
2765
2766                         switch (fieldtype) {
2767                         case TYPE_INT:
2768                         case TYPE_ADR:
2769                                 M_IST32(s2, s1, disp);
2770                                 break;
2771                         case TYPE_LNG:
2772                                 M_LST32(s2, s1, disp);
2773                                 break;
2774                         case TYPE_FLT:
2775                                 emit_fstps_membase32(cd, s1, disp);
2776                                 break;
2777                         case TYPE_DBL:
2778                                 emit_fstpl_membase32(cd, s1, disp);
2779                                 break;
2780                         }
2781                         break;
2782
2783                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2784                                           /* val = value (in current instruction)     */
2785                                           /* following NOP)                           */
2786
2787                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2788                         gen_nullptr_check(s1);
2789
2790                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2791                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
2792
2793                                 fieldtype = uf->fieldref->parseddesc.fd->type;
2794
2795                                 codegen_addpatchref(cd, PATCHER_putfieldconst,
2796                                                                         uf, 0);
2797
2798                                 if (opt_showdisassemble) {
2799                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2800                                 }
2801
2802                                 disp = 0;
2803
2804                         }
2805                         else
2806                         {
2807                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2808
2809                                 fieldtype = fi->type;
2810                                 disp = fi->offset;
2811                         }
2812
2813
2814                         switch (fieldtype) {
2815                         case TYPE_INT:
2816                         case TYPE_ADR:
2817                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2818                                 break;
2819                         case TYPE_LNG:
2820                                 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2821                                 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2822                                 break;
2823                         default:
2824                                 assert(0);
2825                         }
2826                         break;
2827
2828
2829                 /* branch operations **************************************************/
2830
2831                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2832
2833                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2834                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2835
2836 #ifdef ENABLE_VERIFIER
2837                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2838                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2839                                                                         iptr->sx.s23.s2.uc, 0);
2840
2841                                 if (opt_showdisassemble) {
2842                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2843                                 }
2844                         }
2845 #endif /* ENABLE_VERIFIER */
2846
2847                         M_CALL_IMM(0);                            /* passing exception pc */
2848                         M_POP(REG_ITMP2_XPC);
2849
2850                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2851                         M_JMP(REG_ITMP3);
2852                         break;
2853
2854                 case ICMD_INLINE_GOTO:
2855 #if 0
2856                         M_COPY(src, iptr->dst.var);
2857 #endif
2858                         /* FALLTHROUGH! */
2859
2860                 case ICMD_GOTO:         /* ... ==> ...                                */
2861
2862 #if defined(ENABLE_SSA)
2863                         if ( ls != NULL ) {
2864                                 last_cmd_was_goto = true;
2865                                 /* In case of a Goto phimoves have to be inserted before the */
2866                                 /* jump */
2867                                 codegen_insert_phi_moves(cd, rd, ls, bptr);
2868                         }
2869 #endif
2870                         M_JMP_IMM(0);
2871                         codegen_addreference(cd, iptr->dst.block);
2872                         ALIGNCODENOP;
2873                         break;
2874
2875                 case ICMD_JSR:          /* ... ==> ...                                */
2876
2877                         M_CALL_IMM(0);
2878                         codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2879                         break;
2880                         
2881                 case ICMD_RET:          /* ... ==> ...                                */
2882                                         /* s1.localindex = local variable                       */
2883
2884                         var = &(jd->var[iptr->s1.varindex]);
2885                         if (var->flags & INMEMORY) {
2886                                 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2887                                 M_JMP(REG_ITMP1);
2888                         }
2889                         else
2890                                 M_JMP(var->regoff);
2891                         break;
2892
2893                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2894
2895                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2896                         M_TEST(s1);
2897                         M_BEQ(0);
2898                         codegen_addreference(cd, iptr->dst.block);
2899                         break;
2900
2901                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2902
2903                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2904                         M_TEST(s1);
2905                         M_BNE(0);
2906                         codegen_addreference(cd, iptr->dst.block);
2907                         break;
2908
2909                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2910
2911                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2912                         M_CMP_IMM(iptr->sx.val.i, s1);
2913                         M_BEQ(0);
2914                         codegen_addreference(cd, iptr->dst.block);
2915                         break;
2916
2917                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2918
2919                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2920                         M_CMP_IMM(iptr->sx.val.i, s1);
2921                         M_BLT(0);
2922                         codegen_addreference(cd, iptr->dst.block);
2923                         break;
2924
2925                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2926
2927                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2928                         M_CMP_IMM(iptr->sx.val.i, s1);
2929                         M_BLE(0);
2930                         codegen_addreference(cd, iptr->dst.block);
2931                         break;
2932
2933                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2934
2935                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2936                         M_CMP_IMM(iptr->sx.val.i, s1);
2937                         M_BNE(0);
2938                         codegen_addreference(cd, iptr->dst.block);
2939                         break;
2940
2941                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2942
2943                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2944                         M_CMP_IMM(iptr->sx.val.i, s1);
2945                         M_BGT(0);
2946                         codegen_addreference(cd, iptr->dst.block);
2947                         break;
2948
2949                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2950
2951                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2952                         M_CMP_IMM(iptr->sx.val.i, s1);
2953                         M_BGE(0);
2954                         codegen_addreference(cd, iptr->dst.block);
2955                         break;
2956
2957                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2958
2959                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2960                         if (iptr->sx.val.l == 0) {
2961                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2962                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2963                         }
2964                         else {
2965                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2966                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2967                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2968                                 M_OR(REG_ITMP2, REG_ITMP1);
2969                         }
2970                         M_BEQ(0);
2971                         codegen_addreference(cd, iptr->dst.block);
2972                         break;
2973
2974                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2975
2976                         if (iptr->sx.val.l == 0) {
2977                                 /* If high 32-bit are less than zero, then the 64-bits
2978                                    are too. */
2979                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2980                                 M_CMP_IMM(0, s1);
2981                                 M_BLT(0);
2982                         }
2983                         else {
2984                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2985                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2986                                 M_BLT(0);
2987                                 codegen_addreference(cd, iptr->dst.block);
2988                                 M_BGT(6 + 6);
2989                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2990                                 M_BB(0);
2991                         }                       
2992                         codegen_addreference(cd, iptr->dst.block);
2993                         break;
2994
2995                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2996
2997                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2998                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2999                         M_BLT(0);
3000                         codegen_addreference(cd, iptr->dst.block);
3001                         M_BGT(6 + 6);
3002                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3003                         M_BBE(0);
3004                         codegen_addreference(cd, iptr->dst.block);
3005                         break;
3006
3007                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
3008
3009                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3010                         if (iptr->sx.val.l == 0) {
3011                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
3012                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
3013                         }
3014                         else {
3015                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
3016                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
3017                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
3018                                 M_OR(REG_ITMP2, REG_ITMP1);
3019                         }
3020                         M_BNE(0);
3021                         codegen_addreference(cd, iptr->dst.block);
3022                         break;
3023
3024                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
3025
3026                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3027                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
3028                         M_BGT(0);
3029                         codegen_addreference(cd, iptr->dst.block);
3030                         M_BLT(6 + 6);
3031                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3032                         M_BA(0);
3033                         codegen_addreference(cd, iptr->dst.block);
3034                         break;
3035
3036                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
3037
3038                         if (iptr->sx.val.l == 0) {
3039                                 /* If high 32-bit are greater equal zero, then the
3040                                    64-bits are too. */
3041                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3042                                 M_CMP_IMM(0, s1);
3043                                 M_BGE(0);
3044                         }
3045                         else {
3046                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3047                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
3048                                 M_BGT(0);
3049                                 codegen_addreference(cd, iptr->dst.block);
3050                                 M_BLT(6 + 6);
3051                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3052                                 M_BAE(0);
3053                         }
3054                         codegen_addreference(cd, iptr->dst.block);
3055                         break;
3056
3057                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
3058                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
3059
3060                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3061                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3062                         M_CMP(s2, s1);
3063                         M_BEQ(0);
3064                         codegen_addreference(cd, iptr->dst.block);
3065                         break;
3066
3067                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
3068
3069                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3070                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3071                         M_INTMOVE(s1, REG_ITMP1);
3072                         M_XOR(s2, REG_ITMP1);
3073                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3074                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
3075                         M_INTMOVE(s1, REG_ITMP2);
3076                         M_XOR(s2, REG_ITMP2);
3077                         M_OR(REG_ITMP1, REG_ITMP2);
3078                         M_BEQ(0);
3079                         codegen_addreference(cd, iptr->dst.block);
3080                         break;
3081
3082                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
3083                 case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
3084
3085                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3086                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3087                         M_CMP(s2, s1);
3088                         M_BNE(0);
3089                         codegen_addreference(cd, iptr->dst.block);
3090                         break;
3091
3092                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
3093
3094                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3095                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3096                         M_INTMOVE(s1, REG_ITMP1);
3097                         M_XOR(s2, REG_ITMP1);
3098                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3099                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
3100                         M_INTMOVE(s1, REG_ITMP2);
3101                         M_XOR(s2, REG_ITMP2);
3102                         M_OR(REG_ITMP1, REG_ITMP2);
3103                         M_BNE(0);
3104                         codegen_addreference(cd, iptr->dst.block);
3105                         break;
3106
3107                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
3108
3109                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3110                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3111                         M_CMP(s2, s1);
3112                         M_BLT(0);
3113                         codegen_addreference(cd, iptr->dst.block);
3114                         break;
3115
3116                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
3117
3118                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3119                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3120                         M_CMP(s2, s1);
3121                         M_BLT(0);
3122                         codegen_addreference(cd, iptr->dst.block);
3123                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3124                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3125                         M_BGT(2 + 6);
3126                         M_CMP(s2, s1);
3127                         M_BB(0);
3128                         codegen_addreference(cd, iptr->dst.block);
3129                         break;
3130
3131                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
3132
3133                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3134                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3135                         M_CMP(s2, s1);
3136                         M_BGT(0);
3137                         codegen_addreference(cd, iptr->dst.block);
3138                         break;
3139
3140                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
3141
3142                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3143                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3144                         M_CMP(s2, s1);
3145                         M_BGT(0);
3146                         codegen_addreference(cd, iptr->dst.block);
3147                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3148                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3149                         M_BLT(2 + 6);
3150                         M_CMP(s2, s1);
3151                         M_BA(0);
3152                         codegen_addreference(cd, iptr->dst.block);
3153                         break;
3154
3155                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
3156
3157                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3158                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3159                         M_CMP(s2, s1);
3160                         M_BLE(0);
3161                         codegen_addreference(cd, iptr->dst.block);
3162                         break;
3163
3164                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
3165
3166                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3167                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3168                         M_CMP(s2, s1);
3169                         M_BLT(0);
3170                         codegen_addreference(cd, iptr->dst.block);
3171                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3172                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3173                         M_BGT(2 + 6);
3174                         M_CMP(s2, s1);
3175                         M_BBE(0);
3176                         codegen_addreference(cd, iptr->dst.block);
3177                         break;
3178
3179                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
3180
3181                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3182                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3183                         M_CMP(s2, s1);
3184                         M_BGE(0);
3185                         codegen_addreference(cd, iptr->dst.block);
3186                         break;
3187
3188                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
3189
3190                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3191                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3192                         M_CMP(s2, s1);
3193                         M_BGT(0);
3194                         codegen_addreference(cd, iptr->dst.block);
3195                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3196                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3197                         M_BLT(2 + 6);
3198                         M_CMP(s2, s1);
3199                         M_BAE(0);
3200                         codegen_addreference(cd, iptr->dst.block);
3201                         break;
3202
3203
3204                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
3205
3206                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
3207                         M_INTMOVE(s1, REG_RESULT);
3208                         goto nowperformreturn;
3209
3210                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
3211
3212                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
3213                         M_LNGMOVE(s1, REG_RESULT_PACKED);
3214                         goto nowperformreturn;
3215
3216                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
3217
3218                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
3219                         M_INTMOVE(s1, REG_RESULT);
3220
3221 #ifdef ENABLE_VERIFIER
3222                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3223                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
3224                                                                         iptr->sx.s23.s2.uc, 0);
3225
3226                                 if (opt_showdisassemble) {
3227                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3228                                 }
3229                         }
3230 #endif /* ENABLE_VERIFIER */
3231                         goto nowperformreturn;
3232
3233                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
3234                 case ICMD_DRETURN:
3235
3236                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
3237                         goto nowperformreturn;
3238
3239                 case ICMD_RETURN:      /* ...  ==> ...                                */
3240
3241 nowperformreturn:
3242                         {
3243                         s4 i, p;
3244                         
3245                         p = cd->stackframesize;
3246                         
3247 #if !defined(NDEBUG)
3248                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3249                                 emit_verbosecall_exit(jd);
3250 #endif
3251
3252 #if defined(ENABLE_THREADS)
3253                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3254                                 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
3255
3256                                 /* we need to save the proper return value */
3257                                 switch (iptr->opc) {
3258                                 case ICMD_IRETURN:
3259                                 case ICMD_ARETURN:
3260                                         M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
3261                                         break;
3262
3263                                 case ICMD_LRETURN:
3264                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3265                                         break;
3266
3267                                 case ICMD_FRETURN:
3268                                         emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
3269                                         break;
3270
3271                                 case ICMD_DRETURN:
3272                                         emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
3273                                         break;
3274                                 }
3275
3276                                 M_AST(REG_ITMP2, REG_SP, 0);
3277                                 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
3278                                 M_CALL(REG_ITMP3);
3279
3280                                 /* and now restore the proper return value */
3281                                 switch (iptr->opc) {
3282                                 case ICMD_IRETURN:
3283                                 case ICMD_ARETURN:
3284                                         M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
3285                                         break;
3286
3287                                 case ICMD_LRETURN:
3288                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3289                                         break;
3290
3291                                 case ICMD_FRETURN:
3292                                         emit_flds_membase(cd, REG_SP, rd->memuse * 4);
3293                                         break;
3294
3295                                 case ICMD_DRETURN:
3296                                         emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
3297                                         break;
3298                                 }
3299                         }
3300 #endif
3301
3302                         /* restore saved registers */
3303
3304                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3305                                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
3306                         }
3307
3308                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3309                                 p--;
3310                                 emit_fldl_membase(cd, REG_SP, p * 4);
3311                                 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3312                                         assert(0);
3313 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
3314                                 } else {
3315                                         assert(0);
3316 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
3317                                 }
3318                         }
3319
3320                         /* deallocate stack */
3321
3322                         if (cd->stackframesize)
3323                                 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
3324
3325                         emit_ret(cd);
3326                         }
3327                         break;
3328
3329
3330                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
3331                         {
3332                                 s4 i, l;
3333                                 branch_target_t *table;
3334
3335                                 table = iptr->dst.table;
3336
3337                                 l = iptr->sx.s23.s2.tablelow;
3338                                 i = iptr->sx.s23.s3.tablehigh;
3339
3340                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3341                                 M_INTMOVE(s1, REG_ITMP1);
3342
3343                                 if (l != 0)
3344                                         M_ISUB_IMM(l, REG_ITMP1);
3345
3346                                 i = i - l + 1;
3347
3348                 /* range check */
3349                                 M_CMP_IMM(i - 1, REG_ITMP1);
3350                                 M_BA(0);
3351
3352                                 codegen_addreference(cd, table[0].block); /* default target */
3353
3354                                 /* build jump table top down and use address of lowest entry */
3355
3356                                 table += i;
3357
3358                                 while (--i >= 0) {
3359                                         dseg_addtarget(cd, table->block); 
3360                                         --table;
3361                                 }
3362
3363                                 /* length of dataseg after last dseg_addtarget is used
3364                                    by load */
3365
3366                                 M_MOV_IMM(0, REG_ITMP2);
3367                                 dseg_adddata(cd);
3368                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3369                                 M_JMP(REG_ITMP1);
3370                         }
3371                         break;
3372
3373
3374                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
3375                         {
3376                                 s4 i;
3377                                 lookup_target_t *lookup;
3378
3379                                 lookup = iptr->dst.lookup;
3380
3381                                 i = iptr->sx.s23.s2.lookupcount;
3382                         
3383                                 MCODECHECK((i<<2)+8);
3384                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3385
3386                                 while (--i >= 0) {
3387                                         M_CMP_IMM(lookup->value, s1);
3388                                         M_BEQ(0);
3389                                         codegen_addreference(cd, lookup->target.block);
3390                                         lookup++;
3391                                 }
3392
3393                                 M_JMP_IMM(0);
3394                         
3395                                 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
3396                         }
3397                         break;
3398
3399                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
3400
3401                         bte = iptr->sx.s23.s3.bte;
3402                         md = bte->md;
3403                         goto gen_method;
3404
3405                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
3406
3407                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3408                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
3409                 case ICMD_INVOKEINTERFACE:
3410
3411                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3412                                 md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
3413                                 lm = NULL;
3414                         }
3415                         else {
3416                                 lm = iptr->sx.s23.s3.fmiref->p.method;
3417                                 md = lm->parseddesc;
3418                         }
3419
3420 gen_method:
3421                         s3 = md->paramcount;
3422
3423                         MCODECHECK((s3 << 1) + 64);
3424
3425                         /* copy arguments to registers or stack location                  */
3426
3427                         for (s3 = s3 - 1; s3 >= 0; s3--) {
3428                                 s1 = iptr->sx.s23.s2.args[s3];
3429                                 var1 = &(jd->var[s1]);
3430           
3431                                 /* Already Preallocated (ARGVAR) ? */
3432                                 if (var1->flags & PREALLOC)
3433                                         continue;
3434                                 if (IS_INT_LNG_TYPE(var1->type)) {
3435                                         if (!md->params[s3].inmemory) {
3436                                                 log_text("No integer argument registers available!");
3437                                                 assert(0);
3438
3439                                         } else {
3440                                                 if (IS_2_WORD_TYPE(var1->type)) {
3441                                                         d = emit_load(jd, iptr, var1, REG_ITMP12_PACKED);
3442                                                         M_LST(d, REG_SP, md->params[s3].regoff * 4);
3443                                                 } else {
3444                                                         d = emit_load(jd, iptr, var1, REG_ITMP1);
3445                                                         M_IST(d, REG_SP, md->params[s3].regoff * 4);
3446                                                 }
3447                                         }
3448
3449                                 } else {
3450                                         if (!md->params[s3].inmemory) {
3451                                                 s1 = rd->argfltregs[md->params[s3].regoff];
3452                                                 d = emit_load(jd, iptr, var1, s1);
3453                                                 M_FLTMOVE(d, s1);
3454
3455                                         } else {
3456                                                 d = emit_load(jd, iptr, var1, REG_FTMP1);
3457                                                 if (IS_2_WORD_TYPE(var1->type))
3458                                                         M_DST(d, REG_SP, md->params[s3].regoff * 4);
3459                                                 else
3460                                                         M_FST(d, REG_SP, md->params[s3].regoff * 4);
3461                                         }
3462                                 }
3463                         } /* end of for */
3464
3465                         switch (iptr->opc) {
3466                         case ICMD_BUILTIN:
3467                                 disp = (ptrint) bte->fp;
3468                                 d = md->returntype.type;
3469
3470                                 M_MOV_IMM(disp, REG_ITMP1);
3471                                 M_CALL(REG_ITMP1);
3472
3473
3474                                 if (INSTRUCTION_MUST_CHECK(iptr)) {
3475                                         M_TEST(REG_RESULT);
3476                                         M_BEQ(0);
3477                                         codegen_add_fillinstacktrace_ref(cd);
3478                                 }
3479                                 break;
3480
3481                         case ICMD_INVOKESPECIAL:
3482                                 M_ALD(REG_ITMP1, REG_SP, 0);
3483                                 M_TEST(REG_ITMP1);
3484                                 M_BEQ(0);
3485                                 codegen_add_nullpointerexception_ref(cd);
3486
3487                                 /* fall through */
3488
3489                         case ICMD_INVOKESTATIC:
3490                                 if (lm == NULL) {
3491                                         unresolved_method *um = iptr->sx.s23.s3.um;
3492
3493                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
3494                                                                                 um, 0);
3495
3496                                         if (opt_showdisassemble) {
3497                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3498                                         }
3499
3500                                         disp = 0;
3501                                         d = md->returntype.type;
3502                                 }
3503                                 else {
3504                                         disp = (ptrint) lm->stubroutine;
3505                                         d = lm->parseddesc->returntype.type;
3506                                 }
3507
3508                                 M_MOV_IMM(disp, REG_ITMP2);
3509                                 M_CALL(REG_ITMP2);
3510                                 break;
3511
3512                         case ICMD_INVOKEVIRTUAL:
3513                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3514                                 gen_nullptr_check(REG_ITMP1);
3515
3516                                 if (lm == NULL) {
3517                                         unresolved_method *um = iptr->sx.s23.s3.um;
3518
3519                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3520
3521                                         if (opt_showdisassemble) {
3522                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3523                                         }
3524
3525                                         s1 = 0;
3526                                         d = md->returntype.type;
3527                                 }
3528                                 else {
3529                                         s1 = OFFSET(vftbl_t, table[0]) +
3530                                                 sizeof(methodptr) * lm->vftblindex;
3531                                         d = md->returntype.type;
3532                                 }
3533
3534                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3535                                           OFFSET(java_objectheader, vftbl));
3536                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3537                                 M_CALL(REG_ITMP3);
3538                                 break;
3539
3540                         case ICMD_INVOKEINTERFACE:
3541                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3542                                 gen_nullptr_check(REG_ITMP1);
3543
3544                                 if (lm == NULL) {
3545                                         unresolved_method *um = iptr->sx.s23.s3.um;
3546
3547                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3548
3549                                         if (opt_showdisassemble) {
3550                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3551                                         }
3552
3553                                         s1 = 0;
3554                                         s2 = 0;
3555                                         d = md->returntype.type;
3556                                 }
3557                                 else {
3558                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3559                                                 sizeof(methodptr) * lm->class->index;
3560
3561                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3562
3563                                         d = md->returntype.type;
3564                                 }
3565
3566                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3567                                           OFFSET(java_objectheader, vftbl));
3568                                 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3569                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3570                                 M_CALL(REG_ITMP3);
3571                                 break;
3572                         }
3573
3574                         /* d contains return type */
3575
3576                         if (d != TYPE_VOID) {
3577 #if defined(ENABLE_SSA)
3578                                 if ((ls == NULL) || (iptr->dst->varkind != TEMPVAR) ||
3579                                         (ls->lifetime[-iptr->dst->varnum-1].type != -1)) 
3580                                         /* a "living" stackslot */
3581 #endif
3582                                 {
3583                                         if (IS_INT_LNG_TYPE(d)) {
3584                                                 if (IS_2_WORD_TYPE(d)) {
3585                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3586                                                         M_LNGMOVE(REG_RESULT_PACKED, s1);
3587                                                 }
3588                                                 else {
3589                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3590                                                         M_INTMOVE(REG_RESULT, s1);
3591                                                 }
3592                                         }
3593                                         else {
3594                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
3595                                         }
3596                                         emit_store_dst(jd, iptr, s1);
3597                                 }
3598                         }
3599                         break;
3600
3601
3602                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3603                                       /* val.a: (classinfo*) superclass               */
3604
3605                         /*  superclass is an interface:
3606                          *
3607                          *  OK if ((sub == NULL) ||
3608                          *         (sub->vftbl->interfacetablelength > super->index) &&
3609                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
3610                          *
3611                          *  superclass is a class:
3612                          *
3613                          *  OK if ((sub == NULL) || (0
3614                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3615                          *         super->vftbl->diffval));
3616                          */
3617
3618                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3619                                 /* object type cast-check */
3620
3621                                 classinfo *super;
3622                                 vftbl_t   *supervftbl;
3623                                 s4         superindex;
3624
3625                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3626                                         super = NULL;
3627                                         superindex = 0;
3628                                         supervftbl = NULL;
3629                                 }
3630                                 else {
3631                                         super = iptr->sx.s23.s3.c.cls;
3632                                         superindex = super->index;
3633                                         supervftbl = super->vftbl;
3634                                 }
3635                         
3636 #if defined(ENABLE_THREADS)
3637                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3638 #endif
3639                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3640
3641                                 /* calculate interface checkcast code size */
3642
3643                                 s2 = 2; /* mov_membase_reg */
3644                                 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3645
3646                                 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
3647                                            2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3648                                            2 /* test */ + 6 /* jcc */);
3649
3650                                 if (!super)
3651                                         s2 += (opt_showdisassemble ? 5 : 0);
3652
3653                                 /* calculate class checkcast code size */
3654
3655                                 s3 = 2; /* mov_membase_reg */
3656                                 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3657
3658                                 s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
3659
3660 #if 0
3661                                 if (s1 != REG_ITMP1) {
3662                                         a += 2;
3663                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3664                                 
3665                                         a += 2;
3666                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3667                                 
3668                                         a += 2;
3669                                 
3670                                 } else
3671 #endif
3672                                         {
3673                                                 s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
3674                                                            5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
3675                                                 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3676                                         }
3677
3678                                 s3 += 2 /* cmp */ + 6 /* jcc */;
3679
3680                                 if (super == NULL)
3681                                         s3 += (opt_showdisassemble ? 5 : 0);
3682
3683                                 /* if class is not resolved, check which code to call */
3684
3685                                 if (super == NULL) {
3686                                         M_TEST(s1);
3687                                         M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3688
3689                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3690                                                                                 iptr->sx.s23.s3.c.ref, 0);
3691
3692                                         if (opt_showdisassemble) {
3693                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3694                                         }
3695
3696                                         M_MOV_IMM(0, REG_ITMP2);                  /* super->flags */
3697                                         M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3698                                         M_BEQ(s2 + 5);
3699                                 }
3700
3701                                 /* interface checkcast code */
3702
3703                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3704                                         if (super != NULL) {
3705                                                 M_TEST(s1);
3706                                                 M_BEQ(s2);
3707                                         }
3708
3709                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3710
3711                                         if (super == NULL) {
3712                                                 codegen_addpatchref(cd,
3713                                                                                         PATCHER_checkcast_instanceof_interface,
3714                                                                                         iptr->sx.s23.s3.c.ref,
3715                                                                                         0);
3716
3717                                                 if (opt_showdisassemble) {
3718                                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3719                                                 }
3720                                         }
3721
3722                                         M_ILD32(REG_ITMP3,
3723                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3724                                         M_ISUB_IMM32(superindex, REG_ITMP3);
3725                                         M_TEST(REG_ITMP3);
3726                                         M_BLE(0);
3727                                         codegen_add_classcastexception_ref(cd, s1);
3728                                         M_ALD32(REG_ITMP3, REG_ITMP2,
3729                                                         OFFSET(vftbl_t, interfacetable[0]) -
3730                                                         superindex * sizeof(methodptr*));
3731                                         M_TEST(REG_ITMP3);
3732                                         M_BEQ(0);
3733                                         codegen_add_classcastexception_ref(cd, s1);
3734
3735                                         if (super == NULL)
3736                                                 M_JMP_IMM(s3);
3737                                 }
3738
3739                                 /* class checkcast code */
3740
3741                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3742                                         if (super != NULL) {
3743                                                 M_TEST(s1);
3744                                                 M_BEQ(s3);
3745                                         }
3746
3747                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3748
3749                                         if (super == NULL) {
3750                                                 codegen_addpatchref(cd, PATCHER_checkcast_class,
3751                                                                                         iptr->sx.s23.s3.c.ref,
3752                                                                                         0);
3753
3754                                                 if (opt_showdisassemble) {
3755                                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3756                                                 }
3757                                         }
3758
3759                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3760 #if defined(ENABLE_THREADS)
3761                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3762 #endif
3763                                         M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3764
3765                                         /*                              if (s1 != REG_ITMP1) { */
3766                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3767                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3768                                         /* #if defined(ENABLE_THREADS) */
3769                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3770                                         /* #endif */
3771                                         /*                                      emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3772
3773                                         /*                              } else { */
3774                                         M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3775                                         M_ISUB(REG_ITMP3, REG_ITMP2);
3776                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3777                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3778 #if defined(ENABLE_THREADS)
3779                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3780 #endif
3781                                         /*                              } */
3782
3783                                         M_CMP(REG_ITMP3, REG_ITMP2);
3784                                         M_BA(0);         /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
3785                                         codegen_add_classcastexception_ref(cd, s1);
3786                                 }
3787
3788                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3789                         }
3790                         else {
3791                                 /* array type cast-check */
3792
3793                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3794                                 M_AST(s1, REG_SP, 0 * 4);
3795
3796                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3797                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3798                                                                                 iptr->sx.s23.s3.c.ref, 0);
3799
3800                                         if (opt_showdisassemble) {
3801                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3802                                         }
3803                                 }
3804
3805                                 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
3806                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3807                                 M_CALL(REG_ITMP3);
3808
3809                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3810                                 M_TEST(REG_RESULT);
3811                                 M_BEQ(0);
3812                                 codegen_add_classcastexception_ref(cd, s1);
3813
3814                                 d = codegen_reg_of_dst(jd, iptr, s1);
3815                         }
3816
3817                         M_INTMOVE(s1, d);
3818                         emit_store_dst(jd, iptr, d);
3819                         break;
3820
3821                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3822                                       /* val.a: (classinfo*) superclass               */
3823
3824                         /*  superclass is an interface:
3825                          *
3826                          *  return (sub != NULL) &&
3827                          *         (sub->vftbl->interfacetablelength > super->index) &&
3828                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3829                          *
3830                          *  superclass is a class:
3831                          *
3832                          *  return ((sub != NULL) && (0
3833                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3834                          *          super->vftbl->diffvall));
3835                          */
3836
3837                         {
3838                         classinfo *super;
3839                         vftbl_t   *supervftbl;
3840                         s4         superindex;
3841
3842                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3843                                 super = NULL;
3844                                 superindex = 0;
3845                                 supervftbl = NULL;
3846
3847                         } else {
3848                                 super = iptr->sx.s23.s3.c.cls;
3849                                 superindex = super->index;
3850                                 supervftbl = super->vftbl;
3851                         }
3852                         
3853 #if defined(ENABLE_THREADS)
3854                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3855 #endif
3856
3857                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3858                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3859                         if (s1 == d) {
3860                                 M_INTMOVE(s1, REG_ITMP1);
3861                                 s1 = REG_ITMP1;
3862                         }
3863
3864                         /* calculate interface instanceof code size */
3865
3866                         s2 = 2; /* mov_membase_reg */
3867                         CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3868
3869                         s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
3870                                    2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3871                                    2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3872
3873                         if (!super)
3874                                 s2 += (opt_showdisassemble ? 5 : 0);
3875
3876                         /* calculate class instanceof code size */
3877
3878                         s3 = 2; /* mov_membase_reg */
3879                         CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3880                         s3 += 5; /* mov_imm_reg */
3881                         s3 += 2;
3882                         CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3883                         s3 += 2;
3884                         CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3885                         s3 += 2;
3886                         CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3887
3888                         s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
3889                                    2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3890
3891                         if (!super)
3892                                 s3 += (opt_showdisassemble ? 5 : 0);
3893
3894                         M_CLR(d);
3895
3896                         /* if class is not resolved, check which code to call */
3897
3898                         if (!super) {
3899                                 M_TEST(s1);
3900                                 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3901
3902                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3903                                                                         iptr->sx.s23.s3.c.ref, 0);
3904
3905                                 if (opt_showdisassemble) {
3906                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3907                                 }
3908
3909                                 M_MOV_IMM(0, REG_ITMP3);                      /* super->flags */
3910                                 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3911                                 M_BEQ(s2 + 5);
3912                         }
3913
3914                         /* interface instanceof code */
3915
3916                         if (!super || (super->flags & ACC_INTERFACE)) {
3917                                 if (super) {
3918                                         M_TEST(s1);
3919                                         M_BEQ(s2);
3920                                 }
3921
3922                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3923
3924                                 if (!super) {
3925                                         codegen_addpatchref(cd,
3926                                                                                 PATCHER_checkcast_instanceof_interface,
3927                                                                                 iptr->sx.s23.s3.c.ref, 0);
3928
3929                                         if (opt_showdisassemble) {
3930                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3931                                         }
3932                                 }
3933
3934                                 M_ILD32(REG_ITMP3,
3935                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3936                                 M_ISUB_IMM32(superindex, REG_ITMP3);
3937                                 M_TEST(REG_ITMP3);
3938
3939                                 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3940                                                 6 /* jcc */ + 5 /* mov_imm_reg */);
3941
3942                                 M_BLE(disp);
3943                                 M_ALD32(REG_ITMP1, REG_ITMP1,
3944                                                 OFFSET(vftbl_t, interfacetable[0]) -
3945                                                 superindex * sizeof(methodptr*));
3946                                 M_TEST(REG_ITMP1);
3947 /*                                      emit_setcc_reg(cd, CC_A, d); */
3948 /*                                      emit_jcc(cd, CC_BE, 5); */
3949                                 M_BEQ(5);
3950                                 M_MOV_IMM(1, d);
3951
3952                                 if (!super)
3953                                         M_JMP_IMM(s3);
3954                         }
3955
3956                         /* class instanceof code */
3957
3958                         if (!super || !(super->flags & ACC_INTERFACE)) {
3959                                 if (super) {
3960                                         M_TEST(s1);
3961                                         M_BEQ(s3);
3962                                 }
3963
3964                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3965
3966                                 if (!super) {
3967                                         codegen_addpatchref(cd, PATCHER_instanceof_class,
3968                                                                                 iptr->sx.s23.s3.c.ref, 0);
3969
3970                                         if (opt_showdisassemble) {
3971                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3972                                         }
3973                                 }
3974
3975                                 M_MOV_IMM(supervftbl, REG_ITMP2);
3976 #if defined(ENABLE_THREADS)
3977                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3978 #endif
3979                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3980                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3981                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3982 #if defined(ENABLE_THREADS)
3983                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3984 #endif
3985                                 M_ISUB(REG_ITMP2, REG_ITMP1);
3986                                 M_CLR(d);                                 /* may be REG_ITMP2 */
3987                                 M_CMP(REG_ITMP3, REG_ITMP1);
3988                                 M_BA(5);
3989                                 M_MOV_IMM(1, d);
3990                         }
3991                         emit_store_dst(jd, iptr, d);
3992                         }
3993                         break;
3994
3995                         break;
3996
3997                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3998
3999                         /* check for negative sizes and copy sizes to stack if necessary  */
4000
4001                         MCODECHECK((iptr->s1.argcount << 1) + 64);
4002
4003                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
4004                                 /* copy SAVEDVAR sizes to stack */
4005                                 s3 = iptr->sx.s23.s2.args[s1];
4006                                 var1 = &(jd->var[s3]);
4007
4008                                 /* Already Preallocated (ARGVAR) ? */
4009                                 if (!(var1->flags & PREALLOC)) {
4010                                         if (var1->flags & INMEMORY) {
4011                                                 M_ILD(REG_ITMP1, REG_SP, var1->regoff * 4);
4012                                                 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
4013                                         }
4014                                         else
4015                                                 M_IST(var1->regoff, REG_SP, (s1 + 3) * 4);
4016                                 }
4017                         }
4018
4019                         /* is a patcher function set? */
4020
4021                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
4022                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
4023                                                                         iptr->sx.s23.s3.c.ref, 0);
4024
4025                                 if (opt_showdisassemble) {
4026                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4027                                 }
4028
4029                                 disp = 0;
4030
4031                         }
4032                         else
4033                                 disp = (ptrint) iptr->sx.s23.s3.c.cls;
4034
4035                         /* a0 = dimension count */
4036
4037                         M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
4038
4039                         /* a1 = arraydescriptor */
4040
4041                         M_IST_IMM(disp, REG_SP, 1 * 4);
4042
4043                         /* a2 = pointer to dimensions = stack pointer */
4044
4045                         M_MOV(REG_SP, REG_ITMP1);
4046                         M_AADD_IMM(3 * 4, REG_ITMP1);
4047                         M_AST(REG_ITMP1, REG_SP, 2 * 4);
4048
4049                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
4050                         M_CALL(REG_ITMP1);
4051
4052                         /* check for exception before result assignment */
4053
4054                         M_TEST(REG_RESULT);
4055                         M_BEQ(0);
4056                         codegen_add_fillinstacktrace_ref(cd);
4057
4058                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
4059                         M_INTMOVE(REG_RESULT, s1);
4060                         emit_store_dst(jd, iptr, s1);
4061                         break;
4062
4063                 default:
4064                         *exceptionptr =
4065                                 new_internalerror("Unknown ICMD %d", iptr->opc);
4066                         return false;
4067         } /* switch */
4068                 
4069         } /* for instruction */
4070                 
4071         /* copy values to interface registers */
4072
4073         len = bptr->outdepth;
4074         MCODECHECK(64+len);
4075 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
4076         if (!opt_lsra)
4077 #endif
4078 #if defined(ENABLE_SSA)
4079         if ( ls != NULL ) {
4080                 /* by edge splitting, in Blocks with phi moves there can only */
4081                 /* be a goto as last command, no other Jump/Branch Command    */
4082                 if (!last_cmd_was_goto)
4083                         codegen_insert_phi_moves(cd, rd, ls, bptr);
4084         }
4085
4086 #endif
4087
4088         /* At the end of a basic block we may have to append some nops,
4089            because the patcher stub calling code might be longer than the
4090            actual instruction. So codepatching does not change the
4091            following block unintentionally. */
4092
4093         if (cd->mcodeptr < cd->lastmcodeptr) {
4094                 while (cd->mcodeptr < cd->lastmcodeptr) {
4095                         M_NOP;
4096                 }
4097         }
4098
4099         } /* if (bptr -> flags >= BBREACHED) */
4100         } /* for basic block */
4101
4102         dseg_createlinenumbertable(cd);
4103
4104
4105         /* generate exception and patcher stubs */
4106
4107         emit_exception_stubs(jd);
4108         emit_patcher_stubs(jd);
4109 #if 0
4110         emit_replacement_stubs(jd);
4111 #endif
4112
4113         codegen_finish(jd);
4114
4115         /* everything's ok */
4116
4117         return true;
4118 }
4119 #else
4120 bool codegen(jitdata *jd)
4121 {
4122         methodinfo         *m;
4123         codeinfo           *code;
4124         codegendata        *cd;
4125         registerdata       *rd;
4126         s4                  len, s1, s2, s3, d, disp;
4127         stackptr            src;
4128         varinfo            *var;
4129         basicblock         *bptr;
4130         instruction        *iptr;
4131         exceptiontable     *ex;
4132         u2                  currentline;
4133         methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
4134         unresolved_method  *um;
4135         builtintable_entry *bte;
4136         methoddesc         *md;
4137         rplpoint           *replacementpoint;
4138         s4                 fieldtype;
4139 #if defined(ENABLE_SSA)
4140         lsradata *ls;
4141         bool last_cmd_was_goto;
4142
4143         last_cmd_was_goto = false;
4144         ls = jd->ls;
4145 #endif
4146
4147         /* get required compiler data */
4148
4149         m    = jd->m;
4150         code = jd->code;
4151         cd   = jd->cd;
4152         rd   = jd->rd;
4153
4154         /* prevent compiler warnings */
4155
4156         d = 0;
4157         currentline = 0;
4158         lm = NULL;
4159         bte = NULL;
4160         s2 = 0;
4161
4162         {
4163         s4 i, p, t, l;
4164         s4 savedregs_num = 0;
4165         s4 stack_off = 0;
4166
4167         /* space to save used callee saved registers */
4168
4169         savedregs_num += (INT_SAV_CNT - rd->savintreguse);
4170
4171         /* float register are saved on 2 4-byte stackslots */
4172         savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
4173
4174         cd->stackframesize = rd->memuse + savedregs_num;
4175
4176            
4177 #if defined(ENABLE_THREADS)
4178         /* space to save argument of monitor_enter */
4179
4180         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
4181                 /* reserve 2 slots for long/double return values for monitorexit */
4182
4183                 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
4184                         cd->stackframesize += 2;
4185                 else
4186                         cd->stackframesize++;
4187         }
4188 #endif
4189
4190         /* create method header */
4191
4192     /* Keep stack of non-leaf functions 16-byte aligned. */
4193
4194         if (!jd->isleafmethod)
4195                 cd->stackframesize |= 0x3;
4196
4197         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
4198         (void) dseg_adds4(cd, cd->stackframesize * 4);         /* FrameSize       */
4199
4200 #if defined(ENABLE_THREADS)
4201         /* IsSync contains the offset relative to the stack pointer for the
4202            argument of monitor_exit used in the exception handler. Since the
4203            offset could be zero and give a wrong meaning of the flag it is
4204            offset by one.
4205         */
4206
4207         if (checksync && (m->flags & ACC_SYNCHRONIZED))
4208                 (void) dseg_adds4(cd, (rd->memuse + 1) * 4);       /* IsSync          */
4209         else
4210 #endif
4211                 (void) dseg_adds4(cd, 0);                          /* IsSync          */
4212                                                
4213         (void) dseg_adds4(cd, jd->isleafmethod);               /* IsLeaf          */
4214         (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave         */
4215         (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave         */
4216
4217         /* adds a reference for the length of the line number counter. We don't
4218            know the size yet, since we evaluate the information during code
4219            generation, to save one additional iteration over the whole
4220            instructions. During code optimization the position could have changed
4221            to the information gotten from the class file */
4222         (void) dseg_addlinenumbertablesize(cd);
4223
4224         (void) dseg_adds4(cd, cd->exceptiontablelength);       /* ExTableSize     */
4225         
4226         /* create exception table */
4227
4228         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
4229                 dseg_addtarget(cd, ex->start);
4230                 dseg_addtarget(cd, ex->end);
4231                 dseg_addtarget(cd, ex->handler);
4232                 (void) dseg_addaddress(cd, ex->catchtype.cls);
4233         }
4234         
4235         /* generate method profiling code */
4236
4237         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
4238                 /* count frequency */
4239
4240                 M_MOV_IMM(code, REG_ITMP3);
4241                 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
4242         }
4243
4244         /* create stack frame (if necessary) */
4245
4246         if (cd->stackframesize)
4247                 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
4248
4249         /* save return address and used callee saved registers */
4250
4251         p = cd->stackframesize;
4252         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
4253                 p--; M_AST(rd->savintregs[i], REG_SP, p * 4);
4254         }
4255         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
4256                 p-=2; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 4);
4257         }
4258
4259         /* take arguments out of register or stack frame */
4260
4261         md = m->parseddesc;
4262
4263         stack_off = 0;
4264         for (p = 0, l = 0; p < md->paramcount; p++) {
4265                 t = md->paramtypes[p].type;
4266 #if defined(ENABLE_SSA)
4267                 if ( ls != NULL ) {
4268                         l = ls->local_0[p];
4269                 }
4270 #endif
4271                 var = &(rd->locals[l][t]);
4272                 l++;
4273                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
4274                         l++;
4275                 if (var->type < 0)
4276                         continue;
4277                 s1 = md->params[p].regoff;
4278
4279                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
4280                         if (!md->params[p].inmemory) {           /* register arguments    */
4281                                 log_text("integer register argument");
4282                                 assert(0);
4283                                 if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
4284                                         /* rd->argintregs[md->params[p].regoff -> var->regoff     */
4285                                 } 
4286                                 else {                               /* reg arg -> spilled    */
4287                                         /* rd->argintregs[md->params[p].regoff -> var->regoff * 4 */
4288                                 }
4289                         } 
4290                         else {                                   /* stack arguments       */
4291                                 if (!IS_INMEMORY(var->flags)) {      /* stack arg -> register */
4292                                         emit_mov_membase_reg(           /* + 4 for return address */
4293                                            cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, var->regoff);
4294                                                                         /* + 4 for return address */
4295                                 } 
4296                                 else {                               /* stack arg -> spilled  */
4297                                         if (!IS_2_WORD_TYPE(t)) {
4298 #if defined(ENABLE_SSA)
4299                                                 /* no copy avoiding by now possible with SSA */
4300                                                 if (ls != NULL) {
4301                                                         emit_mov_membase_reg(   /* + 4 for return address */
4302                                                                  cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
4303                                                                  REG_ITMP1);    
4304                                                         emit_mov_reg_membase(
4305                                                                  cd, REG_ITMP1, REG_SP, var->regoff * 4);
4306                                                 }
4307                                                 else 
4308 #endif /*defined(ENABLE_SSA)*/
4309                                                                   /* reuse Stackslotand avoid copying */
4310                                                         var->regoff = cd->stackframesize + s1 + 1;
4311
4312                                         } 
4313                                         else {
4314 #if defined(ENABLE_SSA)
4315                                                 /* no copy avoiding by now possible with SSA */
4316                                                 if (ls != NULL) {
4317                                                         emit_mov_membase_reg(  /* + 4 for return address */
4318                                                                  cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
4319                                                                  REG_ITMP1);
4320                                                         emit_mov_reg_membase(
4321                                                                  cd, REG_ITMP1, REG_SP, var->regoff * 4);
4322                                                         emit_mov_membase_reg(   /* + 4 for return address */
4323                                                                   cd, REG_SP, (cd->stackframesize + s1) * 4 + 4 + 4,
4324                                                                   REG_ITMP1);             
4325                                                         emit_mov_reg_membase(
4326                                                                  cd, REG_ITMP1, REG_SP, var->regoff * 4 + 4);
4327                                                 }
4328                                                 else
4329 #endif /*defined(ENABLE_SSA)*/
4330                                                                   /* reuse Stackslotand avoid copying */
4331                                                         var->regoff = cd->stackframesize + s1 + 1;
4332                                         }
4333                                 }
4334                         }
4335                 }
4336                 else {                                       /* floating args         */
4337                         if (!md->params[p].inmemory) {           /* register arguments    */
4338                                 log_text("There are no float argument registers!");
4339                                 assert(0);
4340                                 if (!IS_INMEMORY(var->flags)) {  /* reg arg -> register   */
4341                                         /* rd->argfltregs[md->params[p].regoff -> var->regoff     */
4342                                 } else {                                     /* reg arg -> spilled    */
4343                                         /* rd->argfltregs[md->params[p].regoff -> var->regoff * 4 */
4344                                 }
4345
4346                         } 
4347                         else {                                   /* stack arguments       */
4348                                 if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
4349                                         if (t == TYPE_FLT) {
4350                                                 emit_flds_membase(
4351                             cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
4352                                                 assert(0);
4353 /*                                              emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
4354
4355                                         } 
4356                                         else {
4357                                                 emit_fldl_membase(
4358                             cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
4359                                                 assert(0);
4360 /*                                              emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
4361                                         }
4362
4363                                 } else {                             /* stack-arg -> spilled  */
4364 #if defined(ENABLE_SSA)
4365                                         /* no copy avoiding by now possible with SSA */
4366                                         if (ls != NULL) {
4367                                                 emit_mov_membase_reg(
4368                                                  cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, REG_ITMP1);
4369                                                 emit_mov_reg_membase(
4370                                                                          cd, REG_ITMP1, REG_SP, var->regoff * 4);
4371                                                 if (t == TYPE_FLT) {
4372                                                         emit_flds_membase(
4373                                                                   cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
4374                                                         emit_fstps_membase(cd, REG_SP, var->regoff * 4);
4375                                                 } 
4376                                                 else {
4377                                                         emit_fldl_membase(
4378                                                                   cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
4379                                                         emit_fstpl_membase(cd, REG_SP, var->regoff * 4);
4380                                                 }
4381                                         }
4382                                         else
4383 #endif /*defined(ENABLE_SSA)*/
4384                                                                   /* reuse Stackslotand avoid copying */
4385                                                 var->regoff = cd->stackframesize + s1 + 1;
4386                                 }
4387                         }
4388                 }
4389         }  /* end for */
4390
4391         /* call monitorenter function */
4392
4393 #if defined(ENABLE_THREADS)
4394         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
4395                 s1 = rd->memuse;
4396
4397                 if (m->flags & ACC_STATIC) {
4398                         M_MOV_IMM(&m->class->object.header, REG_ITMP1);
4399                 }
4400                 else {
4401                         M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 4 + 4);
4402                         M_TEST(REG_ITMP1);
4403                         M_BEQ(0);
4404                         codegen_add_nullpointerexception_ref(cd);
4405                 }
4406
4407                 M_AST(REG_ITMP1, REG_SP, s1 * 4);
4408                 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4409                 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
4410                 M_CALL(REG_ITMP3);
4411         }                       
4412 #endif
4413
4414 #if !defined(NDEBUG)
4415         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4416                 emit_verbosecall_enter(jd);
4417 #endif
4418
4419         } 
4420
4421 #if defined(ENABLE_SSA)
4422         /* with SSA Header is Basic Block 0 - insert phi Moves if necessary */
4423         if ( ls != NULL)
4424                         codegen_insert_phi_moves(cd, rd, ls, ls->basicblocks[0]);
4425 #endif
4426
4427         /* end of header generation */
4428
4429         replacementpoint = jd->code->rplpoints;
4430
4431         /* walk through all basic blocks */
4432         for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
4433
4434                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
4435
4436                 if (bptr->flags >= BBREACHED) {
4437
4438                 /* branch resolving */
4439
4440                 branchref *brefs;
4441                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
4442                         gen_resolvebranch(cd->mcodebase + brefs->branchpos, 
4443                                           brefs->branchpos,
4444                                                           bptr->mpc);
4445                 }
4446
4447 #if 0
4448                 /* handle replacement points */
4449
4450                 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
4451                         replacementpoint->pc = (u1*)bptr->mpc; /* will be resolved later */
4452                         
4453                         replacementpoint++;
4454
4455                         assert(cd->lastmcodeptr <= cd->mcodeptr);
4456                         cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
4457                 }
4458 #endif
4459
4460                 /* copy interface registers to their destination */
4461
4462                 len = bptr->indepth;
4463                 MCODECHECK(512);
4464
4465 #if 0
4466                 /* generate basic block profiling code */
4467
4468                 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
4469                         /* count frequency */
4470
4471                         M_MOV_IMM(code->bbfrequency, REG_ITMP3);
4472                         M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
4473                 }
4474 #endif
4475
4476 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
4477 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
4478                 if (opt_lsra) {
4479 # endif
4480 # if defined(ENABLE_SSA)
4481                 if (ls != NULL) {
4482                         last_cmd_was_goto = false;
4483 # endif
4484                         if (len > 0) {
4485                                 len--;
4486                                 src = bptr->invars[len];
4487                                 if (bptr->type != BBTYPE_STD) {
4488                                         if (!IS_2_WORD_TYPE(src->type)) {
4489                                                 if (bptr->type == BBTYPE_SBR) {
4490                                                         if (!IS_INMEMORY(src->flags))
4491                                                                 d = src->regoff;
4492                                                         else
4493                                                                 d = REG_ITMP1;
4494                                                         emit_pop_reg(cd, d);
4495                                                         emit_store(jd, NULL, src, d);
4496                                                 } else if (bptr->type == BBTYPE_EXH) {
4497                                                         if (!IS_INMEMORY(src->flags))
4498                                                                 d = src->regoff;
4499                                                         else
4500                                                                 d = REG_ITMP1;
4501                                                         M_INTMOVE(REG_ITMP1, d);
4502                                                         emit_store(jd, NULL, src, d);
4503                                                 }
4504
4505                                         } else {
4506                                                 log_text("copy interface registers(EXH, SBR): longs have to be in memory (begin 1)");
4507                                                 assert(0);
4508                                         }
4509                                 }
4510                         }
4511
4512                 } else
4513 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
4514                 {
4515                 while (len) {
4516                         len--;
4517                         src = bptr->invars[len];
4518                         if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
4519                                 if (!IS_2_WORD_TYPE(src->type)) {
4520                                         if (bptr->type == BBTYPE_SBR) {
4521                                                 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
4522                                                 emit_pop_reg(cd, d);
4523                                                 emit_store(jd, NULL, src, d);
4524
4525                                         } else if (bptr->type == BBTYPE_EXH) {
4526                                                 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
4527                                                 M_INTMOVE(REG_ITMP1, d);
4528                                                 emit_store(jd, NULL, src, d);
4529                                         }
4530                                 } else {
4531                                         log_text("copy interface registers: longs have to be in \
4532                                memory (begin 1)");
4533                                         assert(0);
4534                                 }
4535
4536                         } else {
4537 #if defined(NEW_VAR)
4538                                 assert(src->varkind == STACKVAR);
4539                                 /* will be done directly in simplereg lateron          */ 
4540                                 /* for now codegen_reg_of_var has to be called here to */
4541                                 /* set the regoff and flags for all bptr->invars[]     */
4542                                 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
4543 #else
4544                                 if (IS_LNG_TYPE(src->type))
4545                                         d = codegen_reg_of_var(rd, 0, src, 
4546                                                                                    PACK_REGS(REG_ITMP1, REG_ITMP2));
4547                                 else
4548                                         d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
4549 /*                          d = codegen_reg_of_var(rd, 0, src, REG_IFTMP); */
4550                                 
4551                                 if ((src->varkind != STACKVAR)) {
4552                                         s2 = src->type;
4553                                         s1 = rd->interfaces[len][s2].regoff;
4554                                         
4555                                         if (IS_FLT_DBL_TYPE(s2)) {
4556                                                 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
4557                                                         M_FLTMOVE(s1, d);
4558                                                         
4559                                                 } else {
4560                                                         if (IS_2_WORD_TYPE(s2))
4561                                                                 M_DLD(d, REG_SP, s1 * 4);
4562                                                         else
4563                                                                 M_FLD(d, REG_SP, s1 * 4);
4564                                                 }
4565                                                 
4566                                         } else {
4567                                                 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
4568                                                         if (IS_2_WORD_TYPE(s2))
4569                                                                 M_LNGMOVE(s1, d);
4570                                                         else
4571                                                                 M_INTMOVE(s1, d);
4572                                                         
4573                                                 } else {
4574                                                         if (IS_2_WORD_TYPE(s2))
4575                                                                 M_LLD(d, REG_SP, s1 * 4);
4576                                                         else
4577                                                                 M_ILD(d, REG_SP, s1 * 4);
4578                                                 }
4579                                         }
4580                                         
4581                                         emit_store(jd, NULL, src, d);
4582                                 }
4583 #endif
4584                         }
4585                 }
4586                 }
4587
4588                 /* walk through all instructions */
4589                 
4590                 len = bptr->icount;
4591                 currentline = 0;
4592
4593                 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
4594                         if (iptr->line != currentline) {
4595                                 dseg_addlinenumber(cd, iptr->line);
4596                                 currentline = iptr->line;
4597                         }
4598
4599                         MCODECHECK(1024);                         /* 1kB should be enough */
4600
4601                 switch (iptr->opc) {
4602                 case ICMD_INLINE_START:
4603 #if 0
4604                         {
4605                                 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
4606 #if defined(ENABLE_THREADS)
4607                                 if (insinfo->synchronize) {
4608                                         /* add monitor enter code */
4609                                         if (insinfo->method->flags & ACC_STATIC) {
4610                                                 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
4611                                                 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4612                                         } 
4613                                         else {
4614                                                 /* nullpointer check must have been performed before */
4615                                                 /* (XXX not done, yet) */
4616                                                 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
4617                                                 if (IS_INMEMORY(var->flags)) {
4618                                                         emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP1);
4619                                                         M_AST(REG_ITMP1, REG_SP, 0 * 4);
4620                                                 } 
4621                                                 else {
4622                                                         M_AST(var->regoff, REG_SP, 0 * 4);
4623                                                 }
4624                                         }
4625
4626                                         M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
4627                                         M_CALL(REG_ITMP3);
4628                                 }
4629 #endif
4630                                 dseg_addlinenumber_inline_start(cd, iptr);
4631                         }
4632 #endif
4633                         break;
4634
4635                 case ICMD_INLINE_END:
4636 #if 0
4637                         {
4638                                 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
4639
4640                                 dseg_addlinenumber_inline_end(cd, iptr);
4641                                 dseg_addlinenumber(cd, iptr->line);
4642
4643 #if defined(ENABLE_THREADS)
4644                                 if (insinfo->synchronize) {
4645                                         /* add monitor exit code */
4646                                         if (insinfo->method->flags & ACC_STATIC) {
4647                                                 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
4648                                                 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4649                                         } 
4650                                         else {
4651                                                 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
4652                                                 if (IS_INMEMORY(var->flags)) {
4653                                                         M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
4654                                                         M_AST(REG_ITMP1, REG_SP, 0 * 4);
4655                                                 } 
4656                                                 else {
4657                                                         M_AST(var->regoff, REG_SP, 0 * 4);
4658                                                 }
4659                                         }
4660
4661                                         M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
4662                                         M_CALL(REG_ITMP3);
4663                                 }
4664 #endif
4665                         }
4666 #endif
4667                         break;
4668
4669                 case ICMD_NOP:        /* ...  ==> ...                                 */
4670                         break;
4671
4672                 case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
4673
4674                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
4675                         M_TEST(s1);
4676                         M_BEQ(0);
4677                         codegen_add_nullpointerexception_ref(cd);
4678                         break;
4679
4680                 /* constant operations ************************************************/
4681
4682                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
4683
4684                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
4685                         ICONST(d, iptr->sx.val.i);
4686                         emit_store_dst(jd, iptr, d);
4687                         break;
4688
4689                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
4690
4691                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
4692                         LCONST(d, iptr->sx.val.l);
4693                         emit_store_dst(jd, iptr, d);
4694                         break;
4695
4696                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
4697
4698                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
4699                         if (iptr->sx.val.f == 0.0) {
4700                                 emit_fldz(cd);
4701
4702                                 /* -0.0 */
4703                                 if (iptr->sx.val.i == 0x80000000) {
4704                                         emit_fchs(cd);
4705                                 }
4706
4707                         } else if (iptr->sx.val.f == 1.0) {
4708                                 emit_fld1(cd);
4709
4710                         } else if (iptr->sx.val.f == 2.0) {
4711                                 emit_fld1(cd);
4712                                 emit_fld1(cd);
4713                                 emit_faddp(cd);
4714
4715                         } else {
4716                                 disp = dseg_addfloat(cd, iptr->sx.val.f);
4717                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
4718                                 dseg_adddata(cd);
4719                                 emit_flds_membase(cd, REG_ITMP1, disp);
4720                         }
4721                         emit_store_dst(jd, iptr, d);
4722                         break;
4723                 
4724                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
4725
4726                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
4727                         if (iptr->sx.val.d == 0.0) {
4728                                 emit_fldz(cd);
4729
4730                                 /* -0.0 */
4731                                 if (iptr->sx.val.l == 0x8000000000000000LL) {
4732                                         emit_fchs(cd);
4733                                 }
4734
4735                         } else if (iptr->sx.val.d == 1.0) {
4736                                 emit_fld1(cd);
4737
4738                         } else if (iptr->sx.val.d == 2.0) {
4739                                 emit_fld1(cd);
4740                                 emit_fld1(cd);
4741                                 emit_faddp(cd);
4742
4743                         } else {
4744                                 disp = dseg_adddouble(cd, iptr->sx.val.d);
4745                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
4746                                 dseg_adddata(cd);
4747                                 emit_fldl_membase(cd, REG_ITMP1, disp);
4748                         }
4749                         emit_store_dst(jd, iptr, d);
4750                         break;
4751
4752                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
4753
4754                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
4755
4756                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
4757                                 codegen_addpatchref(cd, PATCHER_aconst,
4758                                                                         iptr->sx.val.c.ref, 0);
4759
4760                                 if (opt_showdisassemble) {
4761                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4762                                 }
4763
4764                                 M_MOV_IMM(NULL, d);
4765
4766                         } else {
4767                                 if (iptr->sx.val.anyptr == NULL)
4768                                         M_CLR(d);
4769                                 else
4770                                         M_MOV_IMM(iptr->sx.val.anyptr, d);
4771                         }
4772                         emit_store_dst(jd, iptr, d);
4773                         break;
4774
4775
4776                 /* load/store operations **********************************************/
4777
4778                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
4779                 case ICMD_ALOAD:      /* op1 = local variable                         */
4780
4781                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
4782                         if ((iptr->dst.var->varkind == LOCALVAR) &&
4783                             (iptr->dst.var->varnum == iptr->s1.localindex))
4784                                 break;
4785                         var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
4786                         if (IS_INMEMORY(var->flags))
4787                                 M_ILD(d, REG_SP, var->regoff * 4);
4788                         else
4789                                 M_INTMOVE(var->regoff, d);
4790                         emit_store_dst(jd, iptr, d);
4791                         break;
4792
4793                 case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
4794                                       /* s1.localindex = local variable               */
4795   
4796                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
4797                         if ((iptr->dst.var->varkind == LOCALVAR) &&
4798                             (iptr->dst.var->varnum == iptr->s1.localindex))
4799                                 break;
4800                         var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
4801                         if (IS_INMEMORY(var->flags))
4802                                 M_LLD(d, REG_SP, var->regoff * 4);
4803                         else
4804                                 M_LNGMOVE(var->regoff, d);
4805                         emit_store_dst(jd, iptr, d);
4806                         break;
4807
4808                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
4809                                       /* s1.localindex = local variable               */
4810
4811                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
4812                         if ((iptr->dst.var->varkind == LOCALVAR) &&
4813                             (iptr->dst.var->varnum == iptr->s1.localindex))
4814                                 break;
4815                         var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
4816                         if (IS_INMEMORY(var->flags))
4817                                 M_FLD(d, REG_SP, var->regoff * 4);
4818                         else
4819                                 M_FLTMOVE(var->regoff, d);
4820                         emit_store_dst(jd, iptr, d);
4821                         break;
4822
4823                 case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
4824                                       /* s1.localindex = local variable               */
4825
4826                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
4827                         if ((iptr->dst.var->varkind == LOCALVAR) &&
4828                             (iptr->dst.var->varnum == iptr->s1.localindex))
4829                                 break;
4830                         var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
4831                         if (IS_INMEMORY(var->flags))
4832                                 M_DLD(d, REG_SP, var->regoff * 4);
4833                         else
4834                                 M_FLTMOVE(var->regoff, d);
4835                         emit_store_dst(jd, iptr, d);
4836                         break;
4837
4838                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
4839                 case ICMD_ASTORE:     /* op1 = local variable                         */
4840
4841                         if ((iptr->s1.var->varkind == LOCALVAR) &&
4842                             (iptr->s1.var->varnum == iptr->dst.localindex))
4843                                 break;
4844                         var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
4845                         if (IS_INMEMORY(var->flags)) {
4846                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
4847                                 M_IST(s1, REG_SP, var->regoff * 4);     
4848                         }
4849                         else {
4850                                 s1 = emit_load_s1(jd, iptr, var->regoff);
4851                                 M_INTMOVE(s1, var->regoff);
4852                         }
4853                         break;
4854
4855                 case ICMD_LSTORE:     /* ..., value  ==> ...                          */
4856                                       /* dst.localindex = local variable              */
4857
4858                         if ((iptr->s1.var->varkind == LOCALVAR) &&
4859                             (iptr->s1.var->varnum == iptr->dst.localindex))
4860                                 break;
4861                         var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
4862                         if (IS_INMEMORY(var->flags)) {
4863                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
4864                                 M_LST(s1, REG_SP, var->regoff * 4);
4865                         }
4866                         else {
4867                                 s1 = emit_load_s1(jd, iptr, var->regoff);
4868                                 M_LNGMOVE(s1, var->regoff);
4869                         }
4870                         break;
4871
4872                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
4873                                       /* dst.localindex = local variable              */
4874
4875                         if ((iptr->s1.var->varkind == LOCALVAR) &&
4876                             (iptr->s1.var->varnum == iptr->dst.localindex))
4877                                 break;
4878                         var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
4879                         if (IS_INMEMORY(var->flags)) {
4880                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
4881                                 M_FST(s1, REG_SP, var->regoff * 4);
4882                         }
4883                         else {
4884                                 s1 = emit_load_s1(jd, iptr, var->regoff);
4885                                 M_FLTMOVE(s1, var->regoff);
4886                         }
4887                         break;
4888
4889                 case ICMD_DSTORE:     /* ..., value  ==> ...                          */
4890                                       /* dst.localindex = local variable              */
4891
4892                         if ((iptr->s1.var->varkind == LOCALVAR) &&
4893                             (iptr->s1.var->varnum == iptr->dst.localindex))
4894                                 break;
4895                         var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
4896                         if (IS_INMEMORY(var->flags)) {
4897                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
4898                                 M_DST(s1, REG_SP, var->regoff * 4);
4899                         }
4900                         else {
4901                                 s1 = emit_load_s1(jd, iptr, var->regoff);
4902                                 M_FLTMOVE(s1, var->regoff);
4903                         }
4904                         break;
4905
4906
4907                 /* pop/dup/swap operations ********************************************/
4908
4909                 /* attention: double and longs are only one entry in CACAO ICMDs      */
4910
4911                 case ICMD_POP:        /* ..., value  ==> ...                          */
4912                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
4913                         break;
4914
4915                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
4916
4917                         M_COPY(iptr->s1.var, iptr->dst.var);
4918                         break;
4919
4920                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
4921
4922                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+2]);
4923                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+1]);
4924                         M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
4925                         break;
4926
4927                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
4928
4929                         M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[3+3]);
4930                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[3+2]);
4931                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[3+1]);
4932                         M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
4933                         break;
4934
4935                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
4936
4937                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+1]);
4938                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+0]);
4939                         break;
4940
4941                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
4942
4943                         M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[3+4]);
4944                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[3+3]);
4945                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[3+2]);
4946                         M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
4947                         M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
4948                         break;
4949
4950                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
4951
4952                         M_COPY(iptr->dst.dupslots[  3], iptr->dst.dupslots[4+5]);
4953                         M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[4+4]);
4954                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[4+3]);
4955                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[4+2]);
4956                         M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
4957                         M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
4958                         break;
4959
4960                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
4961
4962                         M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+0]);
4963                         M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+1]);
4964                         break;
4965
4966
4967 #if 0
4968                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
4969
4970                         M_COPY(src,       iptr->dst);
4971                         M_COPY(src->prev, iptr->dst->prev);
4972 #if defined(ENABLE_SSA)
4973                         if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
4974                                 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
4975 #endif
4976                                 M_COPY(iptr->dst, iptr->dst->prev->prev);
4977 #if defined(ENABLE_SSA)
4978                         } else {
4979                                 M_COPY(src, iptr->dst->prev->prev);
4980                         }
4981 #endif
4982                         break;
4983
4984                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
4985
4986                         M_COPY(src,             iptr->dst);
4987                         M_COPY(src->prev,       iptr->dst->prev);
4988                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
4989 #if defined(ENABLE_SSA)
4990                         if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
4991                                 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
4992 #endif
4993                                 M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
4994 #if defined(ENABLE_SSA)
4995                         } else {
4996                                 M_COPY(src, iptr->dst->prev->prev->prev);
4997                         }
4998 #endif
4999                         break;
5000 #endif
5001
5002                 /* integer operations *************************************************/
5003
5004                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
5005
5006                         s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
5007                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5008                         M_INTMOVE(s1, d);
5009                         M_NEG(d);
5010                         emit_store_dst(jd, iptr, d);
5011                         break;
5012
5013                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
5014
5015                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5016                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5017                         M_LNGMOVE(s1, d);
5018                         M_NEG(GET_LOW_REG(d));
5019                         M_IADDC_IMM(0, GET_HIGH_REG(d));
5020                         M_NEG(GET_HIGH_REG(d));
5021                         emit_store_dst(jd, iptr, d);
5022                         break;
5023
5024                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
5025
5026                         s1 = emit_load_s1(jd, iptr, EAX);
5027                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
5028                         M_INTMOVE(s1, EAX);
5029                         M_CLTD;
5030                         M_LNGMOVE(EAX_EDX_PACKED, d);
5031                         emit_store_dst(jd, iptr, d);
5032                         break;
5033
5034                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
5035
5036                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
5037                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5038                         M_INTMOVE(s1, d);
5039                         emit_store_dst(jd, iptr, d);
5040                         break;
5041
5042                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
5043
5044                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5045                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5046                         M_INTMOVE(s1, d);
5047                         M_SLL_IMM(24, d);
5048                         M_SRA_IMM(24, d);
5049                         emit_store_dst(jd, iptr, d);
5050                         break;
5051
5052                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
5053
5054                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5055                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5056                         M_CZEXT(s1, d);
5057                         emit_store_dst(jd, iptr, d);
5058                         break;
5059
5060                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
5061
5062                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5063                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5064                         M_SSEXT(s1, d);
5065                         emit_store_dst(jd, iptr, d);
5066                         break;
5067
5068
5069                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
5070
5071                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5072                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5073                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5074                         if (s2 == d)
5075                                 M_IADD(s1, d);
5076                         else {
5077                                 M_INTMOVE(s1, d);
5078                                 M_IADD(s2, d);
5079                         }
5080                         emit_store_dst(jd, iptr, d);
5081                         break;
5082
5083                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
5084                                       /* sx.val.i = constant                             */
5085
5086                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5087                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5088                         M_INTMOVE(s1, d);
5089                         M_IADD_IMM(iptr->sx.val.i, d);
5090                         emit_store_dst(jd, iptr, d);
5091                         break;
5092
5093                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
5094
5095                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5096                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5097                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5098                         M_INTMOVE(s1, GET_LOW_REG(d));
5099                         M_IADD(s2, GET_LOW_REG(d));
5100                         /* don't use REG_ITMP1 */
5101                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5102                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5103                         M_INTMOVE(s1, GET_HIGH_REG(d));
5104                         M_IADDC(s2, GET_HIGH_REG(d));
5105                         emit_store_dst(jd, iptr, d);
5106                         break;
5107
5108                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
5109                                       /* sx.val.l = constant                             */
5110
5111                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5112                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5113                         M_LNGMOVE(s1, d);
5114                         M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5115                         M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5116                         emit_store_dst(jd, iptr, d);
5117                         break;
5118
5119                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
5120
5121                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5122                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5123                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5124                         if (s2 == d) {
5125                                 M_INTMOVE(s1, REG_ITMP1);
5126                                 M_ISUB(s2, REG_ITMP1);
5127                                 M_INTMOVE(REG_ITMP1, d);
5128                         }
5129                         else {
5130                                 M_INTMOVE(s1, d);
5131                                 M_ISUB(s2, d);
5132                         }
5133                         emit_store_dst(jd, iptr, d);
5134                         break;
5135
5136                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
5137                                       /* sx.val.i = constant                             */
5138
5139                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5140                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5141                         M_INTMOVE(s1, d);
5142                         M_ISUB_IMM(iptr->sx.val.i, d);
5143                         emit_store_dst(jd, iptr, d);
5144                         break;
5145
5146                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
5147
5148                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5149                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5150                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5151                         if (s2 == GET_LOW_REG(d)) {
5152                                 M_INTMOVE(s1, REG_ITMP1);
5153                                 M_ISUB(s2, REG_ITMP1);
5154                                 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
5155                         }
5156                         else {
5157                                 M_INTMOVE(s1, GET_LOW_REG(d));
5158                                 M_ISUB(s2, GET_LOW_REG(d));
5159                         }
5160                         /* don't use REG_ITMP1 */
5161                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5162                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5163                         if (s2 == GET_HIGH_REG(d)) {
5164                                 M_INTMOVE(s1, REG_ITMP2);
5165                                 M_ISUBB(s2, REG_ITMP2);
5166                                 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
5167                         }
5168                         else {
5169                                 M_INTMOVE(s1, GET_HIGH_REG(d));
5170                                 M_ISUBB(s2, GET_HIGH_REG(d));
5171                         }
5172                         emit_store_dst(jd, iptr, d);
5173                         break;
5174
5175                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
5176                                       /* sx.val.l = constant                             */
5177
5178                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5179                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5180                         M_LNGMOVE(s1, d);
5181                         M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5182                         M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5183                         emit_store_dst(jd, iptr, d);
5184                         break;
5185
5186                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
5187
5188                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5189                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5190                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5191                         if (s2 == d)
5192                                 M_IMUL(s1, d);
5193                         else {
5194                                 M_INTMOVE(s1, d);
5195                                 M_IMUL(s2, d);
5196                         }
5197                         emit_store_dst(jd, iptr, d);
5198                         break;
5199
5200                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
5201                                       /* sx.val.i = constant                             */
5202
5203                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5204                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5205                         M_IMUL_IMM(s1, iptr->sx.val.i, d);
5206                         emit_store_dst(jd, iptr, d);
5207                         break;
5208
5209                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
5210
5211                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5212                         s2 = emit_load_s2_low(jd, iptr, EDX);
5213                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
5214
5215                         M_INTMOVE(s1, REG_ITMP2);
5216                         M_IMUL(s2, REG_ITMP2);
5217
5218                         s1 = emit_load_s1_low(jd, iptr, EAX);
5219                         s2 = emit_load_s2_high(jd, iptr, EDX);
5220                         M_INTMOVE(s2, EDX);
5221                         M_IMUL(s1, EDX);
5222                         M_IADD(EDX, REG_ITMP2);
5223
5224                         s1 = emit_load_s1_low(jd, iptr, EAX);
5225                         s2 = emit_load_s2_low(jd, iptr, EDX);
5226                         M_INTMOVE(s1, EAX);
5227                         M_MUL(s2);
5228                         M_INTMOVE(EAX, GET_LOW_REG(d));
5229                         M_IADD(REG_ITMP2, GET_HIGH_REG(d));
5230
5231                         emit_store_dst(jd, iptr, d);
5232                         break;
5233
5234                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
5235                                       /* sx.val.l = constant                             */
5236
5237                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
5238                         d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
5239                         ICONST(EAX, iptr->sx.val.l);
5240                         M_MUL(s1);
5241                         M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
5242                         M_IADD(REG_ITMP2, EDX);
5243                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5244                         M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
5245                         M_IADD(REG_ITMP2, EDX);
5246                         M_LNGMOVE(EAX_EDX_PACKED, d);
5247                         emit_store_dst(jd, iptr, d);
5248                         break;
5249
5250                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
5251
5252                         s1 = emit_load_s1(jd, iptr, EAX);
5253                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5254                         d = codegen_reg_of_dst(jd, iptr, EAX);
5255
5256                         if (checknull) {
5257                                 M_TEST(s2);
5258                                 M_BEQ(0);
5259                                 codegen_add_arithmeticexception_ref(cd);
5260                         }
5261
5262                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
5263
5264                         /* check as described in jvm spec */
5265
5266                         M_CMP_IMM(0x80000000, EAX);
5267                         M_BNE(3 + 6);
5268                         M_CMP_IMM(-1, s2);
5269                         M_BEQ(1 + 2);
5270                         M_CLTD;
5271                         M_IDIV(s2);
5272
5273                         M_INTMOVE(EAX, d);           /* if INMEMORY then d is already EAX */
5274                         emit_store_dst(jd, iptr, d);
5275                         break;
5276
5277                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
5278
5279                         s1 = emit_load_s1(jd, iptr, EAX);
5280                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5281                         d = codegen_reg_of_dst(jd, iptr, EDX);
5282
5283                         if (checknull) {
5284                                 M_TEST(s2);
5285                                 M_BEQ(0);
5286                                 codegen_add_arithmeticexception_ref(cd);
5287                         }
5288
5289                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
5290
5291                         /* check as described in jvm spec */
5292
5293                         M_CMP_IMM(0x80000000, EAX);
5294                         M_BNE(2 + 3 + 6);
5295                         M_CLR(EDX);
5296                         M_CMP_IMM(-1, s2);
5297                         M_BEQ(1 + 2);
5298                         M_CLTD;
5299                         M_IDIV(s2);
5300
5301                         M_INTMOVE(EDX, d);           /* if INMEMORY then d is already EDX */
5302                         emit_store_dst(jd, iptr, d);
5303                         break;
5304
5305                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
5306                                       /* sx.val.i = constant                             */
5307
5308                         /* TODO: optimize for `/ 2' */
5309                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5310                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5311                         M_INTMOVE(s1, d);
5312                         M_TEST(d);
5313                         M_BNS(6);
5314                         M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d);  /* 32-bit for jump off. */
5315                         M_SRA_IMM(iptr->sx.val.i, d);
5316                         emit_store_dst(jd, iptr, d);
5317                         break;
5318
5319                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
5320                                       /* sx.val.i = constant                             */
5321
5322                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5323                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5324                         if (s1 == d) {
5325                                 M_MOV(s1, REG_ITMP1);
5326                                 s1 = REG_ITMP1;
5327                         } 
5328                         M_INTMOVE(s1, d);
5329                         M_AND_IMM(iptr->sx.val.i, d);
5330                         M_TEST(s1);
5331                         M_BGE(2 + 2 + 6 + 2);
5332                         M_MOV(s1, d);  /* don't use M_INTMOVE, so we know the jump offset */
5333                         M_NEG(d);
5334                         M_AND_IMM32(iptr->sx.val.i, d);        /* use 32-bit for jump offset */
5335                         M_NEG(d);
5336                         emit_store_dst(jd, iptr, d);
5337                         break;
5338
5339                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
5340                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
5341
5342                         s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
5343                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
5344
5345                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
5346                         M_OR(GET_HIGH_REG(s2), REG_ITMP3);
5347                         M_BEQ(0);
5348                         codegen_add_arithmeticexception_ref(cd);
5349
5350                         bte = iptr->sx.s23.s3.bte;
5351                         md = bte->md;
5352
5353                         M_LST(s2, REG_SP, 2 * 4);
5354
5355                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5356                         M_LST(s1, REG_SP, 0 * 4);
5357
5358                         M_MOV_IMM(bte->fp, REG_ITMP3);
5359                         M_CALL(REG_ITMP3);
5360                         emit_store_dst(jd, iptr, d);
5361                         break;
5362
5363                 case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
5364                                       /* sx.val.i = constant                             */
5365
5366                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5367                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
5368                         M_LNGMOVE(s1, d);
5369                         M_TEST(GET_HIGH_REG(d));
5370                         M_BNS(6 + 3);
5371                         M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
5372                         M_IADDC_IMM(0, GET_HIGH_REG(d));
5373                         M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
5374                         M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
5375                         emit_store_dst(jd, iptr, d);
5376                         break;
5377
5378 #if 0
5379                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
5380                                       /* sx.val.l = constant                             */
5381
5382                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
5383                         if (IS_INMEMORY(iptr->dst.var->flags)) {
5384                                 if (IS_INMEMORY(iptr->s1.var->flags)) {
5385                                         /* Alpha algorithm */
5386                                         disp = 3;
5387                                         CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
5388                                         disp += 3;
5389                                         CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4 + 4);
5390
5391                                         disp += 2;
5392                                         disp += 3;
5393                                         disp += 2;
5394
5395                                         /* TODO: hmm, don't know if this is always correct */
5396                                         disp += 2;
5397                                         CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
5398                                         disp += 2;
5399                                         CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
5400
5401                                         disp += 2;
5402                                         disp += 3;
5403                                         disp += 2;
5404
5405                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
5406                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
5407                                         
5408                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
5409                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
5410                                         emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->regoff * 4 + 4);
5411                                         emit_jcc(cd, CC_GE, disp);
5412
5413                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
5414                                         emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
5415                                         
5416                                         emit_neg_reg(cd, REG_ITMP1);
5417                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
5418                                         emit_neg_reg(cd, REG_ITMP2);
5419                                         
5420                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
5421                                         emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
5422                                         
5423                                         emit_neg_reg(cd, REG_ITMP1);
5424                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
5425                                         emit_neg_reg(cd, REG_ITMP2);
5426
5427                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->regoff * 4);
5428                                         emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->regoff * 4 + 4);
5429                                 }
5430                         }
5431
5432                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5433                         d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
5434                         M_LNGMOVE(s1, d);
5435                         M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));      
5436                         M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5437                         M_TEST(GET_LOW_REG(s1));
5438                         M_BGE(0);
5439                         M_LNGMOVE(s1, d);
5440                 break;
5441 #endif
5442
5443                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
5444
5445                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5446                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5447                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5448                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
5449                         M_INTMOVE(s1, d);
5450                         M_SLL(d);
5451                         emit_store_dst(jd, iptr, d);
5452                         break;
5453
5454                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
5455                                       /* sx.val.i = constant                             */
5456
5457                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5458                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5459                         M_INTMOVE(s1, d);
5460                         M_SLL_IMM(iptr->sx.val.i, d);
5461                         emit_store_dst(jd, iptr, d);
5462                         break;
5463
5464                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
5465
5466                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5467                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5468                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5469                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
5470                         M_INTMOVE(s1, d);
5471                         M_SRA(d);
5472                         emit_store_dst(jd, iptr, d);
5473                         break;
5474
5475                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
5476                                       /* sx.val.i = constant                             */
5477
5478                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5479                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5480                         M_INTMOVE(s1, d);
5481                         M_SRA_IMM(iptr->sx.val.i, d);
5482                         emit_store_dst(jd, iptr, d);
5483                         break;
5484
5485                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
5486
5487                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5488                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5489                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5490                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
5491                         M_INTMOVE(s1, d);
5492                         M_SRL(d);
5493                         emit_store_dst(jd, iptr, d);
5494                         break;
5495
5496                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
5497                                       /* sx.val.i = constant                             */
5498
5499                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5500                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5501                         M_INTMOVE(s1, d);
5502                         M_SRL_IMM(iptr->sx.val.i, d);
5503                         emit_store_dst(jd, iptr, d);
5504                         break;
5505
5506                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
5507
5508                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
5509                         s2 = emit_load_s2(jd, iptr, ECX);
5510                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
5511                         M_LNGMOVE(s1, d);
5512                         M_INTMOVE(s2, ECX);
5513                         M_TEST_IMM(32, ECX);
5514                         M_BEQ(2 + 2);
5515                         M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
5516                         M_CLR(GET_LOW_REG(d));
5517                         M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
5518                         M_SLL(GET_LOW_REG(d));
5519                         emit_store_dst(jd, iptr, d);
5520                         break;
5521
5522         case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
5523                                           /* sx.val.i = constant                             */
5524
5525                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5526                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5527                         M_LNGMOVE(s1, d);
5528                         if (iptr->sx.val.i & 0x20) {
5529                                 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
5530                                 M_CLR(GET_LOW_REG(d));
5531                                 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
5532                         }
5533                         else {
5534                                 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
5535                                 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
5536                         }
5537                         emit_store_dst(jd, iptr, d);
5538                         break;
5539
5540                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
5541
5542                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
5543                         s2 = emit_load_s2(jd, iptr, ECX);
5544                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
5545                         M_LNGMOVE(s1, d);
5546                         M_INTMOVE(s2, ECX);
5547                         M_TEST_IMM(32, ECX);
5548                         M_BEQ(2 + 3);
5549                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
5550                         M_SRA_IMM(31, GET_HIGH_REG(d));
5551                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
5552                         M_SRA(GET_HIGH_REG(d));
5553                         emit_store_dst(jd, iptr, d);
5554                         break;
5555
5556                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
5557                                       /* sx.val.i = constant                          */
5558
5559                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5560                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5561                         M_LNGMOVE(s1, d);
5562                         if (iptr->sx.val.i & 0x20) {
5563                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
5564                                 M_SRA_IMM(31, GET_HIGH_REG(d));
5565                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
5566                                                    GET_LOW_REG(d));
5567                         }
5568                         else {
5569                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
5570                                                    GET_LOW_REG(d));
5571                                 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
5572                         }
5573                         emit_store_dst(jd, iptr, d);
5574                         break;
5575
5576                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
5577
5578                         s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
5579                         s2 = emit_load_s2(jd, iptr, ECX);
5580                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
5581                         M_LNGMOVE(s1, d);
5582                         M_INTMOVE(s2, ECX);
5583                         M_TEST_IMM(32, ECX);
5584                         M_BEQ(2 + 2);
5585                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
5586                         M_CLR(GET_HIGH_REG(d));
5587                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
5588                         M_SRL(GET_HIGH_REG(d));
5589                         emit_store_dst(jd, iptr, d);
5590                         break;
5591
5592                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
5593                                       /* sx.val.l = constant                          */
5594
5595                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5596                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5597                         M_LNGMOVE(s1, d);
5598                         if (iptr->sx.val.i & 0x20) {
5599                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
5600                                 M_CLR(GET_HIGH_REG(d));
5601                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
5602                                                    GET_LOW_REG(d));
5603                         }
5604                         else {
5605                                 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
5606                                                    GET_LOW_REG(d));
5607                                 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
5608                         }
5609                         emit_store_dst(jd, iptr, d);
5610                         break;
5611
5612                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
5613
5614                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5615                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5616                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5617                         if (s2 == d)
5618                                 M_AND(s1, d);
5619                         else {
5620                                 M_INTMOVE(s1, d);
5621                                 M_AND(s2, d);
5622                         }
5623                         emit_store_dst(jd, iptr, d);
5624                         break;
5625
5626                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
5627                                       /* sx.val.i = constant                             */
5628
5629                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5630                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5631                         M_INTMOVE(s1, d);
5632                         M_AND_IMM(iptr->sx.val.i, d);
5633                         emit_store_dst(jd, iptr, d);
5634                         break;
5635
5636                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
5637
5638                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5639                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5640                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5641                         if (s2 == GET_LOW_REG(d))
5642                                 M_AND(s1, GET_LOW_REG(d));
5643                         else {
5644                                 M_INTMOVE(s1, GET_LOW_REG(d));
5645                                 M_AND(s2, GET_LOW_REG(d));
5646                         }
5647                         /* REG_ITMP1 probably contains low 32-bit of destination */
5648                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5649                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5650                         if (s2 == GET_HIGH_REG(d))
5651                                 M_AND(s1, GET_HIGH_REG(d));
5652                         else {
5653                                 M_INTMOVE(s1, GET_HIGH_REG(d));
5654                                 M_AND(s2, GET_HIGH_REG(d));
5655                         }
5656                         emit_store_dst(jd, iptr, d);
5657                         break;
5658
5659                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
5660                                       /* sx.val.l = constant                             */
5661
5662                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5663                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5664                         M_LNGMOVE(s1, d);
5665                         M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5666                         M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5667                         emit_store_dst(jd, iptr, d);
5668                         break;
5669
5670                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
5671
5672                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5673                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5674                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5675                         if (s2 == d)
5676                                 M_OR(s1, d);
5677                         else {
5678                                 M_INTMOVE(s1, d);
5679                                 M_OR(s2, d);
5680                         }
5681                         emit_store_dst(jd, iptr, d);
5682                         break;
5683
5684                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
5685                                       /* sx.val.i = constant                             */
5686
5687                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5688                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5689                         M_INTMOVE(s1, d);
5690                         M_OR_IMM(iptr->sx.val.i, d);
5691                         emit_store_dst(jd, iptr, d);
5692                         break;
5693
5694                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
5695
5696                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5697                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5698                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5699                         if (s2 == GET_LOW_REG(d))
5700                                 M_OR(s1, GET_LOW_REG(d));
5701                         else {
5702                                 M_INTMOVE(s1, GET_LOW_REG(d));
5703                                 M_OR(s2, GET_LOW_REG(d));
5704                         }
5705                         /* REG_ITMP1 probably contains low 32-bit of destination */
5706                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5707                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5708                         if (s2 == GET_HIGH_REG(d))
5709                                 M_OR(s1, GET_HIGH_REG(d));
5710                         else {
5711                                 M_INTMOVE(s1, GET_HIGH_REG(d));
5712                                 M_OR(s2, GET_HIGH_REG(d));
5713                         }
5714                         emit_store_dst(jd, iptr, d);
5715                         break;
5716
5717                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
5718                                       /* sx.val.l = constant                             */
5719
5720                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5721                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5722                         M_LNGMOVE(s1, d);
5723                         M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5724                         M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5725                         emit_store_dst(jd, iptr, d);
5726                         break;
5727
5728                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
5729
5730                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5731                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5732                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5733                         if (s2 == d)
5734                                 M_XOR(s1, d);
5735                         else {
5736                                 M_INTMOVE(s1, d);
5737                                 M_XOR(s2, d);
5738                         }
5739                         emit_store_dst(jd, iptr, d);
5740                         break;
5741
5742                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
5743                                       /* sx.val.i = constant                             */
5744
5745                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5746                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5747                         M_INTMOVE(s1, d);
5748                         M_XOR_IMM(iptr->sx.val.i, d);
5749                         emit_store_dst(jd, iptr, d);
5750                         break;
5751
5752                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
5753
5754                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5755                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5756                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5757                         if (s2 == GET_LOW_REG(d))
5758                                 M_XOR(s1, GET_LOW_REG(d));
5759                         else {
5760                                 M_INTMOVE(s1, GET_LOW_REG(d));
5761                                 M_XOR(s2, GET_LOW_REG(d));
5762                         }
5763                         /* REG_ITMP1 probably contains low 32-bit of destination */
5764                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5765                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5766                         if (s2 == GET_HIGH_REG(d))
5767                                 M_XOR(s1, GET_HIGH_REG(d));
5768                         else {
5769                                 M_INTMOVE(s1, GET_HIGH_REG(d));
5770                                 M_XOR(s2, GET_HIGH_REG(d));
5771                         }
5772                         emit_store_dst(jd, iptr, d);
5773                         break;
5774
5775                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
5776                                       /* sx.val.l = constant                             */
5777
5778                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5779                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5780                         M_LNGMOVE(s1, d);
5781                         M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5782                         M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5783                         emit_store_dst(jd, iptr, d);
5784                         break;
5785
5786                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
5787                                       /* s1.localindex = variable, sx.val.i = constant             */
5788
5789 #if defined(ENABLE_SSA)
5790                         if ( ls != NULL ) {
5791                                 varinfo      *var_t;
5792
5793                                 
5794                                 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
5795                                 var_t = &(rd->locals[iptr->val._i.op1_t][TYPE_INT]);
5796
5797                                 /* set s1 to reg of destination or REG_ITMP1 */
5798                                 if (IS_INMEMORY(var_t->flags))
5799                                         s1 = REG_ITMP1;
5800                                 else
5801                                         s1 = var_t->regoff;
5802
5803                                 /* move source value to s1 */
5804                                 if (IS_INMEMORY(var->flags))
5805                                         M_ILD( s1, REG_SP, var->regoff * 4);
5806                                 else
5807                                         M_INTMOVE(var->regoff, s1);
5808
5809                                 /* `inc reg' is slower on p4's (regarding to ia32
5810                                    optimization reference manual and benchmarks) and as
5811                                    fast on athlon's. */
5812
5813                                 M_IADD_IMM(iptr->val._i.i, s1);
5814
5815                                 if (IS_INMEMORY(var_t->flags))
5816                                         M_IST(s1, REG_SP, var_t->regoff * 4);
5817
5818                         } else
5819 #endif /* defined(ENABLE_SSA) */
5820                         {
5821                                 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
5822                                 if (IS_INMEMORY(var->flags)) {
5823                                         s1 = REG_ITMP1;
5824                                         M_ILD(s1, REG_SP, var->regoff * 4);
5825                                 }
5826                                 else 
5827                                         s1 = var->regoff;
5828
5829                                 /* `inc reg' is slower on p4's (regarding to ia32
5830                                    optimization reference manual and benchmarks) and as
5831                                    fast on athlon's. */
5832
5833                                 M_IADD_IMM(iptr->sx.val.i, s1);
5834
5835                                 if (IS_INMEMORY(var->flags))
5836                                         M_IST(s1, REG_SP, var->regoff * 4);
5837                         }
5838                         break;
5839
5840
5841                 /* floating operations ************************************************/
5842
5843                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
5844
5845                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5846                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5847                         emit_fchs(cd);
5848                         emit_store_dst(jd, iptr, d);
5849                         break;
5850
5851                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
5852
5853                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5854                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5855                         emit_fchs(cd);
5856                         emit_store_dst(jd, iptr, d);
5857                         break;
5858
5859                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
5860
5861                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5862                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5863                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5864                         emit_faddp(cd);
5865                         emit_store_dst(jd, iptr, d);
5866                         break;
5867
5868                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
5869
5870                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5871                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5872                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5873                         emit_faddp(cd);
5874                         emit_store_dst(jd, iptr, d);
5875                         break;
5876
5877                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
5878
5879                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5880                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5881                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5882                         emit_fsubp(cd);
5883                         emit_store_dst(jd, iptr, d);
5884                         break;
5885
5886                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
5887
5888                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5889                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5890                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5891                         emit_fsubp(cd);
5892                         emit_store_dst(jd, iptr, d);
5893                         break;
5894
5895                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
5896
5897                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5898                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5899                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5900                         emit_fmulp(cd);
5901                         emit_store_dst(jd, iptr, d);
5902                         break;
5903
5904                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
5905
5906                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5907                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5908                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5909                         emit_fmulp(cd);
5910                         emit_store_dst(jd, iptr, d);
5911                         break;
5912
5913                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
5914
5915                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5916                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5917                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5918                         emit_fdivp(cd);
5919                         emit_store_dst(jd, iptr, d);
5920                         break;
5921
5922                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
5923
5924                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5925                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5926                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5927                         emit_fdivp(cd);
5928                         emit_store_dst(jd, iptr, d);
5929                         break;
5930
5931                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
5932
5933                         /* exchanged to skip fxch */
5934                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5935                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5936                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5937 /*                      emit_fxch(cd); */
5938                         emit_fprem(cd);
5939                         emit_wait(cd);
5940                         emit_fnstsw(cd);
5941                         emit_sahf(cd);
5942                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
5943                         emit_store_dst(jd, iptr, d);
5944                         emit_ffree_reg(cd, 0);
5945                         emit_fincstp(cd);
5946                         break;
5947
5948                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
5949
5950                         /* exchanged to skip fxch */
5951                         s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5952                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5953                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5954 /*                      emit_fxch(cd); */
5955                         emit_fprem(cd);
5956                         emit_wait(cd);
5957                         emit_fnstsw(cd);
5958                         emit_sahf(cd);
5959                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
5960                         emit_store_dst(jd, iptr, d);
5961                         emit_ffree_reg(cd, 0);
5962                         emit_fincstp(cd);
5963                         break;
5964
5965                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
5966                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
5967
5968                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
5969                         if (IS_INMEMORY(iptr->s1.var->flags)) {
5970                                 emit_fildl_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
5971
5972                         } else {
5973                                 disp = dseg_adds4(cd, 0);
5974                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
5975                                 dseg_adddata(cd);
5976                                 emit_mov_reg_membase(cd, iptr->s1.var->regoff, REG_ITMP1, disp);
5977                                 emit_fildl_membase(cd, REG_ITMP1, disp);
5978                         }
5979                         emit_store_dst(jd, iptr, d);
5980                         break;
5981
5982                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
5983                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
5984
5985                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
5986                         if (IS_INMEMORY(iptr->s1.var->flags)) {
5987                                 emit_fildll_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
5988
5989                         } else {
5990                                 log_text("L2F: longs have to be in memory");
5991                                 assert(0);
5992                         }
5993                         emit_store_dst(jd, iptr, d);
5994                         break;
5995                         
5996                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
5997
5998                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5999                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
6000
6001                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
6002                         dseg_adddata(cd);
6003
6004                         /* Round to zero, 53-bit mode, exception masked */
6005                         disp = dseg_adds4(cd, 0x0e7f);
6006                         emit_fldcw_membase(cd, REG_ITMP1, disp);
6007
6008                         if (IS_INMEMORY(iptr->dst.var->flags)) {
6009                                 emit_fistpl_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
6010
6011                                 /* Round to nearest, 53-bit mode, exceptions masked */
6012                                 disp = dseg_adds4(cd, 0x027f);
6013                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
6014
6015                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4);
6016
6017                                 disp = 3;
6018                                 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6019                                 disp += 5 + 2 + 3;
6020                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6021
6022                         } else {
6023                                 disp = dseg_adds4(cd, 0);
6024                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
6025                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst.var->regoff);
6026
6027                                 /* Round to nearest, 53-bit mode, exceptions masked */
6028                                 disp = dseg_adds4(cd, 0x027f);
6029                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
6030
6031                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst.var->regoff);
6032
6033                                 disp = 3;
6034                                 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6035                                 disp += 5 + 2 + ((REG_RESULT == iptr->dst.var->regoff) ? 0 : 2);
6036                         }
6037
6038                         emit_jcc(cd, CC_NE, disp);
6039
6040                         /* XXX: change this when we use registers */
6041                         emit_flds_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
6042                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
6043                         emit_call_reg(cd, REG_ITMP1);
6044
6045                         if (IS_INMEMORY(iptr->dst.var->flags)) {
6046                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
6047
6048                         } else {
6049                                 M_INTMOVE(REG_RESULT, iptr->dst.var->regoff);
6050                         }
6051                         break;
6052
6053                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
6054
6055                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6056                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
6057
6058                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
6059                         dseg_adddata(cd);
6060
6061                         /* Round to zero, 53-bit mode, exception masked */
6062                         disp = dseg_adds4(cd, 0x0e7f);
6063                         emit_fldcw_membase(cd, REG_ITMP1, disp);
6064
6065                         if (IS_INMEMORY(iptr->dst.var->flags)) {
6066                                 emit_fistpl_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
6067
6068                                 /* Round to nearest, 53-bit mode, exceptions masked */
6069                                 disp = dseg_adds4(cd, 0x027f);
6070                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
6071
6072                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4);
6073
6074                                 disp = 3;
6075                                 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6076                                 disp += 5 + 2 + 3;
6077                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6078
6079                         } else {
6080                                 disp = dseg_adds4(cd, 0);
6081                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
6082                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst.var->regoff);
6083
6084                                 /* Round to nearest, 53-bit mode, exceptions masked */
6085                                 disp = dseg_adds4(cd, 0x027f);
6086                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
6087
6088                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst.var->regoff);
6089
6090                                 disp = 3;
6091                                 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6092                                 disp += 5 + 2 + ((REG_RESULT == iptr->dst.var->regoff) ? 0 : 2);
6093                         }
6094
6095                         emit_jcc(cd, CC_NE, disp);
6096
6097                         /* XXX: change this when we use registers */
6098                         emit_fldl_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
6099                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
6100                         emit_call_reg(cd, REG_ITMP1);
6101
6102                         if (IS_INMEMORY(iptr->dst.var->flags)) {
6103                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
6104                         } else {
6105                                 M_INTMOVE(REG_RESULT, iptr->dst.var->regoff);
6106                         }
6107                         break;
6108
6109                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
6110
6111                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6112                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
6113
6114                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
6115                         dseg_adddata(cd);
6116
6117                         /* Round to zero, 53-bit mode, exception masked */
6118                         disp = dseg_adds4(cd, 0x0e7f);
6119                         emit_fldcw_membase(cd, REG_ITMP1, disp);
6120
6121                         if (IS_INMEMORY(iptr->dst.var->flags)) {
6122                                 emit_fistpll_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
6123
6124                                 /* Round to nearest, 53-bit mode, exceptions masked */
6125                                 disp = dseg_adds4(cd, 0x027f);
6126                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
6127
6128                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4 + 4);
6129
6130                                 disp = 6 + 4;
6131                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6132                                 disp += 3;
6133                                 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6134                                 disp += 5 + 2;
6135                                 disp += 3;
6136                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6137                                 disp += 3;
6138                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4 + 4);
6139
6140                                 emit_jcc(cd, CC_NE, disp);
6141
6142                                 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst.var->regoff * 4);
6143
6144                                 disp = 3;
6145                                 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6146                                 disp += 5 + 2 + 3;
6147                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6148
6149                                 emit_jcc(cd, CC_NE, disp);
6150
6151                                 /* XXX: change this when we use registers */
6152                                 emit_flds_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
6153                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
6154                                 emit_call_reg(cd, REG_ITMP1);
6155                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
6156                                 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst.var->regoff * 4 + 4);
6157
6158                         } else {
6159                                 log_text("F2L: longs have to be in memory");
6160                                 assert(0);
6161                         }
6162                         break;
6163
6164                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
6165
6166                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6167                         d = codegen_reg_of_dst(jd, iptr, REG_NULL);
6168
6169                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
6170                         dseg_adddata(cd);
6171
6172                         /* Round to zero, 53-bit mode, exception masked */
6173                         disp = dseg_adds4(cd, 0x0e7f);
6174                         emit_fldcw_membase(cd, REG_ITMP1, disp);
6175
6176                         if (IS_INMEMORY(iptr->dst.var->flags)) {
6177                                 emit_fistpll_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
6178
6179                                 /* Round to nearest, 53-bit mode, exceptions masked */
6180                                 disp = dseg_adds4(cd, 0x027f);
6181                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
6182
6183                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4 + 4);
6184
6185                                 disp = 6 + 4;
6186                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6187                                 disp += 3;
6188                                 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6189                                 disp += 5 + 2;
6190                                 disp += 3;
6191                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6192                                 disp += 3;
6193                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4 + 4);
6194
6195                                 emit_jcc(cd, CC_NE, disp);
6196
6197                                 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst.var->regoff * 4);
6198
6199                                 disp = 3;
6200                                 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6201                                 disp += 5 + 2 + 3;
6202                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6203
6204                                 emit_jcc(cd, CC_NE, disp);
6205
6206                                 /* XXX: change this when we use registers */
6207                                 emit_fldl_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
6208                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
6209                                 emit_call_reg(cd, REG_ITMP1);
6210                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
6211                                 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst.var->regoff * 4 + 4);
6212
6213                         } else {
6214                                 log_text("D2L: longs have to be in memory");
6215                                 assert(0);
6216                         }
6217                         break;
6218
6219                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
6220
6221                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6222                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
6223                         /* nothing to do */
6224                         emit_store_dst(jd, iptr, d);
6225                         break;
6226
6227                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
6228
6229                         s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6230                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
6231                         /* nothing to do */
6232                         emit_store_dst(jd, iptr, d);
6233                         break;
6234
6235                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
6236                 case ICMD_DCMPL:
6237
6238                         /* exchanged to skip fxch */
6239                         s2 = emit_load_s1(jd, iptr, REG_FTMP1);
6240                         s1 = emit_load_s2(jd, iptr, REG_FTMP2);
6241                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6242 /*                      emit_fxch(cd); */
6243                         emit_fucompp(cd);
6244                         emit_fnstsw(cd);
6245                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as GT */
6246                         emit_jcc(cd, CC_E, 6);
6247                         emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
6248                         emit_sahf(cd);
6249                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
6250                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
6251                         emit_jcc(cd, CC_B, 3 + 5);
6252                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
6253                         emit_jmp_imm(cd, 3);
6254                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
6255                         emit_store_dst(jd, iptr, d);
6256                         break;
6257
6258                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
6259                 case ICMD_DCMPG:
6260
6261                         /* exchanged to skip fxch */
6262                         s2 = emit_load_s1(jd, iptr, REG_FTMP1);
6263                         s1 = emit_load_s2(jd, iptr, REG_FTMP2);
6264                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6265 /*                      emit_fxch(cd); */
6266                         emit_fucompp(cd);
6267                         emit_fnstsw(cd);
6268                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as LT */
6269                         emit_jcc(cd, CC_E, 3);
6270                         emit_movb_imm_reg(cd, 1, REG_AH);
6271                         emit_sahf(cd);
6272                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
6273                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
6274                         emit_jcc(cd, CC_B, 3 + 5);
6275                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
6276                         emit_jmp_imm(cd, 3);
6277                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
6278                         emit_store_dst(jd, iptr, d);
6279                         break;
6280
6281
6282                 /* memory operations **************************************************/
6283
6284                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
6285
6286                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6287                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6288                         gen_nullptr_check(s1);
6289                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
6290                         emit_store_dst(jd, iptr, d);
6291                         break;
6292
6293                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
6294
6295                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6296                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6297                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6298                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6299                                 gen_nullptr_check(s1);
6300                                 gen_bound_check;
6301                         }
6302                         emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
6303                         emit_store_dst(jd, iptr, d);
6304                         break;
6305
6306                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
6307
6308                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6309                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6310                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6311                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6312                                 gen_nullptr_check(s1);
6313                                 gen_bound_check;
6314                         }
6315                         emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
6316                         emit_store_dst(jd, iptr, d);
6317                         break;                  
6318
6319                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
6320
6321                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6322                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6323                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6324                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6325                                 gen_nullptr_check(s1);
6326                                 gen_bound_check;
6327                         }
6328                         emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
6329                         emit_store_dst(jd, iptr, d);
6330                         break;
6331
6332                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
6333
6334                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6335                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6336                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6337                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6338                                 gen_nullptr_check(s1);
6339                                 gen_bound_check;
6340                         }
6341                         emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
6342                         emit_store_dst(jd, iptr, d);
6343                         break;
6344
6345                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
6346
6347                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6348                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6349                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
6350                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6351                                 gen_nullptr_check(s1);
6352                                 gen_bound_check;
6353                         }
6354                         assert(IS_INMEMORY(iptr->dst.var->flags));
6355                         emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
6356                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst.var->regoff * 4);
6357                         emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
6358                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst.var->regoff * 4 + 4);
6359                         break;
6360
6361                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
6362
6363                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6364                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6365                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6366                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6367                                 gen_nullptr_check(s1);
6368                                 gen_bound_check;
6369                         }
6370                         emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
6371                         emit_store_dst(jd, iptr, d);
6372                         break;
6373
6374                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
6375
6376                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6377                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6378                         d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
6379                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6380                                 gen_nullptr_check(s1);
6381                                 gen_bound_check;
6382                         }
6383                         emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
6384                         emit_store_dst(jd, iptr, d);
6385                         break;
6386
6387                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
6388
6389                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6390                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6391                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6392                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6393                                 gen_nullptr_check(s1);
6394                                 gen_bound_check;
6395                         }
6396                         emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
6397                         emit_store_dst(jd, iptr, d);
6398                         break;
6399
6400
6401                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
6402
6403                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6404                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6405                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6406                                 gen_nullptr_check(s1);
6407                                 gen_bound_check;
6408                         }
6409                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6410                         if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
6411                                 M_INTMOVE(s3, REG_ITMP3);
6412                                 s3 = REG_ITMP3;
6413                         }
6414                         emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
6415                         break;
6416
6417                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
6418
6419                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6420                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6421                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6422                                 gen_nullptr_check(s1);
6423                                 gen_bound_check;
6424                         }
6425                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6426                         emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
6427                         break;
6428
6429                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
6430
6431                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6432                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6433                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6434                                 gen_nullptr_check(s1);
6435                                 gen_bound_check;
6436                         }
6437                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6438                         emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
6439                         break;
6440
6441                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
6442
6443                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6444                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6445                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6446                                 gen_nullptr_check(s1);
6447                                 gen_bound_check;
6448                         }
6449                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6450                         emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
6451                         break;
6452
6453                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
6454
6455                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6456                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6457                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6458                                 gen_nullptr_check(s1);
6459                                 gen_bound_check;
6460                         }
6461                         assert(IS_INMEMORY(iptr->sx.s23.s3.var->flags));
6462                         emit_mov_membase_reg(cd, REG_SP, iptr->sx.s23.s3.var->regoff * 4, REG_ITMP3);
6463                         emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
6464                         emit_mov_membase_reg(cd, REG_SP, iptr->sx.s23.s3.var->regoff * 4 + 4, REG_ITMP3);
6465                         emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
6466                         break;
6467
6468                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
6469
6470                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6471                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6472                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6473                                 gen_nullptr_check(s1);
6474                                 gen_bound_check;
6475                         }
6476                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
6477                         emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
6478                         break;
6479
6480                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
6481
6482                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6483                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6484                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6485                                 gen_nullptr_check(s1);
6486                                 gen_bound_check;
6487                         }
6488                         s3 = emit_load_s3(jd, iptr, REG_FTMP1);
6489                         emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
6490                         break;
6491
6492                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
6493
6494                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6495                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6496                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6497                                 gen_nullptr_check(s1);
6498                                 gen_bound_check;
6499                         }
6500                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6501
6502                         M_AST(s1, REG_SP, 0 * 4);
6503                         M_AST(s3, REG_SP, 1 * 4);
6504                         M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
6505                         M_CALL(REG_ITMP1);
6506                         M_TEST(REG_RESULT);
6507                         M_BEQ(0);
6508                         codegen_add_arraystoreexception_ref(cd);
6509
6510                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6511                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6512                         s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6513                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
6514                         break;
6515
6516                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
6517
6518                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6519                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6520                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6521                                 gen_nullptr_check(s1);
6522                                 gen_bound_check;
6523                         }
6524                         emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
6525                         break;
6526
6527                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
6528
6529                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6530                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6531                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6532                                 gen_nullptr_check(s1);
6533                                 gen_bound_check;
6534                         }
6535                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
6536                         break;
6537
6538                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
6539
6540                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6541                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6542                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6543                                 gen_nullptr_check(s1);
6544                                 gen_bound_check;
6545                         }
6546                         emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
6547                         break;
6548
6549                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
6550
6551                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6552                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6553                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6554                                 gen_nullptr_check(s1);
6555                                 gen_bound_check;
6556                         }
6557                         emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
6558                         break;
6559
6560                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
6561
6562                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6563                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6564                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6565                                 gen_nullptr_check(s1);
6566                                 gen_bound_check;
6567                         }
6568                         emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
6569                         emit_mov_imm_memindex(cd, ((s4)iptr->sx.s23.s3.constval) >> 31, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
6570                         break;
6571
6572                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
6573
6574                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6575                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6576                         if (INSTRUCTION_MUST_CHECK(iptr)) {
6577                                 gen_nullptr_check(s1);
6578                                 gen_bound_check;
6579                         }
6580                         emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 2);
6581                         break;
6582
6583
6584                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
6585
6586                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6587                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
6588
6589                                 fieldtype = uf->fieldref->parseddesc.fd->type;
6590
6591                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
6592                                                                         iptr->sx.s23.s3.uf, 0);
6593
6594                                 if (opt_showdisassemble) {
6595                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6596                                 }
6597
6598                                 disp = 0;
6599
6600                         }
6601                         else {
6602                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6603
6604                                 fieldtype = fi->type;
6605
6606                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
6607                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
6608
6609                                         if (opt_showdisassemble) {
6610                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6611                                         }
6612                                 }
6613
6614                                 disp = (ptrint) &(fi->value);
6615                         }
6616
6617                         M_MOV_IMM(disp, REG_ITMP1);
6618                         switch (fieldtype) {
6619                         case TYPE_INT:
6620                         case TYPE_ADR:
6621                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
6622                                 M_ILD(d, REG_ITMP1, 0);
6623                                 break;
6624                         case TYPE_LNG:
6625                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
6626                                 M_LLD(d, REG_ITMP1, 0);
6627                                 break;
6628                         case TYPE_FLT:
6629                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6630                                 M_FLD(d, REG_ITMP1, 0);
6631                                 break;
6632                         case TYPE_DBL:                          
6633                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6634                                 M_DLD(d, REG_ITMP1, 0);
6635                                 break;
6636                         }
6637                         emit_store_dst(jd, iptr, d);
6638                         break;
6639
6640                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
6641
6642                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6643                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
6644
6645                                 fieldtype = uf->fieldref->parseddesc.fd->type;
6646
6647                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
6648                                                                         iptr->sx.s23.s3.uf, 0);
6649
6650                                 if (opt_showdisassemble) {
6651                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6652                                 }
6653
6654                                 disp = 0;
6655
6656                         }
6657                         else {
6658                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6659                                 
6660                                 fieldtype = fi->type;
6661
6662                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
6663                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
6664
6665                                         if (opt_showdisassemble) {
6666                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6667                                         }
6668                                 }
6669
6670                                 disp = (ptrint) &(fi->value);
6671                         }
6672
6673                         M_MOV_IMM(disp, REG_ITMP1);
6674                         switch (fieldtype) {
6675                         case TYPE_INT:
6676                         case TYPE_ADR:
6677                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
6678                                 M_IST(s1, REG_ITMP1, 0);
6679                                 break;
6680                         case TYPE_LNG:
6681                                 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
6682                                 M_LST(s1, REG_ITMP1, 0);
6683                                 break;
6684                         case TYPE_FLT:
6685                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6686                                 emit_fstps_membase(cd, REG_ITMP1, 0);
6687                                 break;
6688                         case TYPE_DBL:
6689                                 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6690                                 emit_fstpl_membase(cd, REG_ITMP1, 0);
6691                                 break;
6692                         }
6693                         break;
6694
6695                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
6696                                           /* val = value (in current instruction)     */
6697                                           /* following NOP)                           */
6698
6699                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6700                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
6701
6702                                 fieldtype = uf->fieldref->parseddesc.fd->type;
6703
6704                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
6705                                                                         uf, 0);
6706
6707                                 if (opt_showdisassemble) {
6708                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6709                                 }
6710
6711                                 disp = 0;
6712
6713                         }
6714                         else {
6715                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6716
6717                                 fieldtype = fi->type;
6718
6719                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
6720                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
6721
6722                                         if (opt_showdisassemble) {
6723                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6724                                         }
6725                                 }
6726
6727                                 disp = (ptrint) &(fi->value);
6728                         }
6729
6730                         M_MOV_IMM(disp, REG_ITMP1);
6731                         switch (fieldtype) {
6732                         case TYPE_INT:
6733                         case TYPE_ADR:
6734                                 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
6735                                 break;
6736                         case TYPE_LNG:
6737                                 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
6738                                 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
6739                                 break;
6740                         default:
6741                                 assert(0);
6742                         }
6743                         break;
6744
6745                 case ICMD_GETFIELD:   /* .., objectref.  ==> ..., value               */
6746
6747                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6748                         gen_nullptr_check(s1);
6749
6750                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6751                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
6752
6753                                 fieldtype = uf->fieldref->parseddesc.fd->type;
6754
6755                                 codegen_addpatchref(cd, PATCHER_getfield,
6756                                                                         iptr->sx.s23.s3.uf, 0);
6757
6758                                 if (opt_showdisassemble) {
6759                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6760                                 }
6761
6762                                 disp = 0;
6763
6764                         }
6765                         else {
6766                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6767                                 
6768                                 fieldtype = fi->type;
6769                                 disp = fi->offset;
6770                         }
6771
6772                         switch (fieldtype) {
6773                         case TYPE_INT:
6774                         case TYPE_ADR:
6775                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
6776                                 M_ILD32(d, s1, disp);
6777                                 break;
6778                         case TYPE_LNG:
6779                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
6780                                 M_LLD32(d, s1, disp);
6781                                 break;
6782                         case TYPE_FLT:
6783                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6784                                 M_FLD32(d, s1, disp);
6785                                 break;
6786                         case TYPE_DBL:                          
6787                                 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6788                                 M_DLD32(d, s1, disp);
6789                                 break;
6790                         }
6791                         emit_store_dst(jd, iptr, d);
6792                         break;
6793
6794                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
6795
6796                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6797                         gen_nullptr_check(s1);
6798
6799                         /* must be done here because of code patching */
6800
6801                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6802                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
6803
6804                                 fieldtype = uf->fieldref->parseddesc.fd->type;
6805                         }
6806                         else {
6807                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6808
6809                                 fieldtype = fi->type;
6810                         }
6811
6812                         if (!IS_FLT_DBL_TYPE(fieldtype)) {
6813                                 if (IS_2_WORD_TYPE(fieldtype))
6814                                         s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
6815                                 else
6816                                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6817                         }
6818                         else
6819                                 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
6820
6821                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6822                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
6823
6824                                 codegen_addpatchref(cd, PATCHER_putfield, uf, 0);
6825
6826                                 if (opt_showdisassemble) {
6827                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6828                                 }
6829
6830                                 disp = 0;
6831
6832                         }
6833                         else {
6834                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6835
6836                                 disp = fi->offset;
6837                         }
6838
6839                         switch (fieldtype) {
6840                         case TYPE_INT:
6841                         case TYPE_ADR:
6842                                 M_IST32(s2, s1, disp);
6843                                 break;
6844                         case TYPE_LNG:
6845                                 M_LST32(s2, s1, disp);
6846                                 break;
6847                         case TYPE_FLT:
6848                                 emit_fstps_membase32(cd, s1, disp);
6849                                 break;
6850                         case TYPE_DBL:
6851                                 emit_fstpl_membase32(cd, s1, disp);
6852                                 break;
6853                         }
6854                         break;
6855
6856                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
6857                                           /* val = value (in current instruction)     */
6858                                           /* following NOP)                           */
6859
6860                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6861                         gen_nullptr_check(s1);
6862
6863                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6864                                 unresolved_field *uf = iptr->sx.s23.s3.uf;
6865
6866                                 fieldtype = uf->fieldref->parseddesc.fd->type;
6867
6868                                 codegen_addpatchref(cd, PATCHER_putfieldconst,
6869                                                                         uf, 0);
6870
6871                                 if (opt_showdisassemble) {
6872                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6873                                 }
6874
6875                                 disp = 0;
6876
6877                         }
6878                         else
6879                         {
6880                                 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6881
6882                                 fieldtype = fi->type;
6883                                 disp = fi->offset;
6884                         }
6885
6886
6887                         switch (fieldtype) {
6888                         case TYPE_INT:
6889                         case TYPE_ADR:
6890                                 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
6891                                 break;
6892                         case TYPE_LNG:
6893                                 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
6894                                 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
6895                                 break;
6896                         default:
6897                                 assert(0);
6898                         }
6899                         break;
6900
6901
6902                 /* branch operations **************************************************/
6903
6904                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
6905
6906                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6907                         M_INTMOVE(s1, REG_ITMP1_XPTR);
6908
6909 #ifdef ENABLE_VERIFIER
6910                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6911                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
6912                                                                         iptr->sx.s23.s2.uc, 0);
6913
6914                                 if (opt_showdisassemble) {
6915                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6916                                 }
6917                         }
6918 #endif /* ENABLE_VERIFIER */
6919
6920                         M_CALL_IMM(0);                            /* passing exception pc */
6921                         M_POP(REG_ITMP2_XPC);
6922
6923                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
6924                         M_JMP(REG_ITMP3);
6925                         break;
6926
6927                 case ICMD_INLINE_GOTO:
6928 #if 0
6929                         M_COPY(src, iptr->dst.var);
6930 #endif
6931                         /* FALLTHROUGH! */
6932
6933                 case ICMD_GOTO:         /* ... ==> ...                                */
6934
6935 #if defined(ENABLE_SSA)
6936                         if ( ls != NULL ) {
6937                                 last_cmd_was_goto = true;
6938                                 /* In case of a Goto phimoves have to be inserted before the */
6939                                 /* jump */
6940                                 codegen_insert_phi_moves(cd, rd, ls, bptr);
6941                         }
6942 #endif
6943                         M_JMP_IMM(0);
6944                         codegen_addreference(cd, iptr->dst.block);
6945                         ALIGNCODENOP;
6946                         break;
6947
6948                 case ICMD_JSR:          /* ... ==> ...                                */
6949
6950                         M_CALL_IMM(0);
6951                         codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
6952                         break;
6953                         
6954                 case ICMD_RET:          /* ... ==> ...                                */
6955                                         /* s1.localindex = local variable                       */
6956
6957                         var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
6958                         if (IS_INMEMORY(var->flags)) {
6959                                 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
6960                                 M_JMP(REG_ITMP1);
6961                         }
6962                         else
6963                                 M_JMP(var->regoff);
6964                         break;
6965
6966                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
6967
6968                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6969                         M_TEST(s1);
6970                         M_BEQ(0);
6971                         codegen_addreference(cd, iptr->dst.block);
6972                         break;
6973
6974                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
6975
6976                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6977                         M_TEST(s1);
6978                         M_BNE(0);
6979                         codegen_addreference(cd, iptr->dst.block);
6980                         break;
6981
6982                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
6983
6984                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6985                         M_CMP_IMM(iptr->sx.val.i, s1);
6986                         M_BEQ(0);
6987                         codegen_addreference(cd, iptr->dst.block);
6988                         break;
6989
6990                 case ICMD_IFLT:         /* ..., value ==> ...                         */
6991
6992                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6993                         M_CMP_IMM(iptr->sx.val.i, s1);
6994                         M_BLT(0);
6995                         codegen_addreference(cd, iptr->dst.block);
6996                         break;
6997
6998                 case ICMD_IFLE:         /* ..., value ==> ...                         */
6999
7000                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7001                         M_CMP_IMM(iptr->sx.val.i, s1);
7002                         M_BLE(0);
7003                         codegen_addreference(cd, iptr->dst.block);
7004                         break;
7005
7006                 case ICMD_IFNE:         /* ..., value ==> ...                         */
7007
7008                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7009                         M_CMP_IMM(iptr->sx.val.i, s1);
7010                         M_BNE(0);
7011                         codegen_addreference(cd, iptr->dst.block);
7012                         break;
7013
7014                 case ICMD_IFGT:         /* ..., value ==> ...                         */
7015
7016                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7017                         M_CMP_IMM(iptr->sx.val.i, s1);
7018                         M_BGT(0);
7019                         codegen_addreference(cd, iptr->dst.block);
7020                         break;
7021
7022                 case ICMD_IFGE:         /* ..., value ==> ...                         */
7023
7024                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7025                         M_CMP_IMM(iptr->sx.val.i, s1);
7026                         M_BGE(0);
7027                         codegen_addreference(cd, iptr->dst.block);
7028                         break;
7029
7030                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
7031
7032                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7033                         if (iptr->sx.val.l == 0) {
7034                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
7035                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
7036                         }
7037                         else {
7038                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
7039                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
7040                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
7041                                 M_OR(REG_ITMP2, REG_ITMP1);
7042                         }
7043                         M_BEQ(0);
7044                         codegen_addreference(cd, iptr->dst.block);
7045                         break;
7046
7047                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
7048
7049                         if (iptr->sx.val.l == 0) {
7050                                 /* If high 32-bit are less than zero, then the 64-bits
7051                                    are too. */
7052                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
7053                                 M_CMP_IMM(0, s1);
7054                                 M_BLT(0);
7055                         }
7056                         else {
7057                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7058                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
7059                                 M_BLT(0);
7060                                 codegen_addreference(cd, iptr->dst.block);
7061                                 M_BGT(6 + 6);
7062                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
7063                                 M_BB(0);
7064                         }                       
7065                         codegen_addreference(cd, iptr->dst.block);
7066                         break;
7067
7068                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
7069
7070                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7071                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
7072                         M_BLT(0);
7073                         codegen_addreference(cd, iptr->dst.block);
7074                         M_BGT(6 + 6);
7075                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
7076                         M_BBE(0);
7077                         codegen_addreference(cd, iptr->dst.block);
7078                         break;
7079
7080                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
7081
7082                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7083                         if (iptr->sx.val.l == 0) {
7084                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
7085                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
7086                         }
7087                         else {
7088                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
7089                                 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
7090                                 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
7091                                 M_OR(REG_ITMP2, REG_ITMP1);
7092                         }
7093                         M_BNE(0);
7094                         codegen_addreference(cd, iptr->dst.block);
7095                         break;
7096
7097                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
7098
7099                         s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7100                         M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
7101                         M_BGT(0);
7102                         codegen_addreference(cd, iptr->dst.block);
7103                         M_BLT(6 + 6);
7104                         M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
7105                         M_BA(0);
7106                         codegen_addreference(cd, iptr->dst.block);
7107                         break;
7108
7109                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
7110
7111                         if (iptr->sx.val.l == 0) {
7112                                 /* If high 32-bit are greater equal zero, then the
7113                                    64-bits are too. */
7114                                 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
7115                                 M_CMP_IMM(0, s1);
7116                                 M_BGE(0);
7117                         }
7118                         else {
7119                                 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7120                                 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
7121                                 M_BGT(0);
7122                                 codegen_addreference(cd, iptr->dst.block);
7123                                 M_BLT(6 + 6);
7124                                 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
7125                                 M_BAE(0);
7126                         }
7127                         codegen_addreference(cd, iptr->dst.block);
7128                         break;
7129
7130                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
7131                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
7132
7133                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7134                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7135                         M_CMP(s2, s1);
7136                         M_BEQ(0);
7137                         codegen_addreference(cd, iptr->dst.block);
7138                         break;
7139
7140                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
7141
7142                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7143                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7144                         M_INTMOVE(s1, REG_ITMP1);
7145                         M_XOR(s2, REG_ITMP1);
7146                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
7147                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
7148                         M_INTMOVE(s1, REG_ITMP2);
7149                         M_XOR(s2, REG_ITMP2);
7150                         M_OR(REG_ITMP1, REG_ITMP2);
7151                         M_BEQ(0);
7152                         codegen_addreference(cd, iptr->dst.block);
7153                         break;
7154
7155                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
7156                 case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
7157
7158                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7159                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7160                         M_CMP(s2, s1);
7161                         M_BNE(0);
7162                         codegen_addreference(cd, iptr->dst.block);
7163                         break;
7164
7165                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
7166
7167                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7168                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7169                         M_INTMOVE(s1, REG_ITMP1);
7170                         M_XOR(s2, REG_ITMP1);
7171                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
7172                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
7173                         M_INTMOVE(s1, REG_ITMP2);
7174                         M_XOR(s2, REG_ITMP2);
7175                         M_OR(REG_ITMP1, REG_ITMP2);
7176                         M_BNE(0);
7177                         codegen_addreference(cd, iptr->dst.block);
7178                         break;
7179
7180                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
7181
7182                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7183                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7184                         M_CMP(s2, s1);
7185                         M_BLT(0);
7186                         codegen_addreference(cd, iptr->dst.block);
7187                         break;
7188
7189                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
7190
7191                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
7192                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
7193                         M_CMP(s2, s1);
7194                         M_BLT(0);
7195                         codegen_addreference(cd, iptr->dst.block);
7196                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7197                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7198                         M_BGT(2 + 6);
7199                         M_CMP(s2, s1);
7200                         M_BB(0);
7201                         codegen_addreference(cd, iptr->dst.block);
7202                         break;
7203
7204                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
7205
7206                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7207                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7208                         M_CMP(s2, s1);
7209                         M_BGT(0);
7210                         codegen_addreference(cd, iptr->dst.block);
7211                         break;
7212
7213                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
7214
7215                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
7216                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
7217                         M_CMP(s2, s1);
7218                         M_BGT(0);
7219                         codegen_addreference(cd, iptr->dst.block);
7220                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7221                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7222                         M_BLT(2 + 6);
7223                         M_CMP(s2, s1);
7224                         M_BA(0);
7225                         codegen_addreference(cd, iptr->dst.block);
7226                         break;
7227
7228                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
7229
7230                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7231                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7232                         M_CMP(s2, s1);
7233                         M_BLE(0);
7234                         codegen_addreference(cd, iptr->dst.block);
7235                         break;
7236
7237                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
7238
7239                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
7240                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
7241                         M_CMP(s2, s1);
7242                         M_BLT(0);
7243                         codegen_addreference(cd, iptr->dst.block);
7244                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7245                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7246                         M_BGT(2 + 6);
7247                         M_CMP(s2, s1);
7248                         M_BBE(0);
7249                         codegen_addreference(cd, iptr->dst.block);
7250                         break;
7251
7252                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
7253
7254                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7255                         s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7256                         M_CMP(s2, s1);
7257                         M_BGE(0);
7258                         codegen_addreference(cd, iptr->dst.block);
7259                         break;
7260
7261                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
7262
7263                         s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
7264                         s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
7265                         M_CMP(s2, s1);
7266                         M_BGT(0);
7267                         codegen_addreference(cd, iptr->dst.block);
7268                         s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7269                         s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7270                         M_BLT(2 + 6);
7271                         M_CMP(s2, s1);
7272                         M_BAE(0);
7273                         codegen_addreference(cd, iptr->dst.block);
7274                         break;
7275
7276
7277                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
7278
7279                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
7280                         M_INTMOVE(s1, REG_RESULT);
7281                         goto nowperformreturn;
7282
7283                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
7284
7285                         s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
7286                         M_LNGMOVE(s1, REG_RESULT_PACKED);
7287                         goto nowperformreturn;
7288
7289                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
7290
7291                         s1 = emit_load_s1(jd, iptr, REG_RESULT);
7292                         M_INTMOVE(s1, REG_RESULT);
7293
7294 #ifdef ENABLE_VERIFIER
7295                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7296                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
7297                                                                         iptr->sx.s23.s2.uc, 0);
7298
7299                                 if (opt_showdisassemble) {
7300                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7301                                 }
7302                         }
7303 #endif /* ENABLE_VERIFIER */
7304                         goto nowperformreturn;
7305
7306                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
7307                 case ICMD_DRETURN:
7308
7309                         s1 = emit_load_s1(jd, iptr, REG_FRESULT);
7310                         goto nowperformreturn;
7311
7312                 case ICMD_RETURN:      /* ...  ==> ...                                */
7313
7314 nowperformreturn:
7315                         {
7316                         s4 i, p;
7317                         
7318                         p = cd->stackframesize;
7319                         
7320 #if !defined(NDEBUG)
7321                         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
7322                                 emit_verbosecall_exit(jd);
7323 #endif
7324
7325 #if defined(ENABLE_THREADS)
7326                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
7327                                 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
7328
7329                                 /* we need to save the proper return value */
7330                                 switch (iptr->opc) {
7331                                 case ICMD_IRETURN:
7332                                 case ICMD_ARETURN:
7333                                         M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
7334                                         break;
7335
7336                                 case ICMD_LRETURN:
7337                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
7338                                         break;
7339
7340                                 case ICMD_FRETURN:
7341                                         emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
7342                                         break;
7343
7344                                 case ICMD_DRETURN:
7345                                         emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
7346                                         break;
7347                                 }
7348
7349                                 M_AST(REG_ITMP2, REG_SP, 0);
7350                                 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
7351                                 M_CALL(REG_ITMP3);
7352
7353                                 /* and now restore the proper return value */
7354                                 switch (iptr->opc) {
7355                                 case ICMD_IRETURN:
7356                                 case ICMD_ARETURN:
7357                                         M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
7358                                         break;
7359
7360                                 case ICMD_LRETURN:
7361                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
7362                                         break;
7363
7364                                 case ICMD_FRETURN:
7365                                         emit_flds_membase(cd, REG_SP, rd->memuse * 4);
7366                                         break;
7367
7368                                 case ICMD_DRETURN:
7369                                         emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
7370                                         break;
7371                                 }
7372                         }
7373 #endif
7374
7375                         /* restore saved registers */
7376
7377                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
7378                                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
7379                         }
7380
7381                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
7382                                 p--;
7383                                 emit_fldl_membase(cd, REG_SP, p * 4);
7384                                 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
7385                                         assert(0);
7386 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
7387                                 } else {
7388                                         assert(0);
7389 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
7390                                 }
7391                         }
7392
7393                         /* deallocate stack */
7394
7395                         if (cd->stackframesize)
7396                                 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
7397
7398                         emit_ret(cd);
7399                         }
7400                         break;
7401
7402
7403                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
7404                         {
7405                                 s4 i, l;
7406                                 branch_target_t *table;
7407
7408                                 table = iptr->dst.table;
7409
7410                                 l = iptr->sx.s23.s2.tablelow;
7411                                 i = iptr->sx.s23.s3.tablehigh;
7412
7413                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7414                                 M_INTMOVE(s1, REG_ITMP1);
7415
7416                                 if (l != 0)
7417                                         M_ISUB_IMM(l, REG_ITMP1);
7418
7419                                 i = i - l + 1;
7420
7421                 /* range check */
7422                                 M_CMP_IMM(i - 1, REG_ITMP1);
7423                                 M_BA(0);
7424
7425                                 codegen_addreference(cd, table[0].block); /* default target */
7426
7427                                 /* build jump table top down and use address of lowest entry */
7428
7429                                 table += i;
7430
7431                                 while (--i >= 0) {
7432                                         dseg_addtarget(cd, table->block); 
7433                                         --table;
7434                                 }
7435
7436                                 /* length of dataseg after last dseg_addtarget is used
7437                                    by load */
7438
7439                                 M_MOV_IMM(0, REG_ITMP2);
7440                                 dseg_adddata(cd);
7441                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
7442                                 M_JMP(REG_ITMP1);
7443                         }
7444                         break;
7445
7446
7447                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
7448                         {
7449                                 s4 i;
7450                                 lookup_target_t *lookup;
7451
7452                                 lookup = iptr->dst.lookup;
7453
7454                                 i = iptr->sx.s23.s2.lookupcount;
7455                         
7456                                 MCODECHECK((i<<2)+8);
7457                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7458
7459                                 while (--i >= 0) {
7460                                         M_CMP_IMM(lookup->value, s1);
7461                                         M_BEQ(0);
7462                                         codegen_addreference(cd, lookup->target.block);
7463                                         lookup++;
7464                                 }
7465
7466                                 M_JMP_IMM(0);
7467                         
7468                                 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
7469                         }
7470                         break;
7471
7472                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
7473
7474                         bte = iptr->sx.s23.s3.bte;
7475                         md  = bte->md;
7476                         goto gen_method;
7477
7478                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
7479
7480                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
7481                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
7482                 case ICMD_INVOKEINTERFACE:
7483
7484                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7485                                 lm = NULL;
7486                                 um = iptr->sx.s23.s3.um;
7487                                 md = um->methodref->parseddesc.md;
7488                         }
7489                         else {
7490                                 lm = iptr->sx.s23.s3.fmiref->p.method;
7491                                 um = NULL;
7492                                 md = lm->parseddesc;
7493                         }
7494
7495 gen_method:
7496                         s3 = md->paramcount;
7497
7498                         MCODECHECK((s3 << 1) + 64);
7499
7500                         /* copy arguments to registers or stack location                  */
7501
7502                         for (s3 = s3 - 1; s3 >= 0; s3--) {
7503                                 src = iptr->sx.s23.s2.args[s3];
7504                 
7505                                 if (src->varkind == ARGVAR)
7506                                         continue;
7507
7508                                 if (IS_INT_LNG_TYPE(src->type)) {
7509                                         if (!md->params[s3].inmemory) {
7510                                                 log_text("No integer argument registers available!");
7511                                                 assert(0);
7512                                         }
7513                                         else {
7514                                                 if (IS_2_WORD_TYPE(src->type)) {
7515                                                         d = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
7516                                                         M_LST(d, REG_SP, md->params[s3].regoff * 4);
7517                                                 }
7518                                                 else {
7519                                                         d = emit_load(jd, iptr, src, REG_ITMP1);
7520                                                         M_IST(d, REG_SP, md->params[s3].regoff * 4);
7521                                                 }
7522                                         }
7523                                 }
7524                                 else {
7525                                         if (!md->params[s3].inmemory) {
7526                                                 s1 = rd->argfltregs[md->params[s3].regoff];
7527                                                 d = emit_load(jd, iptr, src, s1);
7528                                                 M_FLTMOVE(d, s1);
7529                                         }
7530                                         else {
7531                                                 d = emit_load(jd, iptr, src, REG_FTMP1);
7532                                                 if (IS_2_WORD_TYPE(src->type))
7533                                                         M_DST(d, REG_SP, md->params[s3].regoff * 4);
7534                                                 else
7535                                                         M_FST(d, REG_SP, md->params[s3].regoff * 4);
7536                                         }
7537                                 }
7538                         }
7539
7540                         switch (iptr->opc) {
7541                         case ICMD_BUILTIN:
7542                                 M_MOV_IMM(bte->fp, REG_ITMP1);
7543                                 M_CALL(REG_ITMP1);
7544
7545                                 if (INSTRUCTION_MUST_CHECK(iptr)) {
7546                                         M_TEST(REG_RESULT);
7547                                         M_BEQ(0);
7548                                         codegen_add_fillinstacktrace_ref(cd);
7549                                 }
7550                                 break;
7551
7552                         case ICMD_INVOKESPECIAL:
7553                                 M_ALD(REG_ITMP1, REG_SP, 0);
7554                                 M_TEST(REG_ITMP1);
7555                                 M_BEQ(0);
7556                                 codegen_add_nullpointerexception_ref(cd);
7557
7558                                 /* fall through */
7559
7560                         case ICMD_INVOKESTATIC:
7561                                 if (lm == NULL) {
7562                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
7563                                                                                 um, 0);
7564
7565                                         if (opt_showdisassemble) {
7566                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7567                                         }
7568
7569                                         disp = 0;
7570                                 }
7571                                 else
7572                                         disp = (ptrint) lm->stubroutine;
7573
7574                                 M_MOV_IMM(disp, REG_ITMP2);
7575                                 M_CALL(REG_ITMP2);
7576                                 break;
7577
7578                         case ICMD_INVOKEVIRTUAL:
7579                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
7580                                 gen_nullptr_check(REG_ITMP1);
7581
7582                                 if (lm == NULL) {
7583                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
7584
7585                                         if (opt_showdisassemble) {
7586                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7587                                         }
7588
7589                                         s1 = 0;
7590                                 }
7591                                 else
7592                                         s1 = OFFSET(vftbl_t, table[0]) +
7593                                                 sizeof(methodptr) * lm->vftblindex;
7594
7595                                 M_ALD(REG_METHODPTR, REG_ITMP1,
7596                                           OFFSET(java_objectheader, vftbl));
7597                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
7598                                 M_CALL(REG_ITMP3);
7599                                 break;
7600
7601                         case ICMD_INVOKEINTERFACE:
7602                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
7603                                 gen_nullptr_check(REG_ITMP1);
7604
7605                                 if (lm == NULL) {
7606                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
7607
7608                                         if (opt_showdisassemble) {
7609                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7610                                         }
7611
7612                                         s1 = 0;
7613                                         s2 = 0;
7614                                 }
7615                                 else {
7616                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
7617                                                 sizeof(methodptr) * lm->class->index;
7618
7619                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
7620                                 }
7621
7622                                 M_ALD(REG_METHODPTR, REG_ITMP1,
7623                                           OFFSET(java_objectheader, vftbl));
7624                                 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
7625                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
7626                                 M_CALL(REG_ITMP3);
7627                                 break;
7628                         }
7629
7630                         /* store return value */
7631
7632                         d = md->returntype.type;
7633
7634                         if (d != TYPE_VOID) {
7635 #if defined(ENABLE_SSA)
7636                                 if ((ls == NULL) || (iptr->dst->varkind != TEMPVAR) ||
7637                                         (ls->lifetime[-iptr->dst->varnum-1].type != -1)) 
7638                                         /* a "living" stackslot */
7639 #endif
7640                                 {
7641                                         if (IS_INT_LNG_TYPE(d)) {
7642                                                 if (IS_2_WORD_TYPE(d)) {
7643                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
7644                                                         M_LNGMOVE(REG_RESULT_PACKED, s1);
7645                                                 }
7646                                                 else {
7647                                                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
7648                                                         M_INTMOVE(REG_RESULT, s1);
7649                                                 }
7650                                         }
7651                                         else {
7652                                                 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
7653                                         }
7654                                         emit_store_dst(jd, iptr, s1);
7655                                 }
7656                         }
7657                         break;
7658
7659
7660                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
7661                                       /* val.a: (classinfo*) superclass               */
7662
7663                         /*  superclass is an interface:
7664                          *
7665                          *  OK if ((sub == NULL) ||
7666                          *         (sub->vftbl->interfacetablelength > super->index) &&
7667                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
7668                          *
7669                          *  superclass is a class:
7670                          *
7671                          *  OK if ((sub == NULL) || (0
7672                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
7673                          *         super->vftbl->diffval));
7674                          */
7675
7676                         if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
7677                                 /* object type cast-check */
7678
7679                                 classinfo *super;
7680                                 vftbl_t   *supervftbl;
7681                                 s4         superindex;
7682
7683                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7684                                         super = NULL;
7685                                         superindex = 0;
7686                                         supervftbl = NULL;
7687                                 }
7688                                 else {
7689                                         super = iptr->sx.s23.s3.c.cls;
7690                                         superindex = super->index;
7691                                         supervftbl = super->vftbl;
7692                                 }
7693                         
7694 #if defined(ENABLE_THREADS)
7695                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
7696 #endif
7697                                 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7698
7699                                 /* calculate interface checkcast code size */
7700
7701                                 s2 = 2; /* mov_membase_reg */
7702                                 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
7703
7704                                 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
7705                                            2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
7706                                            2 /* test */ + 6 /* jcc */);
7707
7708                                 if (!super)
7709                                         s2 += (opt_showdisassemble ? 5 : 0);
7710
7711                                 /* calculate class checkcast code size */
7712
7713                                 s3 = 2; /* mov_membase_reg */
7714                                 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
7715
7716                                 s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
7717
7718 #if 0
7719                                 if (s1 != REG_ITMP1) {
7720                                         a += 2;
7721                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
7722                                 
7723                                         a += 2;
7724                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
7725                                 
7726                                         a += 2;
7727                                 
7728                                 } else
7729 #endif
7730                                         {
7731                                                 s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
7732                                                            5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
7733                                                 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
7734                                         }
7735
7736                                 s3 += 2 /* cmp */ + 6 /* jcc */;
7737
7738                                 if (super == NULL)
7739                                         s3 += (opt_showdisassemble ? 5 : 0);
7740
7741                                 /* if class is not resolved, check which code to call */
7742
7743                                 if (super == NULL) {
7744                                         M_TEST(s1);
7745                                         M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
7746
7747                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
7748                                                                                 iptr->sx.s23.s3.c.ref, 0);
7749
7750                                         if (opt_showdisassemble) {
7751                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7752                                         }
7753
7754                                         M_MOV_IMM(0, REG_ITMP2);                  /* super->flags */
7755                                         M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
7756                                         M_BEQ(s2 + 5);
7757                                 }
7758
7759                                 /* interface checkcast code */
7760
7761                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
7762                                         if (super != NULL) {
7763                                                 M_TEST(s1);
7764                                                 M_BEQ(s2);
7765                                         }
7766
7767                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
7768
7769                                         if (super == NULL) {
7770                                                 codegen_addpatchref(cd,
7771                                                                                         PATCHER_checkcast_instanceof_interface,
7772                                                                                         iptr->sx.s23.s3.c.ref,
7773                                                                                         0);
7774
7775                                                 if (opt_showdisassemble) {
7776                                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7777                                                 }
7778                                         }
7779
7780                                         M_ILD32(REG_ITMP3,
7781                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
7782                                         M_ISUB_IMM32(superindex, REG_ITMP3);
7783                                         M_TEST(REG_ITMP3);
7784                                         M_BLE(0);
7785                                         codegen_add_classcastexception_ref(cd, s1);
7786                                         M_ALD32(REG_ITMP3, REG_ITMP2,
7787                                                         OFFSET(vftbl_t, interfacetable[0]) -
7788                                                         superindex * sizeof(methodptr*));
7789                                         M_TEST(REG_ITMP3);
7790                                         M_BEQ(0);
7791                                         codegen_add_classcastexception_ref(cd, s1);
7792
7793                                         if (super == NULL)
7794                                                 M_JMP_IMM(s3);
7795                                 }
7796
7797                                 /* class checkcast code */
7798
7799                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
7800                                         if (super != NULL) {
7801                                                 M_TEST(s1);
7802                                                 M_BEQ(s3);
7803                                         }
7804
7805                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
7806
7807                                         if (super == NULL) {
7808                                                 codegen_addpatchref(cd, PATCHER_checkcast_class,
7809                                                                                         iptr->sx.s23.s3.c.ref,
7810                                                                                         0);
7811
7812                                                 if (opt_showdisassemble) {
7813                                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7814                                                 }
7815                                         }
7816
7817                                         M_MOV_IMM(supervftbl, REG_ITMP3);
7818 #if defined(ENABLE_THREADS)
7819                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
7820 #endif
7821                                         M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
7822
7823                                         /*                              if (s1 != REG_ITMP1) { */
7824                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
7825                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
7826                                         /* #if defined(ENABLE_THREADS) */
7827                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
7828                                         /* #endif */
7829                                         /*                                      emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
7830
7831                                         /*                              } else { */
7832                                         M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
7833                                         M_ISUB(REG_ITMP3, REG_ITMP2);
7834                                         M_MOV_IMM(supervftbl, REG_ITMP3);
7835                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
7836 #if defined(ENABLE_THREADS)
7837                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
7838 #endif
7839                                         /*                              } */
7840
7841                                         M_CMP(REG_ITMP3, REG_ITMP2);
7842                                         M_BA(0);         /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
7843                                         codegen_add_classcastexception_ref(cd, s1);
7844                                 }
7845
7846                                 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
7847                         }
7848                         else {
7849                                 /* array type cast-check */
7850
7851                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
7852                                 M_AST(s1, REG_SP, 0 * 4);
7853
7854                                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7855                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
7856                                                                                 iptr->sx.s23.s3.c.ref, 0);
7857
7858                                         if (opt_showdisassemble) {
7859                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7860                                         }
7861                                 }
7862
7863                                 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
7864                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
7865                                 M_CALL(REG_ITMP3);
7866
7867                                 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
7868                                 M_TEST(REG_RESULT);
7869                                 M_BEQ(0);
7870                                 codegen_add_classcastexception_ref(cd, s1);
7871
7872                                 d = codegen_reg_of_dst(jd, iptr, s1);
7873                         }
7874
7875                         M_INTMOVE(s1, d);
7876                         emit_store_dst(jd, iptr, d);
7877                         break;
7878
7879                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
7880                                       /* val.a: (classinfo*) superclass               */
7881
7882                         /*  superclass is an interface:
7883                          *
7884                          *  return (sub != NULL) &&
7885                          *         (sub->vftbl->interfacetablelength > super->index) &&
7886                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
7887                          *
7888                          *  superclass is a class:
7889                          *
7890                          *  return ((sub != NULL) && (0
7891                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
7892                          *          super->vftbl->diffvall));
7893                          */
7894
7895                         {
7896                         classinfo *super;
7897                         vftbl_t   *supervftbl;
7898                         s4         superindex;
7899
7900                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7901                                 super = NULL;
7902                                 superindex = 0;
7903                                 supervftbl = NULL;
7904
7905                         } else {
7906                                 super = iptr->sx.s23.s3.c.cls;
7907                                 superindex = super->index;
7908                                 supervftbl = super->vftbl;
7909                         }
7910                         
7911 #if defined(ENABLE_THREADS)
7912                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
7913 #endif
7914
7915                         s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7916                         d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
7917                         if (s1 == d) {
7918                                 M_INTMOVE(s1, REG_ITMP1);
7919                                 s1 = REG_ITMP1;
7920                         }
7921
7922                         /* calculate interface instanceof code size */
7923
7924                         s2 = 2; /* mov_membase_reg */
7925                         CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
7926
7927                         s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
7928                                    2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
7929                                    2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
7930
7931                         if (!super)
7932                                 s2 += (opt_showdisassemble ? 5 : 0);
7933
7934                         /* calculate class instanceof code size */
7935
7936                         s3 = 2; /* mov_membase_reg */
7937                         CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
7938                         s3 += 5; /* mov_imm_reg */
7939                         s3 += 2;
7940                         CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
7941                         s3 += 2;
7942                         CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
7943                         s3 += 2;
7944                         CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
7945
7946                         s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
7947                                    2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
7948
7949                         if (!super)
7950                                 s3 += (opt_showdisassemble ? 5 : 0);
7951
7952                         M_CLR(d);
7953
7954                         /* if class is not resolved, check which code to call */
7955
7956                         if (!super) {
7957                                 M_TEST(s1);
7958                                 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
7959
7960                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
7961                                                                         iptr->sx.s23.s3.c.ref, 0);
7962
7963                                 if (opt_showdisassemble) {
7964                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7965                                 }
7966
7967                                 M_MOV_IMM(0, REG_ITMP3);                      /* super->flags */
7968                                 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
7969                                 M_BEQ(s2 + 5);
7970                         }
7971
7972                         /* interface instanceof code */
7973
7974                         if (!super || (super->flags & ACC_INTERFACE)) {
7975                                 if (super) {
7976                                         M_TEST(s1);
7977                                         M_BEQ(s2);
7978                                 }
7979
7980                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
7981
7982                                 if (!super) {
7983                                         codegen_addpatchref(cd,
7984                                                                                 PATCHER_checkcast_instanceof_interface,
7985                                                                                 iptr->sx.s23.s3.c.ref, 0);
7986
7987                                         if (opt_showdisassemble) {
7988                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7989                                         }
7990                                 }
7991
7992                                 M_ILD32(REG_ITMP3,
7993                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
7994                                 M_ISUB_IMM32(superindex, REG_ITMP3);
7995                                 M_TEST(REG_ITMP3);
7996
7997                                 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
7998                                                 6 /* jcc */ + 5 /* mov_imm_reg */);
7999
8000                                 M_BLE(disp);
8001                                 M_ALD32(REG_ITMP1, REG_ITMP1,
8002                                                 OFFSET(vftbl_t, interfacetable[0]) -
8003                                                 superindex * sizeof(methodptr*));
8004                                 M_TEST(REG_ITMP1);
8005 /*                                      emit_setcc_reg(cd, CC_A, d); */
8006 /*                                      emit_jcc(cd, CC_BE, 5); */
8007                                 M_BEQ(5);
8008                                 M_MOV_IMM(1, d);
8009
8010                                 if (!super)
8011                                         M_JMP_IMM(s3);
8012                         }
8013
8014                         /* class instanceof code */
8015
8016                         if (!super || !(super->flags & ACC_INTERFACE)) {
8017                                 if (super) {
8018                                         M_TEST(s1);
8019                                         M_BEQ(s3);
8020                                 }
8021
8022                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
8023
8024                                 if (!super) {
8025                                         codegen_addpatchref(cd, PATCHER_instanceof_class,
8026                                                                                 iptr->sx.s23.s3.c.ref, 0);
8027
8028                                         if (opt_showdisassemble) {
8029                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
8030                                         }
8031                                 }
8032
8033                                 M_MOV_IMM(supervftbl, REG_ITMP2);
8034 #if defined(ENABLE_THREADS)
8035                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
8036 #endif
8037                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
8038                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
8039                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
8040 #if defined(ENABLE_THREADS)
8041                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
8042 #endif
8043                                 M_ISUB(REG_ITMP2, REG_ITMP1);
8044                                 M_CLR(d);                                 /* may be REG_ITMP2 */
8045                                 M_CMP(REG_ITMP3, REG_ITMP1);
8046                                 M_BA(5);
8047                                 M_MOV_IMM(1, d);
8048                         }
8049                         emit_store_dst(jd, iptr, d);
8050                         }
8051                         break;
8052
8053                         break;
8054
8055                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
8056
8057                         /* check for negative sizes and copy sizes to stack if necessary  */
8058
8059                         MCODECHECK((iptr->s1.argcount << 1) + 64);
8060
8061                         for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
8062                                 /* copy SAVEDVAR sizes to stack */
8063                                 src = iptr->sx.s23.s2.args[s1];
8064
8065                                 if (src->varkind != ARGVAR) {
8066                                         if (IS_INMEMORY(src->flags)) {
8067                                                 M_ILD(REG_ITMP1, REG_SP, src->regoff * 4);
8068                                                 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
8069                                         }
8070                                         else
8071                                                 M_IST(src->regoff, REG_SP, (s1 + 3) * 4);
8072                                 }
8073                         }
8074
8075                         /* is a patcher function set? */
8076
8077                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
8078                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
8079                                                                         iptr->sx.s23.s3.c.ref, 0);
8080
8081                                 if (opt_showdisassemble) {
8082                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
8083                                 }
8084
8085                                 disp = 0;
8086
8087                         }
8088                         else
8089                                 disp = (ptrint) iptr->sx.s23.s3.c.cls;
8090
8091                         /* a0 = dimension count */
8092
8093                         M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
8094
8095                         /* a1 = arraydescriptor */
8096
8097                         M_IST_IMM(disp, REG_SP, 1 * 4);
8098
8099                         /* a2 = pointer to dimensions = stack pointer */
8100
8101                         M_MOV(REG_SP, REG_ITMP1);
8102                         M_AADD_IMM(3 * 4, REG_ITMP1);
8103                         M_AST(REG_ITMP1, REG_SP, 2 * 4);
8104
8105                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
8106                         M_CALL(REG_ITMP1);
8107
8108                         /* check for exception before result assignment */
8109
8110                         M_TEST(REG_RESULT);
8111                         M_BEQ(0);
8112                         codegen_add_fillinstacktrace_ref(cd);
8113
8114                         s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
8115                         M_INTMOVE(REG_RESULT, s1);
8116                         emit_store_dst(jd, iptr, s1);
8117                         break;
8118
8119                 default:
8120                         *exceptionptr =
8121                                 new_internalerror("Unknown ICMD %d", iptr->opc);
8122                         return false;
8123         } /* switch */
8124                 
8125         } /* for instruction */
8126                 
8127         /* copy values to interface registers */
8128
8129         len = bptr->outdepth;
8130         MCODECHECK(64+len);
8131 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
8132         if (!opt_lsra)
8133 #endif
8134 #if defined(ENABLE_SSA)
8135         if ( ls != NULL ) {
8136                 /* by edge splitting, in Blocks with phi moves there can only */
8137                 /* be a goto as last command, no other Jump/Branch Command    */
8138                 if (!last_cmd_was_goto)
8139                         codegen_insert_phi_moves(cd, rd, ls, bptr);
8140         }
8141  #if !defined(NEW_VAR)
8142         else
8143  #endif
8144 #endif
8145 #if !defined(NEW_VAR)
8146         while (len) {
8147                 len--;
8148                 src = bptr->outvars[len];
8149                 if ((src->varkind != STACKVAR)) {
8150                         s2 = src->type;
8151                         if (IS_FLT_DBL_TYPE(s2)) {
8152                                 s1 = emit_load(jd, iptr, src, REG_FTMP1);
8153                                 if (!IS_INMEMORY(rd->interfaces[len][s2].flags))
8154                                         M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
8155                                 else
8156                                         M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
8157                                 
8158                         } else {
8159                                 if (IS_2_WORD_TYPE(s2))
8160                                         assert(0);
8161 /*                  s1 = emit_load(jd, iptr, src, 
8162                                                        PACK_REGS(REG_ITMP1, REG_ITMP2)); */
8163                                 else
8164                                         s1 = emit_load(jd, iptr, src, REG_ITMP1);
8165                                 
8166                                 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
8167                                         if (IS_2_WORD_TYPE(s2))
8168                                                 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
8169                                         else
8170                                                 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
8171                                         
8172                                 } else {
8173                                         if (IS_2_WORD_TYPE(s2))
8174                                                 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
8175                                         else
8176                                                 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
8177                                 }
8178                         }
8179                 }
8180                 src = src->prev;
8181         }
8182 #endif
8183
8184         /* At the end of a basic block we may have to append some nops,
8185            because the patcher stub calling code might be longer than the
8186            actual instruction. So codepatching does not change the
8187            following block unintentionally. */
8188
8189         if (cd->mcodeptr < cd->lastmcodeptr) {
8190                 while (cd->mcodeptr < cd->lastmcodeptr) {
8191                         M_NOP;
8192                 }
8193         }
8194
8195         } /* if (bptr -> flags >= BBREACHED) */
8196         } /* for basic block */
8197
8198         dseg_createlinenumbertable(cd);
8199
8200
8201         /* generate exception and patcher stubs */
8202
8203         emit_exception_stubs(jd);
8204         emit_patcher_stubs(jd);
8205 #if 0
8206         emit_replacement_stubs(jd);
8207 #endif
8208
8209         codegen_finish(jd);
8210
8211         /* everything's ok */
8212
8213         return true;
8214 }
8215 #endif /* defined(NEW_VAR) */
8216
8217 #if defined(ENABLE_SSA)
8218 void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls, basicblock *bptr) {
8219         /* look for phi moves */
8220         int t_a,s_a,i, type;
8221         int t_lt, s_lt; /* lifetime indices of phi_moves */
8222         bool t_inmemory, s_inmemory;
8223         s4 t_regoff, s_regoff, s_flags, t_flags;
8224         MCODECHECK(512);
8225         
8226         /* Moves from phi functions with highest indices have to be */
8227         /* inserted first, since this is the order as is used for   */
8228         /* conflict resolution */
8229         for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
8230                 t_a = ls->phi_moves[bptr->nr][i][0];
8231                 s_a = ls->phi_moves[bptr->nr][i][1];
8232 #if defined(SSA_DEBUG_VERBOSE)
8233                 if (compileverbose)
8234                         printf("BB %3i Move %3i <- %3i ",bptr->nr,t_a,s_a);
8235 #endif
8236                 if (t_a >= 0) {
8237                         /* local var lifetimes */
8238                         t_lt = ls->maxlifetimes + t_a;
8239                         type = ls->lifetime[t_lt].type;
8240                 } else {
8241                         t_lt = -t_a-1;
8242                         type = ls->lifetime[t_lt].local_ss->s->type;
8243                         /* stackslot lifetime */
8244                 }
8245                 if (type == -1) {
8246 #if defined(SSA_DEBUG_VERBOSE)
8247                 if (compileverbose)
8248                         printf("...returning - phi lifetimes where joined\n");
8249 #endif
8250                         return;
8251                 }
8252                 if (s_a >= 0) {
8253                         /* local var lifetimes */
8254                         s_lt = ls->maxlifetimes + s_a;
8255                         type = ls->lifetime[s_lt].type;
8256                 } else {
8257                         s_lt = -s_a-1;
8258                         type = ls->lifetime[s_lt].type;
8259                         /* stackslot lifetime */
8260                 }
8261                 if (type == -1) {
8262 #if defined(SSA_DEBUG_VERBOSE)
8263                 if (compileverbose)
8264                         printf("...returning - phi lifetimes where joined\n");
8265 #endif
8266                         return;
8267                 }
8268                 if (t_a >= 0) {
8269
8270                         t_inmemory = rd->locals[t_a][type].flags & INMEMORY;
8271                         t_flags = rd->locals[t_a][type].flags;
8272                         t_regoff = rd->locals[t_a][type].regoff;
8273                         
8274                 } else {
8275                         t_inmemory = ls->lifetime[t_lt].local_ss->s->flags & INMEMORY;
8276                         t_flags = ls->lifetime[t_lt].local_ss->s->flags;
8277                         t_regoff = ls->lifetime[t_lt].local_ss->s->regoff;
8278                 }
8279
8280                 if (s_a >= 0) {
8281                         /* local var move */
8282                         
8283                         s_inmemory = rd->locals[s_a][type].flags & INMEMORY;
8284                         s_flags = rd->locals[s_a][type].flags;
8285                         s_regoff = rd->locals[s_a][type].regoff;
8286                 } else {
8287                         /* stackslot lifetime */
8288                         s_inmemory = ls->lifetime[s_lt].local_ss->s->flags & INMEMORY;
8289                         s_flags = ls->lifetime[s_lt].local_ss->s->flags;
8290                         s_regoff = ls->lifetime[s_lt].local_ss->s->regoff;
8291                 }
8292                 if (type == -1) {
8293 #if defined(SSA_DEBUG_VERBOSE)
8294                 if (compileverbose)
8295                         printf("...returning - phi lifetimes where joined\n");
8296 #endif
8297                         return;
8298                 }
8299
8300                 cg_move(cd, type, s_regoff, s_flags, t_regoff, t_flags);
8301
8302 #if defined(SSA_DEBUG_VERBOSE)
8303                 if (compileverbose) {
8304                         if ((t_inmemory) && (s_inmemory)) {
8305                                 /* mem -> mem */
8306                                 printf("M%3i <- M%3i",t_regoff,s_regoff);
8307                         } else  if (s_inmemory) {
8308                                 /* mem -> reg */
8309                                 printf("R%3i <- M%3i",t_regoff,s_regoff);
8310                         } else if (t_inmemory) {
8311                                 /* reg -> mem */
8312                                 printf("M%3i <- R%3i",t_regoff,s_regoff);
8313                         } else {
8314                                 /* reg -> reg */
8315                                 printf("R%3i <- R%3i",t_regoff,s_regoff);
8316                         }
8317                         printf("\n");
8318                 }
8319 #endif /* defined(SSA_DEBUG_VERBOSE) */
8320         }
8321 }
8322
8323 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
8324                          s4 dst_regoff, s4 dst_flags) {
8325         if ((IS_INMEMORY(dst_flags)) && (IS_INMEMORY(src_flags))) {
8326                 /* mem -> mem */
8327                 if (dst_regoff != src_regoff) {
8328                         if (!IS_2_WORD_TYPE(type)) {
8329                                 if (IS_FLT_DBL_TYPE(type)) {
8330                                         emit_flds_membase(cd, REG_SP, src_regoff * 4);
8331                                         emit_fstps_membase(cd, REG_SP, dst_regoff * 4);
8332                                 } else{
8333                                         emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
8334                                                         REG_ITMP1);
8335                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
8336                                 }
8337                         } else { /* LONG OR DOUBLE */
8338                                 if (IS_FLT_DBL_TYPE(type)) {
8339                                         emit_fldl_membase( cd, REG_SP, src_regoff * 4);
8340                                         emit_fstpl_membase(cd, REG_SP, dst_regoff * 4);
8341                                 } else {
8342                                         emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
8343                                                         REG_ITMP1);
8344                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
8345                                         emit_mov_membase_reg(cd, REG_SP, src_regoff * 4 + 4,
8346                             REG_ITMP1);             
8347                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, 
8348                                                         dst_regoff * 4 + 4);
8349                                 }
8350                         }
8351                 }
8352         } else {
8353                 if (IS_FLT_DBL_TYPE(type)) {
8354                         log_text("cg_move: flt/dbl type have to be in memory\n");
8355 /*                      assert(0); */
8356                 }
8357                 if (IS_2_WORD_TYPE(type)) {
8358                         log_text("cg_move: longs have to be in memory\n");
8359 /*                      assert(0); */
8360                 }
8361                 if (IS_INMEMORY(src_flags)) {
8362                         /* mem -> reg */
8363                         emit_mov_membase_reg(cd, REG_SP, src_regoff * 4, dst_regoff);
8364                 } else if (IS_INMEMORY(dst_flags)) {
8365                         /* reg -> mem */
8366                         emit_mov_reg_membase(cd, src_regoff, REG_SP, dst_regoff * 4);
8367                 } else {
8368                         /* reg -> reg */
8369                         /* only ints can be in regs on i386 */
8370                         M_INTMOVE(src_regoff,dst_regoff);
8371                 }
8372         }
8373 }
8374 #endif /* defined(ENABLE_SSA) */
8375
8376 /* createcompilerstub **********************************************************
8377
8378    Creates a stub routine which calls the compiler.
8379         
8380 *******************************************************************************/
8381
8382 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
8383 #define COMPILERSTUB_CODESIZE    12
8384
8385 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
8386
8387
8388 u1 *createcompilerstub(methodinfo *m)
8389 {
8390         u1          *s;                     /* memory to hold the stub            */
8391         ptrint      *d;
8392         codeinfo    *code;
8393         codegendata *cd;
8394         s4           dumpsize;
8395
8396         s = CNEW(u1, COMPILERSTUB_SIZE);
8397
8398         /* set data pointer and code pointer */
8399
8400         d = (ptrint *) s;
8401         s = s + COMPILERSTUB_DATASIZE;
8402
8403         /* mark start of dump memory area */
8404
8405         dumpsize = dump_size();
8406
8407         cd = DNEW(codegendata);
8408         cd->mcodeptr = s;
8409
8410         /* Store the codeinfo pointer in the same place as in the
8411            methodheader for compiled methods. */
8412
8413         code = code_codeinfo_new(m);
8414
8415         d[0] = (ptrint) asm_call_jit_compiler;
8416         d[1] = (ptrint) m;
8417         d[2] = (ptrint) code;
8418
8419         /* code for the stub */
8420
8421         M_MOV_IMM(m, REG_ITMP1);            /* method info                        */
8422         M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
8423         M_JMP(REG_ITMP3);
8424
8425 #if defined(ENABLE_STATISTICS)
8426         if (opt_stat)
8427                 count_cstub_len += COMPILERSTUB_SIZE;
8428 #endif
8429
8430         /* release dump area */
8431
8432         dump_release(dumpsize);
8433         
8434         return s;
8435 }
8436
8437
8438 /* createnativestub ************************************************************
8439
8440    Creates a stub routine which calls a native method.
8441
8442 *******************************************************************************/
8443
8444 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
8445 {
8446         methodinfo   *m;
8447         codeinfo     *code;
8448         codegendata  *cd;
8449         registerdata *rd;
8450         methoddesc   *md;
8451         s4            nativeparams;
8452         s4            i, j;                 /* count variables                    */
8453         s4            t;
8454         s4            s1, s2;
8455
8456         /* get required compiler data */
8457
8458         m    = jd->m;
8459         code = jd->code;
8460         cd   = jd->cd;
8461         rd   = jd->rd;
8462
8463         /* set some variables */
8464
8465         md = m->parseddesc;
8466         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
8467
8468         /* calculate stackframe size */
8469
8470         cd->stackframesize =
8471                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
8472                 sizeof(localref_table) / SIZEOF_VOID_P +
8473                 1 +                             /* function pointer                   */
8474                 4 * 4 +                         /* 4 arguments (start_native_call)    */
8475                 nmd->memuse;
8476
8477     /* keep stack 16-byte aligned */
8478
8479         cd->stackframesize |= 0x3;
8480
8481         /* create method header */
8482
8483         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
8484         (void) dseg_adds4(cd, cd->stackframesize * 4);         /* FrameSize       */
8485         (void) dseg_adds4(cd, 0);                              /* IsSync          */
8486         (void) dseg_adds4(cd, 0);                              /* IsLeaf          */
8487         (void) dseg_adds4(cd, 0);                              /* IntSave         */
8488         (void) dseg_adds4(cd, 0);                              /* FltSave         */
8489         (void) dseg_addlinenumbertablesize(cd);
8490         (void) dseg_adds4(cd, 0);                              /* ExTableSize     */
8491
8492         /* generate native method profiling code */
8493
8494         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
8495                 /* count frequency */
8496
8497                 M_MOV_IMM(code, REG_ITMP1);
8498                 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
8499         }
8500
8501         /* calculate stackframe size for native function */
8502
8503         M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
8504
8505 #if !defined(NDEBUG)
8506         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
8507                 emit_verbosecall_enter(jd);
8508 #endif
8509
8510         /* get function address (this must happen before the stackframeinfo) */
8511
8512 #if !defined(WITH_STATIC_CLASSPATH)
8513         if (f == NULL) {
8514                 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
8515
8516                 if (opt_showdisassemble) {
8517                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
8518                 }
8519         }
8520 #endif
8521
8522         M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
8523
8524         /* Mark the whole fpu stack as free for native functions (only for saved  */
8525         /* register count == 0).                                                  */
8526
8527         emit_ffree_reg(cd, 0);
8528         emit_ffree_reg(cd, 1);
8529         emit_ffree_reg(cd, 2);
8530         emit_ffree_reg(cd, 3);
8531         emit_ffree_reg(cd, 4);
8532         emit_ffree_reg(cd, 5);
8533         emit_ffree_reg(cd, 6);
8534         emit_ffree_reg(cd, 7);
8535
8536         /* prepare data structures for native function call */
8537
8538         M_MOV(REG_SP, REG_ITMP1);
8539         M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
8540
8541         M_AST(REG_ITMP1, REG_SP, 0 * 4);
8542         M_IST_IMM(0, REG_SP, 1 * 4);
8543         dseg_adddata(cd);
8544
8545         M_MOV(REG_SP, REG_ITMP2);
8546         M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
8547
8548         M_AST(REG_ITMP2, REG_SP, 2 * 4);
8549         M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 4);
8550         M_AST(REG_ITMP3, REG_SP, 3 * 4);
8551         M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
8552         M_CALL(REG_ITMP1);
8553
8554         M_ALD(REG_ITMP3, REG_SP, 4 * 4);
8555
8556         /* copy arguments into new stackframe */
8557
8558         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
8559                 t = md->paramtypes[i].type;
8560
8561                 if (!md->params[i].inmemory) {
8562                         /* no integer argument registers */
8563                 } else {       /* float/double in memory can be copied like int/longs */
8564                         s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
8565                         s2 = nmd->params[j].regoff * 4;
8566
8567                         M_ILD(REG_ITMP1, REG_SP, s1);
8568                         M_IST(REG_ITMP1, REG_SP, s2);
8569                         if (IS_2_WORD_TYPE(t)) {
8570                                 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
8571                                 M_IST(REG_ITMP1, REG_SP, s2 + 4);
8572                         }
8573                 }
8574         }
8575
8576         /* if function is static, put class into second argument */
8577
8578         if (m->flags & ACC_STATIC)
8579                 M_AST_IMM(m->class, REG_SP, 1 * 4);
8580
8581         /* put env into first argument */
8582
8583         M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
8584
8585         /* call the native function */
8586
8587         M_CALL(REG_ITMP3);
8588
8589         /* save return value */
8590
8591         if (md->returntype.type != TYPE_VOID) {
8592                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
8593                         if (IS_2_WORD_TYPE(md->returntype.type))
8594                                 M_IST(REG_RESULT2, REG_SP, 2 * 4);
8595                         M_IST(REG_RESULT, REG_SP, 1 * 4);
8596                 }
8597                 else {
8598                         if (IS_2_WORD_TYPE(md->returntype.type))
8599                                 emit_fstl_membase(cd, REG_SP, 1 * 4);
8600                         else
8601                                 emit_fsts_membase(cd, REG_SP, 1 * 4);
8602                 }
8603         }
8604
8605 #if !defined(NDEBUG)
8606         if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
8607                 emit_verbosecall_exit(jd);
8608 #endif
8609
8610         /* remove native stackframe info */
8611
8612         M_MOV(REG_SP, REG_ITMP1);
8613         M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
8614
8615         M_AST(REG_ITMP1, REG_SP, 0 * 4);
8616         M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
8617         M_CALL(REG_ITMP1);
8618         M_MOV(REG_RESULT, REG_ITMP2);                 /* REG_ITMP3 == REG_RESULT2 */
8619
8620         /* restore return value */
8621
8622         if (md->returntype.type != TYPE_VOID) {
8623                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
8624                         if (IS_2_WORD_TYPE(md->returntype.type))
8625                                 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
8626                         M_ILD(REG_RESULT, REG_SP, 1 * 4);
8627                 }
8628                 else {
8629                         if (IS_2_WORD_TYPE(md->returntype.type))
8630                                 emit_fldl_membase(cd, REG_SP, 1 * 4);
8631                         else
8632                                 emit_flds_membase(cd, REG_SP, 1 * 4);
8633                 }
8634         }
8635
8636         M_AADD_IMM(cd->stackframesize * 4, REG_SP);
8637
8638         /* check for exception */
8639
8640         M_TEST(REG_ITMP2);
8641         M_BNE(1);
8642
8643         M_RET;
8644
8645         /* handle exception */
8646
8647         M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
8648         M_ALD(REG_ITMP2_XPC, REG_SP, 0);
8649         M_ASUB_IMM(2, REG_ITMP2_XPC);
8650
8651         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
8652         M_JMP(REG_ITMP3);
8653
8654
8655         /* generate patcher stubs */
8656
8657         emit_patcher_stubs(jd);
8658
8659         codegen_finish(jd);
8660
8661         return code->entrypoint;
8662 }
8663
8664
8665 /*
8666  * These are local overrides for various environment variables in Emacs.
8667  * Please do not remove this and leave it at the end of the file, where
8668  * Emacs will automagically detect them.
8669  * ---------------------------------------------------------------------
8670  * Local variables:
8671  * mode: c
8672  * indent-tabs-mode: t
8673  * c-basic-offset: 4
8674  * tab-width: 4
8675  * End:
8676  * vim:noexpandtab:sw=4:ts=4:
8677  */