* src/vm/jit/jit.h (ICMD_ELSE_ICONST): Removed.
[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 5173 2006-07-25 15:57:11Z 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->debug_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_low(jd, iptr, src->prev, EAX);
1171                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1172                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX_EDX_PACKED);
1173
1174                         M_INTMOVE(s1, EAX);
1175                         M_MUL(s2);
1176                         M_INTMOVE(EAX, GET_LOW_REG(d));
1177                         emit_store_low(jd, iptr, iptr->dst, d);         /* free REG_ITMP1 */
1178
1179                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
1180                         M_INTMOVE(s1, REG_ITMP1);
1181                         M_IMUL(s2, REG_ITMP1);
1182                         M_IADD(REG_ITMP1, EDX);
1183
1184                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1185                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
1186                         M_INTMOVE(s1, REG_ITMP1);
1187                         M_IMUL(s2, REG_ITMP1);
1188                         M_IADD(REG_ITMP1, EDX);
1189                         M_INTMOVE(EDX, GET_HIGH_REG(d));
1190
1191                         emit_store_high(jd, iptr, iptr->dst, d);
1192                         break;
1193
1194                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
1195                                       /* val.l = constant                             */
1196
1197                         s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP2);
1198                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX_EDX_PACKED);
1199                         ICONST(EAX, iptr->val.l);
1200                         M_MUL(s1);
1201                         M_IMUL_IMM(s1, iptr->val.l >> 32, REG_ITMP2);
1202                         M_IADD(REG_ITMP2, EDX);
1203                         s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP2);
1204                         M_IMUL_IMM(s1, iptr->val.l, REG_ITMP2);
1205                         M_IADD(REG_ITMP2, EDX);
1206                         M_LNGMOVE(EAX_EDX_PACKED, d);
1207                         emit_store(jd, iptr, iptr->dst, d);
1208                         break;
1209
1210                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1211
1212                         s1 = emit_load_s1(jd, iptr, src->prev, EAX);
1213                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1214                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX);
1215
1216                         if (checknull) {
1217                                 M_TEST(s2);
1218                                 M_BEQ(0);
1219                                 codegen_add_arithmeticexception_ref(cd);
1220                         }
1221
1222                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
1223
1224                         /* check as described in jvm spec */
1225
1226                         M_CMP_IMM(0x80000000, EAX);
1227                         M_BNE(3 + 6);
1228                         M_CMP_IMM(-1, s2);
1229                         M_BEQ(1 + 2);
1230                         M_CLTD;
1231                         M_IDIV(s2);
1232
1233                         M_INTMOVE(EAX, d);           /* if INMEMORY then d is already EAX */
1234                         emit_store(jd, iptr, iptr->dst, d);
1235                         break;
1236
1237                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1238
1239                         s1 = emit_load_s1(jd, iptr, src->prev, EAX);
1240                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1241                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EDX);
1242
1243                         if (checknull) {
1244                                 M_TEST(s2);
1245                                 M_BEQ(0);
1246                                 codegen_add_arithmeticexception_ref(cd);
1247                         }
1248
1249                         M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
1250
1251                         /* check as described in jvm spec */
1252
1253                         M_CMP_IMM(0x80000000, EAX);
1254                         M_BNE(2 + 3 + 6);
1255                         M_CLR(EDX);
1256                         M_CMP_IMM(-1, s2);
1257                         M_BEQ(1 + 2);
1258                         M_CLTD;
1259                         M_IDIV(s2);
1260
1261                         M_INTMOVE(EDX, d);           /* if INMEMORY then d is already EDX */
1262                         emit_store(jd, iptr, iptr->dst, d);
1263                         break;
1264
1265                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
1266                                       /* val.i = constant                             */
1267
1268                         /* TODO: optimize for `/ 2' */
1269                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1270                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1271                         M_INTMOVE(s1, d);
1272                         M_TEST(d);
1273                         M_BNS(6);
1274                         M_IADD_IMM32((1 << iptr->val.i) - 1, d);  /* 32-bit for jump off. */
1275                         M_SRA_IMM(iptr->val.i, d);
1276                         emit_store(jd, iptr, iptr->dst, d);
1277                         break;
1278
1279                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1280                                       /* val.i = constant                             */
1281
1282                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1283                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1284                         if (s1 == d) {
1285                                 M_MOV(s1, REG_ITMP1);
1286                                 s1 = REG_ITMP1;
1287                         } 
1288                         M_INTMOVE(s1, d);
1289                         M_AND_IMM(iptr->val.i, d);
1290                         M_TEST(s1);
1291                         M_BGE(2 + 2 + 6 + 2);
1292                         M_MOV(s1, d);  /* don't use M_INTMOVE, so we know the jump offset */
1293                         M_NEG(d);
1294                         M_AND_IMM32(iptr->val.i, d);        /* use 32-bit for jump offset */
1295                         M_NEG(d);
1296                         emit_store(jd, iptr, iptr->dst, d);
1297                         break;
1298
1299                 case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1300                 case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1301
1302                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP12_PACKED);
1303                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1304
1305                         M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
1306                         M_OR(GET_HIGH_REG(s2), REG_ITMP3);
1307                         M_BEQ(0);
1308                         codegen_add_arithmeticexception_ref(cd);
1309
1310                         bte = iptr->val.a;
1311                         md = bte->md;
1312
1313                         M_LST(s2, REG_SP, 2 * 4);
1314
1315                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP12_PACKED);
1316                         M_LST(s1, REG_SP, 0 * 4);
1317
1318                         M_MOV_IMM(bte->fp, REG_ITMP3);
1319                         M_CALL(REG_ITMP3);
1320                         emit_store(jd, iptr, iptr->dst, d);
1321                         break;
1322
1323                 case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
1324                                       /* val.i = constant                             */
1325
1326                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1327                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1328                         M_LNGMOVE(s1, d);
1329                         M_TEST(GET_HIGH_REG(d));
1330                         M_BNS(6 + 3);
1331                         M_IADD_IMM32((1 << iptr->val.i) - 1, GET_LOW_REG(d));
1332                         M_IADDC_IMM(0, GET_HIGH_REG(d));
1333                         M_SRLD_IMM(iptr->val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
1334                         M_SRA_IMM(iptr->val.i, GET_HIGH_REG(d));
1335                         emit_store(jd, iptr, iptr->dst, d);
1336                         break;
1337
1338 #if 0
1339                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1340                                       /* val.l = constant                             */
1341
1342                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
1343                         if (iptr->dst->flags & INMEMORY) {
1344                                 if (src->flags & INMEMORY) {
1345                                         /* Alpha algorithm */
1346                                         disp = 3;
1347                                         CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
1348                                         disp += 3;
1349                                         CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4 + 4);
1350
1351                                         disp += 2;
1352                                         disp += 3;
1353                                         disp += 2;
1354
1355                                         /* TODO: hmm, don't know if this is always correct */
1356                                         disp += 2;
1357                                         CALCIMMEDIATEBYTES(disp, iptr->val.l & 0x00000000ffffffff);
1358                                         disp += 2;
1359                                         CALCIMMEDIATEBYTES(disp, iptr->val.l >> 32);
1360
1361                                         disp += 2;
1362                                         disp += 3;
1363                                         disp += 2;
1364
1365                                         emit_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
1366                                         emit_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP2);
1367                                         
1368                                         emit_alu_imm_reg(cd, ALU_AND, iptr->val.l, REG_ITMP1);
1369                                         emit_alu_imm_reg(cd, ALU_AND, iptr->val.l >> 32, REG_ITMP2);
1370                                         emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, src->regoff * 4 + 4);
1371                                         emit_jcc(cd, CC_GE, disp);
1372
1373                                         emit_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
1374                                         emit_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP2);
1375                                         
1376                                         emit_neg_reg(cd, REG_ITMP1);
1377                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1378                                         emit_neg_reg(cd, REG_ITMP2);
1379                                         
1380                                         emit_alu_imm_reg(cd, ALU_AND, iptr->val.l, REG_ITMP1);
1381                                         emit_alu_imm_reg(cd, ALU_AND, iptr->val.l >> 32, REG_ITMP2);
1382                                         
1383                                         emit_neg_reg(cd, REG_ITMP1);
1384                                         emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1385                                         emit_neg_reg(cd, REG_ITMP2);
1386
1387                                         emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
1388                                         emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 4 + 4);
1389                                 }
1390                         }
1391
1392                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1393                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1394                         M_LNGMOVE(s1, d);
1395                         M_AND_IMM(iptr->val.l, GET_LOW_REG(d)); 
1396                         M_AND_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1397                         M_TEST(GET_LOW_REG(s1));
1398                         M_BGE(0);
1399                         M_LNGMOVE(s1, d);
1400                 break;
1401 #endif
1402
1403                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1404
1405                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1406                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1407                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1408                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
1409                         M_INTMOVE(s1, d);
1410                         M_SLL(d);
1411                         emit_store(jd, iptr, iptr->dst, d);
1412                         break;
1413
1414                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1415                                       /* val.i = constant                             */
1416
1417                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1418                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1419                         M_INTMOVE(s1, d);
1420                         M_SLL_IMM(iptr->val.i, d);
1421                         emit_store(jd, iptr, iptr->dst, d);
1422                         break;
1423
1424                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1425
1426                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1427                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1428                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1429                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
1430                         M_INTMOVE(s1, d);
1431                         M_SRA(d);
1432                         emit_store(jd, iptr, iptr->dst, d);
1433                         break;
1434
1435                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1436                                       /* val.i = constant                             */
1437
1438                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1439                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1440                         M_INTMOVE(s1, d);
1441                         M_SRA_IMM(iptr->val.i, d);
1442                         emit_store(jd, iptr, iptr->dst, d);
1443                         break;
1444
1445                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1446
1447                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1448                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1449                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1450                         M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
1451                         M_INTMOVE(s1, d);
1452                         M_SRL(d);
1453                         emit_store(jd, iptr, iptr->dst, d);
1454                         break;
1455
1456                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1457                                       /* val.i = constant                             */
1458
1459                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1460                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1461                         M_INTMOVE(s1, d);
1462                         M_SRL_IMM(iptr->val.i, d);
1463                         emit_store(jd, iptr, iptr->dst, d);
1464                         break;
1465
1466                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1467
1468                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP13_PACKED);
1469                         s2 = emit_load_s2(jd, iptr, src, ECX);
1470                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP13_PACKED);
1471                         M_LNGMOVE(s1, d);
1472                         M_INTMOVE(s2, ECX);
1473                         M_TEST_IMM(32, ECX);
1474                         M_BEQ(2 + 2);
1475                         M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1476                         M_CLR(GET_LOW_REG(d));
1477                         M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
1478                         M_SLL(GET_LOW_REG(d));
1479                         emit_store(jd, iptr, iptr->dst, d);
1480                         break;
1481
1482         case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1483                                           /* val.i = constant                             */
1484
1485                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1486                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1487                         M_LNGMOVE(s1, d);
1488                         if (iptr->val.i & 0x20) {
1489                                 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1490                                 M_CLR(GET_LOW_REG(d));
1491                                 M_SLLD_IMM(iptr->val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
1492                         }
1493                         else {
1494                                 M_SLLD_IMM(iptr->val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
1495                                 M_SLL_IMM(iptr->val.i & 0x3f, GET_LOW_REG(d));
1496                         }
1497                         emit_store(jd, iptr, iptr->dst, d);
1498                         break;
1499
1500                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1501
1502                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP13_PACKED);
1503                         s2 = emit_load_s2(jd, iptr, src, ECX);
1504                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP13_PACKED);
1505                         M_LNGMOVE(s1, d);
1506                         M_INTMOVE(s2, ECX);
1507                         M_TEST_IMM(32, ECX);
1508                         M_BEQ(2 + 3);
1509                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1510                         M_SRA_IMM(31, GET_HIGH_REG(d));
1511                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1512                         M_SRA(GET_HIGH_REG(d));
1513                         emit_store(jd, iptr, iptr->dst, d);
1514                         break;
1515
1516                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1517                                       /* val.i = constant                             */
1518
1519                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1520                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1521                         M_LNGMOVE(s1, d);
1522                         if (iptr->val.i & 0x20) {
1523                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1524                                 M_SRA_IMM(31, GET_HIGH_REG(d));
1525                                 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1526                         }
1527                         else {
1528                                 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1529                                 M_SRA_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d));
1530                         }
1531                         emit_store(jd, iptr, iptr->dst, d);
1532                         break;
1533
1534                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1535
1536                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP13_PACKED);
1537                         s2 = emit_load_s2(jd, iptr, src, ECX);
1538                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP13_PACKED);
1539                         M_LNGMOVE(s1, d);
1540                         M_INTMOVE(s2, ECX);
1541                         M_TEST_IMM(32, ECX);
1542                         M_BEQ(2 + 2);
1543                         M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1544                         M_CLR(GET_HIGH_REG(d));
1545                         M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1546                         M_SRL(GET_HIGH_REG(d));
1547                         emit_store(jd, iptr, iptr->dst, d);
1548                         break;
1549
1550                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1551                                       /* val.l = constant                             */
1552
1553                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1554                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1555                         M_LNGMOVE(s1, d);
1556                         if (iptr->val.i & 0x20) {
1557                                 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1558                                 M_CLR(GET_HIGH_REG(d));
1559                                 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1560                         }
1561                         else {
1562                                 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1563                                 M_SRL_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d));
1564                         }
1565                         emit_store(jd, iptr, iptr->dst, d);
1566                         break;
1567
1568                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1569
1570                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1571                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1572                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1573                         if (s2 == d)
1574                                 M_AND(s1, d);
1575                         else {
1576                                 M_INTMOVE(s1, d);
1577                                 M_AND(s2, d);
1578                         }
1579                         emit_store(jd, iptr, iptr->dst, d);
1580                         break;
1581
1582                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1583                                       /* val.i = constant                             */
1584
1585                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1586                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1587                         M_INTMOVE(s1, d);
1588                         M_AND_IMM(iptr->val.i, d);
1589                         emit_store(jd, iptr, iptr->dst, d);
1590                         break;
1591
1592                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1593
1594                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1595                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1596                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1597                         if (s2 == GET_LOW_REG(d))
1598                                 M_AND(s1, GET_LOW_REG(d));
1599                         else {
1600                                 M_INTMOVE(s1, GET_LOW_REG(d));
1601                                 M_AND(s2, GET_LOW_REG(d));
1602                         }
1603                         /* REG_ITMP1 probably contains low 32-bit of destination */
1604                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1605                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1606                         if (s2 == GET_HIGH_REG(d))
1607                                 M_AND(s1, GET_HIGH_REG(d));
1608                         else {
1609                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1610                                 M_AND(s2, GET_HIGH_REG(d));
1611                         }
1612                         emit_store(jd, iptr, iptr->dst, d);
1613                         break;
1614
1615                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1616                                       /* val.l = constant                             */
1617
1618                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1619                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1620                         M_LNGMOVE(s1, d);
1621                         M_AND_IMM(iptr->val.l, GET_LOW_REG(d));
1622                         M_AND_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1623                         emit_store(jd, iptr, iptr->dst, d);
1624                         break;
1625
1626                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1627
1628                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1629                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1630                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1631                         if (s2 == d)
1632                                 M_OR(s1, d);
1633                         else {
1634                                 M_INTMOVE(s1, d);
1635                                 M_OR(s2, d);
1636                         }
1637                         emit_store(jd, iptr, iptr->dst, d);
1638                         break;
1639
1640                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
1641                                       /* val.i = constant                             */
1642
1643                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1644                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1645                         M_INTMOVE(s1, d);
1646                         M_OR_IMM(iptr->val.i, d);
1647                         emit_store(jd, iptr, iptr->dst, d);
1648                         break;
1649
1650                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1651
1652                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1653                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1654                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1655                         if (s2 == GET_LOW_REG(d))
1656                                 M_OR(s1, GET_LOW_REG(d));
1657                         else {
1658                                 M_INTMOVE(s1, GET_LOW_REG(d));
1659                                 M_OR(s2, GET_LOW_REG(d));
1660                         }
1661                         /* REG_ITMP1 probably contains low 32-bit of destination */
1662                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1663                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1664                         if (s2 == GET_HIGH_REG(d))
1665                                 M_OR(s1, GET_HIGH_REG(d));
1666                         else {
1667                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1668                                 M_OR(s2, GET_HIGH_REG(d));
1669                         }
1670                         emit_store(jd, iptr, iptr->dst, d);
1671                         break;
1672
1673                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
1674                                       /* val.l = constant                             */
1675
1676                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1677                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1678                         M_LNGMOVE(s1, d);
1679                         M_OR_IMM(iptr->val.l, GET_LOW_REG(d));
1680                         M_OR_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1681                         emit_store(jd, iptr, iptr->dst, d);
1682                         break;
1683
1684                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1685
1686                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1687                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1688                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1689                         if (s2 == d)
1690                                 M_XOR(s1, d);
1691                         else {
1692                                 M_INTMOVE(s1, d);
1693                                 M_XOR(s2, d);
1694                         }
1695                         emit_store(jd, iptr, iptr->dst, d);
1696                         break;
1697
1698                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1699                                       /* val.i = constant                             */
1700
1701                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1702                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1703                         M_INTMOVE(s1, d);
1704                         M_XOR_IMM(iptr->val.i, d);
1705                         emit_store(jd, iptr, iptr->dst, d);
1706                         break;
1707
1708                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
1709
1710                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1711                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1712                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1713                         if (s2 == GET_LOW_REG(d))
1714                                 M_XOR(s1, GET_LOW_REG(d));
1715                         else {
1716                                 M_INTMOVE(s1, GET_LOW_REG(d));
1717                                 M_XOR(s2, GET_LOW_REG(d));
1718                         }
1719                         /* REG_ITMP1 probably contains low 32-bit of destination */
1720                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1721                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1722                         if (s2 == GET_HIGH_REG(d))
1723                                 M_XOR(s1, GET_HIGH_REG(d));
1724                         else {
1725                                 M_INTMOVE(s1, GET_HIGH_REG(d));
1726                                 M_XOR(s2, GET_HIGH_REG(d));
1727                         }
1728                         emit_store(jd, iptr, iptr->dst, d);
1729                         break;
1730
1731                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
1732                                       /* val.l = constant                             */
1733
1734                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1735                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1736                         M_LNGMOVE(s1, d);
1737                         M_XOR_IMM(iptr->val.l, GET_LOW_REG(d));
1738                         M_XOR_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1739                         emit_store(jd, iptr, iptr->dst, d);
1740                         break;
1741
1742                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
1743                                       /* op1 = variable, val.i = constant             */
1744
1745                         var = &(rd->locals[iptr->op1][TYPE_INT]);
1746                         if (var->flags & INMEMORY) {
1747                                 s1 = REG_ITMP1;
1748                                 M_ILD(s1, REG_SP, var->regoff * 4);
1749                         }
1750                         else
1751                                 s1 = var->regoff;
1752
1753                         /* `inc reg' is slower on p4's (regarding to ia32
1754                            optimization reference manual and benchmarks) and as
1755                            fast on athlon's. */
1756
1757                         M_IADD_IMM(iptr->val.i, s1);
1758
1759                         if (var->flags & INMEMORY)
1760                                 M_IST(s1, REG_SP, var->regoff * 4);
1761                         break;
1762
1763
1764                 /* floating operations ************************************************/
1765
1766                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
1767
1768                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1769                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1770                         emit_fchs(cd);
1771                         emit_store(jd, iptr, iptr->dst, d);
1772                         break;
1773
1774                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
1775
1776                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1777                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1778                         emit_fchs(cd);
1779                         emit_store(jd, iptr, iptr->dst, d);
1780                         break;
1781
1782                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1783
1784                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1785                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1786                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1787                         emit_faddp(cd);
1788                         emit_store(jd, iptr, iptr->dst, d);
1789                         break;
1790
1791                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1792
1793                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1794                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1795                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1796                         emit_faddp(cd);
1797                         emit_store(jd, iptr, iptr->dst, d);
1798                         break;
1799
1800                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1801
1802                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1803                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1804                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1805                         emit_fsubp(cd);
1806                         emit_store(jd, iptr, iptr->dst, d);
1807                         break;
1808
1809                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1810
1811                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1812                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1813                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1814                         emit_fsubp(cd);
1815                         emit_store(jd, iptr, iptr->dst, d);
1816                         break;
1817
1818                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1819
1820                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1821                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1822                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1823                         emit_fmulp(cd);
1824                         emit_store(jd, iptr, iptr->dst, d);
1825                         break;
1826
1827                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1828
1829                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1830                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1831                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1832                         emit_fmulp(cd);
1833                         emit_store(jd, iptr, iptr->dst, d);
1834                         break;
1835
1836                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1837
1838                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1839                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1840                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1841                         emit_fdivp(cd);
1842                         emit_store(jd, iptr, iptr->dst, d);
1843                         break;
1844
1845                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1846
1847                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1848                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1849                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1850                         emit_fdivp(cd);
1851                         emit_store(jd, iptr, iptr->dst, d);
1852                         break;
1853
1854                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1855
1856                         /* exchanged to skip fxch */
1857                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1858                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1859                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1860 /*                      emit_fxch(cd); */
1861                         emit_fprem(cd);
1862                         emit_wait(cd);
1863                         emit_fnstsw(cd);
1864                         emit_sahf(cd);
1865                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1866                         emit_store(jd, iptr, iptr->dst, d);
1867                         emit_ffree_reg(cd, 0);
1868                         emit_fincstp(cd);
1869                         break;
1870
1871                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1872
1873                         /* exchanged to skip fxch */
1874                         s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1875                         s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1876                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1877 /*                      emit_fxch(cd); */
1878                         emit_fprem(cd);
1879                         emit_wait(cd);
1880                         emit_fnstsw(cd);
1881                         emit_sahf(cd);
1882                         emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1883                         emit_store(jd, iptr, iptr->dst, d);
1884                         emit_ffree_reg(cd, 0);
1885                         emit_fincstp(cd);
1886                         break;
1887
1888                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
1889                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
1890
1891                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1892                         if (src->flags & INMEMORY) {
1893                                 emit_fildl_membase(cd, REG_SP, src->regoff * 4);
1894
1895                         } else {
1896                                 disp = dseg_adds4(cd, 0);
1897                                 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1898                                 dseg_adddata(cd);
1899                                 emit_mov_reg_membase(cd, src->regoff, REG_ITMP1, disp);
1900                                 emit_fildl_membase(cd, REG_ITMP1, disp);
1901                         }
1902                         emit_store(jd, iptr, iptr->dst, d);
1903                         break;
1904
1905                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
1906                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
1907
1908                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1909                         if (src->flags & INMEMORY) {
1910                                 emit_fildll_membase(cd, REG_SP, src->regoff * 4);
1911
1912                         } else {
1913                                 log_text("L2F: longs have to be in memory");
1914                                 assert(0);
1915                         }
1916                         emit_store(jd, iptr, iptr->dst, d);
1917                         break;
1918                         
1919                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
1920
1921                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1922                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
1923
1924                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1925                         dseg_adddata(cd);
1926
1927                         /* Round to zero, 53-bit mode, exception masked */
1928                         disp = dseg_adds4(cd, 0x0e7f);
1929                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1930
1931                         if (iptr->dst->flags & INMEMORY) {
1932                                 emit_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 4);
1933
1934                                 /* Round to nearest, 53-bit mode, exceptions masked */
1935                                 disp = dseg_adds4(cd, 0x027f);
1936                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1937
1938                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4);
1939
1940                                 disp = 3;
1941                                 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
1942                                 disp += 5 + 2 + 3;
1943                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
1944
1945                         } else {
1946                                 disp = dseg_adds4(cd, 0);
1947                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
1948                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst->regoff);
1949
1950                                 /* Round to nearest, 53-bit mode, exceptions masked */
1951                                 disp = dseg_adds4(cd, 0x027f);
1952                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1953
1954                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst->regoff);
1955
1956                                 disp = 3;
1957                                 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
1958                                 disp += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
1959                         }
1960
1961                         emit_jcc(cd, CC_NE, disp);
1962
1963                         /* XXX: change this when we use registers */
1964                         emit_flds_membase(cd, REG_SP, src->regoff * 4);
1965                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
1966                         emit_call_reg(cd, REG_ITMP1);
1967
1968                         if (iptr->dst->flags & INMEMORY) {
1969                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
1970
1971                         } else {
1972                                 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
1973                         }
1974                         break;
1975
1976                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
1977
1978                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1979                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
1980
1981                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
1982                         dseg_adddata(cd);
1983
1984                         /* Round to zero, 53-bit mode, exception masked */
1985                         disp = dseg_adds4(cd, 0x0e7f);
1986                         emit_fldcw_membase(cd, REG_ITMP1, disp);
1987
1988                         if (iptr->dst->flags & INMEMORY) {
1989                                 emit_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 4);
1990
1991                                 /* Round to nearest, 53-bit mode, exceptions masked */
1992                                 disp = dseg_adds4(cd, 0x027f);
1993                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
1994
1995                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4);
1996
1997                                 disp = 3;
1998                                 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
1999                                 disp += 5 + 2 + 3;
2000                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2001
2002                         } else {
2003                                 disp = dseg_adds4(cd, 0);
2004                                 emit_fistpl_membase(cd, REG_ITMP1, disp);
2005                                 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst->regoff);
2006
2007                                 /* Round to nearest, 53-bit mode, exceptions masked */
2008                                 disp = dseg_adds4(cd, 0x027f);
2009                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
2010
2011                                 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst->regoff);
2012
2013                                 disp = 3;
2014                                 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2015                                 disp += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2016                         }
2017
2018                         emit_jcc(cd, CC_NE, disp);
2019
2020                         /* XXX: change this when we use registers */
2021                         emit_fldl_membase(cd, REG_SP, src->regoff * 4);
2022                         emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
2023                         emit_call_reg(cd, REG_ITMP1);
2024
2025                         if (iptr->dst->flags & INMEMORY) {
2026                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2027                         } else {
2028                                 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2029                         }
2030                         break;
2031
2032                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
2033
2034                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2035                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
2036
2037                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
2038                         dseg_adddata(cd);
2039
2040                         /* Round to zero, 53-bit mode, exception masked */
2041                         disp = dseg_adds4(cd, 0x0e7f);
2042                         emit_fldcw_membase(cd, REG_ITMP1, disp);
2043
2044                         if (iptr->dst->flags & INMEMORY) {
2045                                 emit_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 4);
2046
2047                                 /* Round to nearest, 53-bit mode, exceptions masked */
2048                                 disp = dseg_adds4(cd, 0x027f);
2049                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
2050
2051                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4 + 4);
2052
2053                                 disp = 6 + 4;
2054                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2055                                 disp += 3;
2056                                 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2057                                 disp += 5 + 2;
2058                                 disp += 3;
2059                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2060                                 disp += 3;
2061                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4 + 4);
2062
2063                                 emit_jcc(cd, CC_NE, disp);
2064
2065                                 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst->regoff * 4);
2066
2067                                 disp = 3;
2068                                 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2069                                 disp += 5 + 2 + 3;
2070                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2071
2072                                 emit_jcc(cd, CC_NE, disp);
2073
2074                                 /* XXX: change this when we use registers */
2075                                 emit_flds_membase(cd, REG_SP, src->regoff * 4);
2076                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
2077                                 emit_call_reg(cd, REG_ITMP1);
2078                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2079                                 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 4 + 4);
2080
2081                         } else {
2082                                 log_text("F2L: longs have to be in memory");
2083                                 assert(0);
2084                         }
2085                         break;
2086
2087                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
2088
2089                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2090                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
2091
2092                         emit_mov_imm_reg(cd, 0, REG_ITMP1);
2093                         dseg_adddata(cd);
2094
2095                         /* Round to zero, 53-bit mode, exception masked */
2096                         disp = dseg_adds4(cd, 0x0e7f);
2097                         emit_fldcw_membase(cd, REG_ITMP1, disp);
2098
2099                         if (iptr->dst->flags & INMEMORY) {
2100                                 emit_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 4);
2101
2102                                 /* Round to nearest, 53-bit mode, exceptions masked */
2103                                 disp = dseg_adds4(cd, 0x027f);
2104                                 emit_fldcw_membase(cd, REG_ITMP1, disp);
2105
2106                                 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4 + 4);
2107
2108                                 disp = 6 + 4;
2109                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2110                                 disp += 3;
2111                                 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2112                                 disp += 5 + 2;
2113                                 disp += 3;
2114                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2115                                 disp += 3;
2116                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4 + 4);
2117
2118                                 emit_jcc(cd, CC_NE, disp);
2119
2120                                 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst->regoff * 4);
2121
2122                                 disp = 3;
2123                                 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2124                                 disp += 5 + 2 + 3;
2125                                 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2126
2127                                 emit_jcc(cd, CC_NE, disp);
2128
2129                                 /* XXX: change this when we use registers */
2130                                 emit_fldl_membase(cd, REG_SP, src->regoff * 4);
2131                                 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
2132                                 emit_call_reg(cd, REG_ITMP1);
2133                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2134                                 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 4 + 4);
2135
2136                         } else {
2137                                 log_text("D2L: longs have to be in memory");
2138                                 assert(0);
2139                         }
2140                         break;
2141
2142                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
2143
2144                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2145                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
2146                         /* nothing to do */
2147                         emit_store(jd, iptr, iptr->dst, d);
2148                         break;
2149
2150                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
2151
2152                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2153                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
2154                         /* nothing to do */
2155                         emit_store(jd, iptr, iptr->dst, d);
2156                         break;
2157
2158                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
2159                 case ICMD_DCMPL:
2160
2161                         /* exchanged to skip fxch */
2162                         s2 = emit_load_s2(jd, iptr, src->prev, REG_FTMP1);
2163                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
2164                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2165 /*                      emit_fxch(cd); */
2166                         emit_fucompp(cd);
2167                         emit_fnstsw(cd);
2168                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as GT */
2169                         emit_jcc(cd, CC_E, 6);
2170                         emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
2171                         emit_sahf(cd);
2172                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
2173                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2174                         emit_jcc(cd, CC_B, 3 + 5);
2175                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2176                         emit_jmp_imm(cd, 3);
2177                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2178                         emit_store(jd, iptr, iptr->dst, d);
2179                         break;
2180
2181                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
2182                 case ICMD_DCMPG:
2183
2184                         /* exchanged to skip fxch */
2185                         s2 = emit_load_s2(jd, iptr, src->prev, REG_FTMP1);
2186                         s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
2187                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2188 /*                      emit_fxch(cd); */
2189                         emit_fucompp(cd);
2190                         emit_fnstsw(cd);
2191                         emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as LT */
2192                         emit_jcc(cd, CC_E, 3);
2193                         emit_movb_imm_reg(cd, 1, REG_AH);
2194                         emit_sahf(cd);
2195                         emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
2196                         emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2197                         emit_jcc(cd, CC_B, 3 + 5);
2198                         emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2199                         emit_jmp_imm(cd, 3);
2200                         emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2201                         emit_store(jd, iptr, iptr->dst, d);
2202                         break;
2203
2204
2205                 /* memory operations **************************************************/
2206
2207                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
2208
2209                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2210                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2211                         gen_nullptr_check(s1);
2212                         M_ILD(d, s1, OFFSET(java_arrayheader, size));
2213                         emit_store(jd, iptr, iptr->dst, d);
2214                         break;
2215
2216                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
2217
2218                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2219                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2220                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2221                         if (iptr->op1 == 0) {
2222                                 gen_nullptr_check(s1);
2223                                 gen_bound_check;
2224                         }
2225                         emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2226                         emit_store(jd, iptr, iptr->dst, d);
2227                         break;
2228
2229                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
2230
2231                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2232                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2233                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2234                         if (iptr->op1 == 0) {
2235                                 gen_nullptr_check(s1);
2236                                 gen_bound_check;
2237                         }
2238                         emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2239                         emit_store(jd, iptr, iptr->dst, d);
2240                         break;                  
2241
2242                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
2243
2244                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2245                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2246                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2247                         if (iptr->op1 == 0) {
2248                                 gen_nullptr_check(s1);
2249                                 gen_bound_check;
2250                         }
2251                         emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2252                         emit_store(jd, iptr, iptr->dst, d);
2253                         break;
2254
2255                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
2256
2257                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2258                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2259                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2260                         if (iptr->op1 == 0) {
2261                                 gen_nullptr_check(s1);
2262                                 gen_bound_check;
2263                         }
2264                         emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2265                         emit_store(jd, iptr, iptr->dst, d);
2266                         break;
2267
2268                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
2269
2270                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2271                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2272                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
2273                         if (iptr->op1 == 0) {
2274                                 gen_nullptr_check(s1);
2275                                 gen_bound_check;
2276                         }
2277                         assert(iptr->dst->flags & INMEMORY);
2278                         emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2279                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 4);
2280                         emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2281                         emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 4 + 4);
2282                         break;
2283
2284                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
2285
2286                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2287                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2288                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2289                         if (iptr->op1 == 0) {
2290                                 gen_nullptr_check(s1);
2291                                 gen_bound_check;
2292                         }
2293                         emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2294                         emit_store(jd, iptr, iptr->dst, d);
2295                         break;
2296
2297                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
2298
2299                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2300                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2301                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
2302                         if (iptr->op1 == 0) {
2303                                 gen_nullptr_check(s1);
2304                                 gen_bound_check;
2305                         }
2306                         emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2307                         emit_store(jd, iptr, iptr->dst, d);
2308                         break;
2309
2310                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
2311
2312                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2313                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2314                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2315                         if (iptr->op1 == 0) {
2316                                 gen_nullptr_check(s1);
2317                                 gen_bound_check;
2318                         }
2319                         emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2320                         emit_store(jd, iptr, iptr->dst, d);
2321                         break;
2322
2323
2324                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
2325
2326                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2327                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2328                         if (iptr->op1 == 0) {
2329                                 gen_nullptr_check(s1);
2330                                 gen_bound_check;
2331                         }
2332                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2333                         if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
2334                                 M_INTMOVE(s3, REG_ITMP3);
2335                                 s3 = REG_ITMP3;
2336                         }
2337                         emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2338                         break;
2339
2340                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
2341
2342                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2343                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2344                         if (iptr->op1 == 0) {
2345                                 gen_nullptr_check(s1);
2346                                 gen_bound_check;
2347                         }
2348                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2349                         emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2350                         break;
2351
2352                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
2353
2354                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2355                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2356                         if (iptr->op1 == 0) {
2357                                 gen_nullptr_check(s1);
2358                                 gen_bound_check;
2359                         }
2360                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2361                         emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2362                         break;
2363
2364                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
2365
2366                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2367                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2368                         if (iptr->op1 == 0) {
2369                                 gen_nullptr_check(s1);
2370                                 gen_bound_check;
2371                         }
2372                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2373                         emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2374                         break;
2375
2376                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
2377
2378                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2379                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2380                         if (iptr->op1 == 0) {
2381                                 gen_nullptr_check(s1);
2382                                 gen_bound_check;
2383                         }
2384                         assert(src->flags & INMEMORY);
2385                         emit_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP3);
2386                         emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2387                         emit_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP3);
2388                         emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2389                         break;
2390
2391                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
2392
2393                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2394                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2395                         if (iptr->op1 == 0) {
2396                                 gen_nullptr_check(s1);
2397                                 gen_bound_check;
2398                         }
2399                         s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
2400                         emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2401                         break;
2402
2403                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
2404
2405                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2406                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2407                         if (iptr->op1 == 0) {
2408                                 gen_nullptr_check(s1);
2409                                 gen_bound_check;
2410                         }
2411                         s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
2412                         emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2413                         break;
2414
2415                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
2416
2417                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2418                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2419                         if (iptr->op1 == 0) {
2420                                 gen_nullptr_check(s1);
2421                                 gen_bound_check;
2422                         }
2423                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2424
2425                         M_AST(s1, REG_SP, 0 * 4);
2426                         M_AST(s3, REG_SP, 1 * 4);
2427                         M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2428                         M_CALL(REG_ITMP1);
2429                         M_TEST(REG_RESULT);
2430                         M_BEQ(0);
2431                         codegen_add_arraystoreexception_ref(cd);
2432
2433                         s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2434                         s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2435                         s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2436                         emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2437                         break;
2438
2439                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
2440
2441                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2442                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2443                         if (iptr->op1 == 0) {
2444                                 gen_nullptr_check(s1);
2445                                 gen_bound_check;
2446                         }
2447                         emit_movb_imm_memindex(cd, iptr->val.i, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2448                         break;
2449
2450                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
2451
2452                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2453                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2454                         if (iptr->op1 == 0) {
2455                                 gen_nullptr_check(s1);
2456                                 gen_bound_check;
2457                         }
2458                         emit_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_chararray, data[0]), s1, s2, 1);
2459                         break;
2460
2461                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
2462
2463                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2464                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2465                         if (iptr->op1 == 0) {
2466                                 gen_nullptr_check(s1);
2467                                 gen_bound_check;
2468                         }
2469                         emit_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2470                         break;
2471
2472                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
2473
2474                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2475                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2476                         if (iptr->op1 == 0) {
2477                                 gen_nullptr_check(s1);
2478                                 gen_bound_check;
2479                         }
2480                         emit_mov_imm_memindex(cd, iptr->val.i, OFFSET(java_intarray, data[0]), s1, s2, 2);
2481                         break;
2482
2483                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
2484
2485                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2486                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2487                         if (iptr->op1 == 0) {
2488                                 gen_nullptr_check(s1);
2489                                 gen_bound_check;
2490                         }
2491                         emit_mov_imm_memindex(cd, (u4) (iptr->val.l & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2492                         emit_mov_imm_memindex(cd, (u4) (iptr->val.l >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2493                         break;
2494
2495                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
2496
2497                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2498                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2499                         if (iptr->op1 == 0) {
2500                                 gen_nullptr_check(s1);
2501                                 gen_bound_check;
2502                         }
2503                         emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2504                         break;
2505
2506
2507                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
2508                                       /* op1 = type, val.a = field address            */
2509
2510                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2511                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
2512                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2513
2514                                 if (opt_showdisassemble) {
2515                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2516                                 }
2517
2518                                 disp = 0;
2519
2520                         }
2521                         else {
2522                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2523
2524                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2525                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2526
2527                                         if (opt_showdisassemble) {
2528                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2529                                         }
2530                                 }
2531
2532                                 disp = (ptrint) &(fi->value);
2533                         }
2534
2535                         M_MOV_IMM(disp, REG_ITMP1);
2536                         switch (iptr->op1) {
2537                         case TYPE_INT:
2538                         case TYPE_ADR:
2539                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2540                                 M_ILD(d, REG_ITMP1, 0);
2541                                 break;
2542                         case TYPE_LNG:
2543                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP23_PACKED);
2544                                 M_LLD(d, REG_ITMP1, 0);
2545                                 break;
2546                         case TYPE_FLT:
2547                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2548                                 M_FLD(d, REG_ITMP1, 0);
2549                                 break;
2550                         case TYPE_DBL:                          
2551                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2552                                 M_DLD(d, REG_ITMP1, 0);
2553                                 break;
2554                         }
2555                         emit_store(jd, iptr, iptr->dst, d);
2556                         break;
2557
2558                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2559                                       /* op1 = type, val.a = field address            */
2560
2561                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2562                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
2563                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2564
2565                                 if (opt_showdisassemble) {
2566                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2567                                 }
2568
2569                                 disp = 0;
2570
2571                         }
2572                         else {
2573                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2574
2575                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2576                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2577
2578                                         if (opt_showdisassemble) {
2579                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2580                                         }
2581                                 }
2582
2583                                 disp = (ptrint) &(fi->value);
2584                         }
2585
2586                         M_MOV_IMM(disp, REG_ITMP1);
2587                         switch (iptr->op1) {
2588                         case TYPE_INT:
2589                         case TYPE_ADR:
2590                                 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2591                                 M_IST(s2, REG_ITMP1, 0);
2592                                 break;
2593                         case TYPE_LNG:
2594                                 s2 = emit_load_s2(jd, iptr, src, REG_ITMP23_PACKED);
2595                                 M_LST(s2, REG_ITMP1, 0);
2596                                 break;
2597                         case TYPE_FLT:
2598                                 s2 = emit_load_s2(jd, iptr, src, REG_FTMP1);
2599                                 emit_fstps_membase(cd, REG_ITMP1, 0);
2600                                 break;
2601                         case TYPE_DBL:
2602                                 s2 = emit_load_s2(jd, iptr, src, REG_FTMP1);
2603                                 emit_fstpl_membase(cd, REG_ITMP1, 0);
2604                                 break;
2605                         }
2606                         break;
2607
2608                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2609                                           /* val = value (in current instruction)     */
2610                                           /* op1 = type, val.a = field address (in    */
2611                                           /* following NOP)                           */
2612
2613                         if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2614                                 codegen_addpatchref(cd, PATCHER_get_putstatic,
2615                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2616
2617                                 if (opt_showdisassemble) {
2618                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2619                                 }
2620
2621                                 disp = 0;
2622
2623                         }
2624                         else {
2625                                 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2626
2627                                 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2628                                         codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2629
2630                                         if (opt_showdisassemble) {
2631                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2632                                         }
2633                                 }
2634
2635                                 disp = (ptrint) &(fi->value);
2636                         }
2637
2638                         M_MOV_IMM(disp, REG_ITMP1);
2639                         switch (iptr[1].op1) {
2640                         case TYPE_INT:
2641                         case TYPE_FLT:
2642                         case TYPE_ADR:
2643                                 M_IST_IMM(iptr->val.i, REG_ITMP1, 0);
2644                                 break;
2645                         case TYPE_LNG:
2646                         case TYPE_DBL:
2647                                 M_LST_IMM(iptr->val.l, REG_ITMP1, 0);
2648                                 break;
2649                         }
2650                         break;
2651
2652                 case ICMD_GETFIELD:   /* .., objectref.  ==> ..., value               */
2653                                       /* op1 = type, val.i = field offset             */
2654
2655                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2656                         gen_nullptr_check(s1);
2657
2658                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2659                                 codegen_addpatchref(cd, PATCHER_getfield,
2660                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2661
2662                                 if (opt_showdisassemble) {
2663                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2664                                 }
2665
2666                                 disp = 0;
2667
2668                         }
2669                         else
2670                                 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2671
2672                         switch (iptr->op1) {
2673                         case TYPE_INT:
2674                         case TYPE_ADR:
2675                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2676                                 M_ILD32(d, s1, disp);
2677                                 break;
2678                         case TYPE_LNG:
2679                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP23_PACKED);
2680                                 M_LLD32(d, s1, disp);
2681                                 break;
2682                         case TYPE_FLT:
2683                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2684                                 M_FLD32(d, s1, disp);
2685                                 break;
2686                         case TYPE_DBL:                          
2687                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2688                                 M_DLD32(d, s1, disp);
2689                                 break;
2690                         }
2691                         emit_store(jd, iptr, iptr->dst, d);
2692                         break;
2693
2694                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
2695                                       /* op1 = type, val.a = field address            */
2696
2697                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2698                         gen_nullptr_check(s1);
2699
2700                         /* must be done here because of code patching */
2701
2702                         if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2703                                 if (IS_2_WORD_TYPE(iptr->op1))
2704                                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP23_PACKED);
2705                                 else
2706                                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2707                         }
2708                         else
2709                                 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2710
2711                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2712                                 codegen_addpatchref(cd, PATCHER_putfield,
2713                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2714
2715                                 if (opt_showdisassemble) {
2716                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2717                                 }
2718
2719                                 disp = 0;
2720
2721                         }
2722                         else
2723                                 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2724
2725                         switch (iptr->op1) {
2726                         case TYPE_INT:
2727                         case TYPE_ADR:
2728                                 M_IST32(s2, s1, disp);
2729                                 break;
2730                         case TYPE_LNG:
2731                                 M_LST32(s2, s1, disp);
2732                                 break;
2733                         case TYPE_FLT:
2734                                 emit_fstps_membase32(cd, s1, disp);
2735                                 break;
2736                         case TYPE_DBL:
2737                                 emit_fstpl_membase32(cd, s1, disp);
2738                                 break;
2739                         }
2740                         break;
2741
2742                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
2743                                           /* val = value (in current instruction)     */
2744                                           /* op1 = type, val.a = field address (in    */
2745                                           /* following NOP)                           */
2746
2747                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2748                         gen_nullptr_check(s1);
2749
2750                         if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2751                                 codegen_addpatchref(cd, PATCHER_putfieldconst,
2752                                                                         INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2753
2754                                 if (opt_showdisassemble) {
2755                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2756                                 }
2757
2758                                 disp = 0;
2759
2760                         }
2761                         else
2762                                 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2763
2764                         switch (iptr[1].op1) {
2765                         case TYPE_INT:
2766                         case TYPE_FLT:
2767                         case TYPE_ADR:
2768                                 M_IST32_IMM(iptr->val.i, s1, disp);
2769                                 break;
2770                         case TYPE_LNG:
2771                         case TYPE_DBL:
2772                                 M_LST32_IMM(iptr->val.l, s1, disp);
2773                                 break;
2774                         }
2775                         break;
2776
2777
2778                 /* branch operations **************************************************/
2779
2780                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
2781
2782                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2783                         M_INTMOVE(s1, REG_ITMP1_XPTR);
2784
2785 #ifdef ENABLE_VERIFIER
2786                         if (iptr->val.a) {
2787                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2788                                                                         (unresolved_class *) iptr->val.a, 0);
2789
2790                                 if (opt_showdisassemble) {
2791                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2792                                 }
2793                         }
2794 #endif /* ENABLE_VERIFIER */
2795
2796                         M_CALL_IMM(0);                            /* passing exception pc */
2797                         M_POP(REG_ITMP2_XPC);
2798
2799                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2800                         M_JMP(REG_ITMP3);
2801                         break;
2802
2803                 case ICMD_INLINE_GOTO:
2804
2805                         M_COPY(src, iptr->dst);
2806                         /* FALLTHROUGH! */
2807
2808                 case ICMD_GOTO:         /* ... ==> ...                                */
2809                                         /* op1 = target JavaVM pc                     */
2810
2811                         M_JMP_IMM(0);
2812                         codegen_addreference(cd, (basicblock *) iptr->target);
2813                         ALIGNCODENOP;
2814                         break;
2815
2816                 case ICMD_JSR:          /* ... ==> ...                                */
2817                                         /* op1 = target JavaVM pc                     */
2818
2819                         M_CALL_IMM(0);
2820                         codegen_addreference(cd, (basicblock *) iptr->target);
2821                         break;
2822                         
2823                 case ICMD_RET:          /* ... ==> ...                                */
2824                                         /* op1 = local variable                       */
2825
2826                         var = &(rd->locals[iptr->op1][TYPE_ADR]);
2827                         if (var->flags & INMEMORY) {
2828                                 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2829                                 M_JMP(REG_ITMP1);
2830                         }
2831                         else
2832                                 M_JMP(var->regoff);
2833                         break;
2834
2835                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
2836                                         /* op1 = target JavaVM pc                     */
2837
2838                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2839                         M_TEST(s1);
2840                         M_BEQ(0);
2841                         codegen_addreference(cd, (basicblock *) iptr->target);
2842                         break;
2843
2844                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
2845                                         /* op1 = target JavaVM pc                     */
2846
2847                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2848                         M_TEST(s1);
2849                         M_BNE(0);
2850                         codegen_addreference(cd, (basicblock *) iptr->target);
2851                         break;
2852
2853                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
2854                                         /* op1 = target JavaVM pc, val.i = constant   */
2855
2856                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2857                         M_CMP_IMM(iptr->val.i, s1);
2858                         M_BEQ(0);
2859                         codegen_addreference(cd, (basicblock *) iptr->target);
2860                         break;
2861
2862                 case ICMD_IFLT:         /* ..., value ==> ...                         */
2863                                         /* op1 = target JavaVM pc, val.i = constant   */
2864
2865                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2866                         M_CMP_IMM(iptr->val.i, s1);
2867                         M_BLT(0);
2868                         codegen_addreference(cd, (basicblock *) iptr->target);
2869                         break;
2870
2871                 case ICMD_IFLE:         /* ..., value ==> ...                         */
2872                                         /* op1 = target JavaVM pc, val.i = constant   */
2873
2874                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2875                         M_CMP_IMM(iptr->val.i, s1);
2876                         M_BLE(0);
2877                         codegen_addreference(cd, (basicblock *) iptr->target);
2878                         break;
2879
2880                 case ICMD_IFNE:         /* ..., value ==> ...                         */
2881                                         /* op1 = target JavaVM pc, val.i = constant   */
2882
2883                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2884                         M_CMP_IMM(iptr->val.i, s1);
2885                         M_BNE(0);
2886                         codegen_addreference(cd, (basicblock *) iptr->target);
2887                         break;
2888
2889                 case ICMD_IFGT:         /* ..., value ==> ...                         */
2890                                         /* op1 = target JavaVM pc, val.i = constant   */
2891
2892                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2893                         M_CMP_IMM(iptr->val.i, s1);
2894                         M_BGT(0);
2895                         codegen_addreference(cd, (basicblock *) iptr->target);
2896                         break;
2897
2898                 case ICMD_IFGE:         /* ..., value ==> ...                         */
2899                                         /* op1 = target JavaVM pc, val.i = constant   */
2900
2901                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2902                         M_CMP_IMM(iptr->val.i, s1);
2903                         M_BGE(0);
2904                         codegen_addreference(cd, (basicblock *) iptr->target);
2905                         break;
2906
2907                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
2908                                         /* op1 = target JavaVM pc, val.l = constant   */
2909
2910                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2911                         if (iptr->val.l == 0) {
2912                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2913                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2914                         }
2915                         else {
2916                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2917                                 M_XOR_IMM(iptr->val.l, REG_ITMP1);
2918                                 M_XOR_IMM(iptr->val.l >> 32, REG_ITMP2);
2919                                 M_OR(REG_ITMP2, REG_ITMP1);
2920                         }
2921                         M_BEQ(0);
2922                         codegen_addreference(cd, (basicblock *) iptr->target);
2923                         break;
2924
2925                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
2926                                         /* op1 = target JavaVM pc, val.l = constant   */
2927
2928                         if (iptr->val.l == 0) {
2929                                 /* If high 32-bit are less than zero, then the 64-bits
2930                                    are too. */
2931                                 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP2);
2932                                 M_CMP_IMM(0, s1);
2933                                 M_BLT(0);
2934                         }
2935                         else {
2936                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2937                                 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
2938                                 M_BLT(0);
2939                                 codegen_addreference(cd, (basicblock *) iptr->target);
2940                                 M_BGT(6 + 6);
2941                                 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
2942                                 M_BB(0);
2943                         }                       
2944                         codegen_addreference(cd, (basicblock *) iptr->target);
2945                         break;
2946
2947                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
2948                                         /* op1 = target JavaVM pc, val.l = constant   */
2949
2950                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2951                         M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
2952                         M_BLT(0);
2953                         codegen_addreference(cd, (basicblock *) iptr->target);
2954                         M_BGT(6 + 6);
2955                         M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
2956                         M_BBE(0);
2957                         codegen_addreference(cd, (basicblock *) iptr->target);
2958                         break;
2959
2960                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
2961                                         /* op1 = target JavaVM pc, val.l = constant   */
2962
2963                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2964                         if (iptr->val.l == 0) {
2965                                 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2966                                 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2967                         }
2968                         else {
2969                                 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2970                                 M_XOR_IMM(iptr->val.l, REG_ITMP1);
2971                                 M_XOR_IMM(iptr->val.l >> 32, REG_ITMP2);
2972                                 M_OR(REG_ITMP2, REG_ITMP1);
2973                         }
2974                         M_BNE(0);
2975                         codegen_addreference(cd, (basicblock *) iptr->target);
2976                         break;
2977
2978                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
2979                                         /* op1 = target JavaVM pc, val.l = constant   */
2980
2981                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2982                         M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
2983                         M_BGT(0);
2984                         codegen_addreference(cd, (basicblock *) iptr->target);
2985                         M_BLT(6 + 6);
2986                         M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
2987                         M_BA(0);
2988                         codegen_addreference(cd, (basicblock *) iptr->target);
2989                         break;
2990
2991                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
2992                                         /* op1 = target JavaVM pc, val.l = constant   */
2993
2994                         if (iptr->val.l == 0) {
2995                                 /* If high 32-bit are greater equal zero, then the
2996                                    64-bits are too. */
2997                                 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP2);
2998                                 M_CMP_IMM(0, s1);
2999                                 M_BGE(0);
3000                         }
3001                         else {
3002                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3003                                 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
3004                                 M_BGT(0);
3005                                 codegen_addreference(cd, (basicblock *) iptr->target);
3006                                 M_BLT(6 + 6);
3007                                 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
3008                                 M_BAE(0);
3009                         }
3010                         codegen_addreference(cd, (basicblock *) iptr->target);
3011                         break;
3012
3013                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
3014                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
3015
3016                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3017                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3018                         M_CMP(s2, s1);
3019                         M_BEQ(0);
3020                         codegen_addreference(cd, (basicblock *) iptr->target);
3021                         break;
3022
3023                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
3024                                         /* op1 = target JavaVM pc                     */
3025
3026                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3027                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3028                         M_INTMOVE(s1, REG_ITMP1);
3029                         M_XOR(s2, REG_ITMP1);
3030                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
3031                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
3032                         M_INTMOVE(s1, REG_ITMP2);
3033                         M_XOR(s2, REG_ITMP2);
3034                         M_OR(REG_ITMP1, REG_ITMP2);
3035                         M_BEQ(0);
3036                         codegen_addreference(cd, (basicblock *) iptr->target);
3037                         break;
3038
3039                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
3040                 case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
3041
3042                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3043                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3044                         M_CMP(s2, s1);
3045                         M_BNE(0);
3046                         codegen_addreference(cd, (basicblock *) iptr->target);
3047                         break;
3048
3049                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
3050                                         /* op1 = target JavaVM pc                     */
3051
3052                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3053                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3054                         M_INTMOVE(s1, REG_ITMP1);
3055                         M_XOR(s2, REG_ITMP1);
3056                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
3057                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
3058                         M_INTMOVE(s1, REG_ITMP2);
3059                         M_XOR(s2, REG_ITMP2);
3060                         M_OR(REG_ITMP1, REG_ITMP2);
3061                         M_BNE(0);
3062                         codegen_addreference(cd, (basicblock *) iptr->target);
3063                         break;
3064
3065                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
3066                                         /* op1 = target JavaVM pc                     */
3067
3068                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3069                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3070                         M_CMP(s2, s1);
3071                         M_BLT(0);
3072                         codegen_addreference(cd, (basicblock *) iptr->target);
3073                         break;
3074
3075                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
3076                                     /* op1 = target JavaVM pc                     */
3077
3078                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3079                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3080                         M_CMP(s2, s1);
3081                         M_BLT(0);
3082                         codegen_addreference(cd, (basicblock *) iptr->target);
3083                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3084                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3085                         M_BGT(2 + 6);
3086                         M_CMP(s2, s1);
3087                         M_BB(0);
3088                         codegen_addreference(cd, (basicblock *) iptr->target);
3089                         break;
3090
3091                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
3092                                         /* op1 = target JavaVM pc                     */
3093
3094                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3095                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3096                         M_CMP(s2, s1);
3097                         M_BGT(0);
3098                         codegen_addreference(cd, (basicblock *) iptr->target);
3099                         break;
3100
3101                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
3102                                 /* op1 = target JavaVM pc                     */
3103
3104                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3105                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3106                         M_CMP(s2, s1);
3107                         M_BGT(0);
3108                         codegen_addreference(cd, (basicblock *) iptr->target);
3109                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3110                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3111                         M_BLT(2 + 6);
3112                         M_CMP(s2, s1);
3113                         M_BA(0);
3114                         codegen_addreference(cd, (basicblock *) iptr->target);
3115                         break;
3116
3117                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
3118                                         /* op1 = target JavaVM pc                     */
3119
3120                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3121                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3122                         M_CMP(s2, s1);
3123                         M_BLE(0);
3124                         codegen_addreference(cd, (basicblock *) iptr->target);
3125                         break;
3126
3127                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
3128                                         /* op1 = target JavaVM pc                     */
3129
3130                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3131                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3132                         M_CMP(s2, s1);
3133                         M_BLT(0);
3134                         codegen_addreference(cd, (basicblock *) iptr->target);
3135                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3136                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3137                         M_BGT(2 + 6);
3138                         M_CMP(s2, s1);
3139                         M_BBE(0);
3140                         codegen_addreference(cd, (basicblock *) iptr->target);
3141                         break;
3142
3143                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
3144                                         /* op1 = target JavaVM pc                     */
3145
3146                         s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3147                         s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3148                         M_CMP(s2, s1);
3149                         M_BGE(0);
3150                         codegen_addreference(cd, (basicblock *) iptr->target);
3151                         break;
3152
3153                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
3154                                     /* op1 = target JavaVM pc                     */
3155
3156                         s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3157                         s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3158                         M_CMP(s2, s1);
3159                         M_BGT(0);
3160                         codegen_addreference(cd, (basicblock *) iptr->target);
3161                         s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3162                         s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3163                         M_BLT(2 + 6);
3164                         M_CMP(s2, s1);
3165                         M_BAE(0);
3166                         codegen_addreference(cd, (basicblock *) iptr->target);
3167                         break;
3168
3169
3170                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
3171
3172                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
3173                         M_INTMOVE(s1, REG_RESULT);
3174                         goto nowperformreturn;
3175
3176                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
3177
3178                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT_PACKED);
3179                         M_LNGMOVE(s1, REG_RESULT_PACKED);
3180                         goto nowperformreturn;
3181
3182                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
3183
3184                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
3185                         M_INTMOVE(s1, REG_RESULT);
3186
3187 #ifdef ENABLE_VERIFIER
3188                         if (iptr->val.a) {
3189                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
3190                                                                         (unresolved_class *) iptr->val.a, 0);
3191
3192                                 if (opt_showdisassemble) {
3193                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3194                                 }
3195                         }
3196 #endif /* ENABLE_VERIFIER */
3197                         goto nowperformreturn;
3198
3199                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
3200                 case ICMD_DRETURN:
3201
3202                         s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
3203                         goto nowperformreturn;
3204
3205                 case ICMD_RETURN:      /* ...  ==> ...                                */
3206
3207 nowperformreturn:
3208                         {
3209                         s4 i, p;
3210                         
3211                         p = stackframesize;
3212                         
3213 #if !defined(NDEBUG)
3214                         /* call trace function */
3215
3216                         if (opt_verbosecall) {
3217                                 M_ISUB_IMM(4 + 8 + 8 + 4, REG_SP);
3218
3219                                 emit_mov_imm_membase(cd, (s4) m, REG_SP, 0);
3220
3221                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
3222                                 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
3223                                 
3224                                 emit_fstl_membase(cd, REG_SP, 4 + 8);
3225                                 emit_fsts_membase(cd, REG_SP, 4 + 8 + 8);
3226
3227                                 emit_mov_imm_reg(cd, (s4) builtin_displaymethodstop, REG_ITMP1);
3228                                 emit_call_reg(cd, REG_ITMP1);
3229
3230                                 emit_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
3231                                 emit_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
3232
3233                                 emit_alu_imm_reg(cd, ALU_ADD, 4 + 8 + 8 + 4, REG_SP);
3234                         }
3235 #endif /* !defined(NDEBUG) */
3236
3237 #if defined(ENABLE_THREADS)
3238                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3239                                 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
3240
3241                                 /* we need to save the proper return value */
3242                                 switch (iptr->opc) {
3243                                 case ICMD_IRETURN:
3244                                 case ICMD_ARETURN:
3245                                         M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
3246                                         break;
3247
3248                                 case ICMD_LRETURN:
3249                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3250                                         break;
3251
3252                                 case ICMD_FRETURN:
3253                                         emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
3254                                         break;
3255
3256                                 case ICMD_DRETURN:
3257                                         emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
3258                                         break;
3259                                 }
3260
3261                                 M_AST(REG_ITMP2, REG_SP, 0);
3262                                 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
3263                                 M_CALL(REG_ITMP3);
3264
3265                                 /* and now restore the proper return value */
3266                                 switch (iptr->opc) {
3267                                 case ICMD_IRETURN:
3268                                 case ICMD_ARETURN:
3269                                         M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
3270                                         break;
3271
3272                                 case ICMD_LRETURN:
3273                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3274                                         break;
3275
3276                                 case ICMD_FRETURN:
3277                                         emit_flds_membase(cd, REG_SP, rd->memuse * 4);
3278                                         break;
3279
3280                                 case ICMD_DRETURN:
3281                                         emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
3282                                         break;
3283                                 }
3284                         }
3285 #endif
3286
3287                         /* restore saved registers */
3288
3289                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3290                                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
3291                         }
3292
3293                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3294                                 p--;
3295                                 emit_fldl_membase(cd, REG_SP, p * 4);
3296                                 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3297                                         assert(0);
3298 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
3299                                 } else {
3300                                         assert(0);
3301 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
3302                                 }
3303                         }
3304
3305                         /* deallocate stack */
3306
3307                         if (stackframesize)
3308                                 M_AADD_IMM(stackframesize * 4, REG_SP);
3309
3310                         emit_ret(cd);
3311                         }
3312                         break;
3313
3314
3315                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
3316                         {
3317                                 s4 i, l, *s4ptr;
3318                                 void **tptr;
3319
3320                                 tptr = (void **) iptr->target;
3321
3322                                 s4ptr = iptr->val.a;
3323                                 l = s4ptr[1];                          /* low     */
3324                                 i = s4ptr[2];                          /* high    */
3325
3326                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3327                                 M_INTMOVE(s1, REG_ITMP1);
3328
3329                                 if (l != 0)
3330                                         M_ISUB_IMM(l, REG_ITMP1);
3331
3332                                 i = i - l + 1;
3333
3334                 /* range check */
3335
3336                                 M_CMP_IMM(i - 1, REG_ITMP1);
3337                                 M_BA(0);
3338                                 codegen_addreference(cd, (basicblock *) tptr[0]);
3339
3340                                 /* build jump table top down and use address of lowest entry */
3341
3342                                 tptr += i;
3343
3344                                 while (--i >= 0) {
3345                                         dseg_addtarget(cd, (basicblock *) tptr[0]); 
3346                                         --tptr;
3347                                 }
3348
3349                                 /* length of dataseg after last dseg_addtarget is used
3350                                    by load */
3351
3352                                 M_MOV_IMM(0, REG_ITMP2);
3353                                 dseg_adddata(cd);
3354                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3355                                 M_JMP(REG_ITMP1);
3356                         }
3357                         break;
3358
3359
3360                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
3361                         {
3362                                 s4 i, l, val, *s4ptr;
3363                                 void **tptr;
3364
3365                                 tptr = (void **) iptr->target;
3366
3367                                 s4ptr = iptr->val.a;
3368                                 l = s4ptr[0];                          /* default  */
3369                                 i = s4ptr[1];                          /* count    */
3370                         
3371                                 MCODECHECK((i<<2)+8);
3372                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3373
3374                                 while (--i >= 0) {
3375                                         s4ptr += 2;
3376                                         ++tptr;
3377
3378                                         val = s4ptr[0];
3379                                         M_CMP_IMM(val, s1);
3380                                         M_BEQ(0);
3381                                         codegen_addreference(cd, (basicblock *) tptr[0]); 
3382                                 }
3383
3384                                 M_JMP_IMM(0);
3385                         
3386                                 tptr = (void **) iptr->target;
3387                                 codegen_addreference(cd, (basicblock *) tptr[0]);
3388                         }
3389                         break;
3390
3391                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
3392                                         /* op1 = arg count val.a = builtintable entry */
3393
3394                         bte = iptr->val.a;
3395                         md = bte->md;
3396                         goto gen_method;
3397
3398                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
3399                                         /* op1 = arg count, val.a = method pointer    */
3400
3401                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3402                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
3403                 case ICMD_INVOKEINTERFACE:
3404
3405                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3406                                 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3407                                 lm = NULL;
3408                         }
3409                         else {
3410                                 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3411                                 md = lm->parseddesc;
3412                         }
3413
3414 gen_method:
3415                         s3 = md->paramcount;
3416
3417                         MCODECHECK((s3 << 1) + 64);
3418
3419                         /* copy arguments to registers or stack location                  */
3420
3421                         for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3422                                 if (src->varkind == ARGVAR)
3423                                         continue;
3424                                 if (IS_INT_LNG_TYPE(src->type)) {
3425                                         if (!md->params[s3].inmemory) {
3426                                                 log_text("No integer argument registers available!");
3427                                                 assert(0);
3428
3429                                         } else {
3430                                                 if (IS_2_WORD_TYPE(src->type)) {
3431                                                         d = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3432                                                         M_LST(d, REG_SP, md->params[s3].regoff * 4);
3433                                                 } else {
3434                                                         d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3435                                                         M_IST(d, REG_SP, md->params[s3].regoff * 4);
3436                                                 }
3437                                         }
3438
3439                                 } else {
3440                                         if (!md->params[s3].inmemory) {
3441                                                 s1 = rd->argfltregs[md->params[s3].regoff];
3442                                                 d = emit_load_s1(jd, iptr, src, s1);
3443                                                 M_FLTMOVE(d, s1);
3444
3445                                         } else {
3446                                                 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3447                                                 if (IS_2_WORD_TYPE(src->type))
3448                                                         M_DST(d, REG_SP, md->params[s3].regoff * 4);
3449                                                 else
3450                                                         M_FST(d, REG_SP, md->params[s3].regoff * 4);
3451                                         }
3452                                 }
3453                         } /* end of for */
3454
3455                         switch (iptr->opc) {
3456                         case ICMD_BUILTIN:
3457                                 disp = (ptrint) bte->fp;
3458                                 d = md->returntype.type;
3459
3460                                 M_MOV_IMM(disp, REG_ITMP1);
3461                                 M_CALL(REG_ITMP1);
3462
3463                                 /* if op1 == true, we need to check for an exception */
3464
3465                                 if (iptr->op1 == true) {
3466                                         M_TEST(REG_RESULT);
3467                                         M_BEQ(0);
3468                                         codegen_add_fillinstacktrace_ref(cd);
3469                                 }
3470                                 break;
3471
3472                         case ICMD_INVOKESPECIAL:
3473                                 M_ALD(REG_ITMP1, REG_SP, 0);
3474                                 M_TEST(REG_ITMP1);
3475                                 M_BEQ(0);
3476                                 codegen_add_nullpointerexception_ref(cd);
3477
3478                                 /* fall through */
3479
3480                         case ICMD_INVOKESTATIC:
3481                                 if (lm == NULL) {
3482                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3483
3484                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
3485                                                                                 um, 0);
3486
3487                                         if (opt_showdisassemble) {
3488                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3489                                         }
3490
3491                                         disp = 0;
3492                                         d = md->returntype.type;
3493                                 }
3494                                 else {
3495                                         disp = (ptrint) lm->stubroutine;
3496                                         d = lm->parseddesc->returntype.type;
3497                                 }
3498
3499                                 M_MOV_IMM(disp, REG_ITMP2);
3500                                 M_CALL(REG_ITMP2);
3501                                 break;
3502
3503                         case ICMD_INVOKEVIRTUAL:
3504                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3505                                 gen_nullptr_check(REG_ITMP1);
3506
3507                                 if (lm == NULL) {
3508                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3509
3510                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3511
3512                                         if (opt_showdisassemble) {
3513                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3514                                         }
3515
3516                                         s1 = 0;
3517                                         d = md->returntype.type;
3518                                 }
3519                                 else {
3520                                         s1 = OFFSET(vftbl_t, table[0]) +
3521                                                 sizeof(methodptr) * lm->vftblindex;
3522                                         d = md->returntype.type;
3523                                 }
3524
3525                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3526                                           OFFSET(java_objectheader, vftbl));
3527                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3528                                 M_CALL(REG_ITMP3);
3529                                 break;
3530
3531                         case ICMD_INVOKEINTERFACE:
3532                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3533                                 gen_nullptr_check(REG_ITMP1);
3534
3535                                 if (lm == NULL) {
3536                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3537
3538                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3539
3540                                         if (opt_showdisassemble) {
3541                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3542                                         }
3543
3544                                         s1 = 0;
3545                                         s2 = 0;
3546                                         d = md->returntype.type;
3547                                 }
3548                                 else {
3549                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3550                                                 sizeof(methodptr) * lm->class->index;
3551
3552                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3553
3554                                         d = md->returntype.type;
3555                                 }
3556
3557                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3558                                           OFFSET(java_objectheader, vftbl));
3559                                 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3560                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3561                                 M_CALL(REG_ITMP3);
3562                                 break;
3563                         }
3564
3565                         /* d contains return type */
3566
3567                         if (d != TYPE_VOID) {
3568                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3569                                         if (IS_2_WORD_TYPE(iptr->dst->type)) {
3570                                                 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
3571                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
3572                                         }
3573                                         else {
3574                                                 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3575                                                 M_INTMOVE(REG_RESULT, s1);
3576                                         }
3577                                 }
3578                                 else {
3579                                         s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3580                                 }
3581                                 emit_store(jd, iptr, iptr->dst, s1);
3582                         }
3583                         break;
3584
3585
3586                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3587                                       /* op1:   0 == array, 1 == class                */
3588                                       /* val.a: (classinfo*) superclass               */
3589
3590                         /*  superclass is an interface:
3591                          *
3592                          *  OK if ((sub == NULL) ||
3593                          *         (sub->vftbl->interfacetablelength > super->index) &&
3594                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
3595                          *
3596                          *  superclass is a class:
3597                          *
3598                          *  OK if ((sub == NULL) || (0
3599                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3600                          *         super->vftbl->diffval));
3601                          */
3602
3603                         if (iptr->op1 == 1) {
3604                                 /* object type cast-check */
3605
3606                                 classinfo *super;
3607                                 vftbl_t   *supervftbl;
3608                                 s4         superindex;
3609
3610                                 super = (classinfo *) iptr->val.a;
3611
3612                                 if (!super) {
3613                                         superindex = 0;
3614                                         supervftbl = NULL;
3615
3616                                 } else {
3617                                         superindex = super->index;
3618                                         supervftbl = super->vftbl;
3619                                 }
3620                         
3621 #if defined(ENABLE_THREADS)
3622                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3623 #endif
3624                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3625
3626                                 /* calculate interface checkcast code size */
3627
3628                                 s2 = 2; /* mov_membase_reg */
3629                                 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3630
3631                                 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
3632                                            2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3633                                            2 /* test */ + 6 /* jcc */);
3634
3635                                 if (!super)
3636                                         s2 += (opt_showdisassemble ? 5 : 0);
3637
3638                                 /* calculate class checkcast code size */
3639
3640                                 s3 = 2; /* mov_membase_reg */
3641                                 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3642
3643                                 s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
3644
3645 #if 0
3646                                 if (s1 != REG_ITMP1) {
3647                                         a += 2;
3648                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3649                                 
3650                                         a += 2;
3651                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3652                                 
3653                                         a += 2;
3654                                 
3655                                 } else
3656 #endif
3657                                         {
3658                                                 s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
3659                                                            5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
3660                                                 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3661                                         }
3662
3663                                 s3 += 2 /* cmp */ + 6 /* jcc */;
3664
3665                                 if (super == NULL)
3666                                         s3 += (opt_showdisassemble ? 5 : 0);
3667
3668                                 /* if class is not resolved, check which code to call */
3669
3670                                 if (super == NULL) {
3671                                         M_TEST(s1);
3672                                         M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3673
3674                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3675                                                                                 (constant_classref *) iptr->target, 0);
3676
3677                                         if (opt_showdisassemble) {
3678                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3679                                         }
3680
3681                                         M_MOV_IMM(0, REG_ITMP2);                  /* super->flags */
3682                                         M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3683                                         M_BEQ(s2 + 5);
3684                                 }
3685
3686                                 /* interface checkcast code */
3687
3688                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3689                                         if (super != NULL) {
3690                                                 M_TEST(s1);
3691                                                 M_BEQ(s2);
3692                                         }
3693
3694                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3695
3696                                         if (super == NULL) {
3697                                                 codegen_addpatchref(cd,
3698                                                                                         PATCHER_checkcast_instanceof_interface,
3699                                                                                         (constant_classref *) iptr->target,
3700                                                                                         0);
3701
3702                                                 if (opt_showdisassemble) {
3703                                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3704                                                 }
3705                                         }
3706
3707                                         M_ILD32(REG_ITMP3,
3708                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3709                                         M_ISUB_IMM32(superindex, REG_ITMP3);
3710                                         M_TEST(REG_ITMP3);
3711                                         M_BLE(0);
3712                                         codegen_add_classcastexception_ref(cd, s1);
3713                                         M_ALD32(REG_ITMP3, REG_ITMP2,
3714                                                         OFFSET(vftbl_t, interfacetable[0]) -
3715                                                         superindex * sizeof(methodptr*));
3716                                         M_TEST(REG_ITMP3);
3717                                         M_BEQ(0);
3718                                         codegen_add_classcastexception_ref(cd, s1);
3719
3720                                         if (super == NULL)
3721                                                 M_JMP_IMM(s3);
3722                                 }
3723
3724                                 /* class checkcast code */
3725
3726                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3727                                         if (super != NULL) {
3728                                                 M_TEST(s1);
3729                                                 M_BEQ(s3);
3730                                         }
3731
3732                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3733
3734                                         if (super == NULL) {
3735                                                 codegen_addpatchref(cd, PATCHER_checkcast_class,
3736                                                                                         (constant_classref *) iptr->target,
3737                                                                                         0);
3738
3739                                                 if (opt_showdisassemble) {
3740                                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3741                                                 }
3742                                         }
3743
3744                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3745 #if defined(ENABLE_THREADS)
3746                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3747 #endif
3748                                         M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3749
3750                                         /*                              if (s1 != REG_ITMP1) { */
3751                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3752                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3753                                         /* #if defined(ENABLE_THREADS) */
3754                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3755                                         /* #endif */
3756                                         /*                                      emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3757
3758                                         /*                              } else { */
3759                                         M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3760                                         M_ISUB(REG_ITMP3, REG_ITMP2);
3761                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3762                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3763 #if defined(ENABLE_THREADS)
3764                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3765 #endif
3766                                         /*                              } */
3767
3768                                         M_CMP(REG_ITMP3, REG_ITMP2);
3769                                         M_BA(0);         /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
3770                                         codegen_add_classcastexception_ref(cd, s1);
3771                                 }
3772
3773                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
3774                         }
3775                         else {
3776                                 /* array type cast-check */
3777
3778                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
3779                                 M_AST(s1, REG_SP, 0 * 4);
3780
3781                                 if (iptr->val.a == NULL) {
3782                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3783                                                                                 iptr->target, 0);
3784
3785                                         if (opt_showdisassemble) {
3786                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3787                                         }
3788                                 }
3789
3790                                 M_AST_IMM(iptr->val.a, REG_SP, 1 * 4);
3791                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3792                                 M_CALL(REG_ITMP3);
3793
3794                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
3795                                 M_TEST(REG_RESULT);
3796                                 M_BEQ(0);
3797                                 codegen_add_classcastexception_ref(cd, s1);
3798
3799                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3800                         }
3801
3802                         M_INTMOVE(s1, d);
3803                         emit_store(jd, iptr, iptr->dst, d);
3804                         break;
3805
3806                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3807                                       /* op1:   0 == array, 1 == class                */
3808                                       /* val.a: (classinfo*) superclass               */
3809
3810                         /*  superclass is an interface:
3811                          *
3812                          *  return (sub != NULL) &&
3813                          *         (sub->vftbl->interfacetablelength > super->index) &&
3814                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3815                          *
3816                          *  superclass is a class:
3817                          *
3818                          *  return ((sub != NULL) && (0
3819                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3820                          *          super->vftbl->diffvall));
3821                          */
3822
3823                         {
3824                         classinfo *super;
3825                         vftbl_t   *supervftbl;
3826                         s4         superindex;
3827
3828                         super = (classinfo *) iptr->val.a;
3829
3830                         if (!super) {
3831                                 superindex = 0;
3832                                 supervftbl = NULL;
3833
3834                         } else {
3835                                 superindex = super->index;
3836                                 supervftbl = super->vftbl;
3837                         }
3838                         
3839 #if defined(ENABLE_THREADS)
3840                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3841 #endif
3842
3843                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3844                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3845                         if (s1 == d) {
3846                                 M_INTMOVE(s1, REG_ITMP1);
3847                                 s1 = REG_ITMP1;
3848                         }
3849
3850                         /* calculate interface instanceof code size */
3851
3852                         s2 = 2; /* mov_membase_reg */
3853                         CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3854
3855                         s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
3856                                    2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3857                                    2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3858
3859                         if (!super)
3860                                 s2 += (opt_showdisassemble ? 5 : 0);
3861
3862                         /* calculate class instanceof code size */
3863
3864                         s3 = 2; /* mov_membase_reg */
3865                         CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3866                         s3 += 5; /* mov_imm_reg */
3867                         s3 += 2;
3868                         CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3869                         s3 += 2;
3870                         CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3871                         s3 += 2;
3872                         CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3873
3874                         s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
3875                                    2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3876
3877                         if (!super)
3878                                 s3 += (opt_showdisassemble ? 5 : 0);
3879
3880                         M_CLR(d);
3881
3882                         /* if class is not resolved, check which code to call */
3883
3884                         if (!super) {
3885                                 M_TEST(s1);
3886                                 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3887
3888                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3889                                                                         (constant_classref *) iptr->target, 0);
3890
3891                                 if (opt_showdisassemble) {
3892                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3893                                 }
3894
3895                                 M_MOV_IMM(0, REG_ITMP3);                      /* super->flags */
3896                                 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3897                                 M_BEQ(s2 + 5);
3898                         }
3899
3900                         /* interface instanceof code */
3901
3902                         if (!super || (super->flags & ACC_INTERFACE)) {
3903                                 if (super) {
3904                                         M_TEST(s1);
3905                                         M_BEQ(s2);
3906                                 }
3907
3908                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3909
3910                                 if (!super) {
3911                                         codegen_addpatchref(cd,
3912                                                                                 PATCHER_checkcast_instanceof_interface,
3913                                                                                 (constant_classref *) iptr->target, 0);
3914
3915                                         if (opt_showdisassemble) {
3916                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3917                                         }
3918                                 }
3919
3920                                 M_ILD32(REG_ITMP3,
3921                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3922                                 M_ISUB_IMM32(superindex, REG_ITMP3);
3923                                 M_TEST(REG_ITMP3);
3924
3925                                 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3926                                                 6 /* jcc */ + 5 /* mov_imm_reg */);
3927
3928                                 M_BLE(disp);
3929                                 M_ALD32(REG_ITMP1, REG_ITMP1,
3930                                                 OFFSET(vftbl_t, interfacetable[0]) -
3931                                                 superindex * sizeof(methodptr*));
3932                                 M_TEST(REG_ITMP1);
3933 /*                                      emit_setcc_reg(cd, CC_A, d); */
3934 /*                                      emit_jcc(cd, CC_BE, 5); */
3935                                 M_BEQ(5);
3936                                 M_MOV_IMM(1, d);
3937
3938                                 if (!super)
3939                                         M_JMP_IMM(s3);
3940                         }
3941
3942                         /* class instanceof code */
3943
3944                         if (!super || !(super->flags & ACC_INTERFACE)) {
3945                                 if (super) {
3946                                         M_TEST(s1);
3947                                         M_BEQ(s3);
3948                                 }
3949
3950                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3951
3952                                 if (!super) {
3953                                         codegen_addpatchref(cd, PATCHER_instanceof_class,
3954                                                                                 (constant_classref *) iptr->target, 0);
3955
3956                                         if (opt_showdisassemble) {
3957                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3958                                         }
3959                                 }
3960
3961                                 M_MOV_IMM(supervftbl, REG_ITMP2);
3962 #if defined(ENABLE_THREADS)
3963                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3964 #endif
3965                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3966                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3967                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3968 #if defined(ENABLE_THREADS)
3969                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3970 #endif
3971                                 M_ISUB(REG_ITMP2, REG_ITMP1);
3972                                 M_CLR(d);                                 /* may be REG_ITMP2 */
3973                                 M_CMP(REG_ITMP3, REG_ITMP1);
3974                                 M_BA(5);
3975                                 M_MOV_IMM(1, d);
3976                         }
3977                         emit_store(jd, iptr, iptr->dst, d);
3978                         }
3979                         break;
3980
3981                         break;
3982
3983                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
3984                                       /* op1 = dimension, val.a = class               */
3985
3986                         /* check for negative sizes and copy sizes to stack if necessary  */
3987
3988                         MCODECHECK((iptr->op1 << 1) + 64);
3989
3990                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3991                                 /* copy SAVEDVAR sizes to stack */
3992
3993                                 if (src->varkind != ARGVAR) {
3994                                         if (src->flags & INMEMORY) {
3995                                                 M_ILD(REG_ITMP1, REG_SP, src->regoff * 4);
3996                                                 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
3997                                         }
3998                                         else
3999                                                 M_IST(src->regoff, REG_SP, (s1 + 3) * 4);
4000                                 }
4001                         }
4002
4003                         /* is a patcher function set? */
4004
4005                         if (iptr->val.a == NULL) {
4006                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
4007                                                                         (constant_classref *) iptr->target, 0);
4008
4009                                 if (opt_showdisassemble) {
4010                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4011                                 }
4012
4013                                 disp = 0;
4014
4015                         }
4016                         else
4017                                 disp = (ptrint) iptr->val.a;
4018
4019                         /* a0 = dimension count */
4020
4021                         M_IST_IMM(iptr->op1, REG_SP, 0 * 4);
4022
4023                         /* a1 = arraydescriptor */
4024
4025                         M_IST_IMM(disp, REG_SP, 1 * 4);
4026
4027                         /* a2 = pointer to dimensions = stack pointer */
4028
4029                         M_MOV(REG_SP, REG_ITMP1);
4030                         M_AADD_IMM(3 * 4, REG_ITMP1);
4031                         M_AST(REG_ITMP1, REG_SP, 2 * 4);
4032
4033                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
4034                         M_CALL(REG_ITMP1);
4035
4036                         /* check for exception before result assignment */
4037
4038                         M_TEST(REG_RESULT);
4039                         M_BEQ(0);
4040                         codegen_add_fillinstacktrace_ref(cd);
4041
4042                         s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
4043                         M_INTMOVE(REG_RESULT, s1);
4044                         emit_store(jd, iptr, iptr->dst, s1);
4045                         break;
4046
4047                 default:
4048                         *exceptionptr =
4049                                 new_internalerror("Unknown ICMD %d", iptr->opc);
4050                         return false;
4051         } /* switch */
4052                 
4053         } /* for instruction */
4054                 
4055         /* copy values to interface registers */
4056
4057         src = bptr->outstack;
4058         len = bptr->outdepth;
4059         MCODECHECK(64+len);
4060 #if defined(ENABLE_LSRA)
4061         if (!opt_lsra)
4062 #endif
4063         while (src) {
4064                 len--;
4065                 if ((src->varkind != STACKVAR)) {
4066                         s2 = src->type;
4067                         if (IS_FLT_DBL_TYPE(s2)) {
4068                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
4069                                 if (!(rd->interfaces[len][s2].flags & INMEMORY))
4070                                         M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
4071                                 else
4072                                         M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4073
4074                         } else {
4075                                 if (IS_2_WORD_TYPE(s2))
4076                                         assert(0);
4077 /*                                      s1 = emit_load_s1(jd, iptr, src, PACK_REGS(REG_ITMP1, REG_ITMP2)); */
4078                                 else
4079                                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
4080
4081                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4082                                         if (IS_2_WORD_TYPE(s2))
4083                                                 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
4084                                         else
4085                                                 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
4086
4087                                 } else {
4088                                         if (IS_2_WORD_TYPE(s2))
4089                                                 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4090                                         else
4091                                                 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4092                                 }
4093                         }
4094                 }
4095                 src = src->prev;
4096         }
4097
4098         /* At the end of a basic block we may have to append some nops,
4099            because the patcher stub calling code might be longer than the
4100            actual instruction. So codepatching does not change the
4101            following block unintentionally. */
4102
4103         if (cd->mcodeptr < cd->lastmcodeptr) {
4104                 while (cd->mcodeptr < cd->lastmcodeptr) {
4105                         M_NOP;
4106                 }
4107         }
4108
4109         } /* if (bptr -> flags >= BBREACHED) */
4110         } /* for basic block */
4111
4112         dseg_createlinenumbertable(cd);
4113
4114
4115         /* generate exception and patcher stubs */
4116
4117         {
4118                 exceptionref *eref;
4119                 patchref     *pref;
4120                 u8            mcode;
4121                 u1           *savedmcodeptr;
4122                 u1           *tmpmcodeptr;
4123
4124                 savedmcodeptr = NULL;
4125
4126                 /* generate exception stubs */
4127
4128                 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
4129                         gen_resolvebranch(cd->mcodebase + eref->branchpos,
4130                                                           eref->branchpos,
4131                                                           cd->mcodeptr - cd->mcodebase);
4132
4133                         MCODECHECK(512);
4134
4135                         /* Check if the exception is an
4136                            ArrayIndexOutOfBoundsException.  If so, move index register
4137                            into REG_ITMP1. */
4138
4139                         if (eref->reg != -1)
4140                                 M_INTMOVE(eref->reg, REG_ITMP1);
4141
4142                         /* calcuate exception address */
4143
4144                         M_MOV_IMM(0, REG_ITMP2_XPC);
4145                         dseg_adddata(cd);
4146                         M_AADD_IMM32(eref->branchpos - 6, REG_ITMP2_XPC);
4147
4148                         /* move function to call into REG_ITMP3 */
4149
4150                         M_MOV_IMM(eref->function, REG_ITMP3);
4151
4152                         if (savedmcodeptr != NULL) {
4153                                 M_JMP_IMM((savedmcodeptr - cd->mcodeptr) - 5);
4154
4155                         } else {
4156                                 savedmcodeptr = cd->mcodeptr;
4157
4158                                 M_ASUB_IMM(5 * 4, REG_SP);
4159
4160                                 /* first save REG_ITMP1 so we can use it */
4161
4162                                 M_AST(REG_ITMP1, REG_SP, 4 * 4);                /* for AIOOBE */
4163
4164                                 M_AST_IMM(0, REG_SP, 0 * 4);
4165                                 dseg_adddata(cd);
4166                                 M_MOV(REG_SP, REG_ITMP1);
4167                                 M_AADD_IMM(5 * 4, REG_ITMP1);
4168                                 M_AST(REG_ITMP1, REG_SP, 1 * 4);
4169                                 M_ALD(REG_ITMP1, REG_SP, (5 + stackframesize) * 4);
4170                                 M_AST(REG_ITMP1, REG_SP, 2 * 4);
4171                                 M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4);
4172
4173                                 M_CALL(REG_ITMP3);
4174
4175                                 M_ALD(REG_ITMP2_XPC, REG_SP, 3 * 4);
4176                                 M_AADD_IMM(5 * 4, REG_SP);
4177
4178                                 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
4179                                 M_JMP(REG_ITMP3);
4180                         }
4181                 }
4182
4183
4184                 /* generate code patching stub call code */
4185
4186                 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4187                         /* check code segment size */
4188
4189                         MCODECHECK(512);
4190
4191                         /* Get machine code which is patched back in later. A
4192                            `call rel32' is 5 bytes long. */
4193
4194                         savedmcodeptr = cd->mcodebase + pref->branchpos;
4195                         mcode = *((u8 *) savedmcodeptr);
4196
4197                         /* patch in `call rel32' to call the following code */
4198
4199                         tmpmcodeptr  = cd->mcodeptr;    /* save current mcodeptr          */
4200                         cd->mcodeptr = savedmcodeptr;   /* set mcodeptr to patch position */
4201
4202                         M_CALL_IMM(tmpmcodeptr - (savedmcodeptr + PATCHER_CALL_SIZE));
4203
4204                         cd->mcodeptr = tmpmcodeptr;     /* restore the current mcodeptr   */
4205
4206                         /* save REG_ITMP3 */
4207
4208                         M_PUSH(REG_ITMP3);
4209
4210                         /* move pointer to java_objectheader onto stack */
4211
4212 #if defined(ENABLE_THREADS)
4213                         (void) dseg_addaddress(cd, NULL);                         /* flcword    */
4214                         (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4215                         off = dseg_addaddress(cd, NULL);                          /* vftbl      */
4216
4217                         M_MOV_IMM(0, REG_ITMP3);
4218                         dseg_adddata(cd);
4219                         M_AADD_IMM(off, REG_ITMP3);
4220                         M_PUSH(REG_ITMP3);
4221 #else
4222                         M_PUSH_IMM(0);
4223 #endif
4224
4225                         /* move machine code bytes and classinfo pointer into registers */
4226
4227                         M_PUSH_IMM(mcode >> 32);
4228                         M_PUSH_IMM(mcode);
4229                         M_PUSH_IMM(pref->ref);
4230                         M_PUSH_IMM(pref->patcher);
4231
4232                         M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
4233                         M_JMP(REG_ITMP3);
4234                 }
4235         }
4236
4237         /* generate replacement-out stubs */
4238
4239         {
4240                 int i;
4241
4242                 replacementpoint = jd->code->rplpoints;
4243
4244                 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
4245                         /* check code segment size */
4246
4247                         MCODECHECK(512);
4248
4249                         /* note start of stub code */
4250
4251                         replacementpoint->outcode = (u1*) (ptrint)(cd->mcodeptr - cd->mcodebase);
4252
4253                         /* make machine code for patching */
4254
4255                         disp = (ptrint)(replacementpoint->outcode - replacementpoint->pc) - 5;
4256                         replacementpoint->mcode = 0xe9 | ((u8)disp << 8);
4257
4258                         /* push address of `rplpoint` struct */
4259                         
4260                         M_PUSH_IMM(replacementpoint);
4261
4262                         /* jump to replacement function */
4263
4264                         M_PUSH_IMM(asm_replacement_out);
4265                         M_RET;
4266                 }
4267         }
4268         
4269         codegen_finish(jd);
4270
4271         /* everything's ok */
4272
4273         return true;
4274 }
4275
4276
4277 /* createcompilerstub **********************************************************
4278
4279    Creates a stub routine which calls the compiler.
4280         
4281 *******************************************************************************/
4282
4283 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
4284 #define COMPILERSTUB_CODESIZE    12
4285
4286 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
4287
4288
4289 u1 *createcompilerstub(methodinfo *m)
4290 {
4291         u1          *s;                     /* memory to hold the stub            */
4292         ptrint      *d;
4293         codeinfo    *code;
4294         codegendata *cd;
4295         s4           dumpsize;
4296
4297         s = CNEW(u1, COMPILERSTUB_SIZE);
4298
4299         /* set data pointer and code pointer */
4300
4301         d = (ptrint *) s;
4302         s = s + COMPILERSTUB_DATASIZE;
4303
4304         /* mark start of dump memory area */
4305
4306         dumpsize = dump_size();
4307
4308         cd = DNEW(codegendata);
4309         cd->mcodeptr = s;
4310
4311         /* Store the codeinfo pointer in the same place as in the
4312            methodheader for compiled methods. */
4313
4314         code = code_codeinfo_new(m);
4315
4316         d[0] = (ptrint) asm_call_jit_compiler;
4317         d[1] = (ptrint) m;
4318         d[2] = (ptrint) code;
4319
4320         /* code for the stub */
4321
4322         M_MOV_IMM(m, REG_ITMP1);            /* method info                        */
4323         M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
4324         M_JMP(REG_ITMP3);
4325
4326 #if defined(ENABLE_STATISTICS)
4327         if (opt_stat)
4328                 count_cstub_len += COMPILERSTUB_SIZE;
4329 #endif
4330
4331         /* release dump area */
4332
4333         dump_release(dumpsize);
4334         
4335         return s;
4336 }
4337
4338
4339 /* createnativestub ************************************************************
4340
4341    Creates a stub routine which calls a native method.
4342
4343 *******************************************************************************/
4344
4345 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4346 {
4347         methodinfo   *m;
4348         codeinfo     *code;
4349         codegendata  *cd;
4350         registerdata *rd;
4351         methoddesc   *md;
4352         s4            stackframesize;
4353         s4            nativeparams;
4354         s4            i, j;                 /* count variables                    */
4355         s4            t;
4356         s4            s1, s2, disp;
4357
4358         /* get required compiler data */
4359
4360         m    = jd->m;
4361         code = jd->code;
4362         cd   = jd->cd;
4363         rd   = jd->rd;
4364
4365         /* set some variables */
4366
4367         md = m->parseddesc;
4368         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4369
4370         /* calculate stackframe size */
4371
4372         stackframesize =
4373                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4374                 sizeof(localref_table) / SIZEOF_VOID_P +
4375                 1 +                             /* function pointer                   */
4376                 4 * 4 +                         /* 4 arguments (start_native_call)    */
4377                 nmd->memuse;
4378
4379         /* create method header */
4380
4381         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
4382         (void) dseg_adds4(cd, stackframesize * 4);             /* FrameSize       */
4383         (void) dseg_adds4(cd, 0);                              /* IsSync          */
4384         (void) dseg_adds4(cd, 0);                              /* IsLeaf          */
4385         (void) dseg_adds4(cd, 0);                              /* IntSave         */
4386         (void) dseg_adds4(cd, 0);                              /* FltSave         */
4387         (void) dseg_addlinenumbertablesize(cd);
4388         (void) dseg_adds4(cd, 0);                              /* ExTableSize     */
4389
4390         /* generate native method profiling code */
4391
4392         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
4393                 /* count frequency */
4394
4395                 M_MOV_IMM(code, REG_ITMP1);
4396                 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
4397         }
4398
4399         /* calculate stackframe size for native function */
4400
4401         M_ASUB_IMM(stackframesize * 4, REG_SP);
4402
4403 #if !defined(NDEBUG)
4404         if (opt_verbosecall) {
4405                 s4 p, t;
4406
4407                 disp = stackframesize * 4;
4408
4409                 M_ASUB_IMM(TRACE_ARGS_NUM * 8 + 4, REG_SP);
4410     
4411                 for (p = 0; p < md->paramcount && p < TRACE_ARGS_NUM; p++) {
4412                         t = md->paramtypes[p].type;
4413                         if (IS_INT_LNG_TYPE(t)) {
4414                                 if (IS_2_WORD_TYPE(t)) {
4415                                         M_ILD(REG_ITMP1, REG_SP,
4416                                                   4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4417                                         M_ILD(REG_ITMP2, REG_SP,
4418                                                   4 + TRACE_ARGS_NUM * 8 + 4 + disp + 4);
4419                                         M_IST(REG_ITMP1, REG_SP, p * 8);
4420                                         M_IST(REG_ITMP2, REG_SP, p * 8 + 4);
4421
4422                                 } else if (t == TYPE_ADR) {
4423                                         M_ALD(REG_ITMP1, REG_SP,
4424                                                   4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4425                                         M_CLR(REG_ITMP2);
4426                                         M_AST(REG_ITMP1, REG_SP, p * 8);
4427                                         M_AST(REG_ITMP2, REG_SP, p * 8 + 4);
4428
4429                                 } else {
4430                                         M_ILD(EAX, REG_SP, 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4431                                         emit_cltd(cd);
4432                                         M_IST(EAX, REG_SP, p * 8);
4433                                         M_IST(EDX, REG_SP, p * 8 + 4);
4434                                 }
4435
4436                         } else {
4437                                 if (!IS_2_WORD_TYPE(t)) {
4438                                         emit_flds_membase(cd, REG_SP,
4439                                                                           4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4440                                         emit_fstps_membase(cd, REG_SP, p * 8);
4441                                         emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP2, REG_ITMP2);
4442                                         M_IST(REG_ITMP2, REG_SP, p * 8 + 4);
4443
4444                                 } else {
4445                                         emit_fldl_membase(cd, REG_SP,
4446                                             4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4447                                         emit_fstpl_membase(cd, REG_SP, p * 8);
4448                                 }
4449                         }
4450                         disp += (IS_2_WORD_TYPE(t)) ? 8 : 4;
4451                 }
4452         
4453                 M_CLR(REG_ITMP1);
4454                 for (p = md->paramcount; p < TRACE_ARGS_NUM; p++) {
4455                         M_IST(REG_ITMP1, REG_SP, p * 8);
4456                         M_IST(REG_ITMP1, REG_SP, p * 8 + 4);
4457                 }
4458
4459                 M_AST_IMM(m, REG_SP, TRACE_ARGS_NUM * 8);
4460
4461                 M_MOV_IMM(builtin_trace_args, REG_ITMP1);
4462                 M_CALL(REG_ITMP1);
4463
4464                 M_AADD_IMM(TRACE_ARGS_NUM * 8 + 4, REG_SP);
4465         }
4466 #endif /* !defined(NDEBUG) */
4467
4468         /* get function address (this must happen before the stackframeinfo) */
4469
4470 #if !defined(WITH_STATIC_CLASSPATH)
4471         if (f == NULL) {
4472                 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
4473
4474                 if (opt_showdisassemble) {
4475                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4476                 }
4477         }
4478 #endif
4479
4480         M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
4481
4482         /* Mark the whole fpu stack as free for native functions (only for saved  */
4483         /* register count == 0).                                                  */
4484
4485         emit_ffree_reg(cd, 0);
4486         emit_ffree_reg(cd, 1);
4487         emit_ffree_reg(cd, 2);
4488         emit_ffree_reg(cd, 3);
4489         emit_ffree_reg(cd, 4);
4490         emit_ffree_reg(cd, 5);
4491         emit_ffree_reg(cd, 6);
4492         emit_ffree_reg(cd, 7);
4493
4494         /* prepare data structures for native function call */
4495
4496         M_MOV(REG_SP, REG_ITMP1);
4497         M_AADD_IMM(stackframesize * 4, REG_ITMP1);
4498
4499         M_AST(REG_ITMP1, REG_SP, 0 * 4);
4500         M_IST_IMM(0, REG_SP, 1 * 4);
4501         dseg_adddata(cd);
4502
4503         M_MOV(REG_SP, REG_ITMP2);
4504         M_AADD_IMM(stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
4505
4506         M_AST(REG_ITMP2, REG_SP, 2 * 4);
4507         M_ALD(REG_ITMP3, REG_SP, stackframesize * 4);
4508         M_AST(REG_ITMP3, REG_SP, 3 * 4);
4509         M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
4510         M_CALL(REG_ITMP1);
4511
4512         M_ALD(REG_ITMP3, REG_SP, 4 * 4);
4513
4514         /* copy arguments into new stackframe */
4515
4516         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4517                 t = md->paramtypes[i].type;
4518
4519                 if (!md->params[i].inmemory) {
4520                         /* no integer argument registers */
4521                 } else {       /* float/double in memory can be copied like int/longs */
4522                         s1 = (md->params[i].regoff + stackframesize + 1) * 4;
4523                         s2 = nmd->params[j].regoff * 4;
4524
4525                         M_ILD(REG_ITMP1, REG_SP, s1);
4526                         M_IST(REG_ITMP1, REG_SP, s2);
4527                         if (IS_2_WORD_TYPE(t)) {
4528                                 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
4529                                 M_IST(REG_ITMP1, REG_SP, s2 + 4);
4530                         }
4531                 }
4532         }
4533
4534         /* if function is static, put class into second argument */
4535
4536         if (m->flags & ACC_STATIC)
4537                 M_AST_IMM((ptrint) m->class, REG_SP, 1 * 4);
4538
4539         /* put env into first argument */
4540
4541         M_AST_IMM((ptrint) _Jv_env, REG_SP, 0 * 4);
4542
4543         /* call the native function */
4544
4545         M_CALL(REG_ITMP3);
4546
4547         /* save return value */
4548
4549         if (md->returntype.type != TYPE_VOID) {
4550                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4551                         if (IS_2_WORD_TYPE(md->returntype.type))
4552                                 M_IST(REG_RESULT2, REG_SP, 2 * 4);
4553                         M_IST(REG_RESULT, REG_SP, 1 * 4);
4554                 }
4555                 else {
4556                         if (IS_2_WORD_TYPE(md->returntype.type))
4557                                 emit_fstl_membase(cd, REG_SP, 1 * 4);
4558                         else
4559                                 emit_fsts_membase(cd, REG_SP, 1 * 4);
4560                 }
4561         }
4562
4563 #if !defined(NDEBUG)
4564     if (opt_verbosecall) {
4565                 /* restore return value */
4566
4567                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4568                         if (IS_2_WORD_TYPE(md->returntype.type))
4569                                 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
4570                         M_ILD(REG_RESULT, REG_SP, 1 * 4);
4571         
4572                 } else {
4573                         if (IS_2_WORD_TYPE(md->returntype.type))
4574                                 emit_fldl_membase(cd, REG_SP, 1 * 4);
4575                         else
4576                                 emit_flds_membase(cd, REG_SP, 1 * 4);
4577                 }
4578
4579                 M_ASUB_IMM(4 + 8 + 8 + 4, REG_SP);
4580
4581                 M_AST_IMM((ptrint) m, REG_SP, 0);
4582
4583                 M_IST(REG_RESULT, REG_SP, 4);
4584                 M_IST(REG_RESULT2, REG_SP, 4 + 4);
4585
4586                 emit_fstl_membase(cd, REG_SP, 4 + 8);
4587                 emit_fsts_membase(cd, REG_SP, 4 + 8 + 8);
4588
4589                 M_MOV_IMM(builtin_displaymethodstop, REG_ITMP1);
4590                 M_CALL(REG_ITMP1);
4591
4592                 M_AADD_IMM(4 + 8 + 8 + 4, REG_SP);
4593     }
4594 #endif /* !defined(NDEBUG) */
4595
4596         /* remove native stackframe info */
4597
4598         M_MOV(REG_SP, REG_ITMP1);
4599         M_AADD_IMM(stackframesize * 4, REG_ITMP1);
4600
4601         M_AST(REG_ITMP1, REG_SP, 0 * 4);
4602         M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
4603         M_CALL(REG_ITMP1);
4604         M_MOV(REG_RESULT, REG_ITMP2);                 /* REG_ITMP3 == REG_RESULT2 */
4605
4606         /* restore return value */
4607
4608         if (md->returntype.type != TYPE_VOID) {
4609                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4610                         if (IS_2_WORD_TYPE(md->returntype.type))
4611                                 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
4612                         M_ILD(REG_RESULT, REG_SP, 1 * 4);
4613                 }
4614                 else {
4615                         if (IS_2_WORD_TYPE(md->returntype.type))
4616                                 emit_fldl_membase(cd, REG_SP, 1 * 4);
4617                         else
4618                                 emit_flds_membase(cd, REG_SP, 1 * 4);
4619                 }
4620         }
4621
4622         M_AADD_IMM(stackframesize * 4, REG_SP);
4623
4624         /* check for exception */
4625
4626         M_TEST(REG_ITMP2);
4627         M_BNE(1);
4628
4629         M_RET;
4630
4631         /* handle exception */
4632
4633         M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
4634         M_ALD(REG_ITMP2_XPC, REG_SP, 0);
4635         M_ASUB_IMM(2, REG_ITMP2_XPC);
4636
4637         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
4638         M_JMP(REG_ITMP3);
4639
4640
4641         /* process patcher calls **************************************************/
4642
4643         {
4644                 u1       *xcodeptr;
4645                 patchref *pref;
4646                 u8        mcode;
4647                 u1       *tmpmcodeptr;
4648
4649                 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4650                         /* Get machine code which is patched back in later. A
4651                            `call rel32' is 5 bytes long. */
4652
4653                         xcodeptr = cd->mcodebase + pref->branchpos;
4654                         mcode =  *((u8 *) xcodeptr);
4655
4656                         /* patch in `call rel32' to call the following code */
4657
4658                         tmpmcodeptr  = cd->mcodeptr;    /* save current mcodeptr          */
4659                         cd->mcodeptr = xcodeptr;        /* set mcodeptr to patch position */
4660
4661                         M_CALL_IMM(tmpmcodeptr - (xcodeptr + PATCHER_CALL_SIZE));
4662
4663                         cd->mcodeptr = tmpmcodeptr;     /* restore the current mcodeptr   */
4664
4665                         /* save REG_ITMP3 */
4666
4667                         M_PUSH(REG_ITMP3);
4668
4669                         /* move pointer to java_objectheader onto stack */
4670
4671 #if defined(ENABLE_THREADS)
4672                         /* create a virtual java_objectheader */
4673
4674                         (void) dseg_addaddress(cd, NULL);                         /* flcword    */
4675                         (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4676                         disp = dseg_addaddress(cd, NULL);                         /* vftbl      */
4677
4678                         M_MOV_IMM(0, REG_ITMP3);
4679                         dseg_adddata(cd);
4680                         M_AADD_IMM(disp, REG_ITMP3);
4681                         M_PUSH(REG_ITMP3);
4682 #else
4683                         M_PUSH_IMM(0);
4684 #endif
4685
4686                         /* move machine code bytes and classinfo pointer onto stack */
4687
4688                         M_PUSH_IMM((mcode >> 32));
4689                         M_PUSH_IMM(mcode);
4690                         M_PUSH_IMM(pref->ref);
4691                         M_PUSH_IMM(pref->patcher);
4692
4693                         M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
4694                         M_JMP(REG_ITMP3);
4695                 }
4696         }
4697
4698         codegen_finish(jd);
4699
4700         return code->entrypoint;
4701 }
4702
4703
4704 /*
4705  * These are local overrides for various environment variables in Emacs.
4706  * Please do not remove this and leave it at the end of the file, where
4707  * Emacs will automagically detect them.
4708  * ---------------------------------------------------------------------
4709  * Local variables:
4710  * mode: c
4711  * indent-tabs-mode: t
4712  * c-basic-offset: 4
4713  * tab-width: 4
4714  * End:
4715  * vim:noexpandtab:sw=4:ts=4:
4716  */