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