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