changed descriptor2types to parsed descriptors and moved it to method.c
[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 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28             Christian Thalinger
29
30    Changes: Joseph Wenninger
31
32    $Id: codegen.c 2184 2005-04-01 21:19:05Z edwin $
33
34 */
35
36
37 #define _GNU_SOURCE
38
39 #include <stdio.h>
40 #include <ucontext.h>
41 #ifdef __FreeBSD__
42 #include <machine/signal.h>
43 #endif
44
45 #include "config.h"
46 #include "cacao/cacao.h"
47 #include "native/jni.h"
48 #include "native/native.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/loader.h"
53 #include "vm/tables.h"
54 #include "vm/utf8.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/parse.h"
58 #include "vm/jit/reg.h"
59 #include "vm/jit/i386/codegen.h"
60 #include "vm/jit/i386/emitfuncs.h"
61 #include "vm/jit/i386/types.h"
62 #include "vm/jit/i386/asmoffsets.h"
63
64
65 /* register descripton - array ************************************************/
66
67 /* #define REG_RES   0         reserved register for OS or code generator     */
68 /* #define REG_RET   1         return value register                          */
69 /* #define REG_EXC   2         exception value register (only old jit)        */
70 /* #define REG_SAV   3         (callee) saved register                        */
71 /* #define REG_TMP   4         scratch temporary register (caller saved)      */
72 /* #define REG_ARG   5         argument register (caller saved)               */
73
74 /* #define REG_END   -1        last entry in tables */
75
76 static int nregdescint[] = {
77     REG_RET, REG_RES, REG_RES, REG_TMP, REG_RES, REG_SAV, REG_SAV, REG_SAV,
78     REG_END
79 };
80
81
82 static int nregdescfloat[] = {
83   /* rounding problems with callee saved registers */
84 /*      REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_RES, REG_RES, */
85 /*      REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, */
86     REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
87     REG_END
88 };
89
90
91 /*******************************************************************************
92
93     include independent code generation stuff -- include after register
94     descriptions to avoid extern definitions
95
96 *******************************************************************************/
97
98 #include "vm/jit/codegen.inc"
99 #include "vm/jit/reg.inc"
100 #ifdef LSRA
101 #include "vm/jit/lsra.inc"
102 #endif
103
104 void codegen_stubcalled() {
105         log_text("Stub has been called");
106 }
107
108
109 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
110 void thread_restartcriticalsection(ucontext_t *uc)
111 {
112         void *critical;
113 #ifdef __FreeBSD__
114         if ((critical = thread_checkcritical((void*) uc->uc_mcontext.mc_eip)) != NULL)
115                 uc->uc_mcontext.mc_eip = (u4) critical;
116 #else
117         if ((critical = thread_checkcritical((void*) uc->uc_mcontext.gregs[REG_EIP])) != NULL)
118                 uc->uc_mcontext.gregs[REG_EIP] = (u4) critical;
119
120 #endif
121 }
122 #endif
123
124
125
126 /* NullPointerException signal handler for hardware null pointer check */
127
128 void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
129 {
130         sigset_t nsig;
131
132         ucontext_t *_uc = (ucontext_t *) _p;
133 #ifdef __FreeBSD__
134         mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
135 #else
136         struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
137 #endif
138         struct sigaction act;
139
140         /* Reset signal handler - necessary for SysV, does no harm for BSD */
141
142         act.sa_sigaction = catch_NullPointerException;
143         act.sa_flags = SA_SIGINFO;
144         sigaction(sig, &act, NULL);                          /* reinstall handler */
145
146         sigemptyset(&nsig);
147         sigaddset(&nsig, sig);
148         sigprocmask(SIG_UNBLOCK, &nsig, NULL);           /* unblock signal    */
149
150 #ifdef __FreeBSD__
151         sigctx->mc_ecx = sigctx->mc_eip;     /* REG_ITMP2_XPC*/
152         sigctx->mc_eax = (u4) string_java_lang_NullPointerException;
153         sigctx->mc_eip = (u4) asm_throw_and_handle_exception;
154 #else
155         sigctx->ecx = sigctx->eip;             /* REG_ITMP2_XPC     */
156         sigctx->eax = (u4) string_java_lang_NullPointerException;
157         sigctx->eip = (u4) asm_throw_and_handle_exception;
158 #endif
159
160         return;
161 }
162
163
164 /* ArithmeticException signal handler for hardware divide by zero check       */
165
166 void catch_ArithmeticException(int sig, siginfo_t *siginfo, void *_p)
167 {
168         sigset_t nsig;
169
170 #ifdef __FreeBSD__
171         ucontext_t *_uc = (ucontext_t *) _p;
172         mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
173 #else
174         struct ucontext *_uc = (struct ucontext *) _p;
175         struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
176 #endif
177
178         struct sigaction act;
179
180         /* Reset signal handler - necessary for SysV, does no harm for BSD        */
181
182         act.sa_sigaction = catch_ArithmeticException;
183         act.sa_flags = SA_SIGINFO;
184         sigaction(sig, &act, NULL);                          /* reinstall handler */
185
186         sigemptyset(&nsig);
187         sigaddset(&nsig, sig);
188         sigprocmask(SIG_UNBLOCK, &nsig, NULL);               /* unblock signal    */
189
190 #ifdef __FreeBSD__
191         sigctx->mc_ecx = sigctx->mc_eip;                 /* REG_ITMP2_XPC     */
192         sigctx->mc_eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
193 #else
194         sigctx->ecx = sigctx->eip;                     /* REG_ITMP2_XPC     */
195         sigctx->eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
196 #endif
197         return;
198 }
199
200
201 void init_exceptions(void)
202 {
203         struct sigaction act;
204
205         /* install signal handlers we need to convert to exceptions */
206         sigemptyset(&act.sa_mask);
207
208         if (!checknull) {
209                 act.sa_sigaction = catch_NullPointerException;
210                 act.sa_flags = SA_SIGINFO;
211
212 #if defined(SIGSEGV)
213                 sigaction(SIGSEGV, &act, NULL);
214 #endif
215
216 #if defined(SIGBUS)
217                 sigaction(SIGBUS, &act, NULL);
218 #endif
219         }
220
221 #if defined(SIGFPE)
222         act.sa_sigaction = catch_ArithmeticException;
223         act.sa_flags = SA_SIGINFO;
224         sigaction(SIGFPE, &act, NULL);
225 #endif
226 }
227
228
229 /* function codegen ************************************************************
230
231         generates machine code
232
233 *******************************************************************************/
234
235 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
236 {
237         s4 len, s1, s2, s3, d;
238         s4 a;
239         stackptr      src;
240         varinfo      *var;
241         basicblock   *bptr;
242         instruction  *iptr;
243         s4 parentargs_base;
244         u2 currentline;
245         s4 fpu_st_offset = 0;
246
247         exceptiontable *ex;
248
249         {
250         s4 i, p, pa, t, l;
251         s4 savedregs_num = 0;
252
253         /* space to save used callee saved registers */
254
255         savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
256         savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
257
258         parentargs_base = rd->maxmemuse + savedregs_num;
259
260            
261 #if defined(USE_THREADS)           /* space to save argument of monitor_enter */
262
263         if (checksync && (m->flags & ACC_SYNCHRONIZED))
264                 parentargs_base++;
265
266 #endif
267
268         /* create method header */
269
270         (void) dseg_addaddress(cd, m);                          /* MethodPointer  */
271         (void) dseg_adds4(cd, parentargs_base * 8);             /* FrameSize      */
272
273 #if defined(USE_THREADS)
274
275         /* IsSync contains the offset relative to the stack pointer for the
276            argument of monitor_exit used in the exception handler. Since the
277            offset could be zero and give a wrong meaning of the flag it is
278            offset by one.
279         */
280
281         if (checksync && (m->flags & ACC_SYNCHRONIZED))
282                 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8);         /* IsSync     */
283         else
284
285 #endif
286
287         (void) dseg_adds4(cd, 0);                                   /* IsSync     */
288                                                
289         (void) dseg_adds4(cd, m->isleafmethod);                     /* IsLeaf     */
290         (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse); /* IntSave */
291         (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse); /* FltSave */
292
293         /* adds a reference for the length of the line number counter. We don't
294            know the size yet, since we evaluate the information during code
295            generation, to save one additional iteration over the whole
296            instructions. During code optimization the position could have changed
297            to the information gotten from the class file */
298         (void) dseg_addlinenumbertablesize(cd);
299
300         (void) dseg_adds4(cd, cd->exceptiontablelength);        /* ExTableSize    */
301         
302         /* create exception table */
303
304         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
305                 dseg_addtarget(cd, ex->start);
306                 dseg_addtarget(cd, ex->end);
307                 dseg_addtarget(cd, ex->handler);
308                 (void) dseg_addaddress(cd, ex->catchtype);
309         }
310
311         
312         /* initialize mcode variables */
313         
314         cd->mcodeptr = cd->mcodebase;
315         cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
316         MCODECHECK(128 + m->paramcount);
317
318         /* create stack frame (if necessary) */
319
320         if (parentargs_base) {
321                 i386_alu_imm_reg(cd, I386_SUB, parentargs_base * 8, REG_SP);
322         }
323
324         /* save return address and used callee saved registers */
325
326         p = parentargs_base;
327         for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
328                 p--; i386_mov_reg_membase(cd, rd->savintregs[i], REG_SP, p * 8);
329         }
330         for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
331                 p--; i386_fld_reg(cd, rd->savfltregs[i]); i386_fstpl_membase(cd, REG_SP, p * 8);
332         }
333
334         /* save monitorenter argument */
335
336 #if defined(USE_THREADS)
337         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
338                 s4 func_enter = (m->flags & ACC_STATIC) ?
339                         (s4) builtin_staticmonitorenter : (s4) builtin_monitorenter;
340
341                 if (m->flags & ACC_STATIC) {
342                         i386_mov_imm_reg(cd, (s4) m->class, REG_ITMP1);
343                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, rd->maxmemuse * 8);
344
345                 } else {
346                         i386_mov_membase_reg(cd, REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
347                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, rd->maxmemuse * 8);
348                 }
349
350                 /* call monitorenter function */
351
352                 i386_alu_imm_reg(cd, I386_SUB, 4, REG_SP);
353                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0);
354                 i386_mov_imm_reg(cd, func_enter, REG_ITMP1);
355                 i386_call_reg(cd, REG_ITMP1);
356                 i386_alu_imm_reg(cd, I386_ADD, 4, REG_SP);
357         }                       
358 #endif
359
360         /* copy argument registers to stack and call trace function with pointer
361            to arguments on stack.
362         */
363
364         if (runverbose) {
365                 i386_alu_imm_reg(cd, I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
366
367                 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
368                         t = m->paramtypes[p];
369
370                         if (IS_INT_LNG_TYPE(t)) {
371                                 if (IS_2_WORD_TYPE(t)) {
372                                         i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
373                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
374                                         i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP1);
375                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
376
377 /*                              } else if (t == TYPE_ADR) { */
378                                 } else {
379                                         i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
380                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
381                                         i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
382                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
383
384 /*                              } else { */
385 /*                                      i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, EAX); */
386 /*                                      i386_cltd(cd); */
387 /*                                      i386_mov_reg_membase(cd, EAX, REG_SP, p * 8); */
388 /*                                      i386_mov_reg_membase(cd, EDX, REG_SP, p * 8 + 4); */
389                                 }
390
391                         } else {
392                                 if (!IS_2_WORD_TYPE(t)) {
393                                         i386_flds_membase(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
394                                         i386_fstps_membase(cd, REG_SP, p * 8);
395                                         i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
396                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
397
398                                 } else {
399                                         i386_fldl_membase(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
400                                         i386_fstpl_membase(cd, REG_SP, p * 8);
401                                 }
402                         }
403                 }
404
405                 /* fill up the remaining arguments */
406                 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
407                 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
408                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
409                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
410                 }
411
412                 i386_mov_imm_membase(cd, (s4) m, REG_SP, TRACE_ARGS_NUM * 8);
413                 i386_mov_imm_reg(cd, (s4) builtin_trace_args, REG_ITMP1);
414                 i386_call_reg(cd, REG_ITMP1);
415
416                 i386_alu_imm_reg(cd, I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
417         }
418
419         /* take arguments out of register or stack frame */
420
421         for (p = 0, l = 0; p < m->paramcount; p++) {
422                 t = m->paramtypes[p];
423                 var = &(rd->locals[l][t]);
424                 l++;
425                 if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
426                         l++;
427                 if (var->type < 0)
428                         continue;
429                 if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
430                         if (p < rd->intreg_argnum) {              /* register arguments    */
431                                 panic("integer register argument");
432                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
433 /*                                      M_INTMOVE (argintregs[p], r); */
434
435                                 } else {                             /* reg arg -> spilled    */
436 /*                                      M_LST (argintregs[p], REG_SP, 8 * r); */
437                                 }
438                         } else {                                 /* stack arguments       */
439                                 pa = p - rd->intreg_argnum;
440                                 if (!(var->flags & INMEMORY)) {      /* stack arg -> register */ 
441                                         i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, var->regoff);            /* + 4 for return address */
442                                 } else {                             /* stack arg -> spilled  */
443                                         if (!IS_2_WORD_TYPE(t)) {
444                                                 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1);    /* + 4 for return address */
445                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8);
446
447                                         } else {
448                                                 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1);    /* + 4 for return address */
449                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8);
450                                                 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP1);    /* + 4 for return address */
451                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8 + 4);
452                                         }
453                                 }
454                         }
455                 
456                 } else {                                     /* floating args         */   
457                         if (p < rd->fltreg_argnum) {              /* register arguments    */
458                                 if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
459                                         panic("There are no float argument registers!");
460
461                                 } else {                                         /* reg arg -> spilled    */
462                                         panic("There are no float argument registers!");
463                                 }
464
465                         } else {                                 /* stack arguments       */
466                                 pa = p - rd->fltreg_argnum;
467                                 if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
468                                         if (t == TYPE_FLT) {
469                                                 i386_flds_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
470                                                 fpu_st_offset++;
471                                                 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
472                                                 fpu_st_offset--;
473
474                                         } else {
475                                                 i386_fldl_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
476                                                 fpu_st_offset++;
477                                                 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
478                                                 fpu_st_offset--;
479                                         }
480
481                                 } else {                              /* stack-arg -> spilled  */
482 /*                                      i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
483 /*                                      i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, r * 8); */
484                                         if (t == TYPE_FLT) {
485                                                 i386_flds_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
486                                                 i386_fstps_membase(cd, REG_SP, var->regoff * 8);
487
488                                         } else {
489                                                 i386_fldl_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
490                                                 i386_fstpl_membase(cd, REG_SP, var->regoff * 8);
491                                         }
492                                 }
493                         }
494                 }
495         }  /* end for */
496
497         }
498
499         /* end of header generation */
500
501         /* walk through all basic blocks */
502         for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
503
504                 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
505
506                 if (bptr->flags >= BBREACHED) {
507
508                 /* branch resolving */
509
510                 branchref *brefs;
511                 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
512                         gen_resolvebranch(cd->mcodebase + brefs->branchpos, 
513                                           brefs->branchpos,
514                                                           bptr->mpc);
515                 }
516
517                 /* copy interface registers to their destination */
518
519                 src = bptr->instack;
520                 len = bptr->indepth;
521                 MCODECHECK(64+len);
522
523 #ifdef LSRA
524                 if (opt_lsra) {
525                 while (src != NULL) {
526                         len--;
527                         if ((len == 0) && (bptr->type != BBTYPE_STD)) {
528                                 if (!IS_2_WORD_TYPE(src->type)) {
529                                         if (bptr->type == BBTYPE_SBR) {
530                                                         /*                                                      d = reg_of_var(m, src, REG_ITMP1); */
531                                                         if (!(src->flags & INMEMORY))
532                                                                 d= src->regoff;
533                                                         else
534                                                                 d=REG_ITMP1;
535                                                 i386_pop_reg(cd, d);
536                                                 store_reg_to_var_int(src, d);
537                                                 } else if (bptr->type == BBTYPE_EXH) {
538                                                         /*                                                      d = reg_of_var(m, src, REG_ITMP1); */
539                                                         if (!(src->flags & INMEMORY))
540                                                                 d= src->regoff;
541                                                         else
542                                                                 d=REG_ITMP1;
543                                                         M_INTMOVE(REG_ITMP1, d);
544                                                         store_reg_to_var_int(src, d);
545                                                 }
546
547                                         } else {
548                                                 panic("copy interface registers(EXH, SBR): longs have to me in memory (begin 1)");
549                                         }
550                                 }
551                                 src = src->prev;
552                         }
553                 } else {
554 #endif
555                         while (src != NULL) {
556                                 len--;
557                                 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
558                                         if (!IS_2_WORD_TYPE(src->type)) {
559                                                 if (bptr->type == BBTYPE_SBR) {
560                                                         d = reg_of_var(rd, src, REG_ITMP1);
561                                                         i386_pop_reg(cd, d);
562                                                         store_reg_to_var_int(src, d);
563                                         } else if (bptr->type == BBTYPE_EXH) {
564                                                 d = reg_of_var(rd, src, REG_ITMP1);
565                                                 M_INTMOVE(REG_ITMP1, d);
566                                                 store_reg_to_var_int(src, d);
567                                         }
568
569                                 } else {
570                                         panic("copy interface registers: longs have to me in memory (begin 1)");
571                                 }
572
573                         } else {
574                                 d = reg_of_var(rd, src, REG_ITMP1);
575                                 if ((src->varkind != STACKVAR)) {
576                                         s2 = src->type;
577                                         if (IS_FLT_DBL_TYPE(s2)) {
578                                                 s1 = rd->interfaces[len][s2].regoff;
579                                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
580                                                         M_FLTMOVE(s1, d);
581
582                                                 } else {
583                                                         if (s2 == TYPE_FLT) {
584                                                                 i386_flds_membase(cd, REG_SP, s1 * 8);
585
586                                                         } else {
587                                                                 i386_fldl_membase(cd, REG_SP, s1 * 8);
588                                                         }
589                                                 }
590                                                 store_reg_to_var_flt(src, d);
591
592                                         } else {
593                                                 s1 = rd->interfaces[len][s2].regoff;
594                                                 if (!IS_2_WORD_TYPE(rd->interfaces[len][s2].type)) {
595                                                         if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
596                                                                 M_INTMOVE(s1, d);
597
598                                                         } else {
599                                                                 i386_mov_membase_reg(cd, REG_SP, s1 * 8, d);
600                                                         }
601                                                         store_reg_to_var_int(src, d);
602
603                                                 } else {
604                                                         if (rd->interfaces[len][s2].flags & INMEMORY) {
605                                                                 M_LNGMEMMOVE(s1, src->regoff);
606
607                                                         } else {
608                                                                 panic("copy interface registers: longs have to be in memory (begin 2)");
609                                                         }
610                                                 }
611                                         }
612                                 }
613                         }
614                         src = src->prev;
615                 }
616 #ifdef LSRA
617                 }
618 #endif
619
620                 /* walk through all instructions */
621                 
622                 src = bptr->instack;
623                 len = bptr->icount;
624                 currentline = 0;
625                 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
626                         if (iptr->line != currentline) {
627                                 dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
628                                 currentline = iptr->line;
629                         }
630
631                         MCODECHECK(64);   /* an instruction usually needs < 64 words      */
632
633                 switch (iptr->opc) {
634                 case ICMD_INLINE_START:
635                 case ICMD_INLINE_END:
636                         break;
637
638                 case ICMD_NOP:        /* ...  ==> ...                                 */
639                         break;
640
641                 case ICMD_NULLCHECKPOP: /* ..., objectref  ==> ...                    */
642                         if (src->flags & INMEMORY) {
643                                 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
644
645                         } else {
646                                 i386_test_reg_reg(cd, src->regoff, src->regoff);
647                         }
648                         i386_jcc(cd, I386_CC_E, 0);
649                         codegen_addxnullrefs(cd, cd->mcodeptr);
650                         break;
651
652                 /* constant operations ************************************************/
653
654                 case ICMD_ICONST:     /* ...  ==> ..., constant                       */
655                                       /* op1 = 0, val.i = constant                    */
656
657                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
658                         if (iptr->dst->flags & INMEMORY) {
659                                 i386_mov_imm_membase(cd, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
660
661                         } else {
662                                 if (iptr->val.i == 0) {
663                                         i386_alu_reg_reg(cd, I386_XOR, d, d);
664
665                                 } else {
666                                         i386_mov_imm_reg(cd, iptr->val.i, d);
667                                 }
668                         }
669                         break;
670
671                 case ICMD_LCONST:     /* ...  ==> ..., constant                       */
672                                       /* op1 = 0, val.l = constant                    */
673
674                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
675                         if (iptr->dst->flags & INMEMORY) {
676                                 i386_mov_imm_membase(cd, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
677                                 i386_mov_imm_membase(cd, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
678                                 
679                         } else {
680                                 panic("LCONST: longs have to be in memory");
681                         }
682                         break;
683
684                 case ICMD_FCONST:     /* ...  ==> ..., constant                       */
685                                       /* op1 = 0, val.f = constant                    */
686
687                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
688                         if (iptr->val.f == 0.0) {
689                                 i386_fldz(cd);
690                                 fpu_st_offset++;
691
692                                 /* -0.0 */
693                                 if (iptr->val.i == 0x80000000) {
694                                         i386_fchs(cd);
695                                 }
696
697                         } else if (iptr->val.f == 1.0) {
698                                 i386_fld1(cd);
699                                 fpu_st_offset++;
700
701                         } else if (iptr->val.f == 2.0) {
702                                 i386_fld1(cd);
703                                 i386_fld1(cd);
704                                 i386_faddp(cd);
705                                 fpu_st_offset++;
706
707                         } else {
708                                 a = dseg_addfloat(cd, iptr->val.f);
709                                 i386_mov_imm_reg(cd, 0, REG_ITMP1);
710                                 dseg_adddata(cd, cd->mcodeptr);
711                                 i386_flds_membase(cd, REG_ITMP1, a);
712                                 fpu_st_offset++;
713                         }
714                         store_reg_to_var_flt(iptr->dst, d);
715                         break;
716                 
717                 case ICMD_DCONST:     /* ...  ==> ..., constant                       */
718                                       /* op1 = 0, val.d = constant                    */
719
720                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
721                         if (iptr->val.d == 0.0) {
722                                 i386_fldz(cd);
723                                 fpu_st_offset++;
724
725                                 /* -0.0 */
726                                 if (iptr->val.l == 0x8000000000000000LL) {
727                                         i386_fchs(cd);
728                                 }
729
730                         } else if (iptr->val.d == 1.0) {
731                                 i386_fld1(cd);
732                                 fpu_st_offset++;
733
734                         } else if (iptr->val.d == 2.0) {
735                                 i386_fld1(cd);
736                                 i386_fld1(cd);
737                                 i386_faddp(cd);
738                                 fpu_st_offset++;
739
740                         } else {
741                                 a = dseg_adddouble(cd, iptr->val.d);
742                                 i386_mov_imm_reg(cd, 0, REG_ITMP1);
743                                 dseg_adddata(cd, cd->mcodeptr);
744                                 i386_fldl_membase(cd, REG_ITMP1, a);
745                                 fpu_st_offset++;
746                         }
747                         store_reg_to_var_flt(iptr->dst, d);
748                         break;
749
750                 case ICMD_ACONST:     /* ...  ==> ..., constant                       */
751                                       /* op1 = 0, val.a = constant                    */
752
753                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
754                         if (iptr->dst->flags & INMEMORY) {
755                                 i386_mov_imm_membase(cd, (s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
756
757                         } else {
758                                 if ((s4) iptr->val.a == 0) {
759                                         i386_alu_reg_reg(cd, I386_XOR, d, d);
760
761                                 } else {
762                                         i386_mov_imm_reg(cd, (s4) iptr->val.a, d);
763                                 }
764                         }
765                         break;
766
767
768                 /* load/store operations **********************************************/
769
770                 case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
771                 case ICMD_ALOAD:      /* op1 = local variable                         */
772
773                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
774                         if ((iptr->dst->varkind == LOCALVAR) &&
775                             (iptr->dst->varnum == iptr->op1)) {
776                                 break;
777                         }
778                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
779                         if (iptr->dst->flags & INMEMORY) {
780                                 if (var->flags & INMEMORY) {
781                                         i386_mov_membase_reg(cd, REG_SP, var->regoff * 8, REG_ITMP1);
782                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
783
784                                 } else {
785                                         i386_mov_reg_membase(cd, var->regoff, REG_SP, iptr->dst->regoff * 8);
786                                 }
787
788                         } else {
789                                 if (var->flags & INMEMORY) {
790                                         i386_mov_membase_reg(cd, REG_SP, var->regoff * 8, iptr->dst->regoff);
791
792                                 } else {
793                                         M_INTMOVE(var->regoff, iptr->dst->regoff);
794                                 }
795                         }
796                         break;
797
798                 case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
799                                       /* op1 = local variable                         */
800
801                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
802                         if ((iptr->dst->varkind == LOCALVAR) &&
803                             (iptr->dst->varnum == iptr->op1)) {
804                                 break;
805                         }
806                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
807                         if (iptr->dst->flags & INMEMORY) {
808                                 if (var->flags & INMEMORY) {
809                                         M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
810
811                                 } else {
812                                         panic("LLOAD: longs have to be in memory");
813                                 }
814
815                         } else {
816                                 panic("LLOAD: longs have to be in memory");
817                         }
818                         break;
819
820                 case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
821                                       /* op1 = local variable                         */
822
823                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
824                         if ((iptr->dst->varkind == LOCALVAR) &&
825                             (iptr->dst->varnum == iptr->op1)) {
826                                 break;
827                         }
828                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
829                         if (var->flags & INMEMORY) {
830                                 i386_flds_membase(cd, REG_SP, var->regoff * 8);
831                                 fpu_st_offset++;
832                         } else {
833                                 i386_fld_reg(cd, var->regoff + fpu_st_offset);
834                                 fpu_st_offset++;
835                         }
836                         store_reg_to_var_flt(iptr->dst, d);
837                         break;
838
839                 case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
840                                       /* op1 = local variable                         */
841
842                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
843                         if ((iptr->dst->varkind == LOCALVAR) &&
844                             (iptr->dst->varnum == iptr->op1)) {
845                                 break;
846                         }
847                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
848                         if (var->flags & INMEMORY) {
849                                 i386_fldl_membase(cd, REG_SP, var->regoff * 8);
850                                 fpu_st_offset++;
851                         } else {
852                                 i386_fld_reg(cd, var->regoff + fpu_st_offset);
853                                 fpu_st_offset++;
854                         }
855                         store_reg_to_var_flt(iptr->dst, d);
856                         break;
857
858                 case ICMD_ISTORE:     /* ..., value  ==> ...                          */
859                 case ICMD_ASTORE:     /* op1 = local variable                         */
860
861                         if ((src->varkind == LOCALVAR) &&
862                             (src->varnum == iptr->op1)) {
863                                 break;
864                         }
865                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
866                         if (var->flags & INMEMORY) {
867                                 if (src->flags & INMEMORY) {
868                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
869                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8);
870                                         
871                                 } else {
872                                         i386_mov_reg_membase(cd, src->regoff, REG_SP, var->regoff * 8);
873                                 }
874
875                         } else {
876                                 var_to_reg_int(s1, src, var->regoff);
877                                 M_INTMOVE(s1, var->regoff);
878                         }
879                         break;
880
881                 case ICMD_LSTORE:     /* ..., value  ==> ...                          */
882                                       /* op1 = local variable                         */
883
884                         if ((src->varkind == LOCALVAR) &&
885                             (src->varnum == iptr->op1)) {
886                                 break;
887                         }
888                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
889                         if (var->flags & INMEMORY) {
890                                 if (src->flags & INMEMORY) {
891                                         M_LNGMEMMOVE(src->regoff, var->regoff);
892
893                                 } else {
894                                         panic("LSTORE: longs have to be in memory");
895                                 }
896
897                         } else {
898                                 panic("LSTORE: longs have to be in memory");
899                         }
900                         break;
901
902                 case ICMD_FSTORE:     /* ..., value  ==> ...                          */
903                                       /* op1 = local variable                         */
904
905                         if ((src->varkind == LOCALVAR) &&
906                             (src->varnum == iptr->op1)) {
907                                 break;
908                         }
909                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
910                         if (var->flags & INMEMORY) {
911                                 var_to_reg_flt(s1, src, REG_FTMP1);
912                                 i386_fstps_membase(cd, REG_SP, var->regoff * 8);
913                                 fpu_st_offset--;
914                         } else {
915                                 var_to_reg_flt(s1, src, var->regoff);
916 /*                              M_FLTMOVE(s1, var->regoff); */
917                                 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
918                                 fpu_st_offset--;
919                         }
920                         break;
921
922                 case ICMD_DSTORE:     /* ..., value  ==> ...                          */
923                                       /* op1 = local variable                         */
924
925                         if ((src->varkind == LOCALVAR) &&
926                             (src->varnum == iptr->op1)) {
927                                 break;
928                         }
929                         var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
930                         if (var->flags & INMEMORY) {
931                                 var_to_reg_flt(s1, src, REG_FTMP1);
932                                 i386_fstpl_membase(cd, REG_SP, var->regoff * 8);
933                                 fpu_st_offset--;
934                         } else {
935                                 var_to_reg_flt(s1, src, var->regoff);
936 /*                              M_FLTMOVE(s1, var->regoff); */
937                                 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
938                                 fpu_st_offset--;
939                         }
940                         break;
941
942
943                 /* pop/dup/swap operations ********************************************/
944
945                 /* attention: double and longs are only one entry in CACAO ICMDs      */
946
947                 case ICMD_POP:        /* ..., value  ==> ...                          */
948                 case ICMD_POP2:       /* ..., value, value  ==> ...                   */
949                         break;
950
951                 case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
952                         M_COPY(src, iptr->dst);
953                         break;
954
955                 case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
956
957                         M_COPY(src,       iptr->dst);
958                         M_COPY(src->prev, iptr->dst->prev);
959                         break;
960
961                 case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
962
963                         M_COPY(src,       iptr->dst);
964                         M_COPY(src->prev, iptr->dst->prev);
965                         M_COPY(iptr->dst, iptr->dst->prev->prev);
966                         break;
967
968                 case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
969
970                         M_COPY(src,             iptr->dst);
971                         M_COPY(src->prev,       iptr->dst->prev);
972                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
973                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
974                         break;
975
976                 case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
977
978                         M_COPY(src,             iptr->dst);
979                         M_COPY(src->prev,       iptr->dst->prev);
980                         M_COPY(src->prev->prev, iptr->dst->prev->prev);
981                         M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
982                         M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev);
983                         break;
984
985                 case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
986
987                         M_COPY(src,                   iptr->dst);
988                         M_COPY(src->prev,             iptr->dst->prev);
989                         M_COPY(src->prev->prev,       iptr->dst->prev->prev);
990                         M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
991                         M_COPY(iptr->dst,             iptr->dst->prev->prev->prev->prev);
992                         M_COPY(iptr->dst->prev,       iptr->dst->prev->prev->prev->prev->prev);
993                         break;
994
995                 case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
996
997                         M_COPY(src,       iptr->dst->prev);
998                         M_COPY(src->prev, iptr->dst);
999                         break;
1000
1001
1002                 /* integer operations *************************************************/
1003
1004                 case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
1005
1006                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1007                         if (iptr->dst->flags & INMEMORY) {
1008                                 if (src->flags & INMEMORY) {
1009                                         if (src->regoff == iptr->dst->regoff) {
1010                                                 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8);
1011
1012                                         } else {
1013                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1014                                                 i386_neg_reg(cd, REG_ITMP1);
1015                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1016                                         }
1017
1018                                 } else {
1019                                         i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1020                                         i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8);
1021                                 }
1022
1023                         } else {
1024                                 if (src->flags & INMEMORY) {
1025                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1026                                         i386_neg_reg(cd, iptr->dst->regoff);
1027
1028                                 } else {
1029                                         M_INTMOVE(src->regoff, iptr->dst->regoff);
1030                                         i386_neg_reg(cd, iptr->dst->regoff);
1031                                 }
1032                         }
1033                         break;
1034
1035                 case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
1036
1037                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1038                         if (iptr->dst->flags & INMEMORY) {
1039                                 if (src->flags & INMEMORY) {
1040                                         if (src->regoff == iptr->dst->regoff) {
1041                                                 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8);
1042                                                 i386_alu_imm_membase(cd, I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1043                                                 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8 + 4);
1044
1045                                         } else {
1046                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1047                                                 i386_neg_reg(cd, REG_ITMP1);
1048                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1049                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1050                                                 i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP1);
1051                                                 i386_neg_reg(cd, REG_ITMP1);
1052                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1053                                         }
1054                                 }
1055                         }
1056                         break;
1057
1058                 case ICMD_I2L:        /* ..., value  ==> ..., value                   */
1059
1060                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1061                         if (iptr->dst->flags & INMEMORY) {
1062                                 if (src->flags & INMEMORY) {
1063                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, EAX);
1064                                         i386_cltd(cd);
1065                                         i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1066                                         i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1067
1068                                 } else {
1069                                         M_INTMOVE(src->regoff, EAX);
1070                                         i386_cltd(cd);
1071                                         i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1072                                         i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1073                                 }
1074                         }
1075                         break;
1076
1077                 case ICMD_L2I:        /* ..., value  ==> ..., value                   */
1078
1079                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1080                         if (iptr->dst->flags & INMEMORY) {
1081                                 if (src->flags & INMEMORY) {
1082                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1083                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1084                                 }
1085
1086                         } else {
1087                                 if (src->flags & INMEMORY) {
1088                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1089                                 }
1090                         }
1091                         break;
1092
1093                 case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
1094
1095                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1096                         if (iptr->dst->flags & INMEMORY) {
1097                                 if (src->flags & INMEMORY) {
1098                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1099                                         i386_shift_imm_reg(cd, I386_SHL, 24, REG_ITMP1);
1100                                         i386_shift_imm_reg(cd, I386_SAR, 24, REG_ITMP1);
1101                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1102
1103                                 } else {
1104                                         i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1105                                         i386_shift_imm_membase(cd, I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1106                                         i386_shift_imm_membase(cd, I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1107                                 }
1108
1109                         } else {
1110                                 if (src->flags & INMEMORY) {
1111                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1112                                         i386_shift_imm_reg(cd, I386_SHL, 24, iptr->dst->regoff);
1113                                         i386_shift_imm_reg(cd, I386_SAR, 24, iptr->dst->regoff);
1114
1115                                 } else {
1116                                         M_INTMOVE(src->regoff, iptr->dst->regoff);
1117                                         i386_shift_imm_reg(cd, I386_SHL, 24, iptr->dst->regoff);
1118                                         i386_shift_imm_reg(cd, I386_SAR, 24, iptr->dst->regoff);
1119                                 }
1120                         }
1121                         break;
1122
1123                 case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
1124
1125                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1126                         if (iptr->dst->flags & INMEMORY) {
1127                                 if (src->flags & INMEMORY) {
1128                                         if (src->regoff == iptr->dst->regoff) {
1129                                                 i386_alu_imm_membase(cd, I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1130
1131                                         } else {
1132                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1133                                                 i386_alu_imm_reg(cd, I386_AND, 0x0000ffff, REG_ITMP1);
1134                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1135                                         }
1136
1137                                 } else {
1138                                         i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1139                                         i386_alu_imm_membase(cd, I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1140                                 }
1141
1142                         } else {
1143                                 if (src->flags & INMEMORY) {
1144                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1145                                         i386_alu_imm_reg(cd, I386_AND, 0x0000ffff, iptr->dst->regoff);
1146
1147                                 } else {
1148                                         M_INTMOVE(src->regoff, iptr->dst->regoff);
1149                                         i386_alu_imm_reg(cd, I386_AND, 0x0000ffff, iptr->dst->regoff);
1150                                 }
1151                         }
1152                         break;
1153
1154                 case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
1155
1156                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1157                         if (iptr->dst->flags & INMEMORY) {
1158                                 if (src->flags & INMEMORY) {
1159                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1160                                         i386_shift_imm_reg(cd, I386_SHL, 16, REG_ITMP1);
1161                                         i386_shift_imm_reg(cd, I386_SAR, 16, REG_ITMP1);
1162                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1163
1164                                 } else {
1165                                         i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1166                                         i386_shift_imm_membase(cd, I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1167                                         i386_shift_imm_membase(cd, I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1168                                 }
1169
1170                         } else {
1171                                 if (src->flags & INMEMORY) {
1172                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1173                                         i386_shift_imm_reg(cd, I386_SHL, 16, iptr->dst->regoff);
1174                                         i386_shift_imm_reg(cd, I386_SAR, 16, iptr->dst->regoff);
1175
1176                                 } else {
1177                                         M_INTMOVE(src->regoff, iptr->dst->regoff);
1178                                         i386_shift_imm_reg(cd, I386_SHL, 16, iptr->dst->regoff);
1179                                         i386_shift_imm_reg(cd, I386_SAR, 16, iptr->dst->regoff);
1180                                 }
1181                         }
1182                         break;
1183
1184
1185                 case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1186
1187                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1188                         i386_emit_ialu(cd, I386_ADD, src, iptr);
1189                         break;
1190
1191                 case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
1192                                       /* val.i = constant                             */
1193
1194                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1195                         i386_emit_ialuconst(cd, I386_ADD, src, iptr);
1196                         break;
1197
1198                 case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
1199
1200                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1201                         if (iptr->dst->flags & INMEMORY) {
1202                                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1203                                         if (src->regoff == iptr->dst->regoff) {
1204                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1205                                                 i386_alu_reg_membase(cd, I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1206                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1207                                                 i386_alu_reg_membase(cd, I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1208
1209                                         } else if (src->prev->regoff == iptr->dst->regoff) {
1210                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1211                                                 i386_alu_reg_membase(cd, I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1212                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1213                                                 i386_alu_reg_membase(cd, I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1214
1215                                         } else {
1216                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1217                                                 i386_alu_membase_reg(cd, I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1218                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1219                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1220                                                 i386_alu_membase_reg(cd, I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1221                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1222                                         }
1223
1224                                 }
1225                         }
1226                         break;
1227
1228                 case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
1229                                       /* val.l = constant                             */
1230
1231                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1232                         if (iptr->dst->flags & INMEMORY) {
1233                                 if (src->flags & INMEMORY) {
1234                                         if (src->regoff == iptr->dst->regoff) {
1235                                                 i386_alu_imm_membase(cd, I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1236                                                 i386_alu_imm_membase(cd, I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1237
1238                                         } else {
1239                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1240                                                 i386_alu_imm_reg(cd, I386_ADD, iptr->val.l, REG_ITMP1);
1241                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1242                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1243                                                 i386_alu_imm_reg(cd, I386_ADC, iptr->val.l >> 32, REG_ITMP1);
1244                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1245                                         }
1246                                 }
1247                         }
1248                         break;
1249
1250                 case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1251
1252                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1253                         if (iptr->dst->flags & INMEMORY) {
1254                                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1255                                         if (src->prev->regoff == iptr->dst->regoff) {
1256                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1257                                                 i386_alu_reg_membase(cd, I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1258
1259                                         } else {
1260                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1261                                                 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1262                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1263                                         }
1264
1265                                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1266                                         M_INTMOVE(src->prev->regoff, REG_ITMP1);
1267                                         i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1268                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1269
1270                                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1271                                         if (src->prev->regoff == iptr->dst->regoff) {
1272                                                 i386_alu_reg_membase(cd, I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1273
1274                                         } else {
1275                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1276                                                 i386_alu_reg_reg(cd, I386_SUB, src->regoff, REG_ITMP1);
1277                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1278                                         }
1279
1280                                 } else {
1281                                         i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1282                                         i386_alu_reg_membase(cd, I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1283                                 }
1284
1285                         } else {
1286                                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1287                                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, d);
1288                                         i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, d);
1289
1290                                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1291                                         M_INTMOVE(src->prev->regoff, d);
1292                                         i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, d);
1293
1294                                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1295                                         /* workaround for reg alloc */
1296                                         if (src->regoff == iptr->dst->regoff) {
1297                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1298                                                 i386_alu_reg_reg(cd, I386_SUB, src->regoff, REG_ITMP1);
1299                                                 M_INTMOVE(REG_ITMP1, d);
1300
1301                                         } else {
1302                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, d);
1303                                                 i386_alu_reg_reg(cd, I386_SUB, src->regoff, d);
1304                                         }
1305
1306                                 } else {
1307                                         /* workaround for reg alloc */
1308                                         if (src->regoff == iptr->dst->regoff) {
1309                                                 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1310                                                 i386_alu_reg_reg(cd, I386_SUB, src->regoff, REG_ITMP1);
1311                                                 M_INTMOVE(REG_ITMP1, d);
1312
1313                                         } else {
1314                                                 M_INTMOVE(src->prev->regoff, d);
1315                                                 i386_alu_reg_reg(cd, I386_SUB, src->regoff, d);
1316                                         }
1317                                 }
1318                         }
1319                         break;
1320
1321                 case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
1322                                       /* val.i = constant                             */
1323
1324                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1325                         i386_emit_ialuconst(cd, I386_SUB, src, iptr);
1326                         break;
1327
1328                 case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
1329
1330                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1331                         if (iptr->dst->flags & INMEMORY) {
1332                                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1333                                         if (src->prev->regoff == iptr->dst->regoff) {
1334                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1335                                                 i386_alu_reg_membase(cd, I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1336                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1337                                                 i386_alu_reg_membase(cd, I386_SBB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1338
1339                                         } else {
1340                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1341                                                 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1342                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1343                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1344                                                 i386_alu_membase_reg(cd, I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1345                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1346                                         }
1347                                 }
1348                         }
1349                         break;
1350
1351                 case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
1352                                       /* val.l = constant                             */
1353
1354                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1355                         if (iptr->dst->flags & INMEMORY) {
1356                                 if (src->flags & INMEMORY) {
1357                                         if (src->regoff == iptr->dst->regoff) {
1358                                                 i386_alu_imm_membase(cd, I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1359                                                 i386_alu_imm_membase(cd, I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1360
1361                                         } else {
1362                                                 /* TODO: could be size optimized with lea -- see gcc output */
1363                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1364                                                 i386_alu_imm_reg(cd, I386_SUB, iptr->val.l, REG_ITMP1);
1365                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1366                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1367                                                 i386_alu_imm_reg(cd, I386_SBB, iptr->val.l >> 32, REG_ITMP1);
1368                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1369                                         }
1370                                 }
1371                         }
1372                         break;
1373
1374                 case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1375
1376                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1377                         if (iptr->dst->flags & INMEMORY) {
1378                                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1379                                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1380                                         i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1381                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1382
1383                                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1384                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1385                                         i386_imul_reg_reg(cd, src->prev->regoff, REG_ITMP1);
1386                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1387
1388                                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1389                                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1390                                         i386_imul_reg_reg(cd, src->regoff, REG_ITMP1);
1391                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1392
1393                                 } else {
1394                                         i386_mov_reg_reg(cd, src->prev->regoff, REG_ITMP1);
1395                                         i386_imul_reg_reg(cd, src->regoff, REG_ITMP1);
1396                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1397                                 }
1398
1399                         } else {
1400                                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1401                                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1402                                         i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1403
1404                                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1405                                         M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1406                                         i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1407
1408                                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1409                                         M_INTMOVE(src->regoff, iptr->dst->regoff);
1410                                         i386_imul_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1411
1412                                 } else {
1413                                         if (src->regoff == iptr->dst->regoff) {
1414                                                 i386_imul_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
1415
1416                                         } else {
1417                                                 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1418                                                 i386_imul_reg_reg(cd, src->regoff, iptr->dst->regoff);
1419                                         }
1420                                 }
1421                         }
1422                         break;
1423
1424                 case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
1425                                       /* val.i = constant                             */
1426
1427                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1428                         if (iptr->dst->flags & INMEMORY) {
1429                                 if (src->flags & INMEMORY) {
1430                                         i386_imul_imm_membase_reg(cd, iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1431                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1432
1433                                 } else {
1434                                         i386_imul_imm_reg_reg(cd, iptr->val.i, src->regoff, REG_ITMP1);
1435                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1436                                 }
1437
1438                         } else {
1439                                 if (src->flags & INMEMORY) {
1440                                         i386_imul_imm_membase_reg(cd, iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1441
1442                                 } else {
1443                                         i386_imul_imm_reg_reg(cd, iptr->val.i, src->regoff, iptr->dst->regoff);
1444                                 }
1445                         }
1446                         break;
1447
1448                 case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
1449
1450                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1451                         if (iptr->dst->flags & INMEMORY) {
1452                                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1453                                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, EAX);             /* mem -> EAX             */
1454                                         /* optimize move EAX -> REG_ITMP3 is slower??? */
1455 /*                                      i386_mov_reg_reg(cd, EAX, REG_ITMP3); */
1456                                         i386_mul_membase(cd, REG_SP, src->regoff * 8);                            /* mem * EAX -> EDX:EAX   */
1457
1458                                         /* TODO: optimize move EAX -> REG_ITMP3 */
1459                                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);   /* mem -> ITMP3           */
1460                                         i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2);            /* mem * ITMP3 -> ITMP3   */
1461                                         i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX);                      /* ITMP3 + EDX -> EDX     */
1462
1463                                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP2);       /* mem -> ITMP3           */
1464                                         i386_imul_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);        /* mem * ITMP3 -> ITMP3   */
1465
1466                                         i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX);                      /* ITMP3 + EDX -> EDX     */
1467                                         i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1468                                         i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1469                                 }
1470                         }
1471                         break;
1472
1473                 case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
1474                                       /* val.l = constant                             */
1475
1476                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1477                         if (iptr->dst->flags & INMEMORY) {
1478                                 if (src->flags & INMEMORY) {
1479                                         i386_mov_imm_reg(cd, iptr->val.l, EAX);                                   /* imm -> EAX             */
1480                                         i386_mul_membase(cd, REG_SP, src->regoff * 8);                            /* mem * EAX -> EDX:EAX   */
1481                                         /* TODO: optimize move EAX -> REG_ITMP3 */
1482                                         i386_mov_imm_reg(cd, iptr->val.l >> 32, REG_ITMP2);                       /* imm -> ITMP3           */
1483                                         i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2);            /* mem * ITMP3 -> ITMP3   */
1484
1485                                         i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX);                      /* ITMP3 + EDX -> EDX     */
1486                                         i386_mov_imm_reg(cd, iptr->val.l, REG_ITMP2);                             /* imm -> ITMP3           */
1487                                         i386_imul_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);        /* mem * ITMP3 -> ITMP3   */
1488
1489                                         i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX);                      /* ITMP3 + EDX -> EDX     */
1490                                         i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1491                                         i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1492                                 }
1493                         }
1494                         break;
1495
1496                 case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
1497
1498                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1499                         var_to_reg_int(s1, src, REG_ITMP2);
1500                         gen_div_check(src);
1501                 if (src->prev->flags & INMEMORY) {
1502                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, EAX);
1503
1504                         } else {
1505                                 M_INTMOVE(src->prev->regoff, EAX);
1506                         }
1507                         
1508                         i386_alu_imm_reg(cd, I386_CMP, 0x80000000, EAX);    /* check as described in jvm spec */
1509                         i386_jcc(cd, I386_CC_NE, 3 + 6);
1510                         i386_alu_imm_reg(cd, I386_CMP, -1, s1);
1511                         i386_jcc(cd, I386_CC_E, 1 + 2);
1512
1513                         i386_cltd(cd);
1514                         i386_idiv_reg(cd, s1);
1515
1516                         if (iptr->dst->flags & INMEMORY) {
1517                                 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1518
1519                         } else {
1520                                 M_INTMOVE(EAX, iptr->dst->regoff);
1521                         }
1522                         break;
1523
1524                 case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
1525
1526                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1527                         var_to_reg_int(s1, src, REG_ITMP2);
1528                         gen_div_check(src);
1529                         if (src->prev->flags & INMEMORY) {
1530                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, EAX);
1531
1532                         } else {
1533                                 M_INTMOVE(src->prev->regoff, EAX);
1534                         }
1535                         
1536                         i386_alu_imm_reg(cd, I386_CMP, 0x80000000, EAX);    /* check as described in jvm spec */
1537                         i386_jcc(cd, I386_CC_NE, 2 + 3 + 6);
1538                         i386_alu_reg_reg(cd, I386_XOR, EDX, EDX);
1539                         i386_alu_imm_reg(cd, I386_CMP, -1, s1);
1540                         i386_jcc(cd, I386_CC_E, 1 + 2);
1541
1542                         i386_cltd(cd);
1543                         i386_idiv_reg(cd, s1);
1544
1545                         if (iptr->dst->flags & INMEMORY) {
1546                                 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8);
1547
1548                         } else {
1549                                 M_INTMOVE(EDX, iptr->dst->regoff);
1550                         }
1551                         break;
1552
1553                 case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
1554                                       /* val.i = constant                             */
1555
1556                         /* TODO: optimize for `/ 2' */
1557                         var_to_reg_int(s1, src, REG_ITMP1);
1558                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1559
1560                         M_INTMOVE(s1, d);
1561                         i386_test_reg_reg(cd, d, d);
1562                         a = 2;
1563                         CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1564                         i386_jcc(cd, I386_CC_NS, a);
1565                         i386_alu_imm_reg(cd, I386_ADD, (1 << iptr->val.i) - 1, d);
1566                                 
1567                         i386_shift_imm_reg(cd, I386_SAR, iptr->val.i, d);
1568                         store_reg_to_var_int(iptr->dst, d);
1569                         break;
1570
1571                 case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
1572                                       /* val.i = constant                             */
1573
1574                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1575                         if (iptr->dst->flags & INMEMORY) {
1576                                 if (src->flags & INMEMORY) {
1577                                         a = 2;
1578                                         CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1579                                         a += 3;
1580                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1581                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1582
1583                                         i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
1584                                         i386_jcc(cd, I386_CC_NS, a);
1585                                         i386_alu_imm_reg(cd, I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1586                                         i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP2);
1587                                         i386_shrd_imm_reg_reg(cd, iptr->val.i, REG_ITMP2, REG_ITMP1);
1588                                         i386_shift_imm_reg(cd, I386_SAR, iptr->val.i, REG_ITMP2);
1589
1590                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1591                                         i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1592                                 }
1593                         }
1594                         break;
1595
1596                 case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
1597                                       /* val.i = constant                             */
1598
1599                         var_to_reg_int(s1, src, REG_ITMP1);
1600                         d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1601                         if (s1 == d) {
1602                                 M_INTMOVE(s1, REG_ITMP1);
1603                                 s1 = REG_ITMP1;
1604                         } 
1605
1606                         a = 2;
1607                         a += 2;
1608                         a += 2;
1609                         CALCIMMEDIATEBYTES(a, iptr->val.i);
1610                         a += 2;
1611
1612                         /* TODO: optimize */
1613                         M_INTMOVE(s1, d);
1614                         i386_alu_imm_reg(cd, I386_AND, iptr->val.i, d);
1615                         i386_test_reg_reg(cd, s1, s1);
1616                         i386_jcc(cd, I386_CC_GE, a);
1617                         i386_mov_reg_reg(cd, s1, d);
1618                         i386_neg_reg(cd, d);
1619                         i386_alu_imm_reg(cd, I386_AND, iptr->val.i, d);
1620                         i386_neg_reg(cd, d);
1621
1622 /*                      M_INTMOVE(s1, EAX); */
1623 /*                      i386_cltd(cd); */
1624 /*                      i386_alu_reg_reg(cd, I386_XOR, EDX, EAX); */
1625 /*                      i386_alu_reg_reg(cd, I386_SUB, EDX, EAX); */
1626 /*                      i386_alu_reg_reg(cd, I386_AND, iptr->val.i, EAX); */
1627 /*                      i386_alu_reg_reg(cd, I386_XOR, EDX, EAX); */
1628 /*                      i386_alu_reg_reg(cd, I386_SUB, EDX, EAX); */
1629 /*                      M_INTMOVE(EAX, d); */
1630
1631 /*                      i386_alu_reg_reg(cd, I386_XOR, d, d); */
1632 /*                      i386_mov_imm_reg(cd, iptr->val.i, ECX); */
1633 /*                      i386_shrd_reg_reg(cd, s1, d); */
1634 /*                      i386_shift_imm_reg(cd, I386_SHR, 32 - iptr->val.i, d); */
1635
1636                         store_reg_to_var_int(iptr->dst, d);
1637                         break;
1638
1639                 case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
1640                                       /* val.l = constant                             */
1641
1642                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1643                         if (iptr->dst->flags & INMEMORY) {
1644                                 if (src->flags & INMEMORY) {
1645                                         /* Intel algorithm -- does not work, because constant is wrong */
1646 /*                                      i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1); */
1647 /*                                      i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1648
1649 /*                                      M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1650 /*                                      i386_test_reg_reg(cd, REG_ITMP3, REG_ITMP3); */
1651 /*                                      i386_jcc(cd, I386_CC_NS, offset); */
1652 /*                                      i386_alu_imm_reg(cd, I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1653 /*                                      i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP3); */
1654                                         
1655 /*                                      i386_shrd_imm_reg_reg(cd, iptr->val.l, REG_ITMP3, REG_ITMP2); */
1656 /*                                      i386_shift_imm_reg(cd, I386_SAR, iptr->val.l, REG_ITMP3); */
1657 /*                                      i386_shld_imm_reg_reg(cd, iptr->val.l, REG_ITMP2, REG_ITMP3); */
1658
1659 /*                                      i386_shift_imm_reg(cd, I386_SHL, iptr->val.l, REG_ITMP2); */
1660
1661 /*                                      i386_alu_reg_reg(cd, I386_SUB, REG_ITMP2, REG_ITMP1); */
1662 /*                                      i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1663 /*                                      i386_alu_reg_reg(cd, I386_SBB, REG_ITMP3, REG_ITMP2); */
1664
1665 /*                                      i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1666 /*                                      i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1667
1668                                         /* Alpha algorithm */
1669                                         a = 3;
1670                                         CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
1671                                         a += 3;
1672                                         CALCOFFSETBYTES(a, REG_SP, src->regoff * 8 + 4);
1673
1674                                         a += 2;
1675                                         a += 3;
1676                                         a += 2;
1677
1678                                         /* TODO: hmm, don't know if this is always correct */
1679                                         a += 2;
1680                                         CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1681                                         a += 2;
1682                                         CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1683
1684                                         a += 2;
1685                                         a += 3;
1686                                         a += 2;
1687
1688                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1689                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1690                                         
1691                                         i386_alu_imm_reg(cd, I386_AND, iptr->val.l, REG_ITMP1);
1692                                         i386_alu_imm_reg(cd, I386_AND, iptr->val.l >> 32, REG_ITMP2);
1693                                         i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1694                                         i386_jcc(cd, I386_CC_GE, a);
1695
1696                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1697                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1698                                         
1699                                         i386_neg_reg(cd, REG_ITMP1);
1700                                         i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP2);
1701                                         i386_neg_reg(cd, REG_ITMP2);
1702                                         
1703                                         i386_alu_imm_reg(cd, I386_AND, iptr->val.l, REG_ITMP1);
1704                                         i386_alu_imm_reg(cd, I386_AND, iptr->val.l >> 32, REG_ITMP2);
1705                                         
1706                                         i386_neg_reg(cd, REG_ITMP1);
1707                                         i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP2);
1708                                         i386_neg_reg(cd, REG_ITMP2);
1709
1710                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1711                                         i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1712                                 }
1713                         }
1714                         break;
1715
1716                 case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1717
1718                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1719                         i386_emit_ishift(cd, I386_SHL, src, iptr);
1720                         break;
1721
1722                 case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
1723                                       /* val.i = constant                             */
1724
1725                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1726                         i386_emit_ishiftconst(cd, I386_SHL, src, iptr);
1727                         break;
1728
1729                 case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1730
1731                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1732                         i386_emit_ishift(cd, I386_SAR, src, iptr);
1733                         break;
1734
1735                 case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
1736                                       /* val.i = constant                             */
1737
1738                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1739                         i386_emit_ishiftconst(cd, I386_SAR, src, iptr);
1740                         break;
1741
1742                 case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1743
1744                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1745                         i386_emit_ishift(cd, I386_SHR, src, iptr);
1746                         break;
1747
1748                 case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1749                                       /* val.i = constant                             */
1750
1751                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1752                         i386_emit_ishiftconst(cd, I386_SHR, src, iptr);
1753                         break;
1754
1755                 case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
1756
1757                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1758                         if (iptr->dst->flags & INMEMORY ){
1759                                 if (src->prev->flags & INMEMORY) {
1760 /*                                      if (src->prev->regoff == iptr->dst->regoff) { */
1761 /*                                              i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1762
1763 /*                                              if (src->flags & INMEMORY) { */
1764 /*                                                      i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX); */
1765 /*                                              } else { */
1766 /*                                                      M_INTMOVE(src->regoff, ECX); */
1767 /*                                              } */
1768
1769 /*                                              i386_test_imm_reg(cd, 32, ECX); */
1770 /*                                              i386_jcc(cd, I386_CC_E, 2 + 2); */
1771 /*                                              i386_mov_reg_reg(cd, REG_ITMP1, REG_ITMP2); */
1772 /*                                              i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1); */
1773                                                 
1774 /*                                              i386_shld_reg_membase(cd, REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1775 /*                                              i386_shift_membase(cd, I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1776
1777 /*                                      } else { */
1778                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1779                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1780                                                 
1781                                                 if (src->flags & INMEMORY) {
1782                                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
1783                                                 } else {
1784                                                         M_INTMOVE(src->regoff, ECX);
1785                                                 }
1786                                                 
1787                                                 i386_test_imm_reg(cd, 32, ECX);
1788                                                 i386_jcc(cd, I386_CC_E, 2 + 2);
1789                                                 i386_mov_reg_reg(cd, REG_ITMP1, REG_ITMP3);
1790                                                 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
1791                                                 
1792                                                 i386_shld_reg_reg(cd, REG_ITMP1, REG_ITMP3);
1793                                                 i386_shift_reg(cd, I386_SHL, REG_ITMP1);
1794                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1795                                                 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1796 /*                                      } */
1797                                 }
1798                         }
1799                         break;
1800
1801         case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
1802                                           /* val.i = constant                             */
1803
1804                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1805                         if (iptr->dst->flags & INMEMORY ) {
1806                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1807                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1808
1809                                 if (iptr->val.i & 0x20) {
1810                                         i386_mov_reg_reg(cd, REG_ITMP1, REG_ITMP2);
1811                                         i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
1812                                         i386_shld_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1813
1814                                 } else {
1815                                         i386_shld_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1816                                         i386_shift_imm_reg(cd, I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
1817                                 }
1818
1819                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1820                                 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1821                         }
1822                         break;
1823
1824                 case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
1825
1826                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1827                         if (iptr->dst->flags & INMEMORY ){
1828                                 if (src->prev->flags & INMEMORY) {
1829 /*                                      if (src->prev->regoff == iptr->dst->regoff) { */
1830                                                 /* TODO: optimize */
1831 /*                                              i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1832 /*                                              i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
1833
1834 /*                                              if (src->flags & INMEMORY) { */
1835 /*                                                      i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX); */
1836 /*                                              } else { */
1837 /*                                                      M_INTMOVE(src->regoff, ECX); */
1838 /*                                              } */
1839
1840 /*                                              i386_test_imm_reg(cd, 32, ECX); */
1841 /*                                              i386_jcc(cd, I386_CC_E, 2 + 3); */
1842 /*                                              i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1843 /*                                              i386_shift_imm_reg(cd, I386_SAR, 31, REG_ITMP2); */
1844                                                 
1845 /*                                              i386_shrd_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1846 /*                                              i386_shift_reg(cd, I386_SAR, REG_ITMP2); */
1847 /*                                              i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1848 /*                                              i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1849
1850 /*                                      } else { */
1851                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1852                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1853
1854                                                 if (src->flags & INMEMORY) {
1855                                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
1856                                                 } else {
1857                                                         M_INTMOVE(src->regoff, ECX);
1858                                                 }
1859
1860                                                 i386_test_imm_reg(cd, 32, ECX);
1861                                                 i386_jcc(cd, I386_CC_E, 2 + 3);
1862                                                 i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1863                                                 i386_shift_imm_reg(cd, I386_SAR, 31, REG_ITMP3);
1864                                                 
1865                                                 i386_shrd_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1866                                                 i386_shift_reg(cd, I386_SAR, REG_ITMP3);
1867                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1868                                                 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1869 /*                                      } */
1870                                 }
1871                         }
1872                         break;
1873
1874                 case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
1875                                       /* val.i = constant                             */
1876
1877                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1878                         if (iptr->dst->flags & INMEMORY ) {
1879                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1880                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1881
1882                                 if (iptr->val.i & 0x20) {
1883                                         i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1);
1884                                         i386_shift_imm_reg(cd, I386_SAR, 31, REG_ITMP2);
1885                                         i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1886
1887                                 } else {
1888                                         i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1889                                         i386_shift_imm_reg(cd, I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
1890                                 }
1891
1892                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1893                                 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1894                         }
1895                         break;
1896
1897                 case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
1898
1899                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1900                         if (iptr->dst->flags & INMEMORY ){
1901                                 if (src->prev->flags & INMEMORY) {
1902 /*                                      if (src->prev->regoff == iptr->dst->regoff) { */
1903                                                 /* TODO: optimize */
1904 /*                                              i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1905 /*                                              i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
1906
1907 /*                                              if (src->flags & INMEMORY) { */
1908 /*                                                      i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX); */
1909 /*                                              } else { */
1910 /*                                                      M_INTMOVE(src->regoff, ECX); */
1911 /*                                              } */
1912
1913 /*                                              i386_test_imm_reg(cd, 32, ECX); */
1914 /*                                              i386_jcc(cd, I386_CC_E, 2 + 2); */
1915 /*                                              i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1916 /*                                              i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2); */
1917                                                 
1918 /*                                              i386_shrd_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1919 /*                                              i386_shift_reg(cd, I386_SHR, REG_ITMP2); */
1920 /*                                              i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1921 /*                                              i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1922
1923 /*                                      } else { */
1924                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1925                                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1926
1927                                                 if (src->flags & INMEMORY) {
1928                                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
1929                                                 } else {
1930                                                         M_INTMOVE(src->regoff, ECX);
1931                                                 }
1932
1933                                                 i386_test_imm_reg(cd, 32, ECX);
1934                                                 i386_jcc(cd, I386_CC_E, 2 + 2);
1935                                                 i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1936                                                 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP3, REG_ITMP3);
1937                                                 
1938                                                 i386_shrd_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1939                                                 i386_shift_reg(cd, I386_SHR, REG_ITMP3);
1940                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1941                                                 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1942 /*                                      } */
1943                                 }
1944                         }
1945                         break;
1946
1947                 case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
1948                                       /* val.l = constant                             */
1949
1950                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1951                         if (iptr->dst->flags & INMEMORY ) {
1952                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1953                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1954
1955                                 if (iptr->val.i & 0x20) {
1956                                         i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1);
1957                                         i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2);
1958                                         i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1959
1960                                 } else {
1961                                         i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1962                                         i386_shift_imm_reg(cd, I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
1963                                 }
1964
1965                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1966                                 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1967                         }
1968                         break;
1969
1970                 case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1971
1972                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1973                         i386_emit_ialu(cd, I386_AND, src, iptr);
1974                         break;
1975
1976                 case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
1977                                       /* val.i = constant                             */
1978
1979                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1980                         i386_emit_ialuconst(cd, I386_AND, src, iptr);
1981                         break;
1982
1983                 case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
1984
1985                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1986                         i386_emit_lalu(cd, I386_AND, src, iptr);
1987                         break;
1988
1989                 case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
1990                                       /* val.l = constant                             */
1991
1992                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1993                         i386_emit_laluconst(cd, I386_AND, src, iptr);
1994                         break;
1995
1996                 case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
1997
1998                         d = reg_of_var(rd, iptr->dst, REG_NULL);
1999                         i386_emit_ialu(cd, I386_OR, src, iptr);
2000                         break;
2001
2002                 case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
2003                                       /* val.i = constant                             */
2004
2005                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2006                         i386_emit_ialuconst(cd, I386_OR, src, iptr);
2007                         break;
2008
2009                 case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
2010
2011                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2012                         i386_emit_lalu(cd, I386_OR, src, iptr);
2013                         break;
2014
2015                 case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
2016                                       /* val.l = constant                             */
2017
2018                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2019                         i386_emit_laluconst(cd, I386_OR, src, iptr);
2020                         break;
2021
2022                 case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
2023
2024                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2025                         i386_emit_ialu(cd, I386_XOR, src, iptr);
2026                         break;
2027
2028                 case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
2029                                       /* val.i = constant                             */
2030
2031                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2032                         i386_emit_ialuconst(cd, I386_XOR, src, iptr);
2033                         break;
2034
2035                 case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
2036
2037                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2038                         i386_emit_lalu(cd, I386_XOR, src, iptr);
2039                         break;
2040
2041                 case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
2042                                       /* val.l = constant                             */
2043
2044                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2045                         i386_emit_laluconst(cd, I386_XOR, src, iptr);
2046                         break;
2047
2048                 case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
2049                                       /* op1 = variable, val.i = constant             */
2050
2051                         var = &(rd->locals[iptr->op1][TYPE_INT]);
2052                         if (var->flags & INMEMORY) {
2053                                 i386_alu_imm_membase(cd, I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2054
2055                         } else {
2056                                 /* `inc reg' is slower on p4's (regarding to ia32             */
2057                                 /* optimization reference manual and benchmarks) and as fast  */
2058                                 /* on athlon's.                                               */
2059                                 i386_alu_imm_reg(cd, I386_ADD, iptr->val.i, var->regoff);
2060                         }
2061                         break;
2062
2063
2064                 /* floating operations ************************************************/
2065 #if 0
2066 #define ROUND_TO_SINGLE \
2067                         i386_fstps_membase(cd, REG_SP, -8); \
2068                         i386_flds_membase(cd, REG_SP, -8);
2069
2070 #define ROUND_TO_DOUBLE \
2071                         i386_fstpl_membase(cd, REG_SP, -8); \
2072                         i386_fldl_membase(cd, REG_SP, -8);
2073
2074 #define FPU_SET_24BIT_MODE \
2075                         if (!fpu_in_24bit_mode) { \
2076                                 i386_fldcw_mem(cd, &fpu_ctrlwrd_24bit); \
2077                                 fpu_in_24bit_mode = 1; \
2078                         }
2079
2080 #define FPU_SET_53BIT_MODE \
2081                         if (fpu_in_24bit_mode) { \
2082                                 i386_fldcw_mem(cd, &fpu_ctrlwrd_53bit); \
2083                                 fpu_in_24bit_mode = 0; \
2084                         }
2085 #else
2086 #define ROUND_TO_SINGLE
2087 #define ROUND_TO_DOUBLE
2088 #define FPU_SET_24BIT_MODE
2089 #define FPU_SET_53BIT_MODE
2090 #endif
2091                 case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
2092
2093                         FPU_SET_24BIT_MODE;
2094                         var_to_reg_flt(s1, src, REG_FTMP1);
2095                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2096                         i386_fchs(cd);
2097                         store_reg_to_var_flt(iptr->dst, d);
2098                         break;
2099
2100                 case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
2101
2102                         FPU_SET_53BIT_MODE;
2103                         var_to_reg_flt(s1, src, REG_FTMP1);
2104                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2105                         i386_fchs(cd);
2106                         store_reg_to_var_flt(iptr->dst, d);
2107                         break;
2108
2109                 case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
2110
2111                         FPU_SET_24BIT_MODE;
2112                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2113                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2114                         var_to_reg_flt(s2, src, REG_FTMP2);
2115                         i386_faddp(cd);
2116                         fpu_st_offset--;
2117                         store_reg_to_var_flt(iptr->dst, d);
2118                         break;
2119
2120                 case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
2121
2122                         FPU_SET_53BIT_MODE;
2123                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2124                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2125                         var_to_reg_flt(s2, src, REG_FTMP2);
2126                         i386_faddp(cd);
2127                         fpu_st_offset--;
2128                         store_reg_to_var_flt(iptr->dst, d);
2129                         break;
2130
2131                 case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
2132
2133                         FPU_SET_24BIT_MODE;
2134                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2135                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2136                         var_to_reg_flt(s2, src, REG_FTMP2);
2137                         i386_fsubp(cd);
2138                         fpu_st_offset--;
2139                         store_reg_to_var_flt(iptr->dst, d);
2140                         break;
2141
2142                 case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
2143
2144                         FPU_SET_53BIT_MODE;
2145                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2146                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2147                         var_to_reg_flt(s2, src, REG_FTMP2);
2148                         i386_fsubp(cd);
2149                         fpu_st_offset--;
2150                         store_reg_to_var_flt(iptr->dst, d);
2151                         break;
2152
2153                 case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
2154
2155                         FPU_SET_24BIT_MODE;
2156                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2157                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2158                         var_to_reg_flt(s2, src, REG_FTMP2);
2159                         i386_fmulp(cd);
2160                         fpu_st_offset--;
2161                         ROUND_TO_SINGLE;
2162                         store_reg_to_var_flt(iptr->dst, d);
2163                         break;
2164
2165                 case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
2166
2167                         FPU_SET_53BIT_MODE;
2168                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2169                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2170
2171 /*                      i386_fldt_mem(cd, subnormal_bias1); */
2172 /*                      i386_fmulp(cd); */
2173
2174                         var_to_reg_flt(s2, src, REG_FTMP2);
2175
2176                         i386_fmulp(cd);
2177                         fpu_st_offset--;
2178
2179 /*                      i386_fldt_mem(cd, subnormal_bias2); */
2180 /*                      i386_fmulp(cd); */
2181
2182                         store_reg_to_var_flt(iptr->dst, d);
2183                         break;
2184
2185                 case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
2186
2187                         FPU_SET_24BIT_MODE;
2188                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2189                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2190                         var_to_reg_flt(s2, src, REG_FTMP2);
2191                         i386_fdivp(cd);
2192                         fpu_st_offset--;
2193                         ROUND_TO_SINGLE;
2194                         store_reg_to_var_flt(iptr->dst, d);
2195                         break;
2196
2197                 case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
2198
2199                         FPU_SET_53BIT_MODE;
2200                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2201                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2202
2203 /*                      i386_fldt_mem(cd, subnormal_bias1); */
2204 /*                      i386_fmulp(cd); */
2205
2206                         var_to_reg_flt(s2, src, REG_FTMP2);
2207
2208                         i386_fdivp(cd);
2209                         fpu_st_offset--;
2210
2211 /*                      i386_fldt_mem(cd, subnormal_bias2); */
2212 /*                      i386_fmulp(cd); */
2213
2214                         store_reg_to_var_flt(iptr->dst, d);
2215                         break;
2216
2217                 case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
2218
2219                         FPU_SET_24BIT_MODE;
2220                         /* exchanged to skip fxch */
2221                         var_to_reg_flt(s2, src, REG_FTMP2);
2222                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2223                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2224 /*                      i386_fxch(cd); */
2225                         i386_fprem(cd);
2226                         i386_wait(cd);
2227                         i386_fnstsw(cd);
2228                         i386_sahf(cd);
2229                         i386_jcc(cd, I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2230                         store_reg_to_var_flt(iptr->dst, d);
2231                         i386_ffree_reg(cd, 0);
2232                         i386_fincstp(cd);
2233                         fpu_st_offset--;
2234                         break;
2235
2236                 case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
2237
2238                         FPU_SET_53BIT_MODE;
2239                         /* exchanged to skip fxch */
2240                         var_to_reg_flt(s2, src, REG_FTMP2);
2241                         var_to_reg_flt(s1, src->prev, REG_FTMP1);
2242                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2243 /*                      i386_fxch(cd); */
2244                         i386_fprem(cd);
2245                         i386_wait(cd);
2246                         i386_fnstsw(cd);
2247                         i386_sahf(cd);
2248                         i386_jcc(cd, I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2249                         store_reg_to_var_flt(iptr->dst, d);
2250                         i386_ffree_reg(cd, 0);
2251                         i386_fincstp(cd);
2252                         fpu_st_offset--;
2253                         break;
2254
2255                 case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
2256                 case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
2257
2258                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2259                         if (src->flags & INMEMORY) {
2260                                 i386_fildl_membase(cd, REG_SP, src->regoff * 8);
2261                                 fpu_st_offset++;
2262
2263                         } else {
2264                                 a = dseg_adds4(cd, 0);
2265                                 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2266                                 dseg_adddata(cd, cd->mcodeptr);
2267                                 i386_mov_reg_membase(cd, src->regoff, REG_ITMP1, a);
2268                                 i386_fildl_membase(cd, REG_ITMP1, a);
2269                                 fpu_st_offset++;
2270                         }
2271                         store_reg_to_var_flt(iptr->dst, d);
2272                         break;
2273
2274                 case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
2275                 case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
2276
2277                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2278                         if (src->flags & INMEMORY) {
2279                                 i386_fildll_membase(cd, REG_SP, src->regoff * 8);
2280                                 fpu_st_offset++;
2281
2282                         } else {
2283                                 panic("L2F: longs have to be in memory");
2284                         }
2285                         store_reg_to_var_flt(iptr->dst, d);
2286                         break;
2287                         
2288                 case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
2289
2290                         var_to_reg_flt(s1, src, REG_FTMP1);
2291                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2292
2293                         a = dseg_adds4(cd, 0x0e7f);    /* Round to zero, 53-bit mode, exception masked */
2294                         i386_mov_imm_reg(cd, 0, REG_ITMP1);
2295                         dseg_adddata(cd, cd->mcodeptr);
2296                         i386_fldcw_membase(cd, REG_ITMP1, a);
2297
2298                         if (iptr->dst->flags & INMEMORY) {
2299                                 i386_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 8);
2300                                 fpu_st_offset--;
2301
2302                                 a = dseg_adds4(cd, 0x027f);    /* Round to nearest, 53-bit mode, exceptions masked */
2303                                 i386_fldcw_membase(cd, REG_ITMP1, a);
2304
2305                                 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2306
2307                                 a = 3;
2308                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2309                                 a += 5 + 2 + 3;
2310                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2311
2312                         } else {
2313                                 a = dseg_adds4(cd, 0);
2314                                 i386_fistpl_membase(cd, REG_ITMP1, a);
2315                                 fpu_st_offset--;
2316                                 i386_mov_membase_reg(cd, REG_ITMP1, a, iptr->dst->regoff);
2317
2318                                 a = dseg_adds4(cd, 0x027f);    /* Round to nearest, 53-bit mode, exceptions masked */
2319                                 i386_fldcw_membase(cd, REG_ITMP1, a);
2320
2321                                 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, iptr->dst->regoff);
2322
2323                                 a = 3;
2324                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2325                                 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2326                         }
2327
2328                         i386_jcc(cd, I386_CC_NE, a);
2329
2330                         /* XXX: change this when we use registers */
2331                         i386_flds_membase(cd, REG_SP, src->regoff * 8);
2332                         i386_mov_imm_reg(cd, (s4) asm_builtin_f2i, REG_ITMP1);
2333                         i386_call_reg(cd, REG_ITMP1);
2334
2335                         if (iptr->dst->flags & INMEMORY) {
2336                                 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2337
2338                         } else {
2339                                 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2340                         }
2341                         break;
2342
2343                 case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
2344
2345                         var_to_reg_flt(s1, src, REG_FTMP1);
2346                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2347
2348                         a = dseg_adds4(cd, 0x0e7f);    /* Round to zero, 53-bit mode, exception masked */
2349                         i386_mov_imm_reg(cd, 0, REG_ITMP1);
2350                         dseg_adddata(cd, cd->mcodeptr);
2351                         i386_fldcw_membase(cd, REG_ITMP1, a);
2352
2353                         if (iptr->dst->flags & INMEMORY) {
2354                                 i386_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 8);
2355                                 fpu_st_offset--;
2356
2357                                 a = dseg_adds4(cd, 0x027f);    /* Round to nearest, 53-bit mode, exceptions masked */
2358                                 i386_fldcw_membase(cd, REG_ITMP1, a);
2359
2360                                 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2361
2362                                 a = 3;
2363                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2364                                 a += 5 + 2 + 3;
2365                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2366
2367                         } else {
2368                                 a = dseg_adds4(cd, 0);
2369                                 i386_fistpl_membase(cd, REG_ITMP1, a);
2370                                 fpu_st_offset--;
2371                                 i386_mov_membase_reg(cd, REG_ITMP1, a, iptr->dst->regoff);
2372
2373                                 a = dseg_adds4(cd, 0x027f);    /* Round to nearest, 53-bit mode, exceptions masked */
2374                                 i386_fldcw_membase(cd, REG_ITMP1, a);
2375
2376                                 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, iptr->dst->regoff);
2377
2378                                 a = 3;
2379                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2380                                 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2381                         }
2382
2383                         i386_jcc(cd, I386_CC_NE, a);
2384
2385                         /* XXX: change this when we use registers */
2386                         i386_fldl_membase(cd, REG_SP, src->regoff * 8);
2387                         i386_mov_imm_reg(cd, (s4) asm_builtin_d2i, REG_ITMP1);
2388                         i386_call_reg(cd, REG_ITMP1);
2389
2390                         if (iptr->dst->flags & INMEMORY) {
2391                                 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2392                         } else {
2393                                 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2394                         }
2395                         break;
2396
2397                 case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
2398
2399                         var_to_reg_flt(s1, src, REG_FTMP1);
2400                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2401
2402                         a = dseg_adds4(cd, 0x0e7f);    /* Round to zero, 53-bit mode, exception masked */
2403                         i386_mov_imm_reg(cd, 0, REG_ITMP1);
2404                         dseg_adddata(cd, cd->mcodeptr);
2405                         i386_fldcw_membase(cd, REG_ITMP1, a);
2406
2407                         if (iptr->dst->flags & INMEMORY) {
2408                                 i386_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 8);
2409                                 fpu_st_offset--;
2410
2411                                 a = dseg_adds4(cd, 0x027f);    /* Round to nearest, 53-bit mode, exceptions masked */
2412                                 i386_fldcw_membase(cd, REG_ITMP1, a);
2413
2414                                 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2415
2416                                 a = 6 + 4;
2417                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2418                                 a += 3;
2419                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2420                                 a += 5 + 2;
2421                                 a += 3;
2422                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2423                                 a += 3;
2424                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2425
2426                                 i386_jcc(cd, I386_CC_NE, a);
2427
2428                                 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2429
2430                                 a = 3;
2431                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2432                                 a += 5 + 2 + 3;
2433                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2434
2435                                 i386_jcc(cd, I386_CC_NE, a);
2436
2437                                 /* XXX: change this when we use registers */
2438                                 i386_flds_membase(cd, REG_SP, src->regoff * 8);
2439                                 i386_mov_imm_reg(cd, (s4) asm_builtin_f2l, REG_ITMP1);
2440                                 i386_call_reg(cd, REG_ITMP1);
2441                                 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2442                                 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2443
2444                         } else {
2445                                 panic("F2L: longs have to be in memory");
2446                         }
2447                         break;
2448
2449                 case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
2450
2451                         var_to_reg_flt(s1, src, REG_FTMP1);
2452                         d = reg_of_var(rd, iptr->dst, REG_NULL);
2453
2454                         a = dseg_adds4(cd, 0x0e7f);    /* Round to zero, 53-bit mode, exception masked */
2455                         i386_mov_imm_reg(cd, 0, REG_ITMP1);
2456                         dseg_adddata(cd, cd->mcodeptr);
2457                         i386_fldcw_membase(cd, REG_ITMP1, a);
2458
2459                         if (iptr->dst->flags & INMEMORY) {
2460                                 i386_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 8);
2461                                 fpu_st_offset--;
2462
2463                                 a = dseg_adds4(cd, 0x027f);    /* Round to nearest, 53-bit mode, exceptions masked */
2464                                 i386_fldcw_membase(cd, REG_ITMP1, a);
2465
2466                                 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2467
2468                                 a = 6 + 4;
2469                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2470                                 a += 3;
2471                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2472                                 a += 5 + 2;
2473                                 a += 3;
2474                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2475                                 a += 3;
2476                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2477
2478                                 i386_jcc(cd, I386_CC_NE, a);
2479
2480                                 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2481
2482                                 a = 3;
2483                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2484                                 a += 5 + 2 + 3;
2485                                 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2486
2487                                 i386_jcc(cd, I386_CC_NE, a);
2488
2489                                 /* XXX: change this when we use registers */
2490                                 i386_fldl_membase(cd, REG_SP, src->regoff * 8);
2491                                 i386_mov_imm_reg(cd, (s4) asm_builtin_d2l, REG_ITMP1);
2492                                 i386_call_reg(cd, REG_ITMP1);
2493                                 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2494                                 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2495
2496                         } else {
2497                                 panic("D2L: longs have to be in memory");
2498                         }
2499                         break;
2500
2501                 case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
2502
2503                         var_to_reg_flt(s1, src, REG_FTMP1);
2504                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2505                         /* nothing to do */
2506                         store_reg_to_var_flt(iptr->dst, d);
2507                         break;
2508
2509                 case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
2510
2511                         var_to_reg_flt(s1, src, REG_FTMP1);
2512                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2513                         /* nothing to do */
2514                         store_reg_to_var_flt(iptr->dst, d);
2515                         break;
2516
2517                 case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
2518                 case ICMD_DCMPL:
2519
2520                         /* exchanged to skip fxch */
2521                         var_to_reg_flt(s2, src->prev, REG_FTMP1);
2522                         var_to_reg_flt(s1, src, REG_FTMP2);
2523                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2524 /*                      i386_fxch(cd); */
2525                         i386_fucompp(cd);
2526                         fpu_st_offset -= 2;
2527                         i386_fnstsw(cd);
2528                         i386_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as GT */
2529                         i386_jcc(cd, I386_CC_E, 6);
2530                         i386_alu_imm_reg(cd, I386_AND, 0x000000ff, EAX);
2531                         i386_sahf(cd);
2532                         i386_mov_imm_reg(cd, 0, d);    /* does not affect flags */
2533                         i386_jcc(cd, I386_CC_E, 6 + 3 + 5 + 3);
2534                         i386_jcc(cd, I386_CC_B, 3 + 5);
2535                         i386_alu_imm_reg(cd, I386_SUB, 1, d);
2536                         i386_jmp_imm(cd, 3);
2537                         i386_alu_imm_reg(cd, I386_ADD, 1, d);
2538                         store_reg_to_var_int(iptr->dst, d);
2539                         break;
2540
2541                 case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
2542                 case ICMD_DCMPG:
2543
2544                         /* exchanged to skip fxch */
2545                         var_to_reg_flt(s2, src->prev, REG_FTMP1);
2546                         var_to_reg_flt(s1, src, REG_FTMP2);
2547                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2548 /*                      i386_fxch(cd); */
2549                         i386_fucompp(cd);
2550                         fpu_st_offset -= 2;
2551                         i386_fnstsw(cd);
2552                         i386_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as LT */
2553                         i386_jcc(cd, I386_CC_E, 3);
2554                         i386_movb_imm_reg(cd, 1, I386_AH);
2555                         i386_sahf(cd);
2556                         i386_mov_imm_reg(cd, 0, d);    /* does not affect flags */
2557                         i386_jcc(cd, I386_CC_E, 6 + 3 + 5 + 3);
2558                         i386_jcc(cd, I386_CC_B, 3 + 5);
2559                         i386_alu_imm_reg(cd, I386_SUB, 1, d);
2560                         i386_jmp_imm(cd, 3);
2561                         i386_alu_imm_reg(cd, I386_ADD, 1, d);
2562                         store_reg_to_var_int(iptr->dst, d);
2563                         break;
2564
2565
2566                 /* memory operations **************************************************/
2567
2568                 case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
2569
2570                         var_to_reg_int(s1, src, REG_ITMP1);
2571                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2572                         gen_nullptr_check(s1);
2573                         i386_mov_membase_reg(cd, s1, OFFSET(java_arrayheader, size), d);
2574                         store_reg_to_var_int(iptr->dst, d);
2575                         break;
2576
2577                 case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
2578
2579                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2580                         var_to_reg_int(s2, src, REG_ITMP2);
2581                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2582                         if (iptr->op1 == 0) {
2583                                 gen_nullptr_check(s1);
2584                                 gen_bound_check;
2585                         }
2586                         i386_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2587                         store_reg_to_var_int(iptr->dst, d);
2588                         break;
2589
2590                 case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
2591
2592                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2593                         var_to_reg_int(s2, src, REG_ITMP2);
2594                         d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2595                         if (iptr->op1 == 0) {
2596                                 gen_nullptr_check(s1);
2597                                 gen_bound_check;
2598                         }
2599                         
2600                         if (iptr->dst->flags & INMEMORY) {
2601                                 i386_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2602                                 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2603                                 i386_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2604                                 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2605                         }
2606                         break;
2607
2608                 case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
2609
2610                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2611                         var_to_reg_int(s2, src, REG_ITMP2);
2612                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2613                         if (iptr->op1 == 0) {
2614                                 gen_nullptr_check(s1);
2615                                 gen_bound_check;
2616                         }
2617                         i386_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2618                         store_reg_to_var_int(iptr->dst, d);
2619                         break;
2620
2621                 case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
2622
2623                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2624                         var_to_reg_int(s2, src, REG_ITMP2);
2625                         d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2626                         if (iptr->op1 == 0) {
2627                                 gen_nullptr_check(s1);
2628                                 gen_bound_check;
2629                         }
2630                         i386_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2631                         fpu_st_offset++;
2632                         store_reg_to_var_flt(iptr->dst, d);
2633                         break;
2634
2635                 case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
2636
2637                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2638                         var_to_reg_int(s2, src, REG_ITMP2);
2639                         d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2640                         if (iptr->op1 == 0) {
2641                                 gen_nullptr_check(s1);
2642                                 gen_bound_check;
2643                         }
2644                         i386_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2645                         fpu_st_offset++;
2646                         store_reg_to_var_flt(iptr->dst, d);
2647                         break;
2648
2649                 case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
2650
2651                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2652                         var_to_reg_int(s2, src, REG_ITMP2);
2653                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2654                         if (iptr->op1 == 0) {
2655                                 gen_nullptr_check(s1);
2656                                 gen_bound_check;
2657                         }
2658                         i386_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2659                         store_reg_to_var_int(iptr->dst, d);
2660                         break;                  
2661
2662                 case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
2663
2664                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2665                         var_to_reg_int(s2, src, REG_ITMP2);
2666                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2667                         if (iptr->op1 == 0) {
2668                                 gen_nullptr_check(s1);
2669                                 gen_bound_check;
2670                         }
2671                         i386_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2672                         store_reg_to_var_int(iptr->dst, d);
2673                         break;
2674
2675                 case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
2676
2677                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2678                         var_to_reg_int(s2, src, REG_ITMP2);
2679                         d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2680                         if (iptr->op1 == 0) {
2681                                 gen_nullptr_check(s1);
2682                                 gen_bound_check;
2683                         }
2684                         i386_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2685                         store_reg_to_var_int(iptr->dst, d);
2686                         break;
2687
2688
2689                 case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
2690
2691                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2692                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2693                         if (iptr->op1 == 0) {
2694                                 gen_nullptr_check(s1);
2695                                 gen_bound_check;
2696                         }
2697                         var_to_reg_int(s3, src, REG_ITMP3);
2698                         i386_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2699                         break;
2700
2701                 case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
2702
2703                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2704                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2705                         if (iptr->op1 == 0) {
2706                                 gen_nullptr_check(s1);
2707                                 gen_bound_check;
2708                         }
2709
2710                         if (src->flags & INMEMORY) {
2711                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP3);
2712                                 i386_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2713                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2714                                 i386_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2715                         }
2716                         break;
2717
2718                 case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
2719
2720                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2721                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2722                         if (iptr->op1 == 0) {
2723                                 gen_nullptr_check(s1);
2724                                 gen_bound_check;
2725                         }
2726                         var_to_reg_int(s3, src, REG_ITMP3);
2727                         i386_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2728                         break;
2729
2730                 case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
2731
2732                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2733                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2734                         if (iptr->op1 == 0) {
2735                                 gen_nullptr_check(s1);
2736                                 gen_bound_check;
2737                         }
2738                         var_to_reg_flt(s3, src, REG_FTMP1);
2739                         i386_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2740                         fpu_st_offset--;
2741                         break;
2742
2743                 case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
2744
2745                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2746                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2747                         if (iptr->op1 == 0) {
2748                                 gen_nullptr_check(s1);
2749                                 gen_bound_check;
2750                         }
2751                         var_to_reg_flt(s3, src, REG_FTMP1);
2752                         i386_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2753                         fpu_st_offset--;
2754                         break;
2755
2756                 case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
2757
2758                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2759                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2760                         if (iptr->op1 == 0) {
2761                                 gen_nullptr_check(s1);
2762                                 gen_bound_check;
2763                         }
2764                         var_to_reg_int(s3, src, REG_ITMP3);
2765                         i386_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2766                         break;
2767
2768                 case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
2769
2770                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2771                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2772                         if (iptr->op1 == 0) {
2773                                 gen_nullptr_check(s1);
2774                                 gen_bound_check;
2775                         }
2776                         var_to_reg_int(s3, src, REG_ITMP3);
2777                         i386_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2778                         break;
2779
2780                 case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
2781
2782                         var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2783                         var_to_reg_int(s2, src->prev, REG_ITMP2);
2784                         if (iptr->op1 == 0) {
2785                                 gen_nullptr_check(s1);
2786                                 gen_bound_check;
2787                         }
2788                         var_to_reg_int(s3, src, REG_ITMP3);
2789                         if (s3 >= EBP) {    /* because EBP, ESI, EDI have no xH and xL nibbles */
2790                                 M_INTMOVE(s3, REG_ITMP3);
2791                                 s3 = REG_ITMP3;
2792                         }
2793                         i386_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2794                         break;
2795
2796                 case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
2797
2798                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2799                         var_to_reg_int(s2, src, REG_ITMP2);
2800                         if (iptr->op1 == 0) {
2801                                 gen_nullptr_check(s1);
2802                                 gen_bound_check;
2803                         }
2804                         i386_mov_imm_memindex(cd, iptr->val.i, OFFSET(java_intarray, data[0]), s1, s2, 2);
2805                         break;
2806
2807                 case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
2808
2809                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2810                         var_to_reg_int(s2, src, REG_ITMP2);
2811                         if (iptr->op1 == 0) {
2812                                 gen_nullptr_check(s1);
2813                                 gen_bound_check;
2814                         }
2815
2816                         i386_mov_imm_memindex(cd, (u4) (iptr->val.l & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2817                         i386_mov_imm_memindex(cd, (u4) (iptr->val.l >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2818                         break;
2819
2820                 case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
2821
2822                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2823                         var_to_reg_int(s2, src, REG_ITMP2);
2824                         if (iptr->op1 == 0) {
2825                                 gen_nullptr_check(s1);
2826                                 gen_bound_check;
2827                         }
2828                         i386_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2829                         break;
2830
2831                 case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
2832
2833                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2834                         var_to_reg_int(s2, src, REG_ITMP2);
2835                         if (iptr->op1 == 0) {
2836                                 gen_nullptr_check(s1);
2837                                 gen_bound_check;
2838                         }
2839                         i386_movb_imm_memindex(cd, iptr->val.i, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2840                         break;
2841
2842                 case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
2843
2844                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2845                         var_to_reg_int(s2, src, REG_ITMP2);
2846                         if (iptr->op1 == 0) {
2847                                 gen_nullptr_check(s1);
2848                                 gen_bound_check;
2849                         }
2850                         i386_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_chararray, data[0]), s1, s2, 1);
2851                         break;
2852
2853                 case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
2854
2855                         var_to_reg_int(s1, src->prev, REG_ITMP1);
2856                         var_to_reg_int(s2, src, REG_ITMP2);
2857                         if (iptr->op1 == 0) {
2858                                 gen_nullptr_check(s1);
2859                                 gen_bound_check;
2860                         }
2861                         i386_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2862                         break;
2863
2864
2865                 case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
2866                                       /* op1 = type, val.a = field address            */
2867
2868                         /* If the static fields' class is not yet initialized, we do it   */
2869                         /* now. The call code is generated later.                         */
2870                         if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2871                                 codegen_addclinitref(cd, cd->mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2872
2873                                 /* This is just for debugging purposes. Is very difficult to  */
2874                                 /* read patched code. Here we patch the following 5 nop's     */
2875                                 /* so that the real code keeps untouched.                     */
2876                                 if (showdisassemble) {
2877                                         i386_nop(cd);
2878                                         i386_nop(cd);
2879                                         i386_nop(cd);
2880                                         i386_nop(cd);
2881                                         i386_nop(cd);
2882                                 }
2883                         }
2884
2885                         a = (ptrint) &(((fieldinfo *) iptr->val.a)->value);
2886                         switch (iptr->op1) {
2887                         case TYPE_INT:
2888                         case TYPE_ADR:
2889                                 var_to_reg_int(s2, src, REG_ITMP1);
2890                                 i386_mov_reg_mem(cd, s2, a);
2891                                 break;
2892                         case TYPE_LNG:
2893                                 if (src->flags & INMEMORY) {
2894                                         /* Using both REG_ITMP1 and REG_ITMP2 is faster than only */
2895                                         /* using REG_ITMP1 alternating.                           */
2896                                         s2 = src->regoff;
2897                                         i386_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
2898                                         i386_mov_membase_reg(cd, REG_SP, s2 * 8 + 4, REG_ITMP2);
2899                                         i386_mov_reg_mem(cd, REG_ITMP1, a);
2900                                         i386_mov_reg_mem(cd, REG_ITMP2, a + 4);
2901                                 } else {
2902                                         panic("PUTSTATIC: longs have to be in memory");
2903                                 }
2904                                 break;
2905                         case TYPE_FLT:
2906                                 var_to_reg_flt(s2, src, REG_FTMP1);
2907                                 i386_fstps_mem(cd, a);
2908                                 fpu_st_offset--;
2909                                 break;
2910                         case TYPE_DBL:
2911                                 var_to_reg_flt(s2, src, REG_FTMP1);
2912                                 i386_fstpl_mem(cd, a);
2913                                 fpu_st_offset--;
2914                                 break;
2915                         }
2916                         break;
2917
2918                 case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
2919                                           /* val = value (in current instruction)     */
2920                                           /* op1 = type, val.a = field address (in    */
2921                                           /* following NOP)                           */
2922
2923                         /* If the static fields' class is not yet initialized, we do it   */
2924                         /* now. The call code is generated later.                         */
2925                         if (!((fieldinfo *) iptr[1].val.a)->class->initialized) {
2926                                 codegen_addclinitref(cd, cd->mcodeptr, ((fieldinfo *) iptr[1].val.a)->class);
2927
2928                                 /* This is just for debugging purposes. Is very difficult to  */
2929                                 /* read patched code. Here we patch the following 5 nop's     */
2930                                 /* so that the real code keeps untouched.                     */
2931                                 if (showdisassemble) {
2932                                         i386_nop(cd);
2933                                         i386_nop(cd);
2934                                         i386_nop(cd);
2935                                         i386_nop(cd);
2936                                         i386_nop(cd);
2937                                 }
2938                         }
2939
2940                         a = (ptrint) &(((fieldinfo *) iptr[1].val.a)->value);
2941                         switch (iptr[1].op1) {
2942                         case TYPE_INT:
2943                         case TYPE_FLT:
2944                                 i386_mov_imm_mem(cd, iptr->val.i, a);
2945                                 break;
2946                         case TYPE_ADR:
2947                                 i386_mov_imm_mem(cd, (ptrint) iptr->val.a, a);
2948                                 break;
2949                         case TYPE_LNG:
2950                         case TYPE_DBL:
2951                                 i386_mov_imm_mem(cd, iptr->val.l, a);
2952                                 i386_mov_imm_mem(cd, iptr->val.l >> 32, a + 4);
2953                                 break;
2954                         }
2955                         break;
2956
2957                 case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
2958                                       /* op1 = type, val.a = field address            */
2959
2960                         /* If the static fields' class is not yet initialized, we do it   */
2961                         /* now. The call code is generated later.                         */
2962                         if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2963                                 codegen_addclinitref(cd, cd->mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2964
2965                                 /* This is just for debugging purposes. Is very difficult to  */
2966                                 /* read patched code. Here we patch the following 5 nop's     */
2967                                 /* so that the real code keeps untouched.                     */
2968                                 if (showdisassemble) {
2969                                         i386_nop(cd);
2970                                         i386_nop(cd);
2971                                         i386_nop(cd);
2972                                         i386_nop(cd);
2973                                         i386_nop(cd);
2974                                 }
2975                         }
2976
2977                         a = (ptrint) &(((fieldinfo *) iptr->val.a)->value);
2978                         switch (iptr->op1) {
2979                         case TYPE_INT:
2980                         case TYPE_ADR:
2981                                 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2982                                 i386_mov_mem_reg(cd, a, d);
2983                                 store_reg_to_var_int(iptr->dst, d);
2984                                 break;
2985                         case TYPE_LNG:
2986                                 d = reg_of_var(rd, iptr->dst, REG_NULL);
2987                                 if (iptr->dst->flags & INMEMORY) {
2988                                         /* Using both REG_ITMP1 and REG_ITMP2 is faster than only */
2989                                         /* using REG_ITMP1 alternating.                           */
2990                                         i386_mov_mem_reg(cd, a, REG_ITMP1);
2991                                         i386_mov_mem_reg(cd, a + 4, REG_ITMP2);
2992                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2993                                         i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2994                                 } else {
2995                                         panic("GETSTATIC: longs have to be in memory");
2996                                 }
2997                                 break;
2998                         case TYPE_FLT:
2999                                 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
3000                                 i386_flds_mem(cd, a);
3001                                 fpu_st_offset++;
3002                                 store_reg_to_var_flt(iptr->dst, d);
3003                                 break;
3004                         case TYPE_DBL:                          
3005                                 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
3006                                 i386_fldl_mem(cd, a);
3007                                 fpu_st_offset++;
3008                                 store_reg_to_var_flt(iptr->dst, d);
3009                                 break;
3010                         }
3011                         break;
3012
3013                 case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
3014                                       /* op1 = type, val.a = field address            */
3015
3016                         a = ((fieldinfo *) (iptr->val.a))->offset;
3017                         var_to_reg_int(s1, src->prev, REG_ITMP1);
3018                         gen_nullptr_check(s1);
3019                         switch (iptr->op1) {
3020                         case TYPE_INT:
3021                         case TYPE_ADR:
3022                                 var_to_reg_int(s2, src, REG_ITMP2);
3023                                 i386_mov_reg_membase(cd, s2, s1, a);
3024                                 break;
3025                         case TYPE_LNG:
3026                                 if (src->flags & INMEMORY) {
3027                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2);
3028                                         i386_mov_reg_membase(cd, REG_ITMP2, s1, a);
3029                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3030                                         i386_mov_reg_membase(cd, REG_ITMP2, s1, a + 4);
3031                                 } else {
3032                                         panic("PUTFIELD: longs have to be in memory");
3033                                 }
3034                                 break;
3035                         case TYPE_FLT:
3036                                 var_to_reg_flt(s2, src, REG_FTMP1);
3037                                 i386_fstps_membase(cd, s1, a);
3038                                 fpu_st_offset--;
3039                                 break;
3040                         case TYPE_DBL:
3041                                 var_to_reg_flt(s2, src, REG_FTMP1);
3042                                 i386_fstpl_membase(cd, s1, a);
3043                                 fpu_st_offset--;
3044                                 break;
3045                         }
3046                         break;
3047
3048                 case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
3049                                           /* val = value (in current instruction)     */
3050                                           /* op1 = type, val.a = field address (in    */
3051                                           /* following NOP)                           */
3052
3053                         a = ((fieldinfo *) (iptr[1].val.a))->offset;
3054                         var_to_reg_int(s1, src, REG_ITMP1);
3055                         gen_nullptr_check(s1);
3056                         switch (iptr[1].op1) {
3057                         case TYPE_INT:
3058                         case TYPE_FLT:
3059                                 i386_mov_imm_membase(cd, iptr->val.i, s1, a);
3060                                 break;
3061                         case TYPE_ADR:
3062                                 i386_mov_imm_membase(cd, (ptrint) iptr->val.a, s1, a);
3063                                 break;
3064                         case TYPE_LNG:
3065                         case TYPE_DBL:
3066                                 i386_mov_imm_membase(cd, iptr->val.l, s1, a);
3067                                 i386_mov_imm_membase(cd, iptr->val.l >> 32, s1, a + 4);
3068                                 break;
3069                         }
3070                         break;
3071
3072                 case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
3073                                       /* op1 = type, val.i = field offset             */
3074
3075                         a = ((fieldinfo *) (iptr->val.a))->offset;
3076                         var_to_reg_int(s1, src, REG_ITMP1);
3077                         gen_nullptr_check(s1);
3078                         switch (iptr->op1) {
3079                         case TYPE_INT:
3080                         case TYPE_ADR:
3081                                 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3082                                 i386_mov_membase_reg(cd, s1, a, d);
3083                                 store_reg_to_var_int(iptr->dst, d);
3084                                 break;
3085                         case TYPE_LNG:
3086                                 d = reg_of_var(rd, iptr->dst, REG_NULL);
3087                                 i386_mov_membase_reg(cd, s1, a, REG_ITMP2);
3088                                 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3089                                 i386_mov_membase_reg(cd, s1, a + 4, REG_ITMP2);
3090                                 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3091                                 break;
3092                         case TYPE_FLT:
3093                                 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
3094                                 i386_flds_membase(cd, s1, a);
3095                                 fpu_st_offset++;
3096                                 store_reg_to_var_flt(iptr->dst, d);
3097                                 break;
3098                         case TYPE_DBL:                          
3099                                 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
3100                                 i386_fldl_membase(cd, s1, a);
3101                                 fpu_st_offset++;
3102                                 store_reg_to_var_flt(iptr->dst, d);
3103                                 break;
3104                         }
3105                         break;
3106
3107
3108                 /* branch operations **************************************************/
3109
3110                 case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
3111
3112                         var_to_reg_int(s1, src, REG_ITMP1);
3113                         M_INTMOVE(s1, REG_ITMP1_XPTR);
3114
3115                         i386_call_imm(cd, 0);                /* passing exception pointer */
3116                         i386_pop_reg(cd, REG_ITMP2_XPC);
3117
3118                         i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
3119                         i386_jmp_reg(cd, REG_ITMP3);
3120                         ALIGNCODENOP;
3121                         break;
3122
3123                 case ICMD_GOTO:         /* ... ==> ...                                */
3124                                         /* op1 = target JavaVM pc                     */
3125
3126                         i386_jmp_imm(cd, 0);
3127                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3128                         ALIGNCODENOP;
3129                         break;
3130
3131                 case ICMD_JSR:          /* ... ==> ...                                */
3132                                         /* op1 = target JavaVM pc                     */
3133
3134                         i386_call_imm(cd, 0);
3135                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3136                         break;
3137                         
3138                 case ICMD_RET:          /* ... ==> ...                                */
3139                                         /* op1 = local variable                       */
3140
3141                         var = &(rd->locals[iptr->op1][TYPE_ADR]);
3142                         var_to_reg_int(s1, var, REG_ITMP1);
3143                         i386_jmp_reg(cd, s1);
3144                         break;
3145
3146                 case ICMD_IFNULL:       /* ..., value ==> ...                         */
3147                                         /* op1 = target JavaVM pc                     */
3148
3149                         if (src->flags & INMEMORY) {
3150                                 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
3151
3152                         } else {
3153                                 i386_test_reg_reg(cd, src->regoff, src->regoff);
3154                         }
3155                         i386_jcc(cd, I386_CC_E, 0);
3156                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3157                         break;
3158
3159                 case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
3160                                         /* op1 = target JavaVM pc                     */
3161
3162                         if (src->flags & INMEMORY) {
3163                                 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
3164
3165                         } else {
3166                                 i386_test_reg_reg(cd, src->regoff, src->regoff);
3167                         }
3168                         i386_jcc(cd, I386_CC_NE, 0);
3169                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3170                         break;
3171
3172                 case ICMD_IFEQ:         /* ..., value ==> ...                         */
3173                                         /* op1 = target JavaVM pc, val.i = constant   */
3174
3175                         if (src->flags & INMEMORY) {
3176                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3177
3178                         } else {
3179                                 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3180                         }
3181                         i386_jcc(cd, I386_CC_E, 0);
3182                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3183                         break;
3184
3185                 case ICMD_IFLT:         /* ..., value ==> ...                         */
3186                                         /* op1 = target JavaVM pc, val.i = constant   */
3187
3188                         if (src->flags & INMEMORY) {
3189                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3190
3191                         } else {
3192                                 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3193                         }
3194                         i386_jcc(cd, I386_CC_L, 0);
3195                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3196                         break;
3197
3198                 case ICMD_IFLE:         /* ..., value ==> ...                         */
3199                                         /* op1 = target JavaVM pc, val.i = constant   */
3200
3201                         if (src->flags & INMEMORY) {
3202                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3203
3204                         } else {
3205                                 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3206                         }
3207                         i386_jcc(cd, I386_CC_LE, 0);
3208                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3209                         break;
3210
3211                 case ICMD_IFNE:         /* ..., value ==> ...                         */
3212                                         /* op1 = target JavaVM pc, val.i = constant   */
3213
3214                         if (src->flags & INMEMORY) {
3215                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3216
3217                         } else {
3218                                 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3219                         }
3220                         i386_jcc(cd, I386_CC_NE, 0);
3221                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3222                         break;
3223
3224                 case ICMD_IFGT:         /* ..., value ==> ...                         */
3225                                         /* op1 = target JavaVM pc, val.i = constant   */
3226
3227                         if (src->flags & INMEMORY) {
3228                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3229
3230                         } else {
3231                                 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3232                         }
3233                         i386_jcc(cd, I386_CC_G, 0);
3234                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3235                         break;
3236
3237                 case ICMD_IFGE:         /* ..., value ==> ...                         */
3238                                         /* op1 = target JavaVM pc, val.i = constant   */
3239
3240                         if (src->flags & INMEMORY) {
3241                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3242
3243                         } else {
3244                                 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3245                         }
3246                         i386_jcc(cd, I386_CC_GE, 0);
3247                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3248                         break;
3249
3250                 case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
3251                                         /* op1 = target JavaVM pc, val.l = constant   */
3252
3253                         if (src->flags & INMEMORY) {
3254                                 if (iptr->val.l == 0) {
3255                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3256                                         i386_alu_membase_reg(cd, I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3257
3258                                 } else {
3259                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3260                                         i386_alu_imm_reg(cd, I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3261                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3262                                         i386_alu_imm_reg(cd, I386_XOR, iptr->val.l, REG_ITMP1);
3263                                         i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3264                                 }
3265                         }
3266                         i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3267                         i386_jcc(cd, I386_CC_E, 0);
3268                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3269                         break;
3270
3271                 case ICMD_IF_LLT:       /* ..., value ==> ...                         */
3272                                         /* op1 = target JavaVM pc, val.l = constant   */
3273
3274                         if (src->flags & INMEMORY) {
3275                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3276                                 i386_jcc(cd, I386_CC_L, 0);
3277                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3278
3279                                 a = 3 + 6;
3280                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3281                                 CALCIMMEDIATEBYTES(a, iptr->val.l);
3282
3283                                 i386_jcc(cd, I386_CC_G, a);
3284
3285                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3286                                 i386_jcc(cd, I386_CC_B, 0);
3287                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3288                         }                       
3289                         break;
3290
3291                 case ICMD_IF_LLE:       /* ..., value ==> ...                         */
3292                                         /* op1 = target JavaVM pc, val.l = constant   */
3293
3294                         if (src->flags & INMEMORY) {
3295                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3296                                 i386_jcc(cd, I386_CC_L, 0);
3297                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3298
3299                                 a = 3 + 6;
3300                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3301                                 CALCIMMEDIATEBYTES(a, iptr->val.l);
3302                                 
3303                                 i386_jcc(cd, I386_CC_G, a);
3304
3305                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3306                                 i386_jcc(cd, I386_CC_BE, 0);
3307                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3308                         }                       
3309                         break;
3310
3311                 case ICMD_IF_LNE:       /* ..., value ==> ...                         */
3312                                         /* op1 = target JavaVM pc, val.l = constant   */
3313
3314                         if (src->flags & INMEMORY) {
3315                                 if (iptr->val.l == 0) {
3316                                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3317                                         i386_alu_membase_reg(cd, I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3318
3319                                 } else {
3320                                         i386_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
3321                                         i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3322                                         i386_mov_imm_reg(cd, iptr->val.l >> 32, REG_ITMP2);
3323                                         i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3324                                         i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3325                                 }
3326                         }
3327                         i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3328                         i386_jcc(cd, I386_CC_NE, 0);
3329                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3330                         break;
3331
3332                 case ICMD_IF_LGT:       /* ..., value ==> ...                         */
3333                                         /* op1 = target JavaVM pc, val.l = constant   */
3334
3335                         if (src->flags & INMEMORY) {
3336                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3337                                 i386_jcc(cd, I386_CC_G, 0);
3338                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3339
3340                                 a = 3 + 6;
3341                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3342                                 CALCIMMEDIATEBYTES(a, iptr->val.l);
3343
3344                                 i386_jcc(cd, I386_CC_L, a);
3345
3346                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3347                                 i386_jcc(cd, I386_CC_A, 0);
3348                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3349                         }                       
3350                         break;
3351
3352                 case ICMD_IF_LGE:       /* ..., value ==> ...                         */
3353                                         /* op1 = target JavaVM pc, val.l = constant   */
3354
3355                         if (src->flags & INMEMORY) {
3356                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3357                                 i386_jcc(cd, I386_CC_G, 0);
3358                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3359
3360                                 a = 3 + 6;
3361                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3362                                 CALCIMMEDIATEBYTES(a, iptr->val.l);
3363
3364                                 i386_jcc(cd, I386_CC_L, a);
3365
3366                                 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3367                                 i386_jcc(cd, I386_CC_AE, 0);
3368                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3369                         }                       
3370                         break;
3371
3372                 case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
3373                 case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
3374
3375                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3376                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3377                                 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3378
3379                         } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3380                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3381
3382                         } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3383                                 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3384
3385                         } else {
3386                                 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3387                         }
3388                         i386_jcc(cd, I386_CC_E, 0);
3389                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3390                         break;
3391
3392                 case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
3393                                         /* op1 = target JavaVM pc                     */
3394
3395                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3396                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3397                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3398                                 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3399                                 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3400                                 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3401                                 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3402                         }                       
3403                         i386_jcc(cd, I386_CC_E, 0);
3404                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3405                         break;
3406
3407                 case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
3408                 case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
3409
3410                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3411                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3412                                 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3413
3414                         } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3415                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3416
3417                         } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3418                                 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3419
3420                         } else {
3421                                 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3422                         }
3423                         i386_jcc(cd, I386_CC_NE, 0);
3424                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3425                         break;
3426
3427                 case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
3428                                         /* op1 = target JavaVM pc                     */
3429
3430                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3431                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3432                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3433                                 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3434                                 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3435                                 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3436                                 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3437                         }                       
3438                         i386_jcc(cd, I386_CC_NE, 0);
3439                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3440                         break;
3441
3442                 case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
3443                                         /* op1 = target JavaVM pc                     */
3444
3445                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3446                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3447                                 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3448
3449                         } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3450                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3451
3452                         } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3453                                 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3454
3455                         } else {
3456                                 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3457                         }
3458                         i386_jcc(cd, I386_CC_L, 0);
3459                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3460                         break;
3461
3462                 case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
3463                                     /* op1 = target JavaVM pc                     */
3464
3465                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3466                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3467                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3468                                 i386_jcc(cd, I386_CC_L, 0);
3469                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3470
3471                                 a = 3 + 3 + 6;
3472                                 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3473                                 CALCOFFSETBYTES(a, REG_SP, src->regoff*8);
3474
3475                                 i386_jcc(cd, I386_CC_G, a);
3476
3477                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3478                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3479                                 i386_jcc(cd, I386_CC_B, 0);
3480                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3481                         }                       
3482                         break;
3483
3484                 case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
3485                                         /* op1 = target JavaVM pc                     */
3486
3487                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3488                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3489                                 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3490
3491                         } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3492                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3493
3494                         } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3495                                 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3496
3497                         } else {
3498                                 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3499                         }
3500                         i386_jcc(cd, I386_CC_G, 0);
3501                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3502                         break;
3503
3504                 case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
3505                                 /* op1 = target JavaVM pc                     */
3506
3507                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3508                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3509                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3510                                 i386_jcc(cd, I386_CC_G, 0);
3511                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3512
3513                                 a = 3 + 3 + 6;
3514                                 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3515                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3516
3517                                 i386_jcc(cd, I386_CC_L, a);
3518
3519                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3520                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3521                                 i386_jcc(cd, I386_CC_A, 0);
3522                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3523                         }                       
3524                         break;
3525
3526                 case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
3527                                         /* op1 = target JavaVM pc                     */
3528
3529                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3530                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3531                                 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3532
3533                         } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3534                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3535
3536                         } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3537                                 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3538
3539                         } else {
3540                                 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3541                         }
3542                         i386_jcc(cd, I386_CC_LE, 0);
3543                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3544                         break;
3545
3546                 case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
3547                                         /* op1 = target JavaVM pc                     */
3548
3549                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3550                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3551                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3552                                 i386_jcc(cd, I386_CC_L, 0);
3553                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3554
3555                                 a = 3 + 3 + 6;
3556                                 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3557                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3558
3559                                 i386_jcc(cd, I386_CC_G, a);
3560
3561                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3562                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3563                                 i386_jcc(cd, I386_CC_BE, 0);
3564                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3565                         }                       
3566                         break;
3567
3568                 case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
3569                                         /* op1 = target JavaVM pc                     */
3570
3571                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3572                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3573                                 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3574
3575                         } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3576                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3577
3578                         } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3579                                 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3580
3581                         } else {
3582                                 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3583                         }
3584                         i386_jcc(cd, I386_CC_GE, 0);
3585                         codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3586                         break;
3587
3588                 case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
3589                                     /* op1 = target JavaVM pc                     */
3590
3591                         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3592                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3593                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3594                                 i386_jcc(cd, I386_CC_G, 0);
3595                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3596
3597                                 a = 3 + 3 + 6;
3598                                 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3599                                 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3600
3601                                 i386_jcc(cd, I386_CC_L, a);
3602
3603                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3604                                 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3605                                 i386_jcc(cd, I386_CC_AE, 0);
3606                                 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3607                         }                       
3608                         break;
3609
3610                 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST                           */
3611
3612                 case ICMD_ELSE_ICONST:  /* handled by IFxx_ICONST                     */
3613                         break;
3614
3615                 case ICMD_IFEQ_ICONST:  /* ..., value ==> ..., constant               */
3616                                         /* val.i = constant                           */
3617
3618                         d = reg_of_var(rd, iptr->dst, REG_NULL);
3619                         i386_emit_ifcc_iconst(cd, I386_CC_NE, src, iptr);
3620                         break;
3621
3622                 case ICMD_IFNE_ICONST:  /* ..., value ==> ..., constant               */
3623                                         /* val.i = constant                           */
3624
3625                         d = reg_of_var(rd, iptr->dst, REG_NULL);
3626                         i386_emit_ifcc_iconst(cd, I386_CC_E, src, iptr);
3627                         break;
3628
3629                 case ICMD_IFLT_ICONST:  /* ..., value ==> ..., constant               */
3630                                         /* val.i = constant                           */
3631
3632                         d = reg_of_var(rd, iptr->dst, REG_NULL);
3633                         i386_emit_ifcc_iconst(cd, I386_CC_GE, src, iptr);
3634                         break;
3635
3636                 case ICMD_IFGE_ICONST:  /* ..., value ==> ..., constant               */
3637                                         /* val.i = constant                           */
3638
3639                         d = reg_of_var(rd, iptr->dst, REG_NULL);
3640                         i386_emit_ifcc_iconst(cd, I386_CC_L, src, iptr);
3641                         break;
3642
3643                 case ICMD_IFGT_ICONST:  /* ..., value ==> ..., constant               */
3644                                         /* val.i = constant                           */
3645
3646                         d = reg_of_var(rd, iptr->dst, REG_NULL);
3647                         i386_emit_ifcc_iconst(cd, I386_CC_LE, src, iptr);
3648                         break;
3649
3650                 case ICMD_IFLE_ICONST:  /* ..., value ==> ..., constant               */
3651                                         /* val.i = constant                           */
3652
3653                         d = reg_of_var(rd, iptr->dst, REG_NULL);
3654                         i386_emit_ifcc_iconst(cd, I386_CC_G, src, iptr);
3655                         break;
3656
3657
3658                 case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
3659                 case ICMD_ARETURN:
3660
3661                         var_to_reg_int(s1, src, REG_RESULT);
3662                         M_INTMOVE(s1, REG_RESULT);
3663
3664                         goto nowperformreturn;
3665
3666                 case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
3667
3668                         if (src->flags & INMEMORY) {
3669                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_RESULT);
3670                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3671
3672                         } else {
3673                                 panic("LRETURN: longs have to be in memory");
3674                         }
3675
3676                         goto nowperformreturn;
3677
3678                 case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
3679                 case ICMD_DRETURN:      /* ..., retvalue ==> ...                      */
3680
3681                         var_to_reg_flt(s1, src, REG_FRESULT);
3682                         /* this may be an early return -- keep the offset correct for the
3683                            remaining code */
3684                         fpu_st_offset--;
3685
3686                         goto nowperformreturn;
3687
3688                 case ICMD_RETURN:      /* ...  ==> ...                                */
3689
3690 nowperformreturn:
3691                         {
3692                         s4 i, p;
3693                         
3694                         p = parentargs_base;
3695                         
3696                         /* call trace function */
3697                         if (runverbose) {
3698                                 i386_alu_imm_reg(cd, I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3699
3700                                 i386_mov_imm_membase(cd, (s4) m, REG_SP, 0);
3701
3702                                 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
3703                                 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
3704                                 
3705                                 i386_fstl_membase(cd, REG_SP, 4 + 8);
3706                                 i386_fsts_membase(cd, REG_SP, 4 + 8 + 8);
3707
3708                                 i386_mov_imm_reg(cd, (s4) builtin_displaymethodstop, REG_ITMP1);
3709                                 i386_call_reg(cd, REG_ITMP1);
3710
3711                                 i386_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
3712                                 i386_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
3713
3714                                 i386_alu_imm_reg(cd, I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3715                         }
3716
3717 #if defined(USE_THREADS)
3718                         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3719                                 i386_mov_membase_reg(cd, REG_SP, 8 * rd->maxmemuse, REG_ITMP2);
3720
3721                                 /* we need to save the proper return value */
3722                                 switch (iptr->opc) {
3723                                 case ICMD_IRETURN:
3724                                 case ICMD_ARETURN:
3725                                         i386_mov_reg_membase(cd, REG_RESULT, REG_SP, rd->maxmemuse * 8);
3726                                         break;
3727
3728                                 case ICMD_LRETURN:
3729                                         i386_mov_reg_membase(cd, REG_RESULT, REG_SP, rd->maxmemuse * 8);
3730                                         i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, rd->maxmemuse * 8 + 4);
3731                                         break;
3732
3733                                 case ICMD_FRETURN:
3734                                         i386_fsts_membase(cd, REG_SP, rd->maxmemuse * 8);
3735                                         break;
3736
3737                                 case ICMD_DRETURN:
3738                                         i386_fstl_membase(cd, REG_SP, rd->maxmemuse * 8);
3739                                         break;
3740                                 }
3741
3742                                 i386_alu_imm_reg(cd, I386_SUB, 4, REG_SP);
3743                                 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, 0);
3744                                 i386_mov_imm_reg(cd, (s4) builtin_monitorexit, REG_ITMP1);
3745                                 i386_call_reg(cd, REG_ITMP1);
3746                                 i386_alu_imm_reg(cd, I386_ADD, 4, REG_SP);
3747
3748                                 /* and now restore the proper return value */
3749                                 switch (iptr->opc) {
3750                                 case ICMD_IRETURN:
3751                                 case ICMD_ARETURN:
3752                                         i386_mov_membase_reg(cd, REG_SP, rd->maxmemuse * 8, REG_RESULT);
3753                                         break;
3754
3755                                 case ICMD_LRETURN:
3756                                         i386_mov_membase_reg(cd, REG_SP, rd->maxmemuse * 8, REG_RESULT);
3757                                         i386_mov_membase_reg(cd, REG_SP, rd->maxmemuse * 8 + 4, REG_RESULT2);
3758                                         break;
3759
3760                                 case ICMD_FRETURN:
3761                                         i386_flds_membase(cd, REG_SP, rd->maxmemuse * 8);
3762                                         break;
3763
3764                                 case ICMD_DRETURN:
3765                                         i386_fldl_membase(cd, REG_SP, rd->maxmemuse * 8);
3766                                         break;
3767                                 }
3768                         }
3769 #endif
3770
3771                         /* restore saved registers */
3772                         for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
3773                                 p--;
3774                                 i386_mov_membase_reg(cd, REG_SP, p * 8, rd->savintregs[i]);
3775                         }
3776                         for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
3777                                 p--;
3778                                 i386_fldl_membase(cd, REG_SP, p * 8);
3779                                 fpu_st_offset++;
3780                                 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3781                                         i386_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1);
3782                                 } else {
3783                                         i386_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset);
3784                                 }
3785                                 fpu_st_offset--;
3786                         }
3787
3788                         /* deallocate stack                                               */
3789                         if (parentargs_base) {
3790                                 i386_alu_imm_reg(cd, I386_ADD, parentargs_base * 8, REG_SP);
3791                         }
3792
3793                         i386_ret(cd);
3794                         ALIGNCODENOP;
3795                         }
3796                         break;
3797
3798
3799                 case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
3800                         {
3801                                 s4 i, l, *s4ptr;
3802                                 void **tptr;
3803
3804                                 tptr = (void **) iptr->target;
3805
3806                                 s4ptr = iptr->val.a;
3807                                 l = s4ptr[1];                          /* low     */
3808                                 i = s4ptr[2];                          /* high    */
3809
3810                                 var_to_reg_int(s1, src, REG_ITMP1);
3811                                 M_INTMOVE(s1, REG_ITMP1);
3812                                 if (l != 0) {
3813                                         i386_alu_imm_reg(cd, I386_SUB, l, REG_ITMP1);
3814                                 }
3815                                 i = i - l + 1;
3816
3817                 /* range check */
3818
3819                                 i386_alu_imm_reg(cd, I386_CMP, i - 1, REG_ITMP1);
3820                                 i386_jcc(cd, I386_CC_A, 0);
3821
3822                 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), cd->mcodeptr); */
3823                                 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
3824
3825                                 /* build jump table top down and use address of lowest entry */
3826
3827                 /* s4ptr += 3 + i; */
3828                                 tptr += i;
3829
3830                                 while (--i >= 0) {
3831                                         /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3832                                         dseg_addtarget(cd, (basicblock *) tptr[0]); 
3833                                         --tptr;
3834                                 }
3835
3836                                 /* length of dataseg after last dseg_addtarget is used by load */
3837
3838                                 i386_mov_imm_reg(cd, 0, REG_ITMP2);
3839                                 dseg_adddata(cd, cd->mcodeptr);
3840                                 i386_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3841                                 i386_jmp_reg(cd, REG_ITMP1);
3842                                 ALIGNCODENOP;
3843                         }
3844                         break;
3845
3846
3847                 case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
3848                         {
3849                                 s4 i, l, val, *s4ptr;
3850                                 void **tptr;
3851
3852                                 tptr = (void **) iptr->target;
3853
3854                                 s4ptr = iptr->val.a;
3855                                 l = s4ptr[0];                          /* default  */
3856                                 i = s4ptr[1];                          /* count    */
3857                         
3858                                 MCODECHECK((i<<2)+8);
3859                                 var_to_reg_int(s1, src, REG_ITMP1);    /* reg compare should always be faster */
3860                                 while (--i >= 0) {
3861                                         s4ptr += 2;
3862                                         ++tptr;
3863
3864                                         val = s4ptr[0];
3865                                         i386_alu_imm_reg(cd, I386_CMP, val, s1);
3866                                         i386_jcc(cd, I386_CC_E, 0);
3867                                         /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), cd->mcodeptr); */
3868                                         codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr); 
3869                                 }
3870
3871                                 i386_jmp_imm(cd, 0);
3872                                 /* codegen_addreference(cd, BlockPtrOfPC(l), cd->mcodeptr); */
3873                         
3874                                 tptr = (void **) iptr->target;
3875                                 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
3876
3877                                 ALIGNCODENOP;
3878                         }
3879                         break;
3880
3881
3882                 case ICMD_BUILTIN3:     /* ..., arg1, arg2, arg3 ==> ...              */
3883                                         /* op1 = return type, val.a = function pointer*/
3884                         s3 = 3;
3885                         goto gen_method;
3886
3887                 case ICMD_BUILTIN2:     /* ..., arg1, arg2 ==> ...                    */
3888                                         /* op1 = return type, val.a = function pointer*/
3889                         s3 = 2;
3890                         goto gen_method;
3891
3892                 case ICMD_BUILTIN1:     /* ..., arg1 ==> ...                          */
3893                                         /* op1 = return type, val.a = function pointer*/
3894                         s3 = 1;
3895                         goto gen_method;
3896
3897                 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
3898                                         /* op1 = arg count, val.a = method pointer    */
3899
3900                 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3901                                         /* op1 = arg count, val.a = method pointer    */
3902
3903                 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3904                                         /* op1 = arg count, val.a = method pointer    */
3905
3906                 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3907                                         /* op1 = arg count, val.a = method pointer    */
3908
3909                         s3 = iptr->op1;
3910
3911 gen_method: {
3912                         methodinfo *lm;
3913
3914                         MCODECHECK((s3 << 1) + 64);
3915
3916                         /* copy arguments to registers or stack location                  */
3917
3918                         for (; --s3 >= 0; src = src->prev) {
3919                                 if (src->varkind == ARGVAR) {
3920                                         continue;
3921                                 }
3922
3923                                 if (IS_INT_LNG_TYPE(src->type)) {
3924                                         if (s3 < rd->intreg_argnum) {
3925                                                 panic("No integer argument registers available!");
3926
3927                                         } else {
3928                                                 if (!IS_2_WORD_TYPE(src->type)) {
3929                                                         if (src->flags & INMEMORY) {
3930                                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3931                                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, s3 * 8);
3932
3933                                                         } else {
3934                                                                 i386_mov_reg_membase(cd, src->regoff, REG_SP, s3 * 8);
3935                                                         }
3936
3937                                                 } else {
3938                                                         if (src->flags & INMEMORY) {
3939                                                                 M_LNGMEMMOVE(src->regoff, s3);
3940
3941                                                         } else {
3942                                                                 panic("copy arguments: longs have to be in memory");
3943                                                         }
3944                                                 }
3945                                         }
3946
3947                                 } else {
3948                                         if (s3 < rd->fltreg_argnum) {
3949                                                 panic("No float argument registers available!");
3950
3951                                         } else {
3952                                                 var_to_reg_flt(d, src, REG_FTMP1);
3953                                                 if (src->type == TYPE_FLT) {
3954                                                         i386_fstps_membase(cd, REG_SP, s3 * 8);
3955
3956                                                 } else {
3957                                                         i386_fstpl_membase(cd, REG_SP, s3 * 8);
3958                                                 }
3959                                         }
3960                                 }
3961                         } /* end of for */
3962
3963                         lm = iptr->val.a;
3964                         switch (iptr->opc) {
3965                         case ICMD_BUILTIN3:
3966                         case ICMD_BUILTIN2:
3967                         case ICMD_BUILTIN1:
3968                                 a = (u4) lm;
3969                                 d = iptr->op1;
3970
3971                                 i386_mov_imm_reg(cd, a, REG_ITMP1);
3972                                 i386_call_reg(cd, REG_ITMP1);
3973                                 break;
3974
3975                         case ICMD_INVOKESTATIC:
3976                                 a = (u4) lm->stubroutine;
3977                                 d = lm->returntype;
3978
3979                                 i386_mov_imm_reg(cd, a, REG_ITMP2);
3980                                 i386_call_reg(cd, REG_ITMP2);
3981                                 break;
3982
3983                         case ICMD_INVOKESPECIAL:
3984                                 a = (u4) lm->stubroutine;
3985                                 d = lm->returntype;
3986
3987                                 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
3988                                 gen_nullptr_check(REG_ITMP1);
3989                                 i386_mov_membase_reg(cd, REG_ITMP1, 0, REG_ITMP1);    /* access memory for hardware nullptr */
3990
3991                                 i386_mov_imm_reg(cd, a, REG_ITMP2);
3992                                 i386_call_reg(cd, REG_ITMP2);
3993                                 break;
3994
3995                         case ICMD_INVOKEVIRTUAL:
3996                                 d = lm->returntype;
3997
3998                                 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
3999                                 gen_nullptr_check(REG_ITMP1);
4000                                 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4001                                 i386_mov_membase32_reg(cd, REG_ITMP2, OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex, REG_ITMP1);
4002
4003                                 i386_call_reg(cd, REG_ITMP1);
4004                                 break;
4005
4006                         case ICMD_INVOKEINTERFACE:
4007                                 d = lm->returntype;
4008
4009                                 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
4010                                 gen_nullptr_check(REG_ITMP1);
4011                                 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4012                                 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr) * lm->class->index, REG_ITMP2);
4013                                 i386_mov_membase32_reg(cd, REG_ITMP2, sizeof(methodptr) * (lm - lm->class->methods), REG_ITMP1);
4014
4015                                 i386_call_reg(cd, REG_ITMP1);
4016                                 break;
4017                         }
4018
4019                         /* d contains return type */
4020
4021                         if (d != TYPE_VOID) {
4022                                 d = reg_of_var(rd, iptr->dst, REG_NULL);
4023
4024                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4025                                         if (IS_2_WORD_TYPE(iptr->dst->type)) {
4026                                                 if (iptr->dst->flags & INMEMORY) {
4027                                                         i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4028                                                         i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4029
4030                                                 } else {
4031                                                         panic("RETURN: longs have to be in memory");
4032                                                 }
4033
4034                                         } else {
4035                                                 if (iptr->dst->flags & INMEMORY) {
4036                                                         i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4037
4038                                                 } else {
4039                                                         M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4040                                                 }
4041                                         }
4042
4043                                 } else {
4044                                         /* fld from called function -- has other fpu_st_offset counter */
4045                                         fpu_st_offset++;
4046                                         store_reg_to_var_flt(iptr->dst, d);
4047                                 }
4048                         }
4049                         }
4050                         break;
4051
4052
4053                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
4054
4055                                       /* op1:   0 == array, 1 == class                */
4056                                       /* val.a: (classinfo*) superclass               */
4057
4058 /*          superclass is an interface:
4059  *
4060  *          return (sub != NULL) &&
4061  *                 (sub->vftbl->interfacetablelength > super->index) &&
4062  *                 (sub->vftbl->interfacetable[-super->index] != NULL);
4063  *
4064  *          superclass is a class:
4065  *
4066  *          return ((sub != NULL) && (0
4067  *                  <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4068  *                  super->vftbl->diffvall));
4069  */
4070
4071                         {
4072                         classinfo *super = (classinfo*) iptr->val.a;
4073                         
4074 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4075                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
4076 #endif
4077                         var_to_reg_int(s1, src, REG_ITMP1);
4078                         d = reg_of_var(rd, iptr->dst, REG_ITMP3);
4079                         if (s1 == d) {
4080                                 M_INTMOVE(s1, REG_ITMP1);
4081                                 s1 = REG_ITMP1;
4082                         }
4083                         i386_alu_reg_reg(cd, I386_XOR, d, d);
4084                         if (iptr->op1) {                               /* class/interface */
4085                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
4086                                         i386_test_reg_reg(cd, s1, s1);
4087
4088                                         /* TODO: clean up this calculation */
4089                                         a = 2;
4090                                         CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4091
4092                                         a += 2;
4093                                         CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
4094                                         
4095                                         a += 2;
4096 /*                                      CALCOFFSETBYTES(a, super->index); */
4097                                         CALCIMMEDIATEBYTES(a, super->index);
4098                                         
4099                                         a += 3;
4100                                         a += 6;
4101
4102                                         a += 2;
4103                                         CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*));
4104
4105                                         a += 3;
4106
4107                                         a += 6;    /* jcc */
4108                                         a += 5;
4109
4110                                         i386_jcc(cd, I386_CC_E, a);
4111
4112                                         i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4113                                         i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength), REG_ITMP2);
4114                                         i386_alu_imm_reg(cd, I386_SUB, super->index, REG_ITMP2);
4115                                         /* TODO: test */
4116                                         i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP2);
4117
4118                                         /* TODO: clean up this calculation */
4119                                         a = 0;
4120                                         a += 2;
4121                                         CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*));
4122
4123                                         a += 3;
4124
4125                                         a += 6;    /* jcc */
4126                                         a += 5;
4127
4128                                         i386_jcc(cd, I386_CC_LE, a);
4129                                         i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4130                                         /* TODO: test */
4131                                         i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP1);
4132 /*                                      i386_setcc_reg(cd, I386_CC_A, d); */
4133 /*                                      i386_jcc(cd, I386_CC_BE, 5); */
4134                                         i386_jcc(cd, I386_CC_E, 5);
4135                                         i386_mov_imm_reg(cd, 1, d);
4136                                         
4137
4138                                 } else {                                   /* class           */
4139                                         i386_test_reg_reg(cd, s1, s1);
4140
4141                                         /* TODO: clean up this calculation */
4142                                         a = 2;
4143                                         CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4144                                         a += 5;
4145                                         a += 2;
4146                                         CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, baseval));
4147                                         a += 2;
4148                                         CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, baseval));
4149                                         
4150                                         a += 2;
4151                                         CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, diffval));
4152                                         
4153                                         a += 2;
4154                                         a += 2;    /* xor */
4155
4156                                         a += 2;
4157
4158                                         a += 6;    /* jcc */
4159                                         a += 5;
4160
4161                                         i386_jcc(cd, I386_CC_E, a);
4162
4163                                         i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4164                                         i386_mov_imm_reg(cd, (s4) super->vftbl, REG_ITMP2);
4165 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4166                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
4167 #endif
4168                                         i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, baseval), REG_ITMP1);
4169                                         i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, baseval), REG_ITMP3);
4170                                         i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, diffval), REG_ITMP2);
4171 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4172                                         codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4173 #endif
4174                                         i386_alu_reg_reg(cd, I386_SUB, REG_ITMP3, REG_ITMP1);
4175                                         i386_alu_reg_reg(cd, I386_XOR, d, d);
4176
4177                                         i386_alu_reg_reg(cd, I386_CMP, REG_ITMP2, REG_ITMP1);
4178                                         i386_jcc(cd, I386_CC_A, 5);
4179                                         i386_mov_imm_reg(cd, 1, d);
4180                                 }
4181                         }
4182                         else
4183                                 panic ("internal error: no inlined array instanceof");
4184                         }
4185                         store_reg_to_var_int(iptr->dst, d);
4186                         break;
4187
4188                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
4189
4190                                       /* op1:   0 == array, 1 == class                */
4191                                       /* val.a: (classinfo*) superclass               */
4192
4193                         /*  superclass is an interface:
4194                          *
4195                          *  OK if ((sub == NULL) ||
4196                          *         (sub->vftbl->interfacetablelength > super->index) &&
4197                          *         (sub->vftbl->interfacetable[-super->index] != NULL));
4198                          *
4199                          *  superclass is a class:
4200                          *
4201                          *  OK if ((sub == NULL) || (0
4202                          *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4203                          *         super->vftbl->diffval));
4204                          */
4205
4206                         {
4207                         classinfo *super = (classinfo *) iptr->val.a;
4208                         
4209 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4210                         codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
4211 #endif
4212                         var_to_reg_int(s1, src, REG_ITMP1);
4213                         if (iptr->op1) {                               /* class/interface */
4214                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
4215                                         i386_test_reg_reg(cd, s1, s1);
4216
4217                                         /* TODO: clean up this calculation */
4218                                         a = 2;
4219                                         CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4220
4221                                         a += 2;
4222                                         CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
4223
4224                                         a += 2;
4225                                         CALCIMMEDIATEBYTES(a, super->index);
4226
4227                                         a += 2;    /* test */
4228                                         a += 6;    /* jcc */
4229
4230                                         a += 2;
4231                                         CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*));
4232
4233                                         a += 2;    /* test */
4234                                         a += 6;    /* jcc */
4235
4236                                         i386_jcc(cd, I386_CC_E, a);
4237
4238                                         i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4239                                         i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength), REG_ITMP3);
4240                                         i386_alu_imm_reg(cd, I386_SUB, super->index, REG_ITMP3);
4241                                         i386_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
4242                                         i386_jcc(cd, I386_CC_LE, 0);
4243                                         codegen_addxcastrefs(cd, cd->mcodeptr);
4244                                         i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP3);
4245                                         i386_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
4246                                         i386_jcc(cd, I386_CC_E, 0);
4247                                         codegen_addxcastrefs(cd, cd->mcodeptr);
4248
4249                                 } else {                                     /* class           */
4250                                         i386_test_reg_reg(cd, s1, s1);
4251
4252                                         /* TODO: clean up this calculation */
4253                                         a = 2;
4254                                         CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4255
4256                                         a += 5;
4257
4258                                         a += 2;
4259                                         CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, baseval));
4260
4261                                         if (s1 != REG_ITMP1) {
4262                                                 a += 2;
4263                                                 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
4264                                                 
4265                                                 a += 2;
4266                                                 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
4267
4268                                                 a += 2;
4269                                                 
4270                                         } else {
4271                                                 a += 2;
4272                                                 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
4273
4274                                                 a += 2;
4275                                                 a += 5;
4276
4277                                                 a += 2;
4278                                                 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
4279                                         }
4280
4281                                         a += 2;    /* cmp */
4282                                         a += 6;    /* jcc */
4283
4284                                         i386_jcc(cd, I386_CC_E, a);
4285
4286                                         i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4287                                         i386_mov_imm_reg(cd, (ptrint) super->vftbl, REG_ITMP3);
4288 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4289                                         codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
4290 #endif
4291                                         i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, baseval), REG_ITMP2);
4292                                         if (s1 != REG_ITMP1) {
4293                                                 i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1);
4294                                                 i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3);
4295 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4296                                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4297 #endif
4298                                                 i386_alu_reg_reg(cd, I386_SUB, REG_ITMP1, REG_ITMP2);
4299
4300                                         } else {
4301                                                 i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP3);
4302                                                 i386_alu_reg_reg(cd, I386_SUB, REG_ITMP3, REG_ITMP2);
4303                                                 i386_mov_imm_reg(cd, (ptrint) super->vftbl, REG_ITMP3);
4304                                                 i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3);
4305 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4306                                                 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4307 #endif
4308                                         }
4309
4310                                         i386_alu_reg_reg(cd, I386_CMP, REG_ITMP3, REG_ITMP2);
4311                                         i386_jcc(cd, I386_CC_A, 0);    /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
4312                                         codegen_addxcastrefs(cd, cd->mcodeptr);
4313                                 }
4314
4315                         } else
4316                                 panic ("internal error: no inlined array checkcast");
4317                         }
4318                         d = reg_of_var(rd, iptr->dst, REG_ITMP3);
4319                         M_INTMOVE(s1, d);
4320                         store_reg_to_var_int(iptr->dst, d);
4321                         break;
4322
4323                 case ICMD_CHECKASIZE:  /* ..., size ==> ..., size                     */
4324
4325                         if (src->flags & INMEMORY) {
4326                                 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
4327                                 
4328                         } else {
4329                                 i386_test_reg_reg(cd, src->regoff, src->regoff);
4330                         }
4331                         i386_jcc(cd, I386_CC_L, 0);
4332                         codegen_addxcheckarefs(cd, cd->mcodeptr);
4333                         break;
4334
4335                 case ICMD_CHECKEXCEPTION:  /* ... ==> ...                             */
4336
4337                         i386_test_reg_reg(cd, REG_RESULT, REG_RESULT);
4338                         i386_jcc(cd, I386_CC_E, 0);
4339                         codegen_addxexceptionrefs(cd, cd->mcodeptr);
4340                         break;
4341
4342                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
4343                                       /* op1 = dimension, val.a = array descriptor    */
4344
4345                         /* check for negative sizes and copy sizes to stack if necessary  */
4346
4347                         MCODECHECK((iptr->op1 << 1) + 64);
4348
4349                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4350                                 if (src->flags & INMEMORY) {
4351                                         i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
4352
4353                                 } else {
4354                                         i386_test_reg_reg(cd, src->regoff, src->regoff);
4355                                 }
4356                                 i386_jcc(cd, I386_CC_L, 0);
4357                                 codegen_addxcheckarefs(cd, cd->mcodeptr);
4358
4359                                 /* 
4360                                  * copy sizes to new stack location, because native function
4361                                  * builtin_nmultianewarray access them as (int *)
4362                                  */
4363                                 /*i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);*/
4364                                 /*i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);*/
4365
4366                                 /* copy SAVEDVAR sizes to stack */
4367
4368                                 if (src->varkind != ARGVAR) {
4369                                         if (src->flags & INMEMORY) {
4370                                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
4371                                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, s1 * 8);
4372
4373                                         } else {
4374                                                 i386_mov_reg_membase(cd, src->regoff, REG_SP, s1 * 8);
4375                                         }
4376                                 }
4377                         }
4378
4379                         /* now copy the (long *) sizes to (int *), skip the first one */
4380
4381                         for (s1 = 1; s1 < iptr->op1; s1++) {
4382                                 i386_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
4383                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, s1 * 4);
4384                         }
4385
4386                         /* save stack pointer */
4387                         M_INTMOVE(REG_SP, REG_ITMP1);
4388
4389                         i386_alu_imm_reg(cd, I386_SUB, 3 * 4, REG_SP);
4390
4391                         /* a0 = dimension count */
4392
4393                         i386_mov_imm_membase(cd, iptr->op1, REG_SP, 0);
4394
4395                         /* a1 = arraydescriptor */
4396
4397                         i386_mov_imm_membase(cd, (u4) iptr->val.a, REG_SP, 4);
4398
4399                         /* a2 = pointer to dimensions = stack pointer */
4400
4401                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 8);
4402
4403                         i386_mov_imm_reg(cd, (u4) (builtin_nmultianewarray), REG_ITMP1);
4404                         i386_call_reg(cd, REG_ITMP1);
4405                         i386_alu_imm_reg(cd, I386_ADD, 3 * 4, REG_SP);
4406
4407                         s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
4408                         M_INTMOVE(REG_RESULT, s1);
4409                         store_reg_to_var_int(iptr->dst, s1);
4410                         break;
4411
4412                 default:
4413                         throw_cacao_exception_exit(string_java_lang_InternalError,
4414                                                                            "Unknown ICMD %d", iptr->opc);
4415         } /* switch */
4416                 
4417         } /* for instruction */
4418                 
4419         /* copy values to interface registers */
4420
4421         src = bptr->outstack;
4422         len = bptr->outdepth;
4423         MCODECHECK(64+len);
4424 #ifdef LSRA
4425         if (!opt_lsra)
4426 #endif
4427         while (src) {
4428                 len--;
4429                 if ((src->varkind != STACKVAR)) {
4430                         s2 = src->type;
4431                         if (IS_FLT_DBL_TYPE(s2)) {
4432                                 var_to_reg_flt(s1, src, REG_FTMP1);
4433                                 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4434                                         M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
4435
4436                                 } else {
4437                                         panic("double store");
4438 /*                                      M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4439                                 }
4440
4441                         } else {
4442                                 var_to_reg_int(s1, src, REG_ITMP1);
4443                                 if (!IS_2_WORD_TYPE(rd->interfaces[len][s2].type)) {
4444                                         if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4445                                                 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
4446
4447                                         } else {
4448                                                 i386_mov_reg_membase(cd, s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
4449                                         }
4450
4451                                 } else {
4452                                         if (rd->interfaces[len][s2].flags & INMEMORY) {
4453                                                 M_LNGMEMMOVE(s1, rd->interfaces[len][s2].regoff);
4454
4455                                         } else {
4456                                                 panic("copy interface registers: longs have to be in memory (end)");
4457                                         }
4458                                 }
4459                         }
4460                 }
4461                 src = src->prev;
4462         }
4463         } /* if (bptr -> flags >= BBREACHED) */
4464         } /* for basic block */
4465
4466         codegen_createlinenumbertable(cd);
4467
4468         {
4469
4470         /* generate bound check stubs */
4471
4472         u1 *xcodeptr = NULL;
4473         branchref *bref;
4474
4475         for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
4476                 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4477                                   bref->branchpos,
4478                                                   cd->mcodeptr - cd->mcodebase);
4479
4480                 MCODECHECK(100);
4481
4482                 /* move index register into REG_ITMP1 */
4483                 i386_mov_reg_reg(cd, bref->reg, REG_ITMP1);                /* 2 bytes */
4484
4485                 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
4486                 dseg_adddata(cd, cd->mcodeptr);
4487                 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP3);      /* 5 bytes */
4488                 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP3, REG_ITMP2_XPC);  /* 2 bytes */
4489
4490                 if (xcodeptr != NULL) {
4491                         i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4492
4493                 } else {
4494                         xcodeptr = cd->mcodeptr;
4495
4496                         i386_push_reg(cd, REG_ITMP2_XPC);
4497
4498                         /*PREPARE_NATIVE_STACKINFO;*/
4499                         i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4500                         i386_push_imm(cd,0);
4501                         i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4502                         i386_call_reg(cd,REG_ITMP3);
4503
4504                         i386_alu_imm_reg(cd, I386_SUB, 1 * 4, REG_SP);
4505                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0 * 4);
4506                         i386_mov_imm_reg(cd, (u4) new_arrayindexoutofboundsexception, REG_ITMP1);
4507                         i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
4508                         i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);
4509
4510                         /*REMOVE_NATIVE_STACKINFO;*/
4511                         i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4512                         i386_call_reg(cd,REG_ITMP3);
4513
4514                         i386_pop_reg(cd, REG_ITMP2_XPC);
4515
4516                         i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4517                         i386_jmp_reg(cd, REG_ITMP3);
4518                 }
4519         }
4520
4521         /* generate negative array size check stubs */
4522
4523         xcodeptr = NULL;
4524         
4525         for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
4526                 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4527                         gen_resolvebranch(cd->mcodebase + bref->branchpos, 
4528                                                           bref->branchpos,
4529                                                           xcodeptr - cd->mcodebase - (5 + 5 + 2));
4530                         continue;
4531                 }
4532
4533                 gen_resolvebranch(cd->mcodebase + bref->branchpos, 
4534                                   bref->branchpos,
4535                                                   cd->mcodeptr - cd->mcodebase);
4536
4537                 MCODECHECK(100);
4538
4539                 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
4540                 dseg_adddata(cd, cd->mcodeptr);
4541                 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
4542                 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
4543
4544                 if (xcodeptr != NULL) {
4545                         i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4546
4547                 } else {
4548                         xcodeptr = cd->mcodeptr;
4549
4550                         i386_push_reg(cd, REG_ITMP2_XPC);
4551
4552                         /*PREPARE_NATIVE_STACKINFO;*/
4553                         i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4554                         i386_push_imm(cd,0);
4555                         i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4556                         i386_call_reg(cd,REG_ITMP3);
4557
4558
4559
4560                         i386_mov_imm_reg(cd, (u4) new_negativearraysizeexception, REG_ITMP1);
4561                         i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
4562                         /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
4563
4564
4565                         /*REMOVE_NATIVE_STACKINFO;*/
4566                         i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4567                         i386_call_reg(cd,REG_ITMP3);
4568
4569
4570                         i386_pop_reg(cd, REG_ITMP2_XPC);
4571
4572                         i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4573                         i386_jmp_reg(cd, REG_ITMP3);
4574                 }
4575         }
4576
4577         /* generate cast check stubs */
4578
4579         xcodeptr = NULL;
4580         
4581         for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
4582                 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4583                         gen_resolvebranch(cd->mcodebase + bref->branchpos, 
4584                                                           bref->branchpos,
4585                                                           xcodeptr - cd->mcodebase - (5 + 5 + 2));
4586                         continue;
4587                 }
4588
4589                 gen_resolvebranch(cd->mcodebase + bref->branchpos, 
4590                                   bref->branchpos,
4591                                                   cd->mcodeptr - cd->mcodebase);
4592
4593                 MCODECHECK(100);
4594
4595                 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
4596                 dseg_adddata(cd, cd->mcodeptr);
4597                 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
4598                 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
4599
4600                 if (xcodeptr != NULL) {
4601                         i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4602                 
4603                 } else {
4604                         xcodeptr = cd->mcodeptr;
4605
4606                         i386_push_reg(cd, REG_ITMP2_XPC);
4607
4608                         /*PREPARE_NATIVE_STACKINFO;*/
4609                         i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4610                         i386_push_imm(cd,0);
4611                         i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4612                         i386_call_reg(cd,REG_ITMP3);
4613
4614
4615                         i386_mov_imm_reg(cd, (u4) new_classcastexception, REG_ITMP1);
4616                         i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
4617                         /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
4618
4619
4620                         /*REMOVE_NATIVE_STACKINFO;*/
4621                         i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4622                         i386_call_reg(cd,REG_ITMP3);
4623
4624
4625                         i386_pop_reg(cd, REG_ITMP2_XPC);
4626
4627                         i386_mov_imm_reg(cd, (u4) asm_handle_exception, REG_ITMP3);
4628                         i386_jmp_reg(cd, REG_ITMP3);
4629                 }
4630         }
4631
4632         /* generate divide by zero check stubs */
4633
4634         xcodeptr = NULL;
4635         
4636         for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
4637                 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4638                         gen_resolvebranch(cd->mcodebase + bref->branchpos, 
4639                                                           bref->branchpos,
4640                                                           xcodeptr - cd->mcodebase - (5 + 5 + 2));
4641                         continue;
4642                 }
4643
4644                 gen_resolvebranch(cd->mcodebase + bref->branchpos, 
4645                                   bref->branchpos,
4646                                                   cd->mcodeptr - cd->mcodebase);
4647
4648                 MCODECHECK(100);
4649
4650                 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
4651                 dseg_adddata(cd, cd->mcodeptr);
4652                 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
4653                 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
4654
4655                 if (xcodeptr != NULL) {
4656                         i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4657                 
4658                 } else {
4659                         xcodeptr = cd->mcodeptr;
4660
4661                         i386_push_reg(cd, REG_ITMP2_XPC);
4662
4663                         /*PREPARE_NATIVE_STACKINFO;*/
4664                         i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4665                         i386_push_imm(cd,0);
4666                         i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4667                         i386_call_reg(cd,REG_ITMP3);
4668
4669
4670
4671                         i386_mov_imm_reg(cd, (u4) new_arithmeticexception, REG_ITMP1);
4672                         i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
4673
4674                         /*REMOVE_NATIVE_STACKINFO;*/
4675                         i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4676                         i386_call_reg(cd,REG_ITMP3);
4677
4678
4679                         i386_pop_reg(cd, REG_ITMP2_XPC);
4680
4681                         i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4682                         i386_jmp_reg(cd, REG_ITMP3);
4683                 }
4684         }
4685
4686         /* generate exception check stubs */
4687
4688         xcodeptr = NULL;
4689         
4690         for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4691                 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4692                         gen_resolvebranch(cd->mcodebase + bref->branchpos,
4693                                                           bref->branchpos,
4694                                                           xcodeptr - cd->mcodebase - (5 + 5 + 2));
4695                         continue;
4696                 }
4697
4698                 gen_resolvebranch(cd->mcodebase + bref->branchpos, 
4699                                   bref->branchpos,
4700                                                   cd->mcodeptr - cd->mcodebase);
4701
4702                 MCODECHECK(200);
4703
4704                 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
4705                 dseg_adddata(cd, cd->mcodeptr);
4706                 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
4707                 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
4708
4709                 if (xcodeptr != NULL) {
4710                         i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4711                 
4712                 } else {
4713                         xcodeptr = cd->mcodeptr;
4714
4715                         i386_push_reg(cd, REG_ITMP2_XPC);
4716
4717                         /*PREPARE_NATIVE_STACKINFO;*/
4718                         i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4719                         i386_push_imm(cd,0);
4720                         i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4721                         i386_call_reg(cd,REG_ITMP3);
4722
4723 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4724                         i386_mov_imm_reg(cd, (s4) &builtin_get_exceptionptrptr, REG_ITMP1);
4725                         i386_call_reg(cd, REG_ITMP1);
4726                         i386_mov_membase_reg(cd, REG_RESULT, 0, REG_ITMP3);
4727                         i386_mov_imm_membase(cd, 0, REG_RESULT, 0);
4728                         i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1_XPTR);
4729 #else
4730                         i386_mov_imm_reg(cd, (s4) &_exceptionptr, REG_ITMP3);
4731                         i386_mov_membase_reg(cd, REG_ITMP3, 0, REG_ITMP1_XPTR);
4732                         i386_mov_imm_membase(cd, 0, REG_ITMP3, 0);
4733 #endif
4734                         i386_push_imm(cd, 0);
4735                         i386_push_reg(cd, REG_ITMP1_XPTR);
4736
4737 /*get the fillInStackTrace Method ID. I simulate a native call here, because I do not want to mess around with the
4738 java stack at this point*/
4739                         i386_mov_membase_reg(cd, REG_ITMP1_XPTR, OFFSET(java_objectheader, vftbl), REG_ITMP3);
4740                         i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, class), REG_ITMP1);
4741                         i386_push_imm(cd, (u4) utf_void__java_lang_Throwable);
4742                         i386_push_imm(cd, (u4) utf_fillInStackTrace);
4743                         i386_push_reg(cd, REG_ITMP1);
4744                         i386_mov_imm_reg(cd, (s4) class_resolvemethod, REG_ITMP3);
4745                         i386_call_reg(cd, REG_ITMP3);
4746 /*cleanup parameters of class_resolvemethod*/
4747                         i386_alu_imm_reg(cd, I386_ADD,3*4 /*class reference + 2x string reference*/,REG_SP);
4748 /*prepare call to asm_calljavafunction2 */                      
4749                         i386_push_imm(cd, 0);
4750                         i386_push_imm(cd, TYPE_ADR); /* --> call block (TYPE,Exceptionptr), each 8 byte  (make this dynamic) (JOWENN)*/
4751                         i386_push_reg(cd, REG_SP);
4752                         i386_push_imm(cd, sizeof(jni_callblock));
4753                         i386_push_imm(cd, 1);
4754                         i386_push_reg(cd, REG_RESULT);
4755                         
4756                         i386_mov_imm_reg(cd, (s4) asm_calljavafunction2, REG_ITMP3);
4757                         i386_call_reg(cd, REG_ITMP3);
4758
4759                         /* check exceptionptr + fail (JOWENN)*/                 
4760
4761                         i386_alu_imm_reg(cd, I386_ADD,6*4,REG_SP);
4762
4763                         i386_pop_reg(cd, REG_ITMP1_XPTR);
4764                         i386_pop_reg(cd, REG_ITMP3); /* just remove the no longer needed 0 from the stack*/
4765
4766                         /*REMOVE_NATIVE_STACKINFO;*/
4767                         i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4768                         i386_call_reg(cd,REG_ITMP3);
4769
4770
4771                         i386_pop_reg(cd, REG_ITMP2_XPC);
4772
4773                         i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4774                         i386_jmp_reg(cd, REG_ITMP3);
4775                 }
4776         }
4777
4778         /* generate null pointer check stubs */
4779
4780         xcodeptr = NULL;
4781         
4782         for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
4783                 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4784                         gen_resolvebranch(cd->mcodebase + bref->branchpos, 
4785                                                           bref->branchpos,
4786                                                           xcodeptr - cd->mcodebase - (5 + 5 + 2));
4787                         continue;
4788                 }
4789
4790                 gen_resolvebranch(cd->mcodebase + bref->branchpos, 
4791                                                   bref->branchpos,
4792                                                   cd->mcodeptr - cd->mcodebase);
4793                 
4794                 MCODECHECK(100);
4795
4796                 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC);                    /* 5 bytes */
4797                 dseg_adddata(cd, cd->mcodeptr);
4798                 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1);      /* 5 bytes */
4799                 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC);  /* 2 bytes */
4800                 
4801                 if (xcodeptr != NULL) {
4802                         i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4803                         
4804                 } else {
4805                         xcodeptr = cd->mcodeptr;
4806                         
4807                         i386_push_reg(cd, REG_ITMP2_XPC);
4808
4809                         /*PREPARE_NATIVE_STACKINFO;*/
4810                         i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4811                         i386_push_imm(cd,0);
4812                         i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4813                         i386_call_reg(cd,REG_ITMP3);
4814
4815
4816
4817 #if 0
4818                         /* create native call block*/
4819                         i386_alu_imm_reg(cd, I386_SUB, 3*4, REG_SP); /* build stack frame (4 * 4 bytes) */
4820
4821
4822                         i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1);
4823                         i386_call_reg(cd, REG_ITMP1);                /*call    codegen_stubcalled*/
4824
4825                         i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1);
4826                         i386_call_reg(cd, REG_ITMP1);                /*call    builtin_asm_get_stackframeinfo*/
4827                         i386_mov_imm_membase(cd, 0,REG_SP, 2*4);        /* builtin */
4828                         i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer  to native call stack*/
4829                         i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */
4830                         i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */
4831                         i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */
4832 #endif                          
4833
4834                         i386_mov_imm_reg(cd, (u4) new_nullpointerexception, REG_ITMP1);
4835                         i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
4836
4837                         /*REMOVE_NATIVE_STACKINFO;*/
4838                         i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4839                         i386_call_reg(cd,REG_ITMP3);
4840
4841
4842 #if 0
4843                         /* restore native call stack */
4844                         i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2);
4845                         i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3);
4846                         i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0);
4847                         i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
4848 #endif
4849
4850                         i386_pop_reg(cd, REG_ITMP2_XPC);
4851
4852                         i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4853                         i386_jmp_reg(cd, REG_ITMP3);
4854                 }
4855         }
4856
4857         /* generate put/getstatic stub call code */
4858
4859         {
4860                 clinitref   *cref;
4861                 codegendata *tmpcd;
4862                 u1           xmcode;
4863                 u4           mcode;
4864
4865                 tmpcd = DNEW(codegendata);
4866
4867                 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
4868                         /* Get machine code which is patched back in later. A             */
4869                         /* `call rel32' is 5 bytes long.                                  */
4870                         xcodeptr = cd->mcodebase + cref->branchpos;
4871                         xmcode = *xcodeptr;
4872                         mcode = *((u4 *) (xcodeptr + 1));
4873
4874                         MCODECHECK(50);
4875
4876                         /* patch in `call rel32' to call the following code               */
4877                         tmpcd->mcodeptr = xcodeptr;     /* set dummy mcode pointer        */
4878                         i386_call_imm(tmpcd, cd->mcodeptr - (xcodeptr + 5));
4879
4880                         /* Save current stack pointer into a temporary register.          */
4881                         i386_mov_reg_reg(cd, REG_SP, REG_ITMP1);
4882
4883                         /* Push machine code bytes to patch onto the stack.               */
4884                         i386_push_imm(cd, (u4) xmcode);
4885                         i386_push_imm(cd, (u4) mcode);
4886
4887                         i386_push_imm(cd, (u4) cref->class);
4888
4889                         /* Push previously saved stack pointer onto stack.                */
4890                         i386_push_reg(cd, REG_ITMP1);
4891
4892                         i386_mov_imm_reg(cd, (u4) asm_check_clinit, REG_ITMP1);
4893                         i386_jmp_reg(cd, REG_ITMP1);
4894                 }
4895         }
4896         }
4897         
4898         codegen_finish(m, cd, (u4) (cd->mcodeptr - cd->mcodebase));
4899 }
4900
4901
4902 /* function createcompilerstub *************************************************
4903
4904    creates a stub routine which calls the compiler
4905         
4906 *******************************************************************************/
4907
4908 #define COMPSTUBSIZE 12
4909
4910 u1 *createcompilerstub(methodinfo *m)
4911 {
4912     u1 *s = CNEW(u1, COMPSTUBSIZE);     /* memory to hold the stub            */
4913         codegendata *cd;
4914         s4 dumpsize;
4915
4916         /* mark start of dump memory area */
4917
4918         dumpsize = dump_size();
4919         
4920         cd = DNEW(codegendata);
4921     cd->mcodeptr = s;
4922
4923     /* code for the stub */
4924     i386_mov_imm_reg(cd, (u4) m, REG_ITMP1);/* pass method pointer to compiler*/
4925
4926         /* we use REG_ITMP3 cause ECX (REG_ITMP2) is used for patching  */
4927     i386_mov_imm_reg(cd, (u4) asm_call_jit_compiler, REG_ITMP3);
4928     i386_jmp_reg(cd, REG_ITMP3);        /* jump to compiler                   */
4929
4930 #if defined(STATISTICS)
4931         if (opt_stat)
4932                 count_cstub_len += COMPSTUBSIZE;
4933 #endif
4934
4935         /* release dump area */
4936
4937         dump_release(dumpsize);
4938         
4939     return s;
4940 }
4941
4942
4943 /* function removecompilerstub *************************************************
4944
4945      deletes a compilerstub from memory  (simply by freeing it)
4946
4947 *******************************************************************************/
4948
4949 void removecompilerstub(u1 *stub) 
4950 {
4951     CFREE(stub, COMPSTUBSIZE);
4952 }
4953
4954
4955 /* function: createnativestub **************************************************
4956
4957         creates a stub routine which calls a native method
4958
4959 *******************************************************************************/
4960
4961 #define NATIVESTUB_SIZE         450        /* keep this size high enough!     */
4962 #define NATIVESTUB_OFFSET       0
4963 #define NATIVESTUB_DATA_SIZE    9 * 4
4964
4965 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4966 static java_objectheader **(*callgetexceptionptrptr)() = builtin_get_exceptionptrptr;
4967 #endif
4968
4969 #if 0
4970 void i386_native_stub_debug(void **p) {
4971         printf("Pos on stack: %p\n",p);
4972         printf("Return adress should be: %p\n",*p);
4973 }
4974
4975 void i386_native_stub_debug2(void **p) {
4976         printf("Pos on stack: %p\n",p);
4977         printf("Return for lookup is: %p\n",*p);
4978 }
4979
4980 void traverseStackInfo() {
4981         void **p=builtin_asm_get_stackframeinfo();
4982         
4983         while ((*p)!=0) {
4984                 methodinfo *m;
4985                 printf("base addr:%p, methodinfo:%p\n",*p,(methodinfo*)((*p)+8));
4986                 m=*((methodinfo**)((*p)+8));
4987                 utf_display(m->name);
4988                 printf("\n");
4989                 p=*p;
4990         }
4991 }
4992 #endif
4993
4994 u1 *createnativestub(functionptr f, methodinfo *m)
4995 {
4996         u1                 *s;              /* pointer to stub memory             */
4997         u4                 *cs;
4998         s4                  stubsize;
4999         codegendata        *cd;
5000         registerdata       *rd;
5001         t_inlining_globals *id;
5002         s4                  dumpsize;
5003         s4                  i;
5004         u1                 *tptr;
5005         s4                  stackframesize;
5006         s4                  stackframeoffset;
5007         bool                require_clinit_call;
5008
5009         s4                 *callAddrPatchPos;
5010         u1                 *jmpInstrPos;
5011         s4                 *jmpInstrPatchPos;
5012
5013         /* initial 4 bytes is space for jni env, + 4 byte thread pointer + 4 byte */
5014         /* previous pointer + method info + 4 offset native                       */
5015         stackframesize = 4 + 16;
5016         stackframeoffset = 4;
5017
5018         /* mark start of dump memory area */
5019
5020         dumpsize = dump_size();
5021
5022         /* allocate required dump memory */
5023
5024         cd = DNEW(codegendata);
5025         rd = DNEW(registerdata);
5026         id = DNEW(t_inlining_globals);
5027
5028         /* setup registers before using it */
5029
5030         inlining_setup(m, id);
5031         reg_setup(m, rd, id);
5032
5033         method_descriptor2types(m);                /* set paramcount and paramtypes      */
5034
5035         require_clinit_call = (m->flags & ACC_STATIC) && !m->class->initialized;
5036
5037         stubsize = NATIVESTUB_SIZE;         /* calculate nativestub size          */
5038
5039         if (require_clinit_call)
5040                 stubsize += NATIVESTUB_DATA_SIZE;
5041
5042 /*      if ((m->flags & ACC_STATIC) && !m->class->initialized) */
5043 /*              stubsize += NATIVESTUB_STATIC_SIZE; */
5044
5045         s = CNEW(u1, stubsize);             /* memory to hold the stub            */
5046
5047         if (require_clinit_call) {
5048                 /* build a dummy data segment *****************************************/
5049
5050                 cs = (u4 *) (s + NATIVESTUB_DATA_SIZE);
5051
5052                 *(cs - 9) = 0;                  /* extable size                       */
5053                 *(cs - 8) = 0;                  /* line number table start            */
5054                 *(cs - 7) = 0;                  /* line number table size             */
5055                 *(cs - 6) = 0;                  /* fltsave                            */
5056                 *(cs - 5) = 0;                  /* intsave                            */
5057                 *(cs - 4) = 0;                  /* isleaf                             */
5058                 *(cs - 3) = 0;                  /* issync                             */
5059                 *(cs - 2) = 0;                  /* frame size                         */
5060                 *(cs - 1) = (u4) m;             /* method pointer                     */
5061
5062         } else {
5063                 cs = (u4 *) s;
5064         }
5065
5066         /* set some required varibles which are normally set by codegen_setup */
5067         cd->mcodebase = (u1 *) cs;
5068         cd->mcodeptr = (u1 *) cs;
5069         cd->clinitrefs = NULL;
5070
5071         /* if function is static, check for initialized */
5072
5073         if (m->flags & ACC_STATIC) {
5074                 stackframesize += 4;
5075                 stackframeoffset += 4;
5076
5077                 /* if class isn't yet initialized, do it */
5078                 if (!m->class->initialized)
5079                         codegen_addclinitref(cd, cd->mcodeptr, m->class);
5080         }
5081
5082         if (runverbose) {
5083                 s4 p, t;
5084
5085                 i386_alu_imm_reg(cd, I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
5086     
5087                 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
5088                         t = m->paramtypes[p];
5089                         if (IS_INT_LNG_TYPE(t)) {
5090                                 if (IS_2_WORD_TYPE(t)) {
5091                                         i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
5092                                         i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
5093                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
5094                                         i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, p * 8 + 4);
5095
5096                                 } else if (t == TYPE_ADR) {
5097                                         i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
5098                                         i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2);
5099                                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
5100                                         i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, p * 8 + 4);
5101
5102                                 } else {
5103                                         i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, EAX);
5104                                         i386_cltd(cd);
5105                                         i386_mov_reg_membase(cd, EAX, REG_SP, p * 8);
5106                                         i386_mov_reg_membase(cd, EDX, REG_SP, p * 8 + 4);
5107                                 }
5108
5109                         } else {
5110                                 if (!IS_2_WORD_TYPE(t)) {
5111                                         i386_flds_membase(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
5112                                         i386_fstps_membase(cd, REG_SP, p * 8);
5113                                         i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2);
5114                                         i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, p * 8 + 4);
5115
5116                                 } else {
5117                                         i386_fldl_membase(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
5118                                         i386_fstpl_membase(cd, REG_SP, p * 8);
5119                                 }
5120                         }
5121                 }
5122         
5123                 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
5124                 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
5125                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
5126                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
5127                 }
5128
5129                 i386_mov_imm_membase(cd, (u4) m, REG_SP, TRACE_ARGS_NUM * 8);
5130
5131                 i386_mov_imm_reg(cd, (u4) builtin_trace_args, REG_ITMP1);
5132                 i386_call_reg(cd, REG_ITMP1);
5133
5134                 i386_alu_imm_reg(cd, I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
5135         }
5136
5137         /* Mark the whole fpu stack as free for native functions (only for saved  */
5138         /* register count == 0).                                                  */
5139         i386_ffree_reg(cd, 0);
5140         i386_ffree_reg(cd, 1);
5141         i386_ffree_reg(cd, 2);
5142         i386_ffree_reg(cd, 3);
5143         i386_ffree_reg(cd, 4);
5144         i386_ffree_reg(cd, 5);
5145         i386_ffree_reg(cd, 6);
5146         i386_ffree_reg(cd, 7);
5147
5148         /* calculate stackframe size for native function */
5149         tptr = m->paramtypes;
5150         for (i = 0; i < m->paramcount; i++) {
5151                 stackframesize += IS_2_WORD_TYPE(*tptr++) ? 8 : 4;
5152         }
5153
5154         i386_alu_imm_reg(cd, I386_SUB, stackframesize, REG_SP);
5155
5156 /* CREATE DYNAMIC STACK INFO -- BEGIN*/
5157         i386_mov_imm_membase(cd,0,REG_SP,stackframesize-4);
5158         i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-8);
5159         i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo, REG_ITMP1);
5160         i386_call_reg(cd, REG_ITMP1);
5161         i386_mov_reg_membase(cd, REG_RESULT,REG_SP,stackframesize-12); /*save thread specific pointer*/
5162         i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); 
5163         i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,stackframesize-16); /*save previous value of memory adress pointed to by thread specific pointer*/
5164         i386_mov_reg_reg(cd, REG_SP,REG_ITMP2);
5165         i386_alu_imm_reg(cd, I386_ADD,stackframesize-16,REG_ITMP2);
5166         i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT,0);
5167
5168 /*TESTING ONLY */
5169 /*   i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-4);
5170    i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-8);
5171    i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-12);*/
5172
5173 /* CREATE DYNAMIC STACK INFO -- END*/
5174
5175 /* RESOLVE NATIVE METHOD -- BEGIN*/
5176 #if !defined(STATIC_CLASSPATH)
5177         if (f == NULL) {
5178                 /*log_text("Dynamic classpath: preparing for delayed native function resolving");*/
5179                 i386_jmp_imm(cd, 0);
5180                 jmpInstrPos = cd->mcodeptr - 4;
5181
5182                 /* patch position */
5183                 i386_mov_imm_reg(cd, (s4) jmpInstrPos, REG_ITMP1);
5184                 i386_push_reg(cd, REG_ITMP1);
5185
5186                 /* jmp offset */
5187                 i386_mov_imm_reg(cd, 0, REG_ITMP1);
5188                 jmpInstrPatchPos = (s4 *) (cd->mcodeptr - 4);
5189                 i386_push_reg(cd, REG_ITMP1);
5190
5191                 /* position of call address to patch */
5192                 i386_mov_imm_reg(cd, 0, REG_ITMP1);
5193                 callAddrPatchPos = (s4 *) (cd->mcodeptr - 4);
5194                 i386_push_reg(cd, REG_ITMP1);
5195
5196                 /* method info structure */
5197                 i386_mov_imm_reg(cd, (s4) m, REG_ITMP1);
5198                 i386_push_reg(cd, REG_ITMP1);
5199
5200                 /* call resolve functions */
5201                 i386_mov_imm_reg(cd, (s4) codegen_resolve_native, REG_ITMP1);
5202                 i386_call_reg(cd, REG_ITMP1);
5203
5204                 /* cleanup */
5205                 i386_alu_imm_reg(cd, I386_ADD, 4 * 4, REG_SP);
5206
5207                 /* fix jmp offset replacement */
5208                 *jmpInstrPatchPos = cd->mcodeptr - jmpInstrPos - 4;
5209         } /*else log_text("Dynamic classpath: immediate native function resolution possible");*/
5210 #endif
5211 /* RESOLVE NATIVE METHOD -- END*/
5212
5213         /* copy arguments into new stackframe */
5214
5215         tptr = m->paramtypes;
5216         for (i = 0; i < m->paramcount; i++) {
5217                 if (IS_2_WORD_TYPE(*tptr++)) {
5218                         i386_mov_membase_reg(cd, REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5219                         i386_mov_membase_reg(cd, REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
5220                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, stackframeoffset);
5221                         i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, stackframeoffset + 4);
5222                         stackframeoffset += 8;
5223
5224                 } else {
5225                         i386_mov_membase_reg(cd, REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5226                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, stackframeoffset);
5227                         stackframeoffset += 4;
5228                 }
5229         }
5230
5231         /* if function is static, put class into second argument */
5232
5233         if (m->flags & ACC_STATIC) {
5234                 i386_mov_imm_membase(cd, (u4) m->class, REG_SP, 4);
5235         }
5236
5237         /* put env into first argument */
5238
5239         i386_mov_imm_membase(cd, (u4) &env, REG_SP, 0);
5240
5241         /* call the native function */
5242
5243         i386_mov_imm_reg(cd, (u4) f, REG_ITMP1);
5244 #if !defined(STATIC_CLASSPATH)
5245         if (f == NULL)
5246                 *callAddrPatchPos = (u4) cd->mcodeptr - 4;
5247 #endif
5248         i386_call_reg(cd, REG_ITMP1);
5249
5250 /*REMOVE DYNAMIC STACK INFO -BEGIN */
5251     i386_push_reg(cd, REG_RESULT2);
5252     i386_mov_membase_reg(cd, REG_SP,stackframesize-12,REG_ITMP2); /*old value*/
5253     i386_mov_membase_reg(cd, REG_SP,stackframesize-8,REG_RESULT2); /*pointer*/
5254     i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT2,0);
5255     i386_pop_reg(cd, REG_RESULT2);
5256 /*REMOVE DYNAMIC STACK INFO -END */
5257
5258     i386_alu_imm_reg(cd, I386_ADD, stackframesize, REG_SP);
5259
5260
5261     if (runverbose) {
5262         i386_alu_imm_reg(cd, I386_SUB, 4 + 8 + 8 + 4, REG_SP);
5263                 
5264         i386_mov_imm_membase(cd, (u4) m, REG_SP, 0);
5265                 
5266         i386_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
5267         i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
5268                 
5269         i386_fstl_membase(cd, REG_SP, 4 + 8);
5270         i386_fsts_membase(cd, REG_SP, 4 + 8 + 8);
5271
5272         i386_mov_imm_reg(cd, (u4) builtin_displaymethodstop, REG_ITMP1);
5273         i386_call_reg(cd, REG_ITMP1);
5274                 
5275         i386_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
5276         i386_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
5277                 
5278         i386_alu_imm_reg(cd, I386_ADD, 4 + 8 + 8 + 4, REG_SP);
5279     }
5280
5281         /* we can't use REG_ITMP3 == REG_RESULT2 */
5282 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5283         i386_push_reg(cd, REG_RESULT);
5284         i386_push_reg(cd, REG_RESULT2);
5285         i386_call_mem(cd, (u4) &callgetexceptionptrptr);
5286         i386_mov_membase_reg(cd, REG_RESULT, 0, REG_ITMP2);
5287         i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
5288         i386_pop_reg(cd, REG_RESULT2);
5289         i386_pop_reg(cd, REG_RESULT);
5290 #else
5291         i386_mov_imm_reg(cd, (u4) &_exceptionptr, REG_ITMP2);
5292         i386_mov_membase_reg(cd, REG_ITMP2, 0, REG_ITMP2);
5293         i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
5294 #endif
5295         i386_jcc(cd, I386_CC_NE, 1);
5296
5297         i386_ret(cd);
5298
5299 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5300         i386_push_reg(cd, REG_ITMP2);
5301         i386_call_mem(cd, (u4) &callgetexceptionptrptr);
5302         i386_mov_imm_membase(cd, 0, REG_RESULT, 0);
5303         i386_pop_reg(cd, REG_ITMP1_XPTR);
5304 #else
5305         i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1_XPTR);
5306         i386_mov_imm_reg(cd, (u4) &_exceptionptr, REG_ITMP2);
5307         i386_mov_imm_membase(cd, 0, REG_ITMP2, 0);
5308 #endif
5309         i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP2_XPC);
5310         i386_alu_imm_reg(cd, I386_SUB, 2, REG_ITMP2_XPC);
5311
5312         i386_mov_imm_reg(cd, (u4) asm_handle_nat_exception, REG_ITMP3);
5313         i386_jmp_reg(cd, REG_ITMP3);
5314
5315         /* patch in a clinit call if required *************************************/
5316
5317         if (require_clinit_call) {
5318                 u1          *xcodeptr;
5319                 clinitref   *cref;
5320                 codegendata *tmpcd;
5321                 u1           xmcode;
5322                 u4           mcode;
5323
5324                 tmpcd = DNEW(codegendata);
5325
5326                 /* there can only be one clinit ref entry                             */
5327                 cref = cd->clinitrefs;
5328
5329                 if (cref) {
5330                         /* Get machine code which is patched back in later. A             */
5331                         /* `call rel32' is 5 bytes long.                                  */
5332                         xcodeptr = cd->mcodebase + cref->branchpos;
5333                         xmcode = *xcodeptr;
5334                         mcode =  *((u4 *) (xcodeptr + 1));
5335
5336                         /* patch in `call rel32' to call the following code               */
5337                         tmpcd->mcodeptr = xcodeptr;     /* set dummy mcode pointer        */
5338                         i386_call_imm(tmpcd, cd->mcodeptr - (xcodeptr + 5));
5339
5340                         /* Save current stack pointer into a temporary register.          */
5341                         i386_mov_reg_reg(cd, REG_SP, REG_ITMP1);
5342
5343                         /* Push machine code bytes to patch onto the stack.               */
5344                         i386_push_imm(cd, (u4) xmcode);
5345                         i386_push_imm(cd, (u4) mcode);
5346
5347                         i386_push_imm(cd, (u4) cref->class);
5348
5349                         /* Push previously saved stack pointer onto stack.                */
5350                         i386_push_reg(cd, REG_ITMP1);
5351
5352                         i386_mov_imm_reg(cd, (u4) asm_check_clinit, REG_ITMP1);
5353                         i386_jmp_reg(cd, REG_ITMP1);
5354                 }
5355
5356                 /* insert the native stub into the method table */
5357
5358                 codegen_insertmethod((functionptr) cs, (functionptr) cd->mcodeptr);
5359         }
5360
5361         /* Check if the stub size is big enough to hold the whole stub generated. */
5362         /* If not, this can lead into unpredictable crashes, because of heap      */
5363         /* corruption.                                                            */
5364         if ((s4) (cd->mcodeptr - s) > stubsize) {
5365                 throw_cacao_exception_exit(string_java_lang_InternalError,
5366                                                                    "Native stub size %d is to small for current stub size %d",
5367                                                                    stubsize, (s4) (cd->mcodeptr - s));
5368         }
5369
5370 #if defined(STATISTICS)
5371         if (opt_stat)
5372                 count_nstub_len += stubsize;
5373 #endif
5374
5375         /* release dump area */
5376
5377         dump_release(dumpsize);
5378
5379         return (u1 *) cs;
5380 }
5381
5382
5383 /* function: removenativestub **************************************************
5384
5385     removes a previously created native-stub from memory
5386     
5387 *******************************************************************************/
5388
5389 void removenativestub(u1 *stub)
5390 {
5391     CFREE(stub, NATIVESTUB_SIZE);
5392 }
5393
5394
5395 /*
5396  * These are local overrides for various environment variables in Emacs.
5397  * Please do not remove this and leave it at the end of the file, where
5398  * Emacs will automagically detect them.
5399  * ---------------------------------------------------------------------
5400  * Local variables:
5401  * mode: c
5402  * indent-tabs-mode: t
5403  * c-basic-offset: 4
5404  * tab-width: 4
5405  * End:
5406  */