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