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