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