merge from gnuclasspath branch. I hope I didn't miss or revert any modifications...
[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 665 2003-11-21 18:36:43Z jowenn $
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                                         sprintf(logtext, "Unkown ICMD-Command: %d", iptr->opc);
4092                                         error();
4093                                 }
4094
4095                         /* d contains return type */
4096
4097                         if (d != TYPE_VOID) {
4098                                 d = reg_of_var(iptr->dst, REG_NULL);
4099
4100                                 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4101                                         if (IS_2_WORD_TYPE(iptr->dst->type)) {
4102                                                 if (iptr->dst->flags & INMEMORY) {
4103                                                         i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4104                                                         i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4105
4106                                                 } else {
4107                                                         panic("RETURN: longs have to be in memory");
4108                                                 }
4109
4110                                         } else {
4111                                                 if (iptr->dst->flags & INMEMORY) {
4112                                                         i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4113
4114                                                 } else {
4115                                                         M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4116                                                 }
4117                                         }
4118
4119                                 } else {
4120                                         /* fld from called function -- has other fpu_st_offset counter */
4121                                         fpu_st_offset++;
4122                                         store_reg_to_var_flt(iptr->dst, d);
4123                                 }
4124                         }
4125                         }
4126                         break;
4127
4128
4129                 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
4130
4131                                       /* op1:   0 == array, 1 == class                */
4132                                       /* val.a: (classinfo*) superclass               */
4133
4134 /*          superclass is an interface:
4135  *
4136  *          return (sub != NULL) &&
4137  *                 (sub->vftbl->interfacetablelength > super->index) &&
4138  *                 (sub->vftbl->interfacetable[-super->index] != NULL);
4139  *
4140  *          superclass is a class:
4141  *
4142  *          return ((sub != NULL) && (0
4143  *                  <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4144  *                  super->vftbl->diffvall));
4145  */
4146
4147                         {
4148                         classinfo *super = (classinfo*) iptr->val.a;
4149                         
4150                         var_to_reg_int(s1, src, REG_ITMP1);
4151                         d = reg_of_var(iptr->dst, REG_ITMP3);
4152                         if (s1 == d) {
4153                                 M_INTMOVE(s1, REG_ITMP1);
4154                                 s1 = REG_ITMP1;
4155                         }
4156                         i386_alu_reg_reg(I386_XOR, d, d);
4157                         if (iptr->op1) {                               /* class/interface */
4158                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
4159                                         i386_test_reg_reg(s1, s1);
4160
4161                                         /* TODO: clean up this calculation */
4162                                         a = 2;
4163                                         CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4164
4165                                         a += 2;
4166                                         CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetablelength));
4167                                         
4168                                         a += 2;
4169                                         CALCOFFSETBYTES(a, super->index);
4170                                         
4171                                         a += 3;
4172                                         a += 6;
4173
4174                                         a += 2;
4175                                         CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4176
4177                                         a += 3;
4178
4179                                         a += 6;    /* jcc */
4180                                         a += 5;
4181
4182                                         i386_jcc(I386_CC_E, a);
4183
4184                                         i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4185                                         i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4186                                         i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4187                                         /* TODO: test */
4188                                         i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4189
4190                                         /* TODO: clean up this calculation */
4191                                         a = 0;
4192                                         a += 2;
4193                                         CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4194
4195                                         a += 3;
4196
4197                                         a += 6;    /* jcc */
4198                                         a += 5;
4199
4200                                         i386_jcc(I386_CC_LE, a);
4201                                         i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4202                                         /* TODO: test */
4203                                         i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4204 /*                                      i386_setcc_reg(I386_CC_A, d); */
4205 /*                                      i386_jcc(I386_CC_BE, 5); */
4206                                         i386_jcc(I386_CC_E, 5);
4207                                         i386_mov_imm_reg(1, d);
4208                                         
4209
4210                                 } else {                                   /* class           */
4211                                         i386_test_reg_reg(s1, s1);
4212
4213                                         /* TODO: clean up this calculation */
4214                                         a = 2;
4215                                         CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4216                                         a += 5;
4217                                         a += 2;
4218                                         CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4219                                         a += 2;
4220                                         CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4221                                         
4222                                         a += 2;
4223                                         CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4224                                         
4225                                         a += 2;
4226                                         a += 2;    /* xor */
4227
4228                                         a += 2;
4229
4230                                         a += 6;    /* jcc */
4231                                         a += 5;
4232
4233                                         i386_jcc(I386_CC_E, a);
4234
4235                                         i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4236                                         i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4237                                         i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4238                                         i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4239                                         i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4240                                         i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4241                                         i386_alu_reg_reg(I386_XOR, d, d);
4242                                         i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4243                                         i386_jcc(I386_CC_A, 5);
4244                                         i386_mov_imm_reg(1, d);
4245                                 }
4246                         }
4247                         else
4248                                 panic ("internal error: no inlined array instanceof");
4249                         }
4250                         store_reg_to_var_int(iptr->dst, d);
4251                         break;
4252
4253                 case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
4254
4255                                       /* op1:   0 == array, 1 == class                */
4256                                       /* val.a: (classinfo*) superclass               */
4257
4258 /*          superclass is an interface:
4259  *
4260  *          OK if ((sub == NULL) ||
4261  *                 (sub->vftbl->interfacetablelength > super->index) &&
4262  *                 (sub->vftbl->interfacetable[-super->index] != NULL));
4263  *
4264  *          superclass is a class:
4265  *
4266  *          OK if ((sub == NULL) || (0
4267  *                 <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4268  *                 super->vftbl->diffvall));
4269  */
4270
4271                         {
4272                         classinfo *super = (classinfo*) iptr->val.a;
4273                         
4274                         d = reg_of_var(iptr->dst, REG_ITMP3);
4275                         var_to_reg_int(s1, src, d);
4276                         if (iptr->op1) {                               /* class/interface */
4277                                 if (super->flags & ACC_INTERFACE) {        /* interface       */
4278                                         i386_test_reg_reg(s1, s1);
4279
4280                                         /* TODO: clean up this calculation */
4281                                         a = 2;
4282                                         CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4283
4284                                         a += 2;
4285                                         CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetablelength));
4286
4287                                         a += 2;
4288                                         CALCOFFSETBYTES(a, super->index);
4289
4290                                         a += 3;
4291                                         a += 6;
4292
4293                                         a += 2;
4294                                         CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4295
4296                                         a += 3;
4297                                         a += 6;
4298
4299                                         i386_jcc(I386_CC_E, a);
4300
4301                                         i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4302                                         i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4303                                         i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4304                                         /* TODO: test */
4305                                         i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4306                                         i386_jcc(I386_CC_LE, 0);
4307                                         codegen_addxcastrefs(mcodeptr);
4308                                         i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4309                                         /* TODO: test */
4310                                         i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4311                                         i386_jcc(I386_CC_E, 0);
4312                                         codegen_addxcastrefs(mcodeptr);
4313
4314                                 } else {                                     /* class           */
4315                                         i386_test_reg_reg(s1, s1);
4316
4317                                         /* TODO: clean up this calculation */
4318                                         a = 2;
4319                                         CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4320
4321                                         a += 5;
4322
4323                                         a += 2;
4324                                         CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4325
4326                                         if (d != REG_ITMP3) {
4327                                                 a += 2;
4328                                                 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4329                                                 
4330                                                 a += 2;
4331                                                 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4332
4333                                                 a += 2;
4334                                                 
4335                                         } else {
4336                                                 a += 2;
4337                                                 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4338
4339                                                 a += 2;
4340
4341                                                 a += 5;
4342
4343                                                 a += 2;
4344                                                 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4345                                         }
4346
4347                                         a += 2;
4348
4349                                         a += 6;
4350
4351                                         i386_jcc(I386_CC_E, a);
4352
4353                                         i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4354                                         i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4355                                         i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4356                                         if (d != REG_ITMP3) {
4357                                                 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4358                                                 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4359                                                 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4360
4361                                         } else {
4362                                                 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
4363                                                 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
4364                                                 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4365                                                 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4366                                         }
4367                                         i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4368                                         i386_jcc(I386_CC_A, 0);    /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4369                                         codegen_addxcastrefs(mcodeptr);
4370                                 }
4371
4372                         } else
4373                                 panic ("internal error: no inlined array checkcast");
4374                         }
4375                         M_INTMOVE(s1, d);
4376                         store_reg_to_var_int(iptr->dst, d);
4377                         break;
4378
4379                 case ICMD_CHECKASIZE:  /* ..., size ==> ..., size                     */
4380
4381                         if (src->flags & INMEMORY) {
4382                                 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4383                                 
4384                         } else {
4385                                 i386_test_reg_reg(src->regoff, src->regoff);
4386                         }
4387                         i386_jcc(I386_CC_L, 0);
4388                         codegen_addxcheckarefs(mcodeptr);
4389                         break;
4390
4391                 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
4392                                       /* op1 = dimension, val.a = array descriptor    */
4393
4394                         /* check for negative sizes and copy sizes to stack if necessary  */
4395
4396                         MCODECHECK((iptr->op1 << 1) + 64);
4397
4398                         for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4399                                 if (src->flags & INMEMORY) {
4400                                         i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4401
4402                                 } else {
4403                                         i386_test_reg_reg(src->regoff, src->regoff);
4404                                 }
4405                                 i386_jcc(I386_CC_L, 0);
4406                                 codegen_addxcheckarefs(mcodeptr);
4407
4408                                 /* 
4409                                  * copy sizes to new stack location, be cause native function
4410                                  * builtin_nmultianewarray access them as (int *)
4411                                  */
4412                                 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4413                                 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4414
4415                                 /* copy sizes to stack (argument numbers >= INT_ARG_CNT)      */
4416
4417                                 if (src->varkind != ARGVAR) {
4418                                         if (src->flags & INMEMORY) {
4419                                                 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
4420                                                 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
4421
4422                                         } else {
4423                                                 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
4424                                         }
4425                                 }
4426                         }
4427                         i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
4428
4429                         /* a0 = dimension count */
4430
4431                         /* save stack pointer */
4432                         M_INTMOVE(REG_SP, REG_ITMP1);
4433
4434                         i386_alu_imm_reg(I386_SUB, 12, REG_SP);
4435                         i386_mov_imm_membase(iptr->op1, REG_SP, 0);
4436
4437                         /* a1 = arraydescriptor */
4438
4439                         i386_mov_imm_membase((s4) iptr->val.a, REG_SP, 4);
4440
4441                         /* a2 = pointer to dimensions = stack pointer */
4442
4443                         i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
4444
4445                         i386_mov_imm_reg((s4) (builtin_nmultianewarray), REG_ITMP1);
4446                         i386_call_reg(REG_ITMP1);
4447                         i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4448
4449                         s1 = reg_of_var(iptr->dst, REG_RESULT);
4450                         M_INTMOVE(REG_RESULT, s1);
4451                         store_reg_to_var_int(iptr->dst, s1);
4452                         break;
4453
4454
4455                 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
4456                          error();
4457         
4458    
4459
4460         } /* switch */
4461                 
4462         } /* for instruction */
4463                 
4464         /* copy values to interface registers */
4465
4466         src = bptr->outstack;
4467         len = bptr->outdepth;
4468         MCODECHECK(64+len);
4469         while (src) {
4470                 len--;
4471                 if ((src->varkind != STACKVAR)) {
4472                         s2 = src->type;
4473                         if (IS_FLT_DBL_TYPE(s2)) {
4474                                 var_to_reg_flt(s1, src, REG_FTMP1);
4475                                 if (!(interfaces[len][s2].flags & INMEMORY)) {
4476                                         M_FLTMOVE(s1,interfaces[len][s2].regoff);
4477
4478                                 } else {
4479                                         panic("double store");
4480 /*                                      M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4481                                 }
4482
4483                         } else {
4484                                 var_to_reg_int(s1, src, REG_ITMP1);
4485                                 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
4486                                         if (!(interfaces[len][s2].flags & INMEMORY)) {
4487                                                 M_INTMOVE(s1, interfaces[len][s2].regoff);
4488
4489                                         } else {
4490                                                 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
4491                                         }
4492
4493                                 } else {
4494                                         if (interfaces[len][s2].flags & INMEMORY) {
4495                                                 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
4496
4497                                         } else {
4498                                                 panic("copy interface registers: longs have to be in memory (end)");
4499                                         }
4500                                 }
4501                         }
4502                 }
4503                 src = src->prev;
4504         }
4505         } /* if (bptr -> flags >= BBREACHED) */
4506         } /* for basic block */
4507
4508         /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
4509
4510         {
4511
4512         /* generate bound check stubs */
4513         u1 *xcodeptr = NULL;
4514         
4515         for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
4516                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4517                         gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
4518                                 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4519                         continue;
4520                         }
4521
4522
4523                 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
4524                                   xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
4525
4526                 MCODECHECK(8);
4527
4528                 i386_mov_imm_reg(0, REG_ITMP2_XPC);    /* 5 bytes */
4529                 dseg_adddata(mcodeptr);
4530                 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP1);    /* 5 bytes */
4531                 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC);    /* 2 bytes */
4532
4533                 if (xcodeptr != NULL) {
4534                         i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4535
4536                 } else {
4537                         xcodeptr = mcodeptr;
4538
4539                         i386_mov_imm_reg((s4) proto_java_lang_ArrayIndexOutOfBoundsException, REG_ITMP1_XPTR);
4540                         i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4541                         i386_jmp_reg(I386_EDI);
4542                 }
4543         }
4544
4545         /* generate negative array size check stubs */
4546         xcodeptr = NULL;
4547         
4548         for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
4549                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4550                         gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
4551                                 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4552                         continue;
4553                         }
4554
4555                 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos, 
4556                                   xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
4557
4558                 MCODECHECK(8);
4559
4560                 i386_mov_imm_reg(0, REG_ITMP2_XPC);    /* 5 bytes */
4561                 dseg_adddata(mcodeptr);
4562                 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1);    /* 5 bytes */
4563                 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC);    /* 2 bytes */
4564
4565                 if (xcodeptr != NULL) {
4566                         i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4567
4568                 } else {
4569                         xcodeptr = mcodeptr;
4570
4571                         i386_mov_imm_reg((s4) proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR);
4572                         i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4573                         i386_jmp_reg(I386_EDI);
4574                 }
4575         }
4576
4577         /* generate cast check stubs */
4578         xcodeptr = NULL;
4579         
4580         for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
4581                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4582                         gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos, 
4583                                 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4584                         continue;
4585                 }
4586
4587                 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos, 
4588                                   xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
4589
4590                 MCODECHECK(8);
4591
4592                 i386_mov_imm_reg(0, REG_ITMP2_XPC);    /* 5 bytes */
4593                 dseg_adddata(mcodeptr);
4594                 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1);    /* 5 bytes */
4595                 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC);    /* 2 bytes */
4596
4597                 if (xcodeptr != NULL) {
4598                         i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4599                 
4600                 } else {
4601                         xcodeptr = mcodeptr;
4602
4603                         i386_mov_imm_reg((s4) proto_java_lang_ClassCastException, REG_ITMP1_XPTR);
4604                         i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4605                         i386_jmp_reg(I386_EDI);
4606                 }
4607         }
4608
4609         /* generate divide by zero check stubs */
4610         xcodeptr = NULL;
4611         
4612         for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
4613                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4614                         gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos, 
4615                                 xdivrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4616                         continue;
4617                 }
4618
4619                 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos, 
4620                                   xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
4621
4622                 MCODECHECK(8);
4623
4624                 i386_mov_imm_reg(0, REG_ITMP2_XPC);    /* 5 bytes */
4625                 dseg_adddata(mcodeptr);
4626                 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1);    /* 5 bytes */
4627                 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC);    /* 2 bytes */
4628
4629                 if (xcodeptr != NULL) {
4630                         i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4631                 
4632                 } else {
4633                         xcodeptr = mcodeptr;
4634
4635                         i386_mov_imm_reg((s4) proto_java_lang_ArithmeticException, REG_ITMP1_XPTR);
4636                         i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4637                         i386_jmp_reg(I386_EDI);
4638                 }
4639         }
4640
4641         /* generate null pointer check stubs */
4642         xcodeptr = NULL;
4643         
4644         for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
4645                 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4646                         gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
4647                                                           xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4648                         continue;
4649                 }
4650
4651                 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos, 
4652                                                   xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
4653                 
4654                 MCODECHECK(8);
4655
4656                 i386_mov_imm_reg(0, REG_ITMP2_XPC);    /* 5 bytes */
4657                 dseg_adddata(mcodeptr);
4658                 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1);    /* 5 bytes */
4659                 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC);    /* 2 bytes */
4660                 
4661                 if (xcodeptr != NULL) {
4662                         i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4663                         
4664                 } else {
4665                         xcodeptr = mcodeptr;
4666                         
4667                         i386_mov_imm_reg((s4) proto_java_lang_NullPointerException, REG_ITMP1_XPTR);
4668                         i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4669                         i386_jmp_reg(I386_EDI);
4670                 }
4671         }
4672         }
4673
4674         codegen_finish((int)((u1*) mcodeptr - mcodebase));
4675 }
4676
4677
4678 /* function createcompilerstub *************************************************
4679
4680    creates a stub routine which calls the compiler
4681         
4682 *******************************************************************************/
4683
4684 #define COMPSTUBSIZE 12
4685
4686 u1 *createcompilerstub(methodinfo *m)
4687 {
4688     u1 *s = CNEW(u1, COMPSTUBSIZE);     /* memory to hold the stub            */
4689     mcodeptr = s;                       /* code generation pointer            */
4690
4691     /* code for the stub */
4692     i386_mov_imm_reg((s4) m, REG_ITMP1);/* pass method pointer to compiler    */
4693
4694         /* we use EDI cause EDX (REG_ITMP2) is used for patching */
4695     i386_mov_imm_reg((s4) asm_call_jit_compiler, I386_EDI);   /* load address */
4696     i386_jmp_reg(I386_EDI);             /* jump to compiler                   */
4697
4698 #ifdef STATISTICS
4699     count_cstub_len += COMPSTUBSIZE;
4700 #endif
4701
4702     return (u1*) s;
4703 }
4704
4705
4706 /* function removecompilerstub *************************************************
4707
4708      deletes a compilerstub from memory  (simply by freeing it)
4709
4710 *******************************************************************************/
4711
4712 void removecompilerstub(u1 *stub) 
4713 {
4714     CFREE(stub, COMPSTUBSIZE);
4715 }
4716
4717 /* function: createnativestub **************************************************
4718
4719         creates a stub routine which calls a native method
4720
4721 *******************************************************************************/
4722
4723 #define NATIVESTUBSIZE 320
4724
4725 u1 *createnativestub(functionptr f, methodinfo *m)
4726 {
4727     u1 *s = CNEW(u1, NATIVESTUBSIZE);   /* memory to hold the stub            */
4728
4729     u1 *tptr;
4730     int i;
4731     int stackframesize = 4;           /* initial 4 bytes is space for jni env */
4732     int stackframeoffset = 4;
4733
4734     int p, t;
4735
4736     mcodeptr = s;                       /* make macros work                   */
4737
4738          if (m->flags & ACC_STATIC) {
4739                  stackframesize += 4;
4740                  stackframeoffset += 4;
4741          }
4742
4743
4744     reg_init(m);
4745     
4746     descriptor2types(m);                     /* set paramcount and paramtypes */
4747
4748     if (runverbose) {
4749         i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4750         
4751         for (p = 0; p < m->paramcount; p++) {
4752             t = m->paramtypes[p];
4753             if (IS_INT_LNG_TYPE(t)) {
4754                 if (IS_2_WORD_TYPE(t)) {
4755                     i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4756                     i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
4757
4758                 } else if (t == TYPE_ADR) {
4759                     i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4760                     i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4761
4762                 } else {
4763                     i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4764                     i386_cltd();
4765                 }
4766                 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4767                 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4768
4769             } else {
4770                 if (t == TYPE_FLT) {
4771                     i386_flds_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4772                     i386_fstps_membase(REG_SP, p * 8);
4773                     i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4774                     i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4775
4776                 } else {
4777                     i386_fldl_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4778                     i386_fstpl_membase(REG_SP, p * 8);
4779                 }
4780             }
4781         }
4782
4783                 
4784         i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
4785         for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
4786             i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4787             i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
4788         }
4789
4790         i386_mov_imm_membase((s4) m, REG_SP, TRACE_ARGS_NUM * 8);
4791
4792         i386_mov_imm_reg((s4) asm_builtin_trace, REG_ITMP1);
4793         i386_call_reg(REG_ITMP1);
4794
4795         i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4796     }
4797
4798     /*
4799          * mark the whole fpu stack as free for native functions
4800          * (only for saved register count == 0)
4801          */
4802     i386_ffree_reg(0);
4803     i386_ffree_reg(1);
4804     i386_ffree_reg(2);
4805     i386_ffree_reg(3);
4806     i386_ffree_reg(4);
4807     i386_ffree_reg(5);
4808     i386_ffree_reg(6);
4809     i386_ffree_reg(7);
4810
4811         /*
4812          * calculate stackframe size for native function
4813          */
4814     tptr = m->paramtypes;
4815     for (i = 0; i < m->paramcount; i++) {
4816         switch (*tptr++) {
4817         case TYPE_INT:
4818         case TYPE_FLT:
4819         case TYPE_ADR:
4820             stackframesize += 4;
4821             break;
4822
4823         case TYPE_LNG:
4824         case TYPE_DBL:
4825             stackframesize += 8;
4826             break;
4827
4828         default:
4829             panic("unknown parameter type in native function");
4830         }
4831     }
4832
4833     i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
4834
4835     tptr = m->paramtypes;
4836     for (i = 0; i < m->paramcount; i++) {
4837         switch (*tptr++) {
4838         case TYPE_INT:
4839         case TYPE_FLT:
4840         case TYPE_ADR:
4841             i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4842             i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4843             stackframeoffset += 4;
4844             break;
4845
4846         case TYPE_LNG:
4847         case TYPE_DBL:
4848             i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4849             i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
4850             i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4851             i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
4852             stackframeoffset += 8;
4853             break;
4854
4855         default:
4856             panic("unknown parameter type in native function");
4857         }
4858     }
4859
4860     i386_mov_imm_membase((s4) &env, REG_SP, 0);
4861     if (m->flags & ACC_STATIC) 
4862         i386_mov_imm_membase((s4) m->class, REG_SP,4);
4863
4864     i386_mov_imm_reg((s4) f, REG_ITMP1);
4865     i386_call_reg(REG_ITMP1);
4866     i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
4867
4868     if (runverbose) {
4869         i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
4870                 
4871         i386_mov_imm_membase((s4) m, REG_SP, 0);
4872                 
4873         i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
4874         i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
4875                 
4876         i386_fstl_membase(REG_SP, 4 + 8);
4877         i386_fsts_membase(REG_SP, 4 + 8 + 8);
4878                 
4879         i386_mov_imm_reg((s4) asm_builtin_exittrace, REG_ITMP1);
4880         i386_call_reg(REG_ITMP1);
4881                 
4882         i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
4883         i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
4884                 
4885         i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
4886     }
4887
4888         /* we can use EDI cause it's not preserved across function calls */
4889         i386_mov_imm_reg((s4) &exceptionptr, I386_EDI);
4890         i386_mov_membase_reg(I386_EDI, 0, I386_EDI);
4891         i386_test_reg_reg(I386_EDI, I386_EDI);
4892         i386_jcc(I386_CC_NE, 1);
4893
4894         i386_ret();
4895
4896         i386_mov_reg_reg(I386_EDI, REG_ITMP1_XPTR);
4897         i386_mov_imm_reg((s4) &exceptionptr, I386_EDI);
4898         i386_mov_imm_membase(0, I386_EDI, 0);
4899         i386_mov_membase_reg(REG_SP, 0, REG_ITMP2_XPC);
4900         i386_alu_imm_reg(I386_SUB, 2, REG_ITMP2_XPC);
4901
4902         i386_mov_imm_reg((s4) asm_handle_nat_exception, I386_EDI);
4903         i386_jmp_reg(I386_EDI);
4904
4905 #ifdef STATISTICS
4906         count_nstub_len += NATIVESTUBSIZE;
4907 #endif
4908
4909         return (u1*) s;
4910 }
4911
4912 /* function: removenativestub **************************************************
4913
4914     removes a previously created native-stub from memory
4915     
4916 *******************************************************************************/
4917
4918 void removenativestub(u1 *stub)
4919 {
4920     CFREE(stub, NATIVESTUBSIZE);
4921 }
4922
4923
4924
4925 void i386_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
4926 {
4927         if (iptr->dst->flags & INMEMORY) {
4928                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4929                         if (src->regoff == iptr->dst->regoff) {
4930                                 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4931                                 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4932
4933                         } else if (src->prev->regoff == iptr->dst->regoff) {
4934                                 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4935                                 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4936
4937                         } else {
4938                                 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4939                                 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
4940                                 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4941                         }
4942
4943                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4944                         if (src->regoff == iptr->dst->regoff) {
4945                                 i386_alu_reg_membase(alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4946
4947                         } else {
4948                                 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4949                                 i386_alu_reg_reg(alu_op, src->prev->regoff, 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->prev->regoff == iptr->dst->regoff) {
4955                                 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4956                                                 
4957                         } else {
4958                                 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4959                                 i386_alu_reg_reg(alu_op, src->regoff, REG_ITMP1);
4960                                 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4961                         }
4962
4963                 } else {
4964                         i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4965                         i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4966                 }
4967
4968         } else {
4969                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4970                         i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4971                         i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4972
4973                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4974                         M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4975                         i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4976
4977                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4978                         M_INTMOVE(src->regoff, iptr->dst->regoff);
4979                         i386_alu_membase_reg(alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4980
4981                 } else {
4982                         if (src->regoff == iptr->dst->regoff) {
4983                                 i386_alu_reg_reg(alu_op, src->prev->regoff, iptr->dst->regoff);
4984
4985                         } else {
4986                                 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4987                                 i386_alu_reg_reg(alu_op, src->regoff, iptr->dst->regoff);
4988                         }
4989                 }
4990         }
4991 }
4992
4993
4994
4995 void i386_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
4996 {
4997         if (iptr->dst->flags & INMEMORY) {
4998                 if (src->flags & INMEMORY) {
4999                         if (src->regoff == iptr->dst->regoff) {
5000                                 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5001
5002                         } else {
5003                                 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5004                                 i386_alu_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
5005                                 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5006                         }
5007
5008                 } else {
5009                         i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5010                         i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5011                 }
5012
5013         } else {
5014                 if (src->flags & INMEMORY) {
5015                         i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5016                         i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5017
5018                 } else {
5019                         M_INTMOVE(src->regoff, iptr->dst->regoff);
5020                         i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5021                 }
5022         }
5023 }
5024
5025
5026
5027 void i386_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
5028 {
5029         if (iptr->dst->flags & INMEMORY) {
5030                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5031                         if (src->regoff == iptr->dst->regoff) {
5032                                 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5033                                 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
5034                                 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5035                                 i386_alu_reg_membase(alu_op, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5036
5037                         } else if (src->prev->regoff == iptr->dst->regoff) {
5038                                 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5039                                 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5040                                 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5041                                 i386_alu_reg_membase(alu_op, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5042
5043                         } else {
5044                                 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5045                                 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
5046                                 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5047                                 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5048                                 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5049                                 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5050                         }
5051                 }
5052         }
5053 }
5054
5055
5056
5057 void i386_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
5058 {
5059         if (iptr->dst->flags & INMEMORY) {
5060                 if (src->flags & INMEMORY) {
5061                         if (src->regoff == iptr->dst->regoff) {
5062                                 i386_alu_imm_membase(alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
5063                                 i386_alu_imm_membase(alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
5064
5065                         } else {
5066                                 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5067                                 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5068                                 i386_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
5069                                 i386_alu_imm_reg(alu_op, iptr->val.l >> 32, REG_ITMP2);
5070                                 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5071                                 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5072                         }
5073                 }
5074         }
5075 }
5076
5077
5078
5079 void i386_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
5080 {
5081         if (iptr->dst->flags & INMEMORY) {
5082                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5083                         if (src->prev->regoff == iptr->dst->regoff) {
5084                                 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5085                                 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5086
5087                         } else {
5088                                 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5089                                 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5090                                 i386_shift_reg(shift_op, REG_ITMP1);
5091                                 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5092                         }
5093
5094                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5095                         i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5096                         i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5097                         i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5098
5099                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5100                         if (src->prev->regoff == iptr->dst->regoff) {
5101                                 M_INTMOVE(src->regoff, I386_ECX);
5102                                 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5103
5104                         } else {
5105                                 M_INTMOVE(src->regoff, I386_ECX);
5106                                 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5107                                 i386_shift_reg(shift_op, REG_ITMP1);
5108                                 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5109                         }
5110
5111                 } else {
5112                         M_INTMOVE(src->regoff, I386_ECX);
5113                         i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5114                         i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5115                 }
5116
5117         } else {
5118                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5119                         i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5120                         i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5121                         i386_shift_reg(shift_op, iptr->dst->regoff);
5122
5123                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5124                         i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5125                         M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5126                         i386_shift_reg(shift_op, iptr->dst->regoff);
5127
5128                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5129                         M_INTMOVE(src->regoff, 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 {
5134                         M_INTMOVE(src->regoff, I386_ECX);
5135                         M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5136                         i386_shift_reg(shift_op, iptr->dst->regoff);
5137                 }
5138         }
5139 }
5140
5141
5142
5143 void i386_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
5144 {
5145         if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5146                 if (src->regoff == iptr->dst->regoff) {
5147                         i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5148
5149                 } else {
5150                         i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5151                         i386_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
5152                         i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5153                 }
5154
5155         } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
5156                 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5157                 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5158                                 
5159         } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5160                 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5161                 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5162
5163         } else {
5164                 M_INTMOVE(src->regoff, iptr->dst->regoff);
5165                 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5166         }
5167 }
5168
5169
5170
5171 void i386_emit_ifcc_iconst(s4 if_op, stackptr src, instruction *iptr)
5172 {
5173         if (iptr->dst->flags & INMEMORY) {
5174                 int offset = 0;
5175
5176                 if (src->flags & INMEMORY) {
5177                         i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5178
5179                 } else {
5180                         i386_test_reg_reg(src->regoff, src->regoff);
5181                 }
5182
5183                 offset += 7;
5184                 CALCOFFSETBYTES(offset, iptr->dst->regoff * 8);
5185         
5186                 i386_jcc(if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
5187                 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5188
5189                 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5190                         i386_jmp_imm(offset);
5191                         i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
5192                 }
5193
5194         } else {
5195                 if (src->flags & INMEMORY) {
5196                         i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5197
5198                 } else {
5199                         i386_test_reg_reg(src->regoff, src->regoff);
5200                 }
5201
5202                 i386_jcc(if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
5203                 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
5204
5205                 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5206                         i386_jmp_imm(5);
5207                         i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
5208                 }
5209         }
5210 }
5211
5212
5213
5214 /*
5215  * mov ops
5216  */
5217 void i386_mov_reg_reg(s4 reg, s4 dreg) {
5218         *(mcodeptr++) = (u1) 0x89;
5219         i386_emit_reg((reg),(dreg));
5220 }
5221
5222
5223 void i386_mov_imm_reg(s4 imm, s4 reg) {
5224         *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07);
5225         i386_emit_imm32((imm));
5226 }
5227
5228
5229 void i386_movb_imm_reg(s4 imm, s4 reg) {
5230         *(mcodeptr++) = (u1) 0xc6;
5231         i386_emit_reg(0,(reg));
5232         i386_emit_imm8((imm));
5233 }
5234
5235
5236 void i386_mov_membase_reg(s4 basereg, s4 disp, s4 reg) {
5237         *(mcodeptr++) = (u1) 0x8b;
5238         i386_emit_membase((basereg),(disp),(reg));
5239 }
5240
5241
5242 /*
5243  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
5244  * constant membase immediate length of 32bit
5245  */
5246 void i386_mov_membase32_reg(s4 basereg, s4 disp, s4 reg) {
5247         *(mcodeptr++) = (u1) 0x8b;
5248         i386_address_byte(2, (reg), (basereg));
5249         i386_emit_imm32((disp));
5250 }
5251
5252
5253 void i386_mov_reg_membase(s4 reg, s4 basereg, s4 disp) {
5254         *(mcodeptr++) = (u1) 0x89;
5255         i386_emit_membase((basereg),(disp),(reg));
5256 }
5257
5258
5259 void i386_mov_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5260         *(mcodeptr++) = (u1) 0x8b;
5261         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5262 }
5263
5264
5265 void i386_mov_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5266         *(mcodeptr++) = (u1) 0x89;
5267         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5268 }
5269
5270
5271 void i386_movw_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5272         *(mcodeptr++) = (u1) 0x66;
5273         *(mcodeptr++) = (u1) 0x89;
5274         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5275 }
5276
5277
5278 void i386_movb_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5279         *(mcodeptr++) = (u1) 0x88;
5280         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5281 }
5282
5283
5284 void i386_mov_imm_membase(s4 imm, s4 basereg, s4 disp) {
5285         *(mcodeptr++) = (u1) 0xc7;
5286         i386_emit_membase((basereg),(disp),0);
5287         i386_emit_imm32((imm));
5288 }
5289
5290
5291 void i386_movsbl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5292         *(mcodeptr++) = (u1) 0x0f;
5293         *(mcodeptr++) = (u1) 0xbe;
5294         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5295 }
5296
5297
5298 void i386_movswl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5299         *(mcodeptr++) = (u1) 0x0f;
5300         *(mcodeptr++) = (u1) 0xbf;
5301         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5302 }
5303
5304
5305 void i386_movzwl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5306         *(mcodeptr++) = (u1) 0x0f;
5307         *(mcodeptr++) = (u1) 0xb7;
5308         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5309 }
5310
5311
5312
5313 /*
5314  * alu operations
5315  */
5316 void i386_alu_reg_reg(s4 opc, s4 reg, s4 dreg) {
5317         *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5318         i386_emit_reg((reg),(dreg));
5319 }
5320
5321
5322 void i386_alu_reg_membase(s4 opc, s4 reg, s4 basereg, s4 disp) {
5323         *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5324         i386_emit_membase((basereg),(disp),(reg));
5325 }
5326
5327
5328 void i386_alu_membase_reg(s4 opc, s4 basereg, s4 disp, s4 reg) {
5329         *(mcodeptr++) = (((u1) (opc)) << 3) + 3;
5330         i386_emit_membase((basereg),(disp),(reg));
5331 }
5332
5333
5334 void i386_alu_imm_reg(s4 opc, s4 imm, s4 dreg) {
5335         if (i386_is_imm8(imm)) { 
5336                 *(mcodeptr++) = (u1) 0x83;
5337                 i386_emit_reg((opc),(dreg));
5338                 i386_emit_imm8((imm));
5339         } else { 
5340                 *(mcodeptr++) = (u1) 0x81;
5341                 i386_emit_reg((opc),(dreg));
5342                 i386_emit_imm32((imm));
5343         } 
5344 }
5345
5346
5347 void i386_alu_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5348         if (i386_is_imm8(imm)) { 
5349                 *(mcodeptr++) = (u1) 0x83;
5350                 i386_emit_membase((basereg),(disp),(opc));
5351                 i386_emit_imm8((imm));
5352         } else { 
5353                 *(mcodeptr++) = (u1) 0x81;
5354                 i386_emit_membase((basereg),(disp),(opc));
5355                 i386_emit_imm32((imm));
5356         } 
5357 }
5358
5359
5360 void i386_test_reg_reg(s4 reg, s4 dreg) {
5361         *(mcodeptr++) = (u1) 0x85;
5362         i386_emit_reg((reg),(dreg));
5363 }
5364
5365
5366 void i386_test_imm_reg(s4 imm, s4 reg) {
5367         *(mcodeptr++) = (u1) 0xf7;
5368         i386_emit_reg(0,(reg));
5369         i386_emit_imm32((imm));
5370 }
5371
5372
5373
5374 /*
5375  * inc, dec operations
5376  */
5377 void i386_inc_reg(s4 reg) {
5378         *(mcodeptr++) = (u1) 0x40 + ((reg) & 0x07);
5379 }
5380
5381
5382 void i386_inc_membase(s4 basereg, s4 disp) {
5383         *(mcodeptr++) = (u1) 0xff;
5384         i386_emit_membase((basereg),(disp),0);
5385 }
5386
5387
5388 void i386_dec_reg(s4 reg) {
5389         *(mcodeptr++) = (u1) 0x48 + ((reg) & 0x07);
5390 }
5391
5392                 
5393 void i386_dec_membase(s4 basereg, s4 disp) {
5394         *(mcodeptr++) = (u1) 0xff;
5395         i386_emit_membase((basereg),(disp),1);
5396 }
5397
5398
5399
5400 void i386_cltd() {
5401         *(mcodeptr++) = (u1) 0x99;
5402 }
5403
5404
5405
5406 void i386_imul_reg_reg(s4 reg, s4 dreg) {
5407         *(mcodeptr++) = (u1) 0x0f;
5408         *(mcodeptr++) = (u1) 0xaf;
5409         i386_emit_reg((dreg),(reg));
5410 }
5411
5412
5413 void i386_imul_membase_reg(s4 basereg, s4 disp, s4 dreg) {
5414         *(mcodeptr++) = (u1) 0x0f;
5415         *(mcodeptr++) = (u1) 0xaf;
5416         i386_emit_membase((basereg),(disp),(dreg));
5417 }
5418
5419
5420 void i386_imul_imm_reg(s4 imm, s4 dreg) {
5421         if (i386_is_imm8((imm))) { 
5422                 *(mcodeptr++) = (u1) 0x6b;
5423                 i386_emit_reg(0,(dreg));
5424                 i386_emit_imm8((imm));
5425         } else { 
5426                 *(mcodeptr++) = (u1) 0x69;
5427                 i386_emit_reg(0,(dreg));
5428                 i386_emit_imm32((imm));
5429         } 
5430 }
5431
5432
5433 void i386_imul_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5434         if (i386_is_imm8((imm))) { 
5435                 *(mcodeptr++) = (u1) 0x6b;
5436                 i386_emit_reg((dreg),(reg));
5437                 i386_emit_imm8((imm));
5438         } else { 
5439                 *(mcodeptr++) = (u1) 0x69;
5440                 i386_emit_reg((dreg),(reg));
5441                 i386_emit_imm32((imm));
5442         } 
5443 }
5444
5445
5446 void i386_imul_imm_membase_reg(s4 imm, s4 basereg, s4 disp, s4 dreg) {
5447         if (i386_is_imm8((imm))) { 
5448                 *(mcodeptr++) = (u1) 0x6b;
5449                 i386_emit_membase((basereg),(disp),(dreg));
5450                 i386_emit_imm8((imm));
5451         } else { 
5452                 *(mcodeptr++) = (u1) 0x69;
5453                 i386_emit_membase((basereg),(disp),(dreg));
5454                 i386_emit_imm32((imm));
5455         } 
5456 }
5457
5458
5459 void i386_mul_membase(s4 basereg, s4 disp) {
5460         *(mcodeptr++) = (u1) 0xf7;
5461         i386_emit_membase((basereg),(disp),4);
5462 }
5463
5464
5465 void i386_idiv_reg(s4 reg) {
5466         *(mcodeptr++) = (u1) 0xf7;
5467         i386_emit_reg(7,(reg));
5468 }
5469
5470
5471
5472 void i386_ret() {
5473         *(mcodeptr++) = (u1) 0xc3;
5474 }
5475
5476
5477
5478 /*
5479  * shift ops
5480  */
5481 void i386_shift_reg(s4 opc, s4 reg) {
5482         *(mcodeptr++) = (u1) 0xd3;
5483         i386_emit_reg((opc),(reg));
5484 }
5485
5486
5487 void i386_shift_membase(s4 opc, s4 basereg, s4 disp) {
5488         *(mcodeptr++) = (u1) 0xd3;
5489         i386_emit_membase((basereg),(disp),(opc));
5490 }
5491
5492
5493 void i386_shift_imm_reg(s4 opc, s4 imm, s4 dreg) {
5494         if ((imm) == 1) { 
5495                 *(mcodeptr++) = (u1) 0xd1;
5496                 i386_emit_reg((opc),(dreg));
5497         } else { 
5498                 *(mcodeptr++) = (u1) 0xc1;
5499                 i386_emit_reg((opc),(dreg));
5500                 i386_emit_imm8((imm));
5501         } 
5502 }
5503
5504
5505 void i386_shift_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5506         if ((imm) == 1) { 
5507                 *(mcodeptr++) = (u1) 0xd1;
5508                 i386_emit_membase((basereg),(disp),(opc));
5509         } else { 
5510                 *(mcodeptr++) = (u1) 0xc1;
5511                 i386_emit_membase((basereg),(disp),(opc));
5512                 i386_emit_imm8((imm));
5513         } 
5514 }
5515
5516
5517 void i386_shld_reg_reg(s4 reg, s4 dreg) {
5518         *(mcodeptr++) = (u1) 0x0f;
5519         *(mcodeptr++) = (u1) 0xa5;
5520         i386_emit_reg((reg),(dreg));
5521 }
5522
5523
5524 void i386_shld_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5525         *(mcodeptr++) = (u1) 0x0f;
5526         *(mcodeptr++) = (u1) 0xa4;
5527         i386_emit_reg((reg),(dreg));
5528         i386_emit_imm8((imm));
5529 }
5530
5531
5532 void i386_shld_reg_membase(s4 reg, s4 basereg, s4 disp) {
5533         *(mcodeptr++) = (u1) 0x0f;
5534         *(mcodeptr++) = (u1) 0xa5;
5535         i386_emit_membase((basereg),(disp),(reg));
5536 }
5537
5538
5539 void i386_shrd_reg_reg(s4 reg, s4 dreg) {
5540         *(mcodeptr++) = (u1) 0x0f;
5541         *(mcodeptr++) = (u1) 0xad;
5542         i386_emit_reg((reg),(dreg));
5543 }
5544
5545
5546 void i386_shrd_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5547         *(mcodeptr++) = (u1) 0x0f;
5548         *(mcodeptr++) = (u1) 0xac;
5549         i386_emit_reg((reg),(dreg));
5550         i386_emit_imm8((imm));
5551 }
5552
5553
5554 void i386_shrd_reg_membase(s4 reg, s4 basereg, s4 disp) {
5555         *(mcodeptr++) = (u1) 0x0f;
5556         *(mcodeptr++) = (u1) 0xad;
5557         i386_emit_membase((basereg),(disp),(reg));
5558 }
5559
5560
5561
5562 /*
5563  * jump operations
5564  */
5565 void i386_jmp_imm(s4 imm) {
5566         *(mcodeptr++) = (u1) 0xe9;
5567         i386_emit_imm32((imm));
5568 }
5569
5570
5571 void i386_jmp_reg(s4 reg) {
5572         *(mcodeptr++) = (u1) 0xff;
5573         i386_emit_reg(4,(reg));
5574 }
5575
5576
5577 void i386_jcc(s4 opc, s4 imm) {
5578         *(mcodeptr++) = (u1) 0x0f;
5579         *(mcodeptr++) = (u1) (0x80 + (opc));
5580         i386_emit_imm32((imm));
5581 }
5582
5583
5584
5585 /*
5586  * conditional set operations
5587  */
5588 void i386_setcc_reg(s4 opc, s4 reg) {
5589         *(mcodeptr++) = (u1) 0x0f;
5590         *(mcodeptr++) = (u1) (0x90 + (opc));
5591         i386_emit_reg(0,(reg));
5592 }
5593
5594
5595 void i386_setcc_membase(s4 opc, s4 basereg, s4 disp) {
5596         *(mcodeptr++) = (u1) 0x0f;
5597         *(mcodeptr++) = (u1) (0x90 + (opc));
5598         i386_emit_membase((basereg),(disp),0);
5599 }
5600
5601
5602
5603 void i386_neg_reg(s4 reg) {
5604         *(mcodeptr++) = (u1) 0xf7;
5605         i386_emit_reg(3,(reg));
5606 }
5607
5608
5609 void i386_neg_membase(s4 basereg, s4 disp) {
5610         *(mcodeptr++) = (u1) 0xf7;
5611         i386_emit_membase((basereg),(disp),3);
5612 }
5613
5614
5615
5616 void i386_push_imm(s4 imm) {
5617         *(mcodeptr++) = (u1) 0x68;
5618         i386_emit_imm32((imm));
5619 }
5620
5621
5622 void i386_pop_reg(s4 reg) {
5623         *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
5624 }
5625
5626
5627 void i386_nop() {
5628         *(mcodeptr++) = (u1) 0x90;
5629 }
5630
5631
5632 /*
5633  * call instructions
5634  */
5635 void i386_call_reg(s4 reg) {
5636         *(mcodeptr++) = (u1) 0xff;
5637         i386_emit_reg(2,(reg));
5638 }
5639
5640
5641 void i386_call_imm(s4 imm) {
5642         *(mcodeptr++) = (u1) 0xe8;
5643         i386_emit_imm32((imm));
5644 }
5645
5646
5647
5648 /*
5649  * floating point instructions
5650  */
5651 void i386_fld1() {
5652         *(mcodeptr++) = (u1) 0xd9;
5653         *(mcodeptr++) = (u1) 0xe8;
5654 }
5655
5656
5657 void i386_fldz() {
5658         *(mcodeptr++) = (u1) 0xd9;
5659         *(mcodeptr++) = (u1) 0xee;
5660 }
5661
5662
5663 void i386_fld_reg(s4 reg) {
5664         *(mcodeptr++) = (u1) 0xd9;
5665         *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5666 }
5667
5668
5669 void i386_flds_membase(s4 basereg, s4 disp) {
5670         *(mcodeptr++) = (u1) 0xd9;
5671         i386_emit_membase((basereg),(disp),0);
5672 }
5673
5674
5675 void i386_fldl_membase(s4 basereg, s4 disp) {
5676         *(mcodeptr++) = (u1) 0xdd;
5677         i386_emit_membase((basereg),(disp),0);
5678 }
5679
5680
5681 void i386_fldt_membase(s4 basereg, s4 disp) {
5682         *(mcodeptr++) = (u1) 0xdb;
5683         i386_emit_membase((basereg),(disp),5);
5684 }
5685
5686
5687 void i386_flds_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5688         *(mcodeptr++) = (u1) 0xd9;
5689         i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5690 }
5691
5692
5693 void i386_fldl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5694         *(mcodeptr++) = (u1) 0xdd;
5695         i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5696 }
5697
5698
5699
5700
5701 void i386_fildl_membase(s4 basereg, s4 disp) {
5702         *(mcodeptr++) = (u1) 0xdb;
5703         i386_emit_membase((basereg),(disp),0);
5704 }
5705
5706
5707 void i386_fildll_membase(s4 basereg, s4 disp) {
5708         *(mcodeptr++) = (u1) 0xdf;
5709         i386_emit_membase((basereg),(disp),5);
5710 }
5711
5712
5713
5714
5715 void i386_fst_reg(s4 reg) {
5716         *(mcodeptr++) = (u1) 0xdd;
5717         *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg));
5718 }
5719
5720
5721 void i386_fsts_membase(s4 basereg, s4 disp) {
5722         *(mcodeptr++) = (u1) 0xd9;
5723         i386_emit_membase((basereg),(disp),2);
5724 }
5725
5726
5727 void i386_fstl_membase(s4 basereg, s4 disp) {
5728         *(mcodeptr++) = (u1) 0xdd;
5729         i386_emit_membase((basereg),(disp),2);
5730 }
5731
5732
5733 void i386_fsts_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5734         *(mcodeptr++) = (u1) 0xd9;
5735         i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5736 }
5737
5738
5739 void i386_fstl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5740         *(mcodeptr++) = (u1) 0xdd;
5741         i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5742 }
5743
5744
5745 void i386_fstp_reg(s4 reg) {
5746         *(mcodeptr++) = (u1) 0xdd;
5747         *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg));
5748 }
5749
5750
5751 void i386_fstps_membase(s4 basereg, s4 disp) {
5752         *(mcodeptr++) = (u1) 0xd9;
5753         i386_emit_membase((basereg),(disp),3);
5754 }
5755
5756
5757 void i386_fstpl_membase(s4 basereg, s4 disp) {
5758         *(mcodeptr++) = (u1) 0xdd;
5759         i386_emit_membase((basereg),(disp),3);
5760 }
5761
5762
5763 void i386_fstpt_membase(s4 basereg, s4 disp) {
5764         *(mcodeptr++) = (u1) 0xdb;
5765         i386_emit_membase((basereg),(disp),7);
5766 }
5767
5768
5769 void i386_fstps_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5770         *(mcodeptr++) = (u1) 0xd9;
5771         i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5772 }
5773
5774
5775 void i386_fstpl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5776         *(mcodeptr++) = (u1) 0xdd;
5777         i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5778 }
5779
5780
5781 void i386_fistl_membase(s4 basereg, s4 disp) {
5782         *(mcodeptr++) = (u1) 0xdb;
5783         i386_emit_membase((basereg),(disp),2);
5784 }
5785
5786
5787 void i386_fistpl_membase(s4 basereg, s4 disp) {
5788         *(mcodeptr++) = (u1) 0xdb;
5789         i386_emit_membase((basereg),(disp),3);
5790 }
5791
5792
5793 void i386_fistpll_membase(s4 basereg, s4 disp) {
5794         *(mcodeptr++) = (u1) 0xdf;
5795         i386_emit_membase((basereg),(disp),7);
5796 }
5797
5798
5799 void i386_fchs() {
5800         *(mcodeptr++) = (u1) 0xd9;
5801         *(mcodeptr++) = (u1) 0xe0;
5802 }
5803
5804
5805 void i386_faddp() {
5806         *(mcodeptr++) = (u1) 0xde;
5807         *(mcodeptr++) = (u1) 0xc1;
5808 }
5809
5810
5811 void i386_fadd_reg_st(s4 reg) {
5812         *(mcodeptr++) = (u1) 0xd8;
5813         *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5814 }
5815
5816
5817 void i386_fadd_st_reg(s4 reg) {
5818         *(mcodeptr++) = (u1) 0xdc;
5819         *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5820 }
5821
5822
5823 void i386_faddp_st_reg(s4 reg) {
5824         *(mcodeptr++) = (u1) 0xde;
5825         *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5826 }
5827
5828
5829 void i386_fadds_membase(s4 basereg, s4 disp) {
5830         *(mcodeptr++) = (u1) 0xd8;
5831         i386_emit_membase((basereg),(disp),0);
5832 }
5833
5834
5835 void i386_faddl_membase(s4 basereg, s4 disp) {
5836         *(mcodeptr++) = (u1) 0xdc;
5837         i386_emit_membase((basereg),(disp),0);
5838 }
5839
5840
5841 void i386_fsub_reg_st(s4 reg) {
5842         *(mcodeptr++) = (u1) 0xd8;
5843         *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5844 }
5845
5846
5847 void i386_fsub_st_reg(s4 reg) {
5848         *(mcodeptr++) = (u1) 0xdc;
5849         *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5850 }
5851
5852
5853 void i386_fsubp_st_reg(s4 reg) {
5854         *(mcodeptr++) = (u1) 0xde;
5855         *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5856 }
5857
5858
5859 void i386_fsubp() {
5860         *(mcodeptr++) = (u1) 0xde;
5861         *(mcodeptr++) = (u1) 0xe9;
5862 }
5863
5864
5865 void i386_fsubs_membase(s4 basereg, s4 disp) {
5866         *(mcodeptr++) = (u1) 0xd8;
5867         i386_emit_membase((basereg),(disp),4);
5868 }
5869
5870
5871 void i386_fsubl_membase(s4 basereg, s4 disp) {
5872         *(mcodeptr++) = (u1) 0xdc;
5873         i386_emit_membase((basereg),(disp),4);
5874 }
5875
5876
5877 void i386_fmul_reg_st(s4 reg) {
5878         *(mcodeptr++) = (u1) 0xd8;
5879         *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5880 }
5881
5882
5883 void i386_fmul_st_reg(s4 reg) {
5884         *(mcodeptr++) = (u1) 0xdc;
5885         *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5886 }
5887
5888
5889 void i386_fmulp() {
5890         *(mcodeptr++) = (u1) 0xde;
5891         *(mcodeptr++) = (u1) 0xc9;
5892 }
5893
5894
5895 void i386_fmulp_st_reg(s4 reg) {
5896         *(mcodeptr++) = (u1) 0xde;
5897         *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5898 }
5899
5900
5901 void i386_fmuls_membase(s4 basereg, s4 disp) {
5902         *(mcodeptr++) = (u1) 0xd8;
5903         i386_emit_membase((basereg),(disp),1);
5904 }
5905
5906
5907 void i386_fmull_membase(s4 basereg, s4 disp) {
5908         *(mcodeptr++) = (u1) 0xdc;
5909         i386_emit_membase((basereg),(disp),1);
5910 }
5911
5912
5913 void i386_fdiv_reg_st(s4 reg) {
5914         *(mcodeptr++) = (u1) 0xd8;
5915         *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg));
5916 }
5917
5918
5919 void i386_fdiv_st_reg(s4 reg) {
5920         *(mcodeptr++) = (u1) 0xdc;
5921         *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5922 }
5923
5924
5925 void i386_fdivp() {
5926         *(mcodeptr++) = (u1) 0xde;
5927         *(mcodeptr++) = (u1) 0xf9;
5928 }
5929
5930
5931 void i386_fdivp_st_reg(s4 reg) {
5932         *(mcodeptr++) = (u1) 0xde;
5933         *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5934 }
5935
5936
5937 void i386_fxch() {
5938         *(mcodeptr++) = (u1) 0xd9;
5939         *(mcodeptr++) = (u1) 0xc9;
5940 }
5941
5942
5943 void i386_fxch_reg(s4 reg) {
5944         *(mcodeptr++) = (u1) 0xd9;
5945         *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5946 }
5947
5948
5949 void i386_fprem() {
5950         *(mcodeptr++) = (u1) 0xd9;
5951         *(mcodeptr++) = (u1) 0xf8;
5952 }
5953
5954
5955 void i386_fprem1() {
5956         *(mcodeptr++) = (u1) 0xd9;
5957         *(mcodeptr++) = (u1) 0xf5;
5958 }
5959
5960
5961 void i386_fucom() {
5962         *(mcodeptr++) = (u1) 0xdd;
5963         *(mcodeptr++) = (u1) 0xe1;
5964 }
5965
5966
5967 void i386_fucom_reg(s4 reg) {
5968         *(mcodeptr++) = (u1) 0xdd;
5969         *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5970 }
5971
5972
5973 void i386_fucomp_reg(s4 reg) {
5974         *(mcodeptr++) = (u1) 0xdd;
5975         *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5976 }
5977
5978
5979 void i386_fucompp() {
5980         *(mcodeptr++) = (u1) 0xda;
5981         *(mcodeptr++) = (u1) 0xe9;
5982 }
5983
5984
5985 void i386_fnstsw() {
5986         *(mcodeptr++) = (u1) 0xdf;
5987         *(mcodeptr++) = (u1) 0xe0;
5988 }
5989
5990
5991 void i386_sahf() {
5992         *(mcodeptr++) = (u1) 0x9e;
5993 }
5994
5995
5996 void i386_finit() {
5997         *(mcodeptr++) = (u1) 0x9b;
5998         *(mcodeptr++) = (u1) 0xdb;
5999         *(mcodeptr++) = (u1) 0xe3;
6000 }
6001
6002
6003 void i386_fldcw_mem(s4 mem) {
6004         *(mcodeptr++) = (u1) 0xd9;
6005         i386_emit_mem(5,(mem));
6006 }
6007
6008
6009 void i386_fldcw_membase(s4 basereg, s4 disp) {
6010         *(mcodeptr++) = (u1) 0xd9;
6011         i386_emit_membase((basereg),(disp),5);
6012 }
6013
6014
6015 void i386_wait() {
6016         *(mcodeptr++) = (u1) 0x9b;
6017 }
6018
6019
6020 void i386_ffree_reg(s4 reg) {
6021         *(mcodeptr++) = (u1) 0xdd;
6022         *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
6023 }
6024
6025
6026 void i386_fdecstp() {
6027         *(mcodeptr++) = (u1) 0xd9;
6028         *(mcodeptr++) = (u1) 0xf6;
6029 }
6030
6031
6032 void i386_fincstp() {
6033         *(mcodeptr++) = (u1) 0xd9;
6034         *(mcodeptr++) = (u1) 0xf7;
6035 }
6036
6037
6038 /*
6039  * These are local overrides for various environment variables in Emacs.
6040  * Please do not remove this and leave it at the end of the file, where
6041  * Emacs will automagically detect them.
6042  * ---------------------------------------------------------------------
6043  * Local variables:
6044  * mode: c
6045  * indent-tabs-mode: t
6046  * c-basic-offset: 4
6047  * tab-width: 4
6048  * End:
6049  */