* src/vm/jit/asmpart.h (asm_wrapper_patcher): Renamed to
[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 5145 2006-07-17 11:48:38Z 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                 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST                           */
3170
3171                 case ICMD_ELSE_ICONST:  /* handled by IFxx_ICONST                     */
3172                         break;
3173
3174                 case ICMD_IFEQ_ICONST:  /* ..., value ==> ..., constant               */
3175                                         /* val.i = constant                           */
3176
3177                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3178                         emit_ifcc_iconst(cd, CC_NE, src, iptr);
3179                         break;
3180
3181                 case ICMD_IFNE_ICONST:  /* ..., value ==> ..., constant               */
3182                                         /* val.i = constant                           */
3183
3184                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3185                         emit_ifcc_iconst(cd, CC_E, src, iptr);
3186                         break;
3187
3188                 case ICMD_IFLT_ICONST:  /* ..., value ==> ..., constant               */
3189                                         /* val.i = constant                           */
3190
3191                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3192                         emit_ifcc_iconst(cd, CC_GE, src, iptr);
3193                         break;
3194
3195                 case ICMD_IFGE_ICONST:  /* ..., value ==> ..., constant               */
3196                                         /* val.i = constant                           */
3197
3198                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3199                         emit_ifcc_iconst(cd, CC_L, src, iptr);
3200                         break;
3201
3202                 case ICMD_IFGT_ICONST:  /* ..., value ==> ..., constant               */
3203                                         /* val.i = constant                           */
3204
3205                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3206                         emit_ifcc_iconst(cd, CC_LE, src, iptr);
3207                         break;
3208
3209                 case ICMD_IFLE_ICONST:  /* ..., value ==> ..., constant               */
3210                                         /* val.i = constant                           */
3211
3212                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3213                         emit_ifcc_iconst(cd, CC_G, src, iptr);
3214                         break;
3215
3216
3217                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
3218
3219                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
3220                         M_INTMOVE(s1, REG_RESULT);
3221                         goto nowperformreturn;
3222
3223                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
3224
3225                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT_PACKED);
3226                         M_LNGMOVE(s1, REG_RESULT_PACKED);
3227                         goto nowperformreturn;
3228
3229                 case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
3230
3231                         s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
3232                         M_INTMOVE(s1, REG_RESULT);
3233
3234 #ifdef ENABLE_VERIFIER
3235                         if (iptr->val.a) {
3236                                 codegen_addpatchref(cd, PATCHER_athrow_areturn,
3237                                                                         (unresolved_class *) iptr->val.a, 0);
3238
3239                                 if (opt_showdisassemble) {
3240                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3241                                 }
3242                         }
3243 #endif /* ENABLE_VERIFIER */
3244                         goto nowperformreturn;
3245
3246                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
3247                 case ICMD_DRETURN:
3248
3249                         s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
3250                         goto nowperformreturn;
3251
3252                 case ICMD_RETURN:      /* ...  ==> ...                                */
3253
3254 nowperformreturn:
3255                         {
3256                         s4 i, p;
3257                         
3258                         p = stackframesize;
3259                         
3260 #if !defined(NDEBUG)
3261                         /* call trace function */
3262
3263                         if (opt_verbosecall) {
3264                                 M_ISUB_IMM(4 + 8 + 8 + 4, REG_SP);
3265
3266                                 emit_mov_imm_membase(cd, (s4) m, REG_SP, 0);
3267
3268                                 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
3269                                 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
3270                                 
3271                                 emit_fstl_membase(cd, REG_SP, 4 + 8);
3272                                 emit_fsts_membase(cd, REG_SP, 4 + 8 + 8);
3273
3274                                 emit_mov_imm_reg(cd, (s4) builtin_displaymethodstop, REG_ITMP1);
3275                                 emit_call_reg(cd, REG_ITMP1);
3276
3277                                 emit_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
3278                                 emit_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
3279
3280                                 emit_alu_imm_reg(cd, ALU_ADD, 4 + 8 + 8 + 4, REG_SP);
3281                         }
3282 #endif /* !defined(NDEBUG) */
3283
3284 #if defined(ENABLE_THREADS)
3285                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3286                                 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
3287
3288                                 /* we need to save the proper return value */
3289                                 switch (iptr->opc) {
3290                                 case ICMD_IRETURN:
3291                                 case ICMD_ARETURN:
3292                                         M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
3293                                         break;
3294
3295                                 case ICMD_LRETURN:
3296                                         M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3297                                         break;
3298
3299                                 case ICMD_FRETURN:
3300                                         emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
3301                                         break;
3302
3303                                 case ICMD_DRETURN:
3304                                         emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
3305                                         break;
3306                                 }
3307
3308                                 M_AST(REG_ITMP2, REG_SP, 0);
3309                                 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
3310                                 M_CALL(REG_ITMP3);
3311
3312                                 /* and now restore the proper return value */
3313                                 switch (iptr->opc) {
3314                                 case ICMD_IRETURN:
3315                                 case ICMD_ARETURN:
3316                                         M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
3317                                         break;
3318
3319                                 case ICMD_LRETURN:
3320                                         M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3321                                         break;
3322
3323                                 case ICMD_FRETURN:
3324                                         emit_flds_membase(cd, REG_SP, rd->memuse * 4);
3325                                         break;
3326
3327                                 case ICMD_DRETURN:
3328                                         emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
3329                                         break;
3330                                 }
3331                         }
3332 #endif
3333
3334                         /* restore saved registers */
3335
3336                         for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3337                                 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
3338                         }
3339
3340                         for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3341                                 p--;
3342                                 emit_fldl_membase(cd, REG_SP, p * 4);
3343                                 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3344                                         assert(0);
3345 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
3346                                 } else {
3347                                         assert(0);
3348 /*                                      emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
3349                                 }
3350                         }
3351
3352                         /* deallocate stack */
3353
3354                         if (stackframesize)
3355                                 M_AADD_IMM(stackframesize * 4, REG_SP);
3356
3357                         emit_ret(cd);
3358                         }
3359                         break;
3360
3361
3362                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
3363                         {
3364                                 s4 i, l, *s4ptr;
3365                                 void **tptr;
3366
3367                                 tptr = (void **) iptr->target;
3368
3369                                 s4ptr = iptr->val.a;
3370                                 l = s4ptr[1];                          /* low     */
3371                                 i = s4ptr[2];                          /* high    */
3372
3373                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3374                                 M_INTMOVE(s1, REG_ITMP1);
3375
3376                                 if (l != 0)
3377                                         M_ISUB_IMM(l, REG_ITMP1);
3378
3379                                 i = i - l + 1;
3380
3381                 /* range check */
3382
3383                                 M_CMP_IMM(i - 1, REG_ITMP1);
3384                                 M_BA(0);
3385                                 codegen_addreference(cd, (basicblock *) tptr[0]);
3386
3387                                 /* build jump table top down and use address of lowest entry */
3388
3389                                 tptr += i;
3390
3391                                 while (--i >= 0) {
3392                                         dseg_addtarget(cd, (basicblock *) tptr[0]); 
3393                                         --tptr;
3394                                 }
3395
3396                                 /* length of dataseg after last dseg_addtarget is used
3397                                    by load */
3398
3399                                 M_MOV_IMM(0, REG_ITMP2);
3400                                 dseg_adddata(cd);
3401                                 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3402                                 M_JMP(REG_ITMP1);
3403                         }
3404                         break;
3405
3406
3407                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
3408                         {
3409                                 s4 i, l, val, *s4ptr;
3410                                 void **tptr;
3411
3412                                 tptr = (void **) iptr->target;
3413
3414                                 s4ptr = iptr->val.a;
3415                                 l = s4ptr[0];                          /* default  */
3416                                 i = s4ptr[1];                          /* count    */
3417                         
3418                                 MCODECHECK((i<<2)+8);
3419                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3420
3421                                 while (--i >= 0) {
3422                                         s4ptr += 2;
3423                                         ++tptr;
3424
3425                                         val = s4ptr[0];
3426                                         M_CMP_IMM(val, s1);
3427                                         M_BEQ(0);
3428                                         codegen_addreference(cd, (basicblock *) tptr[0]); 
3429                                 }
3430
3431                                 M_JMP_IMM(0);
3432                         
3433                                 tptr = (void **) iptr->target;
3434                                 codegen_addreference(cd, (basicblock *) tptr[0]);
3435                         }
3436                         break;
3437
3438                 case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
3439                                         /* op1 = arg count val.a = builtintable entry */
3440
3441                         bte = iptr->val.a;
3442                         md = bte->md;
3443                         goto gen_method;
3444
3445                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
3446                                         /* op1 = arg count, val.a = method pointer    */
3447
3448                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3449                 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
3450                 case ICMD_INVOKEINTERFACE:
3451
3452                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3453                                 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3454                                 lm = NULL;
3455                         }
3456                         else {
3457                                 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3458                                 md = lm->parseddesc;
3459                         }
3460
3461 gen_method:
3462                         s3 = md->paramcount;
3463
3464                         MCODECHECK((s3 << 1) + 64);
3465
3466                         /* copy arguments to registers or stack location                  */
3467
3468                         for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3469                                 if (src->varkind == ARGVAR)
3470                                         continue;
3471                                 if (IS_INT_LNG_TYPE(src->type)) {
3472                                         if (!md->params[s3].inmemory) {
3473                                                 log_text("No integer argument registers available!");
3474                                                 assert(0);
3475
3476                                         } else {
3477                                                 if (IS_2_WORD_TYPE(src->type)) {
3478                                                         d = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3479                                                         M_LST(d, REG_SP, md->params[s3].regoff * 4);
3480                                                 } else {
3481                                                         d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3482                                                         M_IST(d, REG_SP, md->params[s3].regoff * 4);
3483                                                 }
3484                                         }
3485
3486                                 } else {
3487                                         if (!md->params[s3].inmemory) {
3488                                                 s1 = rd->argfltregs[md->params[s3].regoff];
3489                                                 d = emit_load_s1(jd, iptr, src, s1);
3490                                                 M_FLTMOVE(d, s1);
3491
3492                                         } else {
3493                                                 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3494                                                 if (IS_2_WORD_TYPE(src->type))
3495                                                         M_DST(d, REG_SP, md->params[s3].regoff * 4);
3496                                                 else
3497                                                         M_FST(d, REG_SP, md->params[s3].regoff * 4);
3498                                         }
3499                                 }
3500                         } /* end of for */
3501
3502                         switch (iptr->opc) {
3503                         case ICMD_BUILTIN:
3504                                 disp = (ptrint) bte->fp;
3505                                 d = md->returntype.type;
3506
3507                                 M_MOV_IMM(disp, REG_ITMP1);
3508                                 M_CALL(REG_ITMP1);
3509
3510                                 /* if op1 == true, we need to check for an exception */
3511
3512                                 if (iptr->op1 == true) {
3513                                         M_TEST(REG_RESULT);
3514                                         M_BEQ(0);
3515                                         codegen_add_fillinstacktrace_ref(cd);
3516                                 }
3517                                 break;
3518
3519                         case ICMD_INVOKESPECIAL:
3520                                 M_ALD(REG_ITMP1, REG_SP, 0);
3521                                 M_TEST(REG_ITMP1);
3522                                 M_BEQ(0);
3523                                 codegen_add_nullpointerexception_ref(cd);
3524
3525                                 /* fall through */
3526
3527                         case ICMD_INVOKESTATIC:
3528                                 if (lm == NULL) {
3529                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3530
3531                                         codegen_addpatchref(cd, PATCHER_invokestatic_special,
3532                                                                                 um, 0);
3533
3534                                         if (opt_showdisassemble) {
3535                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3536                                         }
3537
3538                                         disp = 0;
3539                                         d = md->returntype.type;
3540                                 }
3541                                 else {
3542                                         disp = (ptrint) lm->stubroutine;
3543                                         d = lm->parseddesc->returntype.type;
3544                                 }
3545
3546                                 M_MOV_IMM(disp, REG_ITMP2);
3547                                 M_CALL(REG_ITMP2);
3548                                 break;
3549
3550                         case ICMD_INVOKEVIRTUAL:
3551                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3552                                 gen_nullptr_check(REG_ITMP1);
3553
3554                                 if (lm == NULL) {
3555                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3556
3557                                         codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3558
3559                                         if (opt_showdisassemble) {
3560                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3561                                         }
3562
3563                                         s1 = 0;
3564                                         d = md->returntype.type;
3565                                 }
3566                                 else {
3567                                         s1 = OFFSET(vftbl_t, table[0]) +
3568                                                 sizeof(methodptr) * lm->vftblindex;
3569                                         d = md->returntype.type;
3570                                 }
3571
3572                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3573                                           OFFSET(java_objectheader, vftbl));
3574                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3575                                 M_CALL(REG_ITMP3);
3576                                 break;
3577
3578                         case ICMD_INVOKEINTERFACE:
3579                                 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3580                                 gen_nullptr_check(REG_ITMP1);
3581
3582                                 if (lm == NULL) {
3583                                         unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3584
3585                                         codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3586
3587                                         if (opt_showdisassemble) {
3588                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3589                                         }
3590
3591                                         s1 = 0;
3592                                         s2 = 0;
3593                                         d = md->returntype.type;
3594                                 }
3595                                 else {
3596                                         s1 = OFFSET(vftbl_t, interfacetable[0]) -
3597                                                 sizeof(methodptr) * lm->class->index;
3598
3599                                         s2 = sizeof(methodptr) * (lm - lm->class->methods);
3600
3601                                         d = md->returntype.type;
3602                                 }
3603
3604                                 M_ALD(REG_METHODPTR, REG_ITMP1,
3605                                           OFFSET(java_objectheader, vftbl));
3606                                 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3607                                 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3608                                 M_CALL(REG_ITMP3);
3609                                 break;
3610                         }
3611
3612                         /* d contains return type */
3613
3614                         if (d != TYPE_VOID) {
3615                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3616                                         if (IS_2_WORD_TYPE(iptr->dst->type)) {
3617                                                 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
3618                                                 M_LNGMOVE(REG_RESULT_PACKED, s1);
3619                                         }
3620                                         else {
3621                                                 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3622                                                 M_INTMOVE(REG_RESULT, s1);
3623                                         }
3624                                 }
3625                                 else {
3626                                         s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3627                                 }
3628                                 emit_store(jd, iptr, iptr->dst, s1);
3629                         }
3630                         break;
3631
3632
3633                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
3634                                       /* op1:   0 == array, 1 == class                */
3635                                       /* val.a: (classinfo*) superclass               */
3636
3637                         /*  superclass is an interface:
3638                          *
3639                          *  OK if ((sub == NULL) ||
3640                          *         (sub->vftbl->interfacetablelength > super->index) &&
3641                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
3642                          *
3643                          *  superclass is a class:
3644                          *
3645                          *  OK if ((sub == NULL) || (0
3646                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3647                          *         super->vftbl->diffval));
3648                          */
3649
3650                         if (iptr->op1 == 1) {
3651                                 /* object type cast-check */
3652
3653                                 classinfo *super;
3654                                 vftbl_t   *supervftbl;
3655                                 s4         superindex;
3656
3657                                 super = (classinfo *) iptr->val.a;
3658
3659                                 if (!super) {
3660                                         superindex = 0;
3661                                         supervftbl = NULL;
3662
3663                                 } else {
3664                                         superindex = super->index;
3665                                         supervftbl = super->vftbl;
3666                                 }
3667                         
3668 #if defined(ENABLE_THREADS)
3669                                 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3670 #endif
3671                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3672
3673                                 /* calculate interface checkcast code size */
3674
3675                                 s2 = 2; /* mov_membase_reg */
3676                                 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3677
3678                                 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
3679                                            2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3680                                            2 /* test */ + 6 /* jcc */);
3681
3682                                 if (!super)
3683                                         s2 += (opt_showdisassemble ? 5 : 0);
3684
3685                                 /* calculate class checkcast code size */
3686
3687                                 s3 = 2; /* mov_membase_reg */
3688                                 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3689
3690                                 s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
3691
3692 #if 0
3693                                 if (s1 != REG_ITMP1) {
3694                                         a += 2;
3695                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3696                                 
3697                                         a += 2;
3698                                         CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3699                                 
3700                                         a += 2;
3701                                 
3702                                 } else
3703 #endif
3704                                         {
3705                                                 s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
3706                                                            5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
3707                                                 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3708                                         }
3709
3710                                 s3 += 2 /* cmp */ + 6 /* jcc */;
3711
3712                                 if (super == NULL)
3713                                         s3 += (opt_showdisassemble ? 5 : 0);
3714
3715                                 /* if class is not resolved, check which code to call */
3716
3717                                 if (super == NULL) {
3718                                         M_TEST(s1);
3719                                         M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3720
3721                                         codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3722                                                                                 (constant_classref *) iptr->target, 0);
3723
3724                                         if (opt_showdisassemble) {
3725                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3726                                         }
3727
3728                                         M_MOV_IMM(0, REG_ITMP2);                  /* super->flags */
3729                                         M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3730                                         M_BEQ(s2 + 5);
3731                                 }
3732
3733                                 /* interface checkcast code */
3734
3735                                 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3736                                         if (super != NULL) {
3737                                                 M_TEST(s1);
3738                                                 M_BEQ(s2);
3739                                         }
3740
3741                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3742
3743                                         if (super == NULL) {
3744                                                 codegen_addpatchref(cd,
3745                                                                                         PATCHER_checkcast_instanceof_interface,
3746                                                                                         (constant_classref *) iptr->target,
3747                                                                                         0);
3748
3749                                                 if (opt_showdisassemble) {
3750                                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3751                                                 }
3752                                         }
3753
3754                                         M_ILD32(REG_ITMP3,
3755                                                         REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3756                                         M_ISUB_IMM32(superindex, REG_ITMP3);
3757                                         M_TEST(REG_ITMP3);
3758                                         M_BLE(0);
3759                                         codegen_add_classcastexception_ref(cd, s1);
3760                                         M_ALD32(REG_ITMP3, REG_ITMP2,
3761                                                         OFFSET(vftbl_t, interfacetable[0]) -
3762                                                         superindex * sizeof(methodptr*));
3763                                         M_TEST(REG_ITMP3);
3764                                         M_BEQ(0);
3765                                         codegen_add_classcastexception_ref(cd, s1);
3766
3767                                         if (super == NULL)
3768                                                 M_JMP_IMM(s3);
3769                                 }
3770
3771                                 /* class checkcast code */
3772
3773                                 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3774                                         if (super != NULL) {
3775                                                 M_TEST(s1);
3776                                                 M_BEQ(s3);
3777                                         }
3778
3779                                         M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3780
3781                                         if (super == NULL) {
3782                                                 codegen_addpatchref(cd, PATCHER_checkcast_class,
3783                                                                                         (constant_classref *) iptr->target,
3784                                                                                         0);
3785
3786                                                 if (opt_showdisassemble) {
3787                                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3788                                                 }
3789                                         }
3790
3791                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3792 #if defined(ENABLE_THREADS)
3793                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3794 #endif
3795                                         M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3796
3797                                         /*                              if (s1 != REG_ITMP1) { */
3798                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3799                                         /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3800                                         /* #if defined(ENABLE_THREADS) */
3801                                         /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3802                                         /* #endif */
3803                                         /*                                      emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3804
3805                                         /*                              } else { */
3806                                         M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3807                                         M_ISUB(REG_ITMP3, REG_ITMP2);
3808                                         M_MOV_IMM(supervftbl, REG_ITMP3);
3809                                         M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3810 #if defined(ENABLE_THREADS)
3811                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3812 #endif
3813                                         /*                              } */
3814
3815                                         M_CMP(REG_ITMP3, REG_ITMP2);
3816                                         M_BA(0);         /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
3817                                         codegen_add_classcastexception_ref(cd, s1);
3818                                 }
3819
3820                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
3821                         }
3822                         else {
3823                                 /* array type cast-check */
3824
3825                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
3826                                 M_AST(s1, REG_SP, 0 * 4);
3827
3828                                 if (iptr->val.a == NULL) {
3829                                         codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3830                                                                                 iptr->target, 0);
3831
3832                                         if (opt_showdisassemble) {
3833                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3834                                         }
3835                                 }
3836
3837                                 M_AST_IMM(iptr->val.a, REG_SP, 1 * 4);
3838                                 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3839                                 M_CALL(REG_ITMP3);
3840
3841                                 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
3842                                 M_TEST(REG_RESULT);
3843                                 M_BEQ(0);
3844                                 codegen_add_classcastexception_ref(cd, s1);
3845
3846                                 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3847                         }
3848
3849                         M_INTMOVE(s1, d);
3850                         emit_store(jd, iptr, iptr->dst, d);
3851                         break;
3852
3853                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
3854                                       /* op1:   0 == array, 1 == class                */
3855                                       /* val.a: (classinfo*) superclass               */
3856
3857                         /*  superclass is an interface:
3858                          *
3859                          *  return (sub != NULL) &&
3860                          *         (sub->vftbl->interfacetablelength > super->index) &&
3861                          *         (sub->vftbl->interfacetable[-super->index] != NULL);
3862                          *
3863                          *  superclass is a class:
3864                          *
3865                          *  return ((sub != NULL) && (0
3866                          *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3867                          *          super->vftbl->diffvall));
3868                          */
3869
3870                         {
3871                         classinfo *super;
3872                         vftbl_t   *supervftbl;
3873                         s4         superindex;
3874
3875                         super = (classinfo *) iptr->val.a;
3876
3877                         if (!super) {
3878                                 superindex = 0;
3879                                 supervftbl = NULL;
3880
3881                         } else {
3882                                 superindex = super->index;
3883                                 supervftbl = super->vftbl;
3884                         }
3885                         
3886 #if defined(ENABLE_THREADS)
3887                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3888 #endif
3889
3890                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3891                         d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3892                         if (s1 == d) {
3893                                 M_INTMOVE(s1, REG_ITMP1);
3894                                 s1 = REG_ITMP1;
3895                         }
3896
3897                         /* calculate interface instanceof code size */
3898
3899                         s2 = 2; /* mov_membase_reg */
3900                         CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3901
3902                         s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
3903                                    2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3904                                    2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3905
3906                         if (!super)
3907                                 s2 += (opt_showdisassemble ? 5 : 0);
3908
3909                         /* calculate class instanceof code size */
3910
3911                         s3 = 2; /* mov_membase_reg */
3912                         CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3913                         s3 += 5; /* mov_imm_reg */
3914                         s3 += 2;
3915                         CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3916                         s3 += 2;
3917                         CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3918                         s3 += 2;
3919                         CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3920
3921                         s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
3922                                    2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3923
3924                         if (!super)
3925                                 s3 += (opt_showdisassemble ? 5 : 0);
3926
3927                         M_CLR(d);
3928
3929                         /* if class is not resolved, check which code to call */
3930
3931                         if (!super) {
3932                                 M_TEST(s1);
3933                                 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3934
3935                                 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3936                                                                         (constant_classref *) iptr->target, 0);
3937
3938                                 if (opt_showdisassemble) {
3939                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3940                                 }
3941
3942                                 M_MOV_IMM(0, REG_ITMP3);                      /* super->flags */
3943                                 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3944                                 M_BEQ(s2 + 5);
3945                         }
3946
3947                         /* interface instanceof code */
3948
3949                         if (!super || (super->flags & ACC_INTERFACE)) {
3950                                 if (super) {
3951                                         M_TEST(s1);
3952                                         M_BEQ(s2);
3953                                 }
3954
3955                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3956
3957                                 if (!super) {
3958                                         codegen_addpatchref(cd,
3959                                                                                 PATCHER_checkcast_instanceof_interface,
3960                                                                                 (constant_classref *) iptr->target, 0);
3961
3962                                         if (opt_showdisassemble) {
3963                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3964                                         }
3965                                 }
3966
3967                                 M_ILD32(REG_ITMP3,
3968                                                 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3969                                 M_ISUB_IMM32(superindex, REG_ITMP3);
3970                                 M_TEST(REG_ITMP3);
3971
3972                                 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3973                                                 6 /* jcc */ + 5 /* mov_imm_reg */);
3974
3975                                 M_BLE(disp);
3976                                 M_ALD32(REG_ITMP1, REG_ITMP1,
3977                                                 OFFSET(vftbl_t, interfacetable[0]) -
3978                                                 superindex * sizeof(methodptr*));
3979                                 M_TEST(REG_ITMP1);
3980 /*                                      emit_setcc_reg(cd, CC_A, d); */
3981 /*                                      emit_jcc(cd, CC_BE, 5); */
3982                                 M_BEQ(5);
3983                                 M_MOV_IMM(1, d);
3984
3985                                 if (!super)
3986                                         M_JMP_IMM(s3);
3987                         }
3988
3989                         /* class instanceof code */
3990
3991                         if (!super || !(super->flags & ACC_INTERFACE)) {
3992                                 if (super) {
3993                                         M_TEST(s1);
3994                                         M_BEQ(s3);
3995                                 }
3996
3997                                 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3998
3999                                 if (!super) {
4000                                         codegen_addpatchref(cd, PATCHER_instanceof_class,
4001                                                                                 (constant_classref *) iptr->target, 0);
4002
4003                                         if (opt_showdisassemble) {
4004                                                 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4005                                         }
4006                                 }
4007
4008                                 M_MOV_IMM(supervftbl, REG_ITMP2);
4009 #if defined(ENABLE_THREADS)
4010                                 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
4011 #endif
4012                                 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
4013                                 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
4014                                 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
4015 #if defined(ENABLE_THREADS)
4016                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4017 #endif
4018                                 M_ISUB(REG_ITMP2, REG_ITMP1);
4019                                 M_CLR(d);                                 /* may be REG_ITMP2 */
4020                                 M_CMP(REG_ITMP3, REG_ITMP1);
4021                                 M_BA(5);
4022                                 M_MOV_IMM(1, d);
4023                         }
4024                         emit_store(jd, iptr, iptr->dst, d);
4025                         }
4026                         break;
4027
4028                         break;
4029
4030                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
4031                                       /* op1 = dimension, val.a = class               */
4032
4033                         /* check for negative sizes and copy sizes to stack if necessary  */
4034
4035                         MCODECHECK((iptr->op1 << 1) + 64);
4036
4037                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4038                                 /* copy SAVEDVAR sizes to stack */
4039
4040                                 if (src->varkind != ARGVAR) {
4041                                         if (src->flags & INMEMORY) {
4042                                                 M_ILD(REG_ITMP1, REG_SP, src->regoff * 4);
4043                                                 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
4044                                         }
4045                                         else
4046                                                 M_IST(src->regoff, REG_SP, (s1 + 3) * 4);
4047                                 }
4048                         }
4049
4050                         /* is a patcher function set? */
4051
4052                         if (iptr->val.a == NULL) {
4053                                 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
4054                                                                         (constant_classref *) iptr->target, 0);
4055
4056                                 if (opt_showdisassemble) {
4057                                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4058                                 }
4059
4060                                 disp = 0;
4061
4062                         }
4063                         else
4064                                 disp = (ptrint) iptr->val.a;
4065
4066                         /* a0 = dimension count */
4067
4068                         M_IST_IMM(iptr->op1, REG_SP, 0 * 4);
4069
4070                         /* a1 = arraydescriptor */
4071
4072                         M_IST_IMM(disp, REG_SP, 1 * 4);
4073
4074                         /* a2 = pointer to dimensions = stack pointer */
4075
4076                         M_MOV(REG_SP, REG_ITMP1);
4077                         M_AADD_IMM(3 * 4, REG_ITMP1);
4078                         M_AST(REG_ITMP1, REG_SP, 2 * 4);
4079
4080                         M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
4081                         M_CALL(REG_ITMP1);
4082
4083                         /* check for exception before result assignment */
4084
4085                         M_TEST(REG_RESULT);
4086                         M_BEQ(0);
4087                         codegen_add_fillinstacktrace_ref(cd);
4088
4089                         s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
4090                         M_INTMOVE(REG_RESULT, s1);
4091                         emit_store(jd, iptr, iptr->dst, s1);
4092                         break;
4093
4094                 default:
4095                         *exceptionptr =
4096                                 new_internalerror("Unknown ICMD %d", iptr->opc);
4097                         return false;
4098         } /* switch */
4099                 
4100         } /* for instruction */
4101                 
4102         /* copy values to interface registers */
4103
4104         src = bptr->outstack;
4105         len = bptr->outdepth;
4106         MCODECHECK(64+len);
4107 #if defined(ENABLE_LSRA)
4108         if (!opt_lsra)
4109 #endif
4110         while (src) {
4111                 len--;
4112                 if ((src->varkind != STACKVAR)) {
4113                         s2 = src->type;
4114                         if (IS_FLT_DBL_TYPE(s2)) {
4115                                 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
4116                                 if (!(rd->interfaces[len][s2].flags & INMEMORY))
4117                                         M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
4118                                 else
4119                                         M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4120
4121                         } else {
4122                                 if (IS_2_WORD_TYPE(s2))
4123                                         assert(0);
4124 /*                                      s1 = emit_load_s1(jd, iptr, src, PACK_REGS(REG_ITMP1, REG_ITMP2)); */
4125                                 else
4126                                         s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
4127
4128                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4129                                         if (IS_2_WORD_TYPE(s2))
4130                                                 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
4131                                         else
4132                                                 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
4133
4134                                 } else {
4135                                         if (IS_2_WORD_TYPE(s2))
4136                                                 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4137                                         else
4138                                                 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4139                                 }
4140                         }
4141                 }
4142                 src = src->prev;
4143         }
4144
4145         /* At the end of a basic block we may have to append some nops,
4146            because the patcher stub calling code might be longer than the
4147            actual instruction. So codepatching does not change the
4148            following block unintentionally. */
4149
4150         if (cd->mcodeptr < cd->lastmcodeptr) {
4151                 while (cd->mcodeptr < cd->lastmcodeptr) {
4152                         M_NOP;
4153                 }
4154         }
4155
4156         } /* if (bptr -> flags >= BBREACHED) */
4157         } /* for basic block */
4158
4159         dseg_createlinenumbertable(cd);
4160
4161
4162         /* generate exception and patcher stubs */
4163
4164         {
4165                 exceptionref *eref;
4166                 patchref     *pref;
4167                 u8            mcode;
4168                 u1           *savedmcodeptr;
4169                 u1           *tmpmcodeptr;
4170
4171                 savedmcodeptr = NULL;
4172
4173                 /* generate exception stubs */
4174
4175                 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
4176                         gen_resolvebranch(cd->mcodebase + eref->branchpos,
4177                                                           eref->branchpos,
4178                                                           cd->mcodeptr - cd->mcodebase);
4179
4180                         MCODECHECK(512);
4181
4182                         /* Check if the exception is an
4183                            ArrayIndexOutOfBoundsException.  If so, move index register
4184                            into REG_ITMP1. */
4185
4186                         if (eref->reg != -1)
4187                                 M_INTMOVE(eref->reg, REG_ITMP1);
4188
4189                         /* calcuate exception address */
4190
4191                         M_MOV_IMM(0, REG_ITMP2_XPC);
4192                         dseg_adddata(cd);
4193                         M_AADD_IMM32(eref->branchpos - 6, REG_ITMP2_XPC);
4194
4195                         /* move function to call into REG_ITMP3 */
4196
4197                         M_MOV_IMM(eref->function, REG_ITMP3);
4198
4199                         if (savedmcodeptr != NULL) {
4200                                 M_JMP_IMM((savedmcodeptr - cd->mcodeptr) - 5);
4201
4202                         } else {
4203                                 savedmcodeptr = cd->mcodeptr;
4204
4205                                 M_ASUB_IMM(5 * 4, REG_SP);
4206
4207                                 /* first save REG_ITMP1 so we can use it */
4208
4209                                 M_AST(REG_ITMP1, REG_SP, 4 * 4);                /* for AIOOBE */
4210
4211                                 M_AST_IMM(0, REG_SP, 0 * 4);
4212                                 dseg_adddata(cd);
4213                                 M_MOV(REG_SP, REG_ITMP1);
4214                                 M_AADD_IMM(5 * 4, REG_ITMP1);
4215                                 M_AST(REG_ITMP1, REG_SP, 1 * 4);
4216                                 M_ALD(REG_ITMP1, REG_SP, (5 + stackframesize) * 4);
4217                                 M_AST(REG_ITMP1, REG_SP, 2 * 4);
4218                                 M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4);
4219
4220                                 M_CALL(REG_ITMP3);
4221
4222                                 M_ALD(REG_ITMP2_XPC, REG_SP, 3 * 4);
4223                                 M_AADD_IMM(5 * 4, REG_SP);
4224
4225                                 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
4226                                 M_JMP(REG_ITMP3);
4227                         }
4228                 }
4229
4230
4231                 /* generate code patching stub call code */
4232
4233                 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4234                         /* check code segment size */
4235
4236                         MCODECHECK(512);
4237
4238                         /* Get machine code which is patched back in later. A
4239                            `call rel32' is 5 bytes long. */
4240
4241                         savedmcodeptr = cd->mcodebase + pref->branchpos;
4242                         mcode = *((u8 *) savedmcodeptr);
4243
4244                         /* patch in `call rel32' to call the following code */
4245
4246                         tmpmcodeptr  = cd->mcodeptr;    /* save current mcodeptr          */
4247                         cd->mcodeptr = savedmcodeptr;   /* set mcodeptr to patch position */
4248
4249                         M_CALL_IMM(tmpmcodeptr - (savedmcodeptr + PATCHER_CALL_SIZE));
4250
4251                         cd->mcodeptr = tmpmcodeptr;     /* restore the current mcodeptr   */
4252
4253                         /* save REG_ITMP3 */
4254
4255                         M_PUSH(REG_ITMP3);
4256
4257                         /* move pointer to java_objectheader onto stack */
4258
4259 #if defined(ENABLE_THREADS)
4260                         (void) dseg_addaddress(cd, NULL);                         /* flcword    */
4261                         (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4262                         off = dseg_addaddress(cd, NULL);                          /* vftbl      */
4263
4264                         M_MOV_IMM(0, REG_ITMP3);
4265                         dseg_adddata(cd);
4266                         M_AADD_IMM(off, REG_ITMP3);
4267                         M_PUSH(REG_ITMP3);
4268 #else
4269                         M_PUSH_IMM(0);
4270 #endif
4271
4272                         /* move machine code bytes and classinfo pointer into registers */
4273
4274                         M_PUSH_IMM(mcode >> 32);
4275                         M_PUSH_IMM(mcode);
4276                         M_PUSH_IMM(pref->ref);
4277                         M_PUSH_IMM(pref->patcher);
4278
4279                         M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
4280                         M_JMP(REG_ITMP3);
4281                 }
4282         }
4283
4284         /* generate replacement-out stubs */
4285
4286         {
4287                 int i;
4288
4289                 replacementpoint = jd->code->rplpoints;
4290
4291                 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
4292                         /* check code segment size */
4293
4294                         MCODECHECK(512);
4295
4296                         /* note start of stub code */
4297
4298                         replacementpoint->outcode = (u1*) (ptrint)(cd->mcodeptr - cd->mcodebase);
4299
4300                         /* make machine code for patching */
4301
4302                         disp = (ptrint)(replacementpoint->outcode - replacementpoint->pc) - 5;
4303                         replacementpoint->mcode = 0xe9 | ((u8)disp << 8);
4304
4305                         /* push address of `rplpoint` struct */
4306                         
4307                         M_PUSH_IMM(replacementpoint);
4308
4309                         /* jump to replacement function */
4310
4311                         M_PUSH_IMM(asm_replacement_out);
4312                         M_RET;
4313                 }
4314         }
4315         
4316         codegen_finish(jd);
4317
4318         /* everything's ok */
4319
4320         return true;
4321 }
4322
4323
4324 /* createcompilerstub **********************************************************
4325
4326    Creates a stub routine which calls the compiler.
4327         
4328 *******************************************************************************/
4329
4330 #define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
4331 #define COMPILERSTUB_CODESIZE    12
4332
4333 #define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
4334
4335
4336 u1 *createcompilerstub(methodinfo *m)
4337 {
4338         u1          *s;                     /* memory to hold the stub            */
4339         ptrint      *d;
4340         codeinfo    *code;
4341         codegendata *cd;
4342         s4           dumpsize;
4343
4344         s = CNEW(u1, COMPILERSTUB_SIZE);
4345
4346         /* set data pointer and code pointer */
4347
4348         d = (ptrint *) s;
4349         s = s + COMPILERSTUB_DATASIZE;
4350
4351         /* mark start of dump memory area */
4352
4353         dumpsize = dump_size();
4354
4355         cd = DNEW(codegendata);
4356         cd->mcodeptr = s;
4357
4358         /* Store the codeinfo pointer in the same place as in the
4359            methodheader for compiled methods. */
4360
4361         code = code_codeinfo_new(m);
4362
4363         d[0] = (ptrint) asm_call_jit_compiler;
4364         d[1] = (ptrint) m;
4365         d[2] = (ptrint) code;
4366
4367         /* code for the stub */
4368
4369         M_MOV_IMM(m, REG_ITMP1);            /* method info                        */
4370         M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
4371         M_JMP(REG_ITMP3);
4372
4373 #if defined(ENABLE_STATISTICS)
4374         if (opt_stat)
4375                 count_cstub_len += COMPILERSTUB_SIZE;
4376 #endif
4377
4378         /* release dump area */
4379
4380         dump_release(dumpsize);
4381         
4382         return s;
4383 }
4384
4385
4386 /* createnativestub ************************************************************
4387
4388    Creates a stub routine which calls a native method.
4389
4390 *******************************************************************************/
4391
4392 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4393 {
4394         methodinfo   *m;
4395         codeinfo     *code;
4396         codegendata  *cd;
4397         registerdata *rd;
4398         methoddesc   *md;
4399         s4            stackframesize;
4400         s4            nativeparams;
4401         s4            i, j;                 /* count variables                    */
4402         s4            t;
4403         s4            s1, s2, disp;
4404
4405         /* get required compiler data */
4406
4407         m    = jd->m;
4408         code = jd->code;
4409         cd   = jd->cd;
4410         rd   = jd->rd;
4411
4412         /* set some variables */
4413
4414         md = m->parseddesc;
4415         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4416
4417         /* calculate stackframe size */
4418
4419         stackframesize =
4420                 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4421                 sizeof(localref_table) / SIZEOF_VOID_P +
4422                 1 +                             /* function pointer                   */
4423                 4 * 4 +                         /* 4 arguments (start_native_call)    */
4424                 nmd->memuse;
4425
4426         /* create method header */
4427
4428         (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
4429         (void) dseg_adds4(cd, stackframesize * 4);             /* FrameSize       */
4430         (void) dseg_adds4(cd, 0);                              /* IsSync          */
4431         (void) dseg_adds4(cd, 0);                              /* IsLeaf          */
4432         (void) dseg_adds4(cd, 0);                              /* IntSave         */
4433         (void) dseg_adds4(cd, 0);                              /* FltSave         */
4434         (void) dseg_addlinenumbertablesize(cd);
4435         (void) dseg_adds4(cd, 0);                              /* ExTableSize     */
4436
4437         /* generate native method profiling code */
4438
4439         if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
4440                 /* count frequency */
4441
4442                 M_MOV_IMM(code, REG_ITMP1);
4443                 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
4444         }
4445
4446         /* calculate stackframe size for native function */
4447
4448         M_ASUB_IMM(stackframesize * 4, REG_SP);
4449
4450 #if !defined(NDEBUG)
4451         if (opt_verbosecall) {
4452                 s4 p, t;
4453
4454                 disp = stackframesize * 4;
4455
4456                 M_ASUB_IMM(TRACE_ARGS_NUM * 8 + 4, REG_SP);
4457     
4458                 for (p = 0; p < md->paramcount && p < TRACE_ARGS_NUM; p++) {
4459                         t = md->paramtypes[p].type;
4460                         if (IS_INT_LNG_TYPE(t)) {
4461                                 if (IS_2_WORD_TYPE(t)) {
4462                                         M_ILD(REG_ITMP1, REG_SP,
4463                                                   4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4464                                         M_ILD(REG_ITMP2, REG_SP,
4465                                                   4 + TRACE_ARGS_NUM * 8 + 4 + disp + 4);
4466                                         M_IST(REG_ITMP1, REG_SP, p * 8);
4467                                         M_IST(REG_ITMP2, REG_SP, p * 8 + 4);
4468
4469                                 } else if (t == TYPE_ADR) {
4470                                         M_ALD(REG_ITMP1, REG_SP,
4471                                                   4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4472                                         M_CLR(REG_ITMP2);
4473                                         M_AST(REG_ITMP1, REG_SP, p * 8);
4474                                         M_AST(REG_ITMP2, REG_SP, p * 8 + 4);
4475
4476                                 } else {
4477                                         M_ILD(EAX, REG_SP, 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4478                                         emit_cltd(cd);
4479                                         M_IST(EAX, REG_SP, p * 8);
4480                                         M_IST(EDX, REG_SP, p * 8 + 4);
4481                                 }
4482
4483                         } else {
4484                                 if (!IS_2_WORD_TYPE(t)) {
4485                                         emit_flds_membase(cd, REG_SP,
4486                                                                           4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4487                                         emit_fstps_membase(cd, REG_SP, p * 8);
4488                                         emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP2, REG_ITMP2);
4489                                         M_IST(REG_ITMP2, REG_SP, p * 8 + 4);
4490
4491                                 } else {
4492                                         emit_fldl_membase(cd, REG_SP,
4493                                             4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4494                                         emit_fstpl_membase(cd, REG_SP, p * 8);
4495                                 }
4496                         }
4497                         disp += (IS_2_WORD_TYPE(t)) ? 8 : 4;
4498                 }
4499         
4500                 M_CLR(REG_ITMP1);
4501                 for (p = md->paramcount; p < TRACE_ARGS_NUM; p++) {
4502                         M_IST(REG_ITMP1, REG_SP, p * 8);
4503                         M_IST(REG_ITMP1, REG_SP, p * 8 + 4);
4504                 }
4505
4506                 M_AST_IMM(m, REG_SP, TRACE_ARGS_NUM * 8);
4507
4508                 M_MOV_IMM(builtin_trace_args, REG_ITMP1);
4509                 M_CALL(REG_ITMP1);
4510
4511                 M_AADD_IMM(TRACE_ARGS_NUM * 8 + 4, REG_SP);
4512         }
4513 #endif /* !defined(NDEBUG) */
4514
4515         /* get function address (this must happen before the stackframeinfo) */
4516
4517 #if !defined(WITH_STATIC_CLASSPATH)
4518         if (f == NULL) {
4519                 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
4520
4521                 if (opt_showdisassemble) {
4522                         M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4523                 }
4524         }
4525 #endif
4526
4527         M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
4528
4529         /* Mark the whole fpu stack as free for native functions (only for saved  */
4530         /* register count == 0).                                                  */
4531
4532         emit_ffree_reg(cd, 0);
4533         emit_ffree_reg(cd, 1);
4534         emit_ffree_reg(cd, 2);
4535         emit_ffree_reg(cd, 3);
4536         emit_ffree_reg(cd, 4);
4537         emit_ffree_reg(cd, 5);
4538         emit_ffree_reg(cd, 6);
4539         emit_ffree_reg(cd, 7);
4540
4541         /* prepare data structures for native function call */
4542
4543         M_MOV(REG_SP, REG_ITMP1);
4544         M_AADD_IMM(stackframesize * 4, REG_ITMP1);
4545
4546         M_AST(REG_ITMP1, REG_SP, 0 * 4);
4547         M_IST_IMM(0, REG_SP, 1 * 4);
4548         dseg_adddata(cd);
4549
4550         M_MOV(REG_SP, REG_ITMP2);
4551         M_AADD_IMM(stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
4552
4553         M_AST(REG_ITMP2, REG_SP, 2 * 4);
4554         M_ALD(REG_ITMP3, REG_SP, stackframesize * 4);
4555         M_AST(REG_ITMP3, REG_SP, 3 * 4);
4556         M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
4557         M_CALL(REG_ITMP1);
4558
4559         M_ALD(REG_ITMP3, REG_SP, 4 * 4);
4560
4561         /* copy arguments into new stackframe */
4562
4563         for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4564                 t = md->paramtypes[i].type;
4565
4566                 if (!md->params[i].inmemory) {
4567                         /* no integer argument registers */
4568                 } else {       /* float/double in memory can be copied like int/longs */
4569                         s1 = (md->params[i].regoff + stackframesize + 1) * 4;
4570                         s2 = nmd->params[j].regoff * 4;
4571
4572                         M_ILD(REG_ITMP1, REG_SP, s1);
4573                         M_IST(REG_ITMP1, REG_SP, s2);
4574                         if (IS_2_WORD_TYPE(t)) {
4575                                 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
4576                                 M_IST(REG_ITMP1, REG_SP, s2 + 4);
4577                         }
4578                 }
4579         }
4580
4581         /* if function is static, put class into second argument */
4582
4583         if (m->flags & ACC_STATIC)
4584                 M_AST_IMM((ptrint) m->class, REG_SP, 1 * 4);
4585
4586         /* put env into first argument */
4587
4588         M_AST_IMM((ptrint) _Jv_env, REG_SP, 0 * 4);
4589
4590         /* call the native function */
4591
4592         M_CALL(REG_ITMP3);
4593
4594         /* save return value */
4595
4596         if (md->returntype.type != TYPE_VOID) {
4597                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4598                         if (IS_2_WORD_TYPE(md->returntype.type))
4599                                 M_IST(REG_RESULT2, REG_SP, 2 * 4);
4600                         M_IST(REG_RESULT, REG_SP, 1 * 4);
4601                 }
4602                 else {
4603                         if (IS_2_WORD_TYPE(md->returntype.type))
4604                                 emit_fstl_membase(cd, REG_SP, 1 * 4);
4605                         else
4606                                 emit_fsts_membase(cd, REG_SP, 1 * 4);
4607                 }
4608         }
4609
4610 #if !defined(NDEBUG)
4611     if (opt_verbosecall) {
4612                 /* restore return value */
4613
4614                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4615                         if (IS_2_WORD_TYPE(md->returntype.type))
4616                                 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
4617                         M_ILD(REG_RESULT, REG_SP, 1 * 4);
4618         
4619                 } else {
4620                         if (IS_2_WORD_TYPE(md->returntype.type))
4621                                 emit_fldl_membase(cd, REG_SP, 1 * 4);
4622                         else
4623                                 emit_flds_membase(cd, REG_SP, 1 * 4);
4624                 }
4625
4626                 M_ASUB_IMM(4 + 8 + 8 + 4, REG_SP);
4627
4628                 M_AST_IMM((ptrint) m, REG_SP, 0);
4629
4630                 M_IST(REG_RESULT, REG_SP, 4);
4631                 M_IST(REG_RESULT2, REG_SP, 4 + 4);
4632
4633                 emit_fstl_membase(cd, REG_SP, 4 + 8);
4634                 emit_fsts_membase(cd, REG_SP, 4 + 8 + 8);
4635
4636                 M_MOV_IMM(builtin_displaymethodstop, REG_ITMP1);
4637                 M_CALL(REG_ITMP1);
4638
4639                 M_AADD_IMM(4 + 8 + 8 + 4, REG_SP);
4640     }
4641 #endif /* !defined(NDEBUG) */
4642
4643         /* remove native stackframe info */
4644
4645         M_MOV(REG_SP, REG_ITMP1);
4646         M_AADD_IMM(stackframesize * 4, REG_ITMP1);
4647
4648         M_AST(REG_ITMP1, REG_SP, 0 * 4);
4649         M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
4650         M_CALL(REG_ITMP1);
4651         M_MOV(REG_RESULT, REG_ITMP2);                 /* REG_ITMP3 == REG_RESULT2 */
4652
4653         /* restore return value */
4654
4655         if (md->returntype.type != TYPE_VOID) {
4656                 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4657                         if (IS_2_WORD_TYPE(md->returntype.type))
4658                                 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
4659                         M_ILD(REG_RESULT, REG_SP, 1 * 4);
4660                 }
4661                 else {
4662                         if (IS_2_WORD_TYPE(md->returntype.type))
4663                                 emit_fldl_membase(cd, REG_SP, 1 * 4);
4664                         else
4665                                 emit_flds_membase(cd, REG_SP, 1 * 4);
4666                 }
4667         }
4668
4669         M_AADD_IMM(stackframesize * 4, REG_SP);
4670
4671         /* check for exception */
4672
4673         M_TEST(REG_ITMP2);
4674         M_BNE(1);
4675
4676         M_RET;
4677
4678         /* handle exception */
4679
4680         M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
4681         M_ALD(REG_ITMP2_XPC, REG_SP, 0);
4682         M_ASUB_IMM(2, REG_ITMP2_XPC);
4683
4684         M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
4685         M_JMP(REG_ITMP3);
4686
4687
4688         /* process patcher calls **************************************************/
4689
4690         {
4691                 u1       *xcodeptr;
4692                 patchref *pref;
4693                 u8        mcode;
4694                 u1       *tmpmcodeptr;
4695
4696                 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4697                         /* Get machine code which is patched back in later. A
4698                            `call rel32' is 5 bytes long. */
4699
4700                         xcodeptr = cd->mcodebase + pref->branchpos;
4701                         mcode =  *((u8 *) xcodeptr);
4702
4703                         /* patch in `call rel32' to call the following code */
4704
4705                         tmpmcodeptr  = cd->mcodeptr;    /* save current mcodeptr          */
4706                         cd->mcodeptr = xcodeptr;        /* set mcodeptr to patch position */
4707
4708                         M_CALL_IMM(tmpmcodeptr - (xcodeptr + PATCHER_CALL_SIZE));
4709
4710                         cd->mcodeptr = tmpmcodeptr;     /* restore the current mcodeptr   */
4711
4712                         /* save REG_ITMP3 */
4713
4714                         M_PUSH(REG_ITMP3);
4715
4716                         /* move pointer to java_objectheader onto stack */
4717
4718 #if defined(ENABLE_THREADS)
4719                         /* create a virtual java_objectheader */
4720
4721                         (void) dseg_addaddress(cd, NULL);                         /* flcword    */
4722                         (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4723                         disp = dseg_addaddress(cd, NULL);                         /* vftbl      */
4724
4725                         M_MOV_IMM(0, REG_ITMP3);
4726                         dseg_adddata(cd);
4727                         M_AADD_IMM(disp, REG_ITMP3);
4728                         M_PUSH(REG_ITMP3);
4729 #else
4730                         M_PUSH_IMM(0);
4731 #endif
4732
4733                         /* move machine code bytes and classinfo pointer onto stack */
4734
4735                         M_PUSH_IMM((mcode >> 32));
4736                         M_PUSH_IMM(mcode);
4737                         M_PUSH_IMM(pref->ref);
4738                         M_PUSH_IMM(pref->patcher);
4739
4740                         M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
4741                         M_JMP(REG_ITMP3);
4742                 }
4743         }
4744
4745         codegen_finish(jd);
4746
4747         return code->entrypoint;
4748 }
4749
4750
4751 /*
4752  * These are local overrides for various environment variables in Emacs.
4753  * Please do not remove this and leave it at the end of the file, where
4754  * Emacs will automagically detect them.
4755  * ---------------------------------------------------------------------
4756  * Local variables:
4757  * mode: c
4758  * indent-tabs-mode: t
4759  * c-basic-offset: 4
4760  * tab-width: 4
4761  * End:
4762  * vim:noexpandtab:sw=4:ts=4:
4763  */