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