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