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