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