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