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