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