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