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