1 /* i386/ngen.c *****************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains the codegenerator for an i386 processor.
8 This module generates i386 machine code for a sequence of
9 pseudo commands (ICMDs).
11 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
12 Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
14 Last Change: $Id: ngen.c 244 2003-03-07 21:38:15Z twisti $
16 *******************************************************************************/
18 #include "jitdef.h" /* phil */
20 /* additional functions and macros to generate code ***************************/
22 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
23 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
27 #define COUNT_SPILLS count_spills++
33 #define CALCOFFSETBYTES(val) \
35 if ((s4) (val) < -128 || (s4) (val) > 127) offset += 4; \
36 else if ((s4) (val) != 0) offset += 1; \
40 /* gen_nullptr_check(objreg) */
42 #ifdef SOFTNULLPTRCHECK
43 #define gen_nullptr_check(objreg) \
45 i386_alu_imm_reg(I386_CMP, 0, (objreg)); \
46 i386_jcc(I386_CC_E, 0); \
47 mcode_addxnullrefs(mcodeptr); \
50 #define gen_nullptr_check(objreg)
54 /* MCODECHECK(icnt) */
56 #define MCODECHECK(icnt) \
57 if((mcodeptr+(icnt))>mcodeend)mcodeptr=mcode_increase((u1*)mcodeptr)
60 generates an integer-move from register a to b.
61 if a and b are the same int-register, no code will be generated.
64 #define M_INTMOVE(reg,dreg) if ((reg) != (dreg)) { i386_mov_reg_reg((reg),(dreg)); }
68 generates a floating-point-move from register a to b.
69 if a and b are the same float-register, no code will be generated
72 #define M_FLTMOVE(a,b) if(a!=b){M_FMOV(a,b);}
76 this function generates code to fetch data from a pseudo-register
78 If the pseudo-register has actually been assigned to a real
79 register, no code will be emitted, since following operations
80 can use this register directly.
82 v: pseudoregister to be fetched from
83 tempregnum: temporary register to be used if v is actually spilled to ram
85 return: the register number, where the operand can be found after
86 fetching (this wil be either tempregnum or the register
87 number allready given to v)
90 #define var_to_reg_int(regnr,v,tempnr) \
92 if ((v)->flags & INMEMORY) { \
94 i386_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
97 regnr = (v)->regoff; \
103 #define var_to_reg_flt(regnr,v,tempnr) \
105 if ((v)->flags & INMEMORY) { \
107 i386_fstps_membase(REG_SP, (v)->regoff * 8); \
110 panic("floats have to be in memory"); \
116 This function determines a register, to which the result of an operation
117 should go, when it is ultimatively intended to store the result in
119 If v is assigned to an actual register, this register will be returned.
120 Otherwise (when v is spilled) this function returns tempregnum.
121 If not already done, regoff and flags are set in the stack location.
124 static int reg_of_var(stackptr v, int tempregnum)
128 switch (v->varkind) {
130 if (!(v->flags & INMEMORY))
134 var = &(interfaces[v->varnum][v->type]);
135 v->regoff = var->regoff;
136 if (!(var->flags & INMEMORY))
140 var = &(locals[v->varnum][v->type]);
141 v->regoff = var->regoff;
142 if (!(var->flags & INMEMORY))
146 v->regoff = v->varnum;
147 if (IS_FLT_DBL_TYPE(v->type)) {
148 if (v->varnum < fltreg_argnum) {
149 v->regoff = argfltregs[v->varnum];
150 return(argfltregs[v->varnum]);
154 if (v->varnum < intreg_argnum) {
155 v->regoff = argintregs[v->varnum];
156 return(argintregs[v->varnum]);
158 v->regoff -= intreg_argnum;
161 v->flags |= INMEMORY;
166 /* store_reg_to_var_xxx:
167 This function generates the code to store the result of an operation
168 back into a spilled pseudo-variable.
169 If the pseudo-variable has not been spilled in the first place, this
170 function will generate nothing.
172 v ............ Pseudovariable
173 tempregnum ... Number of the temporary registers as returned by
177 #define store_reg_to_var_int(sptr, tempregnum) \
179 if ((sptr)->flags & INMEMORY) { \
181 i386_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
186 #define store_reg_to_var_flt(sptr, tempregnum) \
188 if ((sptr)->type == TYPE_FLT) { \
189 if ((sptr)->flags & INMEMORY) { \
191 i386_fsts_membase(REG_SP, (sptr)->regoff * 8); \
193 panic("floats have to be in memory"); \
196 if ((sptr)->flags & INMEMORY) { \
198 i386_fstl_membase(REG_SP, (sptr)->regoff * 8); \
200 panic("doubles have to be in memory"); \
206 /* NullPointerException handlers and exception handling initialisation */
208 typedef struct sigctx_struct {
210 long sc_onstack; /* sigstack state to restore */
211 long sc_mask; /* signal mask to restore */
212 long sc_pc; /* pc at time of signal */
213 long sc_ps; /* psl to retore */
214 long sc_regs[32]; /* processor regs 0 to 31 */
215 long sc_ownedfp; /* fp has been used */
216 long sc_fpregs[32]; /* fp regs 0 to 31 */
217 unsigned long sc_fpcr; /* floating point control register */
218 unsigned long sc_fp_control; /* software fpcr */
220 unsigned long sc_reserved1, sc_reserved2;
221 unsigned long sc_ssize;
223 unsigned long sc_traparg_a0;
224 unsigned long sc_traparg_a1;
225 unsigned long sc_traparg_a2;
226 unsigned long sc_fp_trap_pc;
227 unsigned long sc_fp_trigger_sum;
228 unsigned long sc_fp_trigger_inst;
229 unsigned long sc_retcode[2];
233 /* NullPointerException signal handler for hardware null pointer check */
235 void catch_NullPointerException(int sig, int code, sigctx_struct *sigctx)
241 /* Reset signal handler - necessary for SysV, does no harm for BSD */
243 instr = *((int*)(sigctx->sc_pc));
244 faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f];
246 if (faultaddr == 0) {
247 signal(sig, (void*) catch_NullPointerException); /* reinstall handler */
249 sigaddset(&nsig, sig);
250 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
251 sigctx->sc_regs[REG_ITMP1_XPTR] =
252 (long) proto_java_lang_NullPointerException;
253 sigctx->sc_regs[REG_ITMP2_XPC] = sigctx->sc_pc;
254 sigctx->sc_pc = (long) asm_handle_nat_exception;
258 faultaddr += (long) ((instr << 16) >> 16);
259 fprintf(stderr, "faulting address: 0x%16lx\n", faultaddr);
260 panic("Stack overflow");
264 void init_exceptions(void)
266 /* install signal handlers we need to convert to exceptions */
271 signal(SIGSEGV, (void*) catch_NullPointerException);
275 signal(SIGBUS, (void*) catch_NullPointerException);
281 /* function gen_mcode **********************************************************
283 generates machine code
285 *******************************************************************************/
287 #define MethodPointer -8
288 #define FrameSize -12
293 #define ExTableSize -32
294 #define ExTableStart -32
297 # define ExEntrySize -32
298 # define ExStartPC -8
300 # define ExHandlerPC -24
301 # define ExCatchType -32
303 # define ExEntrySize -16
304 # define ExStartPC -4
306 # define ExHandlerPC -12
307 # define ExCatchType -16
310 static void gen_mcode()
312 int len, s1, s2, s3, d, bbs;
327 /* savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
329 /* space to save used callee saved registers */
331 savedregs_num += (savintregcnt - maxsavintreguse);
332 savedregs_num += (savfltregcnt - maxsavfltreguse);
334 parentargs_base = maxmemuse + savedregs_num;
336 #ifdef USE_THREADS /* space to save argument of monitor_enter */
338 if (checksync && (method->flags & ACC_SYNCHRONIZED))
343 /* create method header */
345 (void) dseg_addaddress(method); /* MethodPointer */
346 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
350 /* IsSync contains the offset relative to the stack pointer for the
351 argument of monitor_exit used in the exception handler. Since the
352 offset could be zero and give a wrong meaning of the flag it is
356 if (checksync && (method->flags & ACC_SYNCHRONIZED))
357 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
362 (void) dseg_adds4(0); /* IsSync */
364 (void) dseg_adds4(isleafmethod); /* IsLeaf */
365 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
366 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
367 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
369 /* create exception table */
371 for (ex = extable; ex != NULL; ex = ex->down) {
374 if (ex->start != NULL)
375 printf("adding start - %d - ", ex->start->debug_nr);
377 printf("PANIC - start is NULL");
382 dseg_addtarget(ex->start);
386 printf("adding end - %d - ", ex->end->debug_nr);
388 printf("PANIC - end is NULL");
393 dseg_addtarget(ex->end);
396 if (ex->handler != NULL)
397 printf("adding handler - %d\n", ex->handler->debug_nr);
399 printf("PANIC - handler is NULL");
404 dseg_addtarget(ex->handler);
406 (void) dseg_addaddress(ex->catchtype);
409 /* initialize mcode variables */
411 mcodeptr = (s4*) mcodebase;
412 mcodeend = (s4*) (mcodebase + mcodesize);
413 MCODECHECK(128 + mparamcount);
415 /* create stack frame (if necessary) */
417 if (parentargs_base) {
418 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
421 /* save return address and used callee saved registers */
425 /* p--; M_AST (REG_RA, REG_SP, 8*p); -- do we really need this on i386 */
427 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
428 p--; i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
430 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
431 p--; M_DST (savfltregs[r], REG_SP, 8 * p);
434 /* save monitorenter argument */
437 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
438 if (method->flags & ACC_STATIC) {
439 p = dseg_addaddress (class);
440 M_ALD(REG_ITMP1, REG_PV, p);
441 M_AST(REG_ITMP1, REG_SP, 8 * maxmemuse);
444 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
445 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8 * maxmemuse);
450 /* copy argument registers to stack and call trace function with pointer
451 to arguments on stack. ToDo: save floating point registers !!!!!!!!!
454 if (runverbose && isleafmethod) {
455 M_LDA (REG_SP, REG_SP, -(14*8));
456 M_AST(REG_RA, REG_SP, 1*8);
458 M_LST(argintregs[0], REG_SP, 2*8);
459 M_LST(argintregs[1], REG_SP, 3*8);
460 M_LST(argintregs[2], REG_SP, 4*8);
461 M_LST(argintregs[3], REG_SP, 5*8);
462 M_LST(argintregs[4], REG_SP, 6*8);
463 M_LST(argintregs[5], REG_SP, 7*8);
465 M_DST(argfltregs[0], REG_SP, 8*8);
466 M_DST(argfltregs[1], REG_SP, 9*8);
467 M_DST(argfltregs[2], REG_SP, 10*8);
468 M_DST(argfltregs[3], REG_SP, 11*8);
469 M_DST(argfltregs[4], REG_SP, 12*8);
470 M_DST(argfltregs[5], REG_SP, 13*8);
472 p = dseg_addaddress (method);
473 M_ALD(REG_ITMP1, REG_PV, p);
474 M_AST(REG_ITMP1, REG_SP, 0);
475 /* p = dseg_addaddress ((void*) (builtin_trace_args)); */
476 M_ALD(REG_PV, REG_PV, p);
477 M_JSR(REG_RA, REG_PV);
478 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
479 M_ALD(REG_RA, REG_SP, 1*8);
481 M_LLD(argintregs[0], REG_SP, 2*8);
482 M_LLD(argintregs[1], REG_SP, 3*8);
483 M_LLD(argintregs[2], REG_SP, 4*8);
484 M_LLD(argintregs[3], REG_SP, 5*8);
485 M_LLD(argintregs[4], REG_SP, 6*8);
486 M_LLD(argintregs[5], REG_SP, 7*8);
488 M_DLD(argfltregs[0], REG_SP, 8*8);
489 M_DLD(argfltregs[1], REG_SP, 9*8);
490 M_DLD(argfltregs[2], REG_SP, 10*8);
491 M_DLD(argfltregs[3], REG_SP, 11*8);
492 M_DLD(argfltregs[4], REG_SP, 12*8);
493 M_DLD(argfltregs[5], REG_SP, 13*8);
495 M_LDA (REG_SP, REG_SP, 14*8);
498 /* take arguments out of register or stack frame */
500 for (p = 0, l = 0; p < mparamcount; p++) {
502 var = &(locals[l][t]);
504 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
509 if (IS_INT_LNG_TYPE(t)) { /* integer args */
510 if (p < INT_ARG_CNT) { /* register arguments */
511 if (!(var->flags & INMEMORY)) /* reg arg -> register */
512 {M_INTMOVE (argintregs[p], r);}
513 else /* reg arg -> spilled */
514 M_LST (argintregs[p], REG_SP, 8 * r);
516 else { /* stack arguments */
517 pa = p - INT_ARG_CNT;
518 if (!(var->flags & INMEMORY)) /* stack arg -> register */
519 M_LLD (r, REG_SP, 8 * (parentargs_base + pa));
520 else { /* stack arg -> spilled */
521 M_LLD (REG_ITMP1, REG_SP, 8 * (parentargs_base + pa));
522 M_LST (REG_ITMP1, REG_SP, 8 * r);
526 else { /* floating args */
527 if (p < FLT_ARG_CNT) { /* register arguments */
528 if (!(var->flags & INMEMORY)) /* reg arg -> register */
529 {M_FLTMOVE (argfltregs[p], r);}
530 else /* reg arg -> spilled */
531 M_DST (argfltregs[p], REG_SP, 8 * r);
533 else { /* stack arguments */
534 pa = p - FLT_ARG_CNT;
535 if (!(var->flags & INMEMORY)) /* stack-arg -> register */
536 M_DLD (r, REG_SP, 8 * (parentargs_base + pa) );
537 else { /* stack-arg -> spilled */
538 M_DLD (REG_FTMP1, REG_SP, 8 * (parentargs_base + pa));
539 M_DST (REG_FTMP1, REG_SP, 8 * r);
546 /* printf("mparamcount=%d\n", mparamcount); */
547 for (p = 0, l = 0; p < mparamcount; p++) {
549 var = &(locals[l][t]);
551 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
556 if (IS_INT_LNG_TYPE(t)) { /* integer args */
557 if (p < INT_ARG_CNT) { /* register arguments */
558 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
559 M_INTMOVE (argintregs[p], r);
560 } else { /* reg arg -> spilled */
561 M_LST (argintregs[p], REG_SP, 8 * r);
563 } else { /* stack arguments */
564 pa = p - INT_ARG_CNT;
565 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
566 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
567 } else { /* stack arg -> spilled */
569 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
570 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP2); /* + 4 for return address */
571 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
572 i386_mov_reg_membase(REG_ITMP2, REG_SP, r * 8 + 4);
575 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
576 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
581 } else { /* floating args */
582 if (p < FLT_ARG_CNT) { /* register arguments */
583 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
584 M_FLTMOVE (argfltregs[p], r);
585 } else { /* reg arg -> spilled */
586 M_DST (argfltregs[p], REG_SP, 8 * r);
588 } else { /* stack arguments */
589 pa = p - FLT_ARG_CNT;
590 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
591 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r);
592 } else { /* stack-arg -> spilled */
593 /* printf("float memory\n"); */
594 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1);
595 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
601 /* call trace function */
603 if (runverbose && !isleafmethod) {
604 M_LDA (REG_SP, REG_SP, -8);
605 p = dseg_addaddress (method);
606 M_ALD(REG_ITMP1, REG_PV, p);
607 M_AST(REG_ITMP1, REG_SP, 0);
608 /* p = dseg_addaddress ((void*) (builtin_trace_args)); */
609 M_ALD(REG_PV, REG_PV, p);
610 M_JSR(REG_RA, REG_PV);
611 M_LDA(REG_PV, REG_RA, -(int)((u1*) mcodeptr - mcodebase));
612 M_LDA(REG_SP, REG_SP, 8);
615 /* call monitorenter function */
618 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
619 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
620 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
621 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
622 i386_mov_imm_reg(builtin_monitorenter, REG_ITMP1);
623 i386_call_reg(REG_ITMP1);
624 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
629 /* end of header generation */
631 /* walk through all basic blocks */
632 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
634 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
636 if (bptr->flags >= BBREACHED) {
638 /* branch resolving */
642 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
643 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
644 brefs->branchpos, bptr->mpc);
648 /* copy interface registers to their destination */
651 /* src = bptr->instack; */
652 /* len = bptr->indepth; */
653 /* MCODECHECK(64+len); */
654 /* while (src != NULL) { */
656 /* if ((len == 0) && (bptr->type != BBTYPE_STD)) { */
657 /* d = reg_of_var(src, REG_ITMP1); */
658 /* M_INTMOVE(REG_ITMP1, d); */
659 /* store_reg_to_var_int(src, d); */
662 /* d = reg_of_var(src, REG_IFTMP); */
663 /* if ((src->varkind != STACKVAR)) { */
664 /* s2 = src->type; */
665 /* if (IS_FLT_DBL_TYPE(s2)) { */
666 /* if (!(interfaces[len][s2].flags & INMEMORY)) { */
667 /* s1 = interfaces[len][s2].regoff; */
668 /* M_FLTMOVE(s1,d); */
671 /* M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff); */
673 /* store_reg_to_var_flt(src, d); */
676 /* if (!(interfaces[len][s2].flags & INMEMORY)) { */
677 /* s1 = interfaces[len][s2].regoff; */
678 /* M_INTMOVE(s1,d); */
681 /* M_LLD(d, REG_SP, 8 * interfaces[len][s2].regoff); */
683 /* store_reg_to_var_int(src, d); */
687 /* src = src->prev; */
692 while (src != NULL) {
694 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
695 d = reg_of_var(src, REG_ITMP1);
696 M_INTMOVE(REG_ITMP1, d);
697 store_reg_to_var_int(src, d);
700 d = reg_of_var(src, REG_ITMP1);
701 if ((src->varkind != STACKVAR)) {
703 if (IS_FLT_DBL_TYPE(s2)) {
704 if (!(interfaces[len][s2].flags & INMEMORY)) {
705 s1 = interfaces[len][s2].regoff;
709 M_DLD(d, REG_SP, 8 * interfaces[len][s2].regoff);
711 store_reg_to_var_flt(src, d);
714 if (!(interfaces[len][s2].flags & INMEMORY)) {
715 s1 = interfaces[len][s2].regoff;
719 i386_mov_membase_reg(REG_SP, interfaces[len][s2].regoff * 8, d);
721 store_reg_to_var_int(src, d);
728 /* walk through all instructions */
732 for (iptr = bptr->iinstr;
734 src = iptr->dst, len--, iptr++) {
736 MCODECHECK(64); /* an instruction usually needs < 64 words */
739 case ICMD_NOP: /* ... ==> ... */
742 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
743 if (src->flags & INMEMORY) {
744 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
747 /* TODO: optimize: test reg,reg */
748 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
750 i386_jcc(I386_CC_E, 0);
751 mcode_addxnullrefs(mcodeptr);
754 /* constant operations ************************************************/
756 case ICMD_ICONST: /* ... ==> ..., constant */
757 /* op1 = 0, val.i = constant */
759 d = reg_of_var(iptr->dst, REG_ITMP1);
760 if (iptr->dst->flags & INMEMORY) {
761 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
764 i386_mov_imm_reg(iptr->val.i, d);
768 case ICMD_LCONST: /* ... ==> ..., constant */
769 /* op1 = 0, val.l = constant */
771 d = reg_of_var(iptr->dst, REG_ITMP1);
772 if (iptr->dst->flags & INMEMORY) {
773 i386_mov_imm_membase(iptr->val.l, REG_SP, iptr->dst->regoff * 8);
774 i386_mov_imm_membase(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
777 panic("longs have to be in memory");
781 case ICMD_FCONST: /* ... ==> ..., constant */
782 /* op1 = 0, val.f = constant */
784 d = reg_of_var(iptr->dst, REG_FTMP1);
785 if (iptr->val.f == 0) {
788 } else if (iptr->val.f == 1) {
791 } else if (iptr->val.f == 2) {
797 a = dseg_addfloat(iptr->val.f);
798 i386_mov_imm_reg(0, REG_ITMP1);
799 dseg_adddata(mcodeptr);
800 i386_flds_membase(REG_ITMP1, a);
802 store_reg_to_var_flt(iptr->dst, d);
805 case ICMD_DCONST: /* ... ==> ..., constant */
806 /* op1 = 0, val.d = constant */
808 d = reg_of_var(iptr->dst, REG_FTMP1);
809 if (iptr->val.d == 0) {
812 } else if (iptr->val.d == 1) {
816 a = dseg_adddouble(iptr->val.d);
817 i386_mov_imm_reg(0, REG_ITMP1);
818 dseg_adddata(mcodeptr);
819 i386_fldl_membase(REG_ITMP1, a);
821 store_reg_to_var_flt(iptr->dst, d);
824 case ICMD_ACONST: /* ... ==> ..., constant */
825 /* op1 = 0, val.a = constant */
827 d = reg_of_var(iptr->dst, REG_ITMP1);
828 if (iptr->dst->flags & INMEMORY) {
829 i386_mov_imm_membase(iptr->val.a, REG_SP, iptr->dst->regoff * 8);
832 i386_mov_imm_reg(iptr->val.a, iptr->dst->regoff);
837 /* load/store operations **********************************************/
839 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
840 /* op1 = local variable */
842 d = reg_of_var(iptr->dst, REG_ITMP1);
843 if ((iptr->dst->varkind == LOCALVAR) &&
844 (iptr->dst->varnum == iptr->op1)) {
847 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
848 if (iptr->dst->flags & INMEMORY) {
849 if (var->flags & INMEMORY) {
850 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
851 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
854 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
858 if (var->flags & INMEMORY) {
859 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
862 printf("ILOAD: dst not in memory (regoff=%d)?\n", iptr->dst->regoff);
863 M_INTMOVE(var->regoff, iptr->dst->regoff);
868 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
869 /* op1 = local variable */
871 d = reg_of_var(iptr->dst, REG_ITMP1);
872 if ((iptr->dst->varkind == LOCALVAR) &&
873 (iptr->dst->varnum == iptr->op1)) {
876 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
877 if (iptr->dst->flags & INMEMORY) {
878 if (var->flags & INMEMORY) {
879 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
880 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
883 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
887 if (var->flags & INMEMORY) {
888 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
891 printf("ALOAD: dst not in memory (regoff=%d)?\n", iptr->dst->regoff);
892 M_INTMOVE(var->regoff, iptr->dst->regoff);
897 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
898 /* op1 = local variable */
900 d = reg_of_var(iptr->dst, REG_ITMP1);
901 if ((iptr->dst->varkind == LOCALVAR) &&
902 (iptr->dst->varnum == iptr->op1)) {
905 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
906 if (iptr->dst->flags & INMEMORY) {
907 if (var->flags & INMEMORY) {
908 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
909 i386_mov_membase_reg(REG_SP, var->regoff * 8 + 4, REG_ITMP2);
910 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
911 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 4 + 4);
914 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 4);
918 printf("LLOAD: dst not in memory?\n");
922 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
923 /* op1 = local variable */
925 d = reg_of_var(iptr->dst, REG_FTMP1);
926 if ((iptr->dst->varkind == LOCALVAR) &&
927 (iptr->dst->varnum == iptr->op1)) {
930 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
931 i386_flds_membase(REG_SP, var->regoff * 8);
932 store_reg_to_var_flt(iptr->dst, d);
935 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
936 /* op1 = local variable */
938 d = reg_of_var(iptr->dst, REG_FTMP1);
939 if ((iptr->dst->varkind == LOCALVAR) &&
940 (iptr->dst->varnum == iptr->op1)) {
943 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
944 i386_fldl_membase(REG_SP, var->regoff * 8);
945 store_reg_to_var_flt(iptr->dst, d);
948 case ICMD_ISTORE: /* ..., value ==> ... */
949 /* op1 = local variable */
951 if ((src->varkind == LOCALVAR) &&
952 (src->varnum == iptr->op1)) {
955 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
956 if (var->flags & INMEMORY) {
957 if (src->flags & INMEMORY) {
958 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
959 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
962 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
966 var_to_reg_int(s1, src, var->regoff);
967 M_INTMOVE(s1, var->regoff);
971 case ICMD_ASTORE: /* ..., value ==> ... */
972 /* op1 = local variable */
974 if ((src->varkind == LOCALVAR) &&
975 (src->varnum == iptr->op1)) {
978 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
979 if (var->flags & INMEMORY) {
980 if (src->flags & INMEMORY) {
981 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
982 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
985 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
989 var_to_reg_int(s1, src, var->regoff);
990 M_INTMOVE(s1, var->regoff);
994 case ICMD_LSTORE: /* ..., value ==> ... */
995 /* op1 = local variable */
997 if ((src->varkind == LOCALVAR) &&
998 (src->varnum == iptr->op1)) {
1001 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1003 /* if (var->flags & INMEMORY) { */
1004 /* var_to_reg_int(s1, src, REG_ITMP1); */
1005 /* i386_mov_reg_membase(s1, REG_SP, var->regoff * 8); */
1008 /* var_to_reg_int(s1, src, var->regoff); */
1009 /* M_INTMOVE(s1, var->regoff); */
1013 case ICMD_FSTORE: /* ..., value ==> ... */
1014 /* op1 = local variable */
1016 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1017 /* i386_fstps_membase(REG_SP, var->regoff * 8); */
1020 case ICMD_DSTORE: /* ..., value ==> ... */
1021 /* op1 = local variable */
1023 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1024 /* i386_fstpl_membase(REG_SP, var->regoff * 8); */
1028 /* pop/dup/swap operations ********************************************/
1030 /* attention: double and longs are only one entry in CACAO ICMDs */
1032 case ICMD_POP: /* ..., value ==> ... */
1033 case ICMD_POP2: /* ..., value, value ==> ... */
1037 /* #define M_COPY(from,to) \ */
1038 /* d = reg_of_var(to, REG_IFTMP); \ */
1039 /* if ((from->regoff != to->regoff) || \ */
1040 /* ((from->flags ^ to->flags) & INMEMORY)) { \ */
1041 /* if (IS_FLT_DBL_TYPE(from->type)) { \ */
1042 /* var_to_reg_flt(s1, from, d); \ */
1043 /* M_FLTMOVE(s1,d); \ */
1044 /* store_reg_to_var_flt(to, d); \ */
1047 /* var_to_reg_int(s1, from, d); \ */
1048 /* M_INTMOVE(s1,d); \ */
1049 /* store_reg_to_var_int(to, d); \ */
1052 /* printf("DUP: from,regoff=%d,%d to,regoff=%d,%d\n", from->flags & INMEMORY, from->regoff, to->flags & INMEMORY, to->regoff); \ */
1053 #define M_COPY(from,to) \
1054 if ((from->regoff != to->regoff) || \
1055 ((from->flags ^ to->flags) & INMEMORY)) { \
1056 if (IS_FLT_DBL_TYPE(from->type)) { \
1057 d = reg_of_var(to, REG_IFTMP); \
1058 var_to_reg_flt(s1, from, d); \
1060 store_reg_to_var_flt(to, d); \
1062 d = reg_of_var(to, REG_ITMP1); \
1063 var_to_reg_int(s1, from, d); \
1065 store_reg_to_var_int(to, d); \
1069 case ICMD_DUP: /* ..., a ==> ..., a, a */
1070 M_COPY(src, iptr->dst);
1073 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1075 M_COPY(src, iptr->dst->prev->prev);
1077 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1079 M_COPY(src, iptr->dst);
1080 M_COPY(src->prev, iptr->dst->prev);
1083 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1085 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1087 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1089 M_COPY(src, iptr->dst);
1090 M_COPY(src->prev, iptr->dst->prev);
1091 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1092 M_COPY(src, iptr->dst->prev->prev->prev);
1095 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1097 M_COPY(src, iptr->dst);
1098 M_COPY(src->prev, iptr->dst->prev);
1099 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1100 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1101 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1102 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1105 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1107 M_COPY(src, iptr->dst->prev);
1108 M_COPY(src->prev, iptr->dst);
1112 /* integer operations *************************************************/
1114 case ICMD_INEG: /* ..., value ==> ..., - value */
1116 d = reg_of_var(iptr->dst, REG_ITMP3);
1117 if (iptr->dst->flags & INMEMORY) {
1118 if (src->flags & INMEMORY) {
1119 if (src->regoff == iptr->dst->regoff) {
1120 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1123 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1124 i386_neg_reg(REG_ITMP1);
1125 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1129 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1130 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1134 if (src->flags & INMEMORY) {
1135 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1136 i386_neg_reg(iptr->dst->regoff);
1139 M_INTMOVE(src->regoff, iptr->dst->regoff);
1140 i386_neg_reg(iptr->dst->regoff);
1145 case ICMD_LNEG: /* ..., value ==> ..., - value */
1147 d = reg_of_var(iptr->dst, REG_ITMP3);
1148 if (iptr->dst->flags & INMEMORY) {
1149 if (src->flags & INMEMORY) {
1150 if (src->regoff == iptr->dst->regoff) {
1151 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1152 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1153 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1156 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1157 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1158 i386_neg_reg(REG_ITMP1);
1159 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1160 i386_neg_reg(REG_ITMP2);
1161 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1162 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1168 case ICMD_I2L: /* ..., value ==> ..., value */
1170 d = reg_of_var(iptr->dst, REG_ITMP3);
1171 if (iptr->dst->flags & INMEMORY) {
1172 if (src->flags & INMEMORY) {
1173 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_EAX);
1175 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1176 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1179 M_INTMOVE(src->regoff, I386_EAX);
1181 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1182 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1187 case ICMD_L2I: /* ..., value ==> ..., value */
1189 d = reg_of_var(iptr->dst, REG_ITMP3);
1190 if (iptr->dst->flags & INMEMORY) {
1191 if (src->flags & INMEMORY) {
1192 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1193 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1196 if (src->flags & INMEMORY) {
1197 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1202 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1204 d = reg_of_var(iptr->dst, REG_ITMP3);
1205 if (iptr->dst->flags & INMEMORY) {
1206 if (src->flags & INMEMORY) {
1207 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1208 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1209 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1210 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1213 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1214 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1215 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1219 if (src->flags & INMEMORY) {
1220 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1221 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1222 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1225 M_INTMOVE(src->regoff, iptr->dst->regoff);
1226 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1227 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1232 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1234 d = reg_of_var(iptr->dst, REG_ITMP3);
1235 if (iptr->dst->flags & INMEMORY) {
1236 if (src->flags & INMEMORY) {
1237 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1238 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1239 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1242 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1243 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1247 if (src->flags & INMEMORY) {
1248 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1249 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1252 M_INTMOVE(src->regoff, iptr->dst->regoff);
1253 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1258 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1260 d = reg_of_var(iptr->dst, REG_ITMP3);
1261 if (iptr->dst->flags & INMEMORY) {
1262 if (src->flags & INMEMORY) {
1263 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1264 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1265 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1266 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1269 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1270 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1271 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1275 if (src->flags & INMEMORY) {
1276 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1277 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1278 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1281 M_INTMOVE(src->regoff, iptr->dst->regoff);
1282 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1283 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1289 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1291 d = reg_of_var(iptr->dst, REG_ITMP3);
1292 if (iptr->dst->flags & INMEMORY) {
1293 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1294 if (src->regoff == iptr->dst->regoff) {
1295 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1296 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1298 } else if (src->prev->regoff == iptr->dst->regoff) {
1299 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1300 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1303 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1304 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1305 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1308 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1309 if (src->regoff == iptr->dst->regoff) {
1310 i386_alu_reg_membase(I386_ADD, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1313 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1314 i386_alu_reg_reg(I386_ADD, src->prev->regoff, REG_ITMP1);
1315 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1318 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1319 if (src->prev->regoff == iptr->dst->regoff) {
1320 i386_alu_reg_membase(I386_ADD, src->regoff, REG_SP, iptr->dst->regoff * 8);
1323 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1324 i386_alu_reg_reg(I386_ADD, src->regoff, REG_ITMP1);
1325 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1329 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1330 i386_alu_reg_membase(I386_ADD, src->regoff, REG_SP, iptr->dst->regoff * 8);
1334 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1335 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1336 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, iptr->dst->regoff);
1338 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1339 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1340 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, iptr->dst->regoff);
1342 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1343 M_INTMOVE(src->regoff, iptr->dst->regoff);
1344 i386_alu_membase_reg(I386_ADD, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1347 if (src->regoff == iptr->dst->regoff) {
1348 i386_alu_reg_reg(I386_ADD, src->prev->regoff, iptr->dst->regoff);
1351 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1352 i386_alu_reg_reg(I386_ADD, src->regoff, iptr->dst->regoff);
1358 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1359 /* val.i = constant */
1361 d = reg_of_var(iptr->dst, REG_ITMP3);
1362 if (iptr->dst->flags & INMEMORY) {
1363 if (src->flags & INMEMORY) {
1364 if (src->regoff == iptr->dst->regoff) {
1365 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1368 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1369 i386_alu_imm_reg(I386_ADD, iptr->val.i, REG_ITMP1);
1370 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1374 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1375 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1379 if (src->flags & INMEMORY) {
1380 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1381 i386_alu_imm_reg(I386_ADD, iptr->val.i, iptr->dst->regoff);
1384 M_INTMOVE(src->regoff, iptr->dst->regoff);
1385 i386_alu_imm_reg(I386_ADD, iptr->val.i, iptr->dst->regoff);
1390 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1392 d = reg_of_var(iptr->dst, REG_ITMP3);
1393 if (iptr->dst->flags & INMEMORY) {
1394 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1395 if (src->regoff == iptr->dst->regoff) {
1396 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1397 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1398 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1399 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1401 } else if (src->prev->regoff == iptr->dst->regoff) {
1402 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1403 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1404 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1405 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1408 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1409 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1410 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1411 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1412 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1413 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1420 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1421 /* val.l = constant */
1423 d = reg_of_var(iptr->dst, REG_ITMP3);
1424 if (iptr->dst->flags & INMEMORY) {
1425 if (src->flags & INMEMORY) {
1426 if (src->regoff == iptr->dst->regoff) {
1427 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1428 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1431 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1432 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1433 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1434 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP2);
1435 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1436 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1442 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1444 d = reg_of_var(iptr->dst, REG_ITMP3);
1445 if (iptr->dst->flags & INMEMORY) {
1446 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1447 if (src->prev->regoff == iptr->dst->regoff) {
1448 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1449 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1452 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1453 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1454 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1457 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1458 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1459 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1460 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1462 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1463 if (src->prev->regoff == iptr->dst->regoff) {
1464 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1467 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1468 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1469 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1473 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1474 i386_alu_reg_membase(I386_SUB, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1478 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1479 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1480 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, iptr->dst->regoff);
1482 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1483 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1484 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, iptr->dst->regoff);
1486 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1487 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1488 i386_alu_reg_reg(I386_SUB, src->regoff, iptr->dst->regoff);
1491 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1492 i386_alu_reg_reg(I386_SUB, src->regoff, iptr->dst->regoff);
1497 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1498 /* val.i = constant */
1500 d = reg_of_var(iptr->dst, REG_ITMP3);
1501 if (iptr->dst->flags & INMEMORY) {
1502 if (src->flags & INMEMORY) {
1503 if (src->regoff == iptr->dst->regoff) {
1504 i386_alu_imm_membase(I386_SUB, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1507 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1508 i386_alu_imm_reg(I386_SUB, iptr->val.i, REG_ITMP1);
1509 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1513 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1514 i386_alu_imm_membase(I386_SUB, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1518 if (src->flags & INMEMORY) {
1519 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1520 i386_alu_imm_reg(I386_SUB, iptr->val.i, iptr->dst->regoff);
1523 M_INTMOVE(src->regoff, iptr->dst->regoff);
1524 i386_alu_imm_reg(I386_SUB, iptr->val.i, iptr->dst->regoff);
1529 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1531 d = reg_of_var(iptr->dst, REG_ITMP3);
1532 if (iptr->dst->flags & INMEMORY) {
1533 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1534 if (src->prev->regoff == iptr->dst->regoff) {
1535 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1536 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1537 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1538 i386_alu_reg_membase(I386_SBB, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1541 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1542 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1543 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1544 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1545 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1546 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1552 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1553 /* val.l = constant */
1555 d = reg_of_var(iptr->dst, REG_ITMP3);
1556 if (iptr->dst->flags & INMEMORY) {
1557 if (src->flags & INMEMORY) {
1558 if (src->regoff == iptr->dst->regoff) {
1559 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1560 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1563 /* TODO: could be size optimized with lea -- see gcc output */
1564 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1565 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1566 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1567 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP2);
1568 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1569 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1575 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1577 d = reg_of_var(iptr->dst, REG_ITMP3);
1578 if (iptr->dst->flags & INMEMORY) {
1579 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1580 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1581 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1582 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1584 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1585 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1586 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1587 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1589 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1590 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1591 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1592 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1595 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1596 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1597 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1601 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1602 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1603 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1605 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1606 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1607 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1609 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1610 M_INTMOVE(src->regoff, iptr->dst->regoff);
1611 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1614 if (src->regoff == iptr->dst->regoff) {
1615 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1618 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1619 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1625 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1626 /* val.i = constant */
1628 d = reg_of_var(iptr->dst, REG_ITMP3);
1629 if (iptr->dst->flags & INMEMORY) {
1630 if (src->flags & INMEMORY) {
1631 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1632 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1635 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1636 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1640 if (src->flags & INMEMORY) {
1641 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1644 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1649 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1651 d = reg_of_var(iptr->dst, REG_ITMP1);
1652 if (iptr->dst->flags & INMEMORY) {
1653 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1654 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_EAX); /* mem -> EAX */
1655 /* i386_mul_membase(REG_SP, src->prev->regoff * 8); /* mem * EAX -> EDX:EAX */
1656 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); /* mem -> ITMP1 */
1657 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); /* ITMP1 -> ITMP2 */
1658 /* i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP2 -> ITMP2 */
1659 /* i386_mov_reg_reg(I386_EDX, REG_ITMP1); /* EDX -> ITMP1 */
1660 /* i386_alu_reg_reg(I386_ADD, REG_ITMP2, REG_ITMP1); /* ITMP2 + ITMP1 -> ITMP1 */
1661 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2); /* mem -> ITMP2 */
1662 /* i386_imul_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP2 -> ITMP2 */
1664 /* i386_alu_reg_reg(I386_ADD, REG_ITMP2, REG_ITMP1); /* ITMP2 + ITMP1 -> ITMP1 */
1665 /* i386_mov_reg_reg(REG_ITMP1, I386_EDX); /* ITMP1 -> EDX */
1666 /* i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8); */
1667 /* i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4); */
1669 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_EAX); /* mem -> EAX */
1670 i386_mul_membase(REG_SP, src->prev->regoff * 8); /* mem * EAX -> EDX:EAX */
1671 /* TODO: optimize move EAX -> REG_ITMP3 */
1672 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem -> ITMP3 */
1674 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1675 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1676 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem -> ITMP3 */
1677 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1678 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1679 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1680 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1685 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1686 /* val.l = constant */
1688 d = reg_of_var(iptr->dst, REG_ITMP1);
1689 if (iptr->dst->flags & INMEMORY) {
1690 if (src->flags & INMEMORY) {
1691 i386_mov_imm_reg(iptr->val.l, I386_EAX); /* imm -> EAX */
1692 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1693 /* TODO: optimize move EAX -> REG_ITMP3 */
1694 i386_mov_imm_reg(iptr->val.l, REG_ITMP3); /* imm -> ITMP3 */
1696 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1697 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1698 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP3); /* imm -> ITMP3 */
1699 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1700 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1701 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1702 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1707 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1709 d = reg_of_var(iptr->dst, REG_ITMP3);
1710 if (src->prev->flags & INMEMORY) {
1711 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1714 M_INTMOVE(src->prev->regoff, I386_EAX);
1719 if (src->flags & INMEMORY) {
1720 i386_idiv_membase(REG_SP, src->regoff * 8);
1723 i386_idiv_reg(src->regoff);
1726 if (iptr->dst->flags & INMEMORY) {
1727 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1730 M_INTMOVE(I386_EAX, iptr->dst->regoff);
1734 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1736 d = reg_of_var(iptr->dst, REG_ITMP3);
1737 if (src->prev->flags & INMEMORY) {
1738 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1741 M_INTMOVE(src->prev->regoff, I386_EAX);
1746 if (src->flags & INMEMORY) {
1747 i386_idiv_membase(REG_SP, src->regoff * 8);
1750 i386_idiv_reg(src->regoff);
1753 if (iptr->dst->flags & INMEMORY) {
1754 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8);
1757 M_INTMOVE(I386_EDX, iptr->dst->regoff);
1761 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1762 /* val.i = constant */
1764 /* d = reg_of_var(iptr->dst, REG_ITMP3); */
1765 /* if (iptr->dst->flags & INMEMORY) { */
1766 /* if (src->flags & INMEMORY) { */
1767 /* if (src->regoff == iptr->dst->regoff) { */
1768 /* i386_shift_imm_membase(I386_SAR, iptr->val.i, REG_SP, iptr->dst->regoff * 8); */
1771 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
1772 /* i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP1); */
1773 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1777 /* i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8); */
1778 /* i386_shift_imm_membase(I386_SAR, iptr->val.i, REG_SP, iptr->dst->regoff * 8); */
1782 /* if (src->flags & INMEMORY) { */
1783 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff); */
1784 /* i386_shift_imm_reg(I386_SAR, iptr->val.i, iptr->dst->regoff); */
1787 /* M_INTMOVE(src->regoff, iptr->dst->regoff); */
1788 /* i386_shift_imm_reg(I386_SAR, iptr->val.i, iptr->dst->regoff); */
1794 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1795 /* val.i = constant */
1797 var_to_reg_int(s1, src, REG_ITMP1);
1798 d = reg_of_var(iptr->dst, REG_ITMP3);
1799 if (iptr->val.i <= 15) {
1800 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
1801 M_CMOVGE(s1, s1, REG_ITMP2);
1804 M_SRA_IMM(s1, 63, REG_ITMP2);
1805 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1806 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1808 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
1809 store_reg_to_var_int(iptr->dst, d);
1812 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1814 d = reg_of_var(iptr->dst, REG_ITMP2);
1815 if (iptr->dst->flags & INMEMORY) {
1816 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1817 if (src->prev->regoff == iptr->dst->regoff) {
1818 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_ECX);
1819 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1822 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1823 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1824 i386_shift_reg(I386_SHL, REG_ITMP1);
1825 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1828 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1829 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1830 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1831 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1833 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1834 if (src->prev->regoff == iptr->dst->regoff) {
1835 M_INTMOVE(src->regoff, I386_ECX);
1836 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1839 M_INTMOVE(src->regoff, I386_ECX);
1840 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1841 i386_shift_reg(I386_SHL, REG_ITMP1);
1842 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1846 M_INTMOVE(src->regoff, I386_ECX);
1847 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1848 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1852 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1853 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1854 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1855 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1857 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1858 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1859 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1860 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1862 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1863 M_INTMOVE(src->regoff, I386_ECX);
1864 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1865 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1868 M_INTMOVE(src->regoff, I386_ECX);
1869 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1870 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1875 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1876 /* val.i = constant */
1878 d = reg_of_var(iptr->dst, REG_ITMP1);
1879 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1880 if (src->regoff == iptr->dst->regoff) {
1881 i386_shift_imm_membase(I386_SHL, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1884 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1885 i386_shift_imm_reg(I386_SHL, iptr->val.i, REG_ITMP1);
1886 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1889 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
1890 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1891 i386_shift_imm_reg(I386_SHL, iptr->val.i, iptr->dst->regoff);
1893 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1894 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1895 i386_shift_imm_membase(I386_SHL, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1898 M_INTMOVE(src->regoff, iptr->dst->regoff);
1899 i386_shift_imm_reg(I386_SHL, iptr->val.i, iptr->dst->regoff);
1903 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1905 d = reg_of_var(iptr->dst, REG_ITMP2);
1906 if (iptr->dst->flags & INMEMORY) {
1907 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1908 if (src->prev->regoff == iptr->dst->regoff) {
1909 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_ECX);
1910 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1913 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1914 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1915 i386_shift_reg(I386_SAR, REG_ITMP1);
1916 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1919 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1920 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1921 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1922 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1924 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1925 if (src->prev->regoff == iptr->dst->regoff) {
1926 M_INTMOVE(src->regoff, I386_ECX);
1927 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1930 M_INTMOVE(src->regoff, I386_ECX);
1931 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1932 i386_shift_reg(I386_SAR, REG_ITMP1);
1933 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1937 M_INTMOVE(src->regoff, I386_ECX);
1938 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1939 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1943 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1944 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1945 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1946 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1948 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1949 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1950 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1951 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1953 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1954 M_INTMOVE(src->regoff, I386_ECX);
1955 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1956 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1959 M_INTMOVE(src->regoff, I386_ECX);
1960 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1961 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1966 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1967 /* val.i = constant */
1969 d = reg_of_var(iptr->dst, REG_ITMP1);
1970 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1971 if (src->regoff == iptr->dst->regoff) {
1972 i386_shift_imm_membase(I386_SAR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1975 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1976 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP1);
1977 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1980 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
1981 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1982 i386_shift_imm_reg(I386_SAR, iptr->val.i, iptr->dst->regoff);
1984 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1985 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1986 i386_shift_imm_membase(I386_SAR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1989 M_INTMOVE(src->regoff, iptr->dst->regoff);
1990 i386_shift_imm_reg(I386_SAR, iptr->val.i, iptr->dst->regoff);
1994 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1996 d = reg_of_var(iptr->dst, REG_ITMP2);
1997 if (iptr->dst->flags & INMEMORY) {
1998 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1999 if (src->prev->regoff == iptr->dst->regoff) {
2000 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_ECX);
2001 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2004 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2005 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2006 i386_shift_reg(I386_SHR, REG_ITMP1);
2007 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2010 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2011 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2012 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2013 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2015 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2016 if (src->prev->regoff == iptr->dst->regoff) {
2017 M_INTMOVE(src->regoff, I386_ECX);
2018 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2020 M_INTMOVE(src->regoff, I386_ECX);
2021 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2022 i386_shift_reg(I386_SHR, REG_ITMP1);
2023 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2027 M_INTMOVE(src->regoff, I386_ECX);
2028 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2029 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2033 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2034 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2035 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2036 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2038 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2039 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2040 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2041 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2043 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2044 M_INTMOVE(src->regoff, I386_ECX);
2045 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2046 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2049 M_INTMOVE(src->regoff, I386_ECX);
2050 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2051 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2056 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
2057 /* val.i = constant */
2059 d = reg_of_var(iptr->dst, REG_ITMP1);
2060 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
2061 if (src->regoff == iptr->dst->regoff) {
2062 i386_shift_imm_membase(I386_SHR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2065 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2066 i386_shift_imm_reg(I386_SHR, iptr->val.i, REG_ITMP1);
2067 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2070 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
2071 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2072 i386_shift_imm_reg(I386_SHR, iptr->val.i, iptr->dst->regoff);
2074 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
2075 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2076 i386_shift_imm_membase(I386_SHR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2079 M_INTMOVE(src->regoff, iptr->dst->regoff);
2080 i386_shift_imm_reg(I386_SHR, iptr->val.i, iptr->dst->regoff);
2084 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
2086 d = reg_of_var(iptr->dst, REG_ITMP1);
2087 if (iptr->dst->flags & INMEMORY ){
2088 if (src->prev->flags & INMEMORY) {
2089 if (src->prev->regoff == iptr->dst->regoff) {
2090 if (src->flags & INMEMORY) {
2091 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2092 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2093 i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4);
2094 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
2097 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2098 M_INTMOVE(src->regoff, I386_ECX);
2099 i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4);
2100 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
2104 if (src->flags & INMEMORY) {
2105 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2106 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2107 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2108 i386_shld_reg_reg(REG_ITMP1, REG_ITMP2);
2109 i386_shift_reg(I386_SHL, REG_ITMP1);
2110 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2111 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2114 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2115 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2116 M_INTMOVE(src->regoff, I386_ECX);
2117 i386_shld_reg_reg(REG_ITMP1, REG_ITMP2);
2118 i386_shift_reg(I386_SHL, REG_ITMP1);
2119 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2120 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2127 /* case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
2128 /* /* val.l = constant */
2130 /* var_to_reg_int(s1, src, REG_ITMP1); */
2131 /* d = reg_of_var(iptr->dst, REG_ITMP3); */
2132 /* M_SLL_IMM(s1, iptr->val.l & 0x3f, d); */
2133 /* store_reg_to_var_int(iptr->dst, d); */
2136 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
2138 d = reg_of_var(iptr->dst, REG_ITMP1);
2139 if (iptr->dst->flags & INMEMORY ){
2140 if (src->prev->flags & INMEMORY) {
2141 if (src->prev->regoff == iptr->dst->regoff) {
2142 if (src->flags & INMEMORY) {
2143 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2144 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2145 i386_shrd_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4);
2146 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
2149 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2150 M_INTMOVE(src->regoff, I386_ECX);
2151 i386_shrd_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4);
2152 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
2156 if (src->flags & INMEMORY) {
2157 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2158 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2159 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2160 i386_shrd_reg_reg(REG_ITMP1, REG_ITMP2);
2161 i386_shift_reg(I386_SAR, REG_ITMP1);
2162 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2163 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2166 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2167 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2168 M_INTMOVE(src->regoff, I386_ECX);
2169 i386_shrd_reg_reg(REG_ITMP1, REG_ITMP2);
2170 i386_shift_reg(I386_SAR, REG_ITMP1);
2171 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2172 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2179 /* case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2180 /* /* val.l = constant */
2182 /* var_to_reg_int(s1, src, REG_ITMP1); */
2183 /* d = reg_of_var(iptr->dst, REG_ITMP3); */
2184 /* M_SRA_IMM(s1, iptr->val.l & 0x3f, d); */
2185 /* store_reg_to_var_int(iptr->dst, d); */
2188 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2190 d = reg_of_var(iptr->dst, REG_ITMP1);
2191 if (iptr->dst->flags & INMEMORY ){
2192 if (src->prev->flags & INMEMORY) {
2193 if (src->prev->regoff == iptr->dst->regoff) {
2194 if (src->flags & INMEMORY) {
2195 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2196 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2197 i386_shrd_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4);
2198 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2201 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2202 M_INTMOVE(src->regoff, I386_ECX);
2203 i386_shrd_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4);
2204 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2208 if (src->flags & INMEMORY) {
2209 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2210 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2211 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2212 i386_shrd_reg_reg(REG_ITMP1, REG_ITMP2);
2213 i386_shift_reg(I386_SHR, REG_ITMP1);
2214 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2215 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2218 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2219 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2220 M_INTMOVE(src->regoff, I386_ECX);
2221 i386_shrd_reg_reg(REG_ITMP1, REG_ITMP2);
2222 i386_shift_reg(I386_SHR, REG_ITMP1);
2223 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2224 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2231 /* case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2232 /* /* val.l = constant */
2234 /* var_to_reg_int(s1, src, REG_ITMP1); */
2235 /* d = reg_of_var(iptr->dst, REG_ITMP3); */
2236 /* M_SRL_IMM(s1, iptr->val.l & 0x3f, d); */
2237 /* store_reg_to_var_int(iptr->dst, d); */
2240 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2242 d = reg_of_var(iptr->dst, REG_ITMP1);
2243 if (iptr->dst->flags & INMEMORY) {
2244 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2245 if (src->regoff == iptr->dst->regoff) {
2246 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2247 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2249 } else if (src->prev->regoff == iptr->dst->regoff) {
2250 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2251 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2254 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2255 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, REG_ITMP1);
2256 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2259 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2260 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2261 i386_alu_reg_reg(I386_AND, src->prev->regoff, REG_ITMP1);
2262 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2264 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2265 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2266 i386_alu_reg_reg(I386_AND, src->regoff, REG_ITMP1);
2267 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2270 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2271 i386_alu_reg_membase(I386_AND, src->regoff, REG_SP, iptr->dst->regoff * 8);
2275 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2276 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2277 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, iptr->dst->regoff);
2279 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2280 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2281 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, iptr->dst->regoff);
2283 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2284 M_INTMOVE(src->regoff, iptr->dst->regoff);
2285 i386_alu_membase_reg(I386_AND, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2288 if (src->regoff == iptr->dst->regoff) {
2289 i386_alu_reg_reg(I386_AND, src->prev->regoff, iptr->dst->regoff);
2292 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2293 i386_alu_reg_reg(I386_AND, src->regoff, iptr->dst->regoff);
2299 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2300 /* val.i = constant */
2302 d = reg_of_var(iptr->dst, REG_ITMP1);
2303 if (iptr->dst->flags & INMEMORY) {
2304 if (src->flags & INMEMORY) {
2305 if (src->regoff == iptr->dst->regoff) {
2306 i386_alu_imm_membase(I386_AND, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2309 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2310 i386_alu_imm_reg(I386_AND, iptr->val.i, REG_ITMP1);
2311 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2315 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2316 i386_alu_imm_membase(I386_AND, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2320 if (src->flags & INMEMORY) {
2321 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2322 i386_alu_imm_reg(I386_AND, iptr->val.i, iptr->dst->regoff);
2325 M_INTMOVE(src->regoff, iptr->dst->regoff);
2326 i386_alu_imm_reg(I386_AND, iptr->val.i, iptr->dst->regoff);
2331 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2333 d = reg_of_var(iptr->dst, REG_ITMP1);
2334 if (iptr->dst->flags & INMEMORY) {
2335 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2336 if (src->regoff == iptr->dst->regoff) {
2337 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2338 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2339 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2340 i386_alu_reg_membase(I386_AND, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2342 } else if (src->prev->regoff == iptr->dst->regoff) {
2343 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2344 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2345 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2346 i386_alu_reg_membase(I386_AND, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2349 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2350 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2351 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, REG_ITMP1);
2352 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2353 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2354 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2360 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2361 /* val.l = constant */
2363 d = reg_of_var(iptr->dst, REG_ITMP1);
2364 if (iptr->dst->flags & INMEMORY) {
2365 if (src->flags & INMEMORY) {
2366 if (src->regoff == iptr->dst->regoff) {
2367 i386_alu_imm_membase(I386_AND, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
2368 i386_alu_imm_membase(I386_AND, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
2371 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2372 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2373 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
2374 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
2375 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2376 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2382 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
2383 /* val.i = constant */
2385 var_to_reg_int(s1, src, REG_ITMP1);
2386 d = reg_of_var(iptr->dst, REG_ITMP3);
2388 M_MOV(s1, REG_ITMP1);
2391 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
2392 M_AND_IMM(s1, iptr->val.i, d);
2394 M_ISUB(REG_ZERO, s1, d);
2395 M_AND_IMM(d, iptr->val.i, d);
2397 else if (iptr->val.i == 0xffff) {
2400 M_ISUB(REG_ZERO, s1, d);
2403 else if (iptr->val.i == 0xffffff) {
2404 M_ZAPNOT_IMM(s1, 0x07, d);
2406 M_ISUB(REG_ZERO, s1, d);
2407 M_ZAPNOT_IMM(d, 0x07, d);
2410 /* ICONST(REG_ITMP2, iptr->val.i); */
2411 M_AND(s1, REG_ITMP2, d);
2413 M_ISUB(REG_ZERO, s1, d);
2414 M_AND(d, REG_ITMP2, d);
2416 M_ISUB(REG_ZERO, d, d);
2417 store_reg_to_var_int(iptr->dst, d);
2420 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
2422 /* b = value & 0xffff;
2424 a = ((b - a) & 0xffff) + (b < a);
2427 var_to_reg_int(s1, src, REG_ITMP1);
2428 d = reg_of_var(iptr->dst, REG_ITMP3);
2430 M_MOV(s1, REG_ITMP3);
2434 M_CZEXT(s1, REG_ITMP2);
2435 M_SRA_IMM(s1, 16, d);
2436 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
2437 M_ISUB(REG_ITMP2, d, d);
2439 M_IADD(d, REG_ITMP1, d);
2440 M_BR(11 + (s1 == REG_ITMP1));
2441 M_ISUB(REG_ZERO, s1, REG_ITMP1);
2442 M_CZEXT(REG_ITMP1, REG_ITMP2);
2443 M_SRA_IMM(REG_ITMP1, 16, d);
2444 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
2445 M_ISUB(REG_ITMP2, d, d);
2447 M_IADD(d, REG_ITMP1, d);
2448 M_ISUB(REG_ZERO, d, d);
2449 if (s1 == REG_ITMP1) {
2450 var_to_reg_int(s1, src, REG_ITMP1);
2452 M_SLL_IMM(s1, 33, REG_ITMP2);
2453 M_CMPEQ(REG_ITMP2, REG_ZERO, REG_ITMP2);
2454 M_ISUB(d, REG_ITMP2, d);
2455 store_reg_to_var_int(iptr->dst, d);
2458 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
2459 /* val.l = constant */
2461 var_to_reg_int(s1, src, REG_ITMP1);
2462 d = reg_of_var(iptr->dst, REG_ITMP3);
2464 M_MOV(s1, REG_ITMP1);
2467 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
2468 M_AND_IMM(s1, iptr->val.l, d);
2470 M_LSUB(REG_ZERO, s1, d);
2471 M_AND_IMM(d, iptr->val.l, d);
2473 else if (iptr->val.l == 0xffffL) {
2476 M_LSUB(REG_ZERO, s1, d);
2479 else if (iptr->val.l == 0xffffffL) {
2480 M_ZAPNOT_IMM(s1, 0x07, d);
2482 M_LSUB(REG_ZERO, s1, d);
2483 M_ZAPNOT_IMM(d, 0x07, d);
2485 else if (iptr->val.l == 0xffffffffL) {
2488 M_LSUB(REG_ZERO, s1, d);
2491 else if (iptr->val.l == 0xffffffffffL) {
2492 M_ZAPNOT_IMM(s1, 0x1f, d);
2494 M_LSUB(REG_ZERO, s1, d);
2495 M_ZAPNOT_IMM(d, 0x1f, d);
2497 else if (iptr->val.l == 0xffffffffffffL) {
2498 M_ZAPNOT_IMM(s1, 0x3f, d);
2500 M_LSUB(REG_ZERO, s1, d);
2501 M_ZAPNOT_IMM(d, 0x3f, d);
2503 else if (iptr->val.l == 0xffffffffffffffL) {
2504 M_ZAPNOT_IMM(s1, 0x7f, d);
2506 M_LSUB(REG_ZERO, s1, d);
2507 M_ZAPNOT_IMM(d, 0x7f, d);
2510 /* LCONST(REG_ITMP2, iptr->val.l); */
2511 M_AND(s1, REG_ITMP2, d);
2513 M_LSUB(REG_ZERO, s1, d);
2514 M_AND(d, REG_ITMP2, d);
2516 M_LSUB(REG_ZERO, d, d);
2517 store_reg_to_var_int(iptr->dst, d);
2520 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
2522 var_to_reg_int(s1, src, REG_ITMP1);
2523 d = reg_of_var(iptr->dst, REG_ITMP3);
2525 M_MOV(s1, REG_ITMP3);
2528 M_CZEXT(s1, REG_ITMP2);
2529 M_SRA_IMM(s1, 16, d);
2530 M_CMPLT(REG_ITMP2, d, REG_ITMP1);
2531 M_LSUB(REG_ITMP2, d, d);
2533 M_LADD(d, REG_ITMP1, d);
2534 M_LDA(REG_ITMP2, REG_ZERO, -1);
2535 M_SRL_IMM(REG_ITMP2, 33, REG_ITMP2);
2536 if (s1 == REG_ITMP1) {
2537 var_to_reg_int(s1, src, REG_ITMP1);
2539 M_CMPULT(s1, REG_ITMP2, REG_ITMP2);
2540 M_BNEZ(REG_ITMP2, 11);
2541 M_LDA(d, REG_ZERO, -257);
2542 M_ZAPNOT_IMM(d, 0xcd, d);
2543 M_LSUB(REG_ZERO, s1, REG_ITMP2);
2544 M_CMOVGE(s1, s1, REG_ITMP2);
2545 M_UMULH(REG_ITMP2, d, REG_ITMP2);
2546 M_SRL_IMM(REG_ITMP2, 16, REG_ITMP2);
2547 M_LSUB(REG_ZERO, REG_ITMP2, d);
2548 M_CMOVGE(s1, REG_ITMP2, d);
2549 M_SLL_IMM(d, 16, REG_ITMP2);
2550 M_LADD(d, REG_ITMP2, d);
2552 store_reg_to_var_int(iptr->dst, d);
2555 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2557 d = reg_of_var(iptr->dst, REG_ITMP1);
2558 if (iptr->dst->flags & INMEMORY) {
2559 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2560 if (src->regoff == iptr->dst->regoff) {
2561 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2562 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2564 } else if (src->prev->regoff == iptr->dst->regoff) {
2565 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2566 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2569 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2570 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, REG_ITMP1);
2571 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2574 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2575 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2576 i386_alu_reg_reg(I386_OR, src->prev->regoff, REG_ITMP1);
2577 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2579 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2580 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2581 i386_alu_reg_reg(I386_OR, src->regoff, REG_ITMP1);
2582 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2585 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2586 i386_alu_reg_membase(I386_OR, src->regoff, REG_SP, iptr->dst->regoff * 8);
2590 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2591 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2592 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2594 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2595 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2596 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2598 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2599 M_INTMOVE(src->regoff, iptr->dst->regoff);
2600 i386_alu_membase_reg(I386_OR, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2603 if (src->regoff == iptr->dst->regoff) {
2604 i386_alu_reg_reg(I386_OR, src->prev->regoff, iptr->dst->regoff);
2607 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2608 i386_alu_reg_reg(I386_OR, src->regoff, iptr->dst->regoff);
2614 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2615 /* val.i = constant */
2617 d = reg_of_var(iptr->dst, REG_ITMP1);
2618 if (iptr->dst->flags & INMEMORY) {
2619 if (src->flags & INMEMORY) {
2620 if (src->regoff == iptr->dst->regoff) {
2621 i386_alu_imm_membase(I386_OR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2624 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2625 i386_alu_imm_reg(I386_OR, iptr->val.i, REG_ITMP1);
2626 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2630 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2631 i386_alu_imm_membase(I386_OR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2635 if (src->flags & INMEMORY) {
2636 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2637 i386_alu_imm_reg(I386_OR, iptr->val.i, iptr->dst->regoff);
2640 M_INTMOVE(src->regoff, iptr->dst->regoff);
2641 i386_alu_imm_reg(I386_OR, iptr->val.i, iptr->dst->regoff);
2646 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2648 d = reg_of_var(iptr->dst, REG_ITMP1);
2649 if (iptr->dst->flags & INMEMORY) {
2650 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2651 if (src->regoff == iptr->dst->regoff) {
2652 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2653 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2654 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2655 i386_alu_reg_membase(I386_OR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2657 } else if (src->prev->regoff == iptr->dst->regoff) {
2658 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2659 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2660 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2661 i386_alu_reg_membase(I386_OR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2664 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2665 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2666 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, REG_ITMP1);
2667 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2668 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2669 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2675 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2676 /* val.l = constant */
2678 d = reg_of_var(iptr->dst, REG_ITMP1);
2679 if (iptr->dst->flags & INMEMORY) {
2680 if (src->flags & INMEMORY) {
2681 if (src->regoff == iptr->dst->regoff) {
2682 i386_alu_imm_membase(I386_OR, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
2683 i386_alu_imm_membase(I386_OR, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
2686 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2687 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2688 i386_alu_imm_reg(I386_OR, iptr->val.l, REG_ITMP1);
2689 i386_alu_imm_reg(I386_OR, iptr->val.l >> 32, REG_ITMP2);
2690 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2691 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2697 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2699 d = reg_of_var(iptr->dst, REG_ITMP1);
2700 if (iptr->dst->flags & INMEMORY) {
2701 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2702 if (src->regoff == iptr->dst->regoff) {
2703 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2704 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2706 } else if (src->prev->regoff == iptr->dst->regoff) {
2707 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2708 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2711 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2712 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
2713 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2716 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2717 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2718 i386_alu_reg_reg(I386_XOR, src->prev->regoff, REG_ITMP1);
2719 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2721 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2722 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2723 i386_alu_reg_reg(I386_XOR, src->regoff, REG_ITMP1);
2724 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2727 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2728 i386_alu_reg_membase(I386_XOR, src->regoff, REG_SP, iptr->dst->regoff * 8);
2732 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2733 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2734 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2736 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2737 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2738 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2740 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2741 M_INTMOVE(src->regoff, iptr->dst->regoff);
2742 i386_alu_membase_reg(I386_XOR, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2745 if (src->regoff == iptr->dst->regoff) {
2746 i386_alu_reg_reg(I386_XOR, src->prev->regoff, iptr->dst->regoff);
2749 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2750 i386_alu_reg_reg(I386_XOR, src->regoff, iptr->dst->regoff);
2756 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2757 /* val.i = constant */
2759 d = reg_of_var(iptr->dst, REG_ITMP1);
2760 if (iptr->dst->flags & INMEMORY) {
2761 if (src->flags & INMEMORY) {
2762 if (src->regoff == iptr->dst->regoff) {
2763 i386_alu_imm_membase(I386_XOR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2766 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2767 i386_alu_imm_reg(I386_XOR, iptr->val.i, REG_ITMP1);
2768 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2772 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2773 i386_alu_imm_membase(I386_XOR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2777 if (src->flags & INMEMORY) {
2778 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2779 i386_alu_imm_reg(I386_XOR, iptr->val.i, iptr->dst->regoff);
2782 M_INTMOVE(src->regoff, iptr->dst->regoff);
2783 i386_alu_imm_reg(I386_XOR, iptr->val.i, iptr->dst->regoff);
2788 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2790 d = reg_of_var(iptr->dst, REG_ITMP1);
2791 if (iptr->dst->flags & INMEMORY) {
2792 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2793 if (src->regoff == iptr->dst->regoff) {
2794 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2795 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2796 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2797 i386_alu_reg_membase(I386_XOR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2799 } else if (src->prev->regoff == iptr->dst->regoff) {
2800 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2801 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2802 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2803 i386_alu_reg_membase(I386_XOR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2806 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2807 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2808 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
2809 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2810 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2811 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2817 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2818 /* val.l = constant */
2820 d = reg_of_var(iptr->dst, REG_ITMP1);
2821 if (iptr->dst->flags & INMEMORY) {
2822 if (src->flags & INMEMORY) {
2823 if (src->regoff == iptr->dst->regoff) {
2824 i386_alu_imm_membase(I386_XOR, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
2825 i386_alu_imm_membase(I386_XOR, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
2828 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2829 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2830 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
2831 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
2832 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2833 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2840 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
2842 var_to_reg_int(s1, src->prev, REG_ITMP1);
2843 var_to_reg_int(s2, src, REG_ITMP2);
2844 d = reg_of_var(iptr->dst, REG_ITMP3);
2845 M_CMPLT(s1, s2, REG_ITMP3);
2846 M_CMPLT(s2, s1, REG_ITMP1);
2847 M_LSUB (REG_ITMP1, REG_ITMP3, d);
2848 store_reg_to_var_int(iptr->dst, d);
2851 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2852 /* op1 = variable, val.i = constant */
2854 var = &(locals[iptr->op1][TYPE_INT]);
2855 if (var->flags & INMEMORY) {
2856 if (iptr->val.i == 1) {
2857 i386_inc_membase(REG_SP, var->regoff * 8);
2859 } else if (iptr->val.i == -1) {
2860 i386_dec_membase(REG_SP, var->regoff * 8);
2863 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2867 if (iptr->val.i == 1) {
2868 i386_inc_reg(var->regoff);
2870 } else if (iptr->val.i == -1) {
2871 i386_dec_reg(var->regoff);
2874 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
2880 /* floating operations ************************************************/
2882 case ICMD_FNEG: /* ..., value ==> ..., - value */
2883 case ICMD_DNEG: /* ..., value ==> ..., - value */
2885 d = reg_of_var(iptr->dst, REG_FTMP3);
2887 store_reg_to_var_flt(iptr->dst, d);
2890 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2891 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2893 d = reg_of_var(iptr->dst, REG_FTMP3);
2895 store_reg_to_var_flt(iptr->dst, d);
2898 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2899 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2901 d = reg_of_var(iptr->dst, REG_FTMP3);
2903 store_reg_to_var_flt(iptr->dst, d);
2906 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2907 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2909 d = reg_of_var(iptr->dst, REG_FTMP3);
2911 store_reg_to_var_flt(iptr->dst, d);
2914 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2915 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2917 d = reg_of_var(iptr->dst, REG_FTMP3);
2919 store_reg_to_var_flt(iptr->dst, d);
2922 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2923 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2925 d = reg_of_var(iptr->dst, REG_FTMP3);
2927 store_reg_to_var_flt(iptr->dst, d);
2930 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2931 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2933 d = reg_of_var(iptr->dst, REG_FTMP1);
2934 if (src->flags & INMEMORY) {
2935 i386_fildl_membase(REG_SP, src->regoff * 8);
2939 i386_mov_imm_reg(0, REG_ITMP1);
2940 dseg_adddata(mcodeptr);
2941 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
2942 i386_fildl_membase(REG_ITMP1, a);
2944 store_reg_to_var_flt(iptr->dst, d);
2947 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2948 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2950 d = reg_of_var(iptr->dst, REG_FTMP1);
2951 if (src->flags & INMEMORY) {
2952 i386_fildll_membase(REG_SP, src->regoff * 8);
2954 panic("longs have to be in memory");
2956 store_reg_to_var_flt(iptr->dst, d);
2959 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2962 d = reg_of_var(iptr->dst, REG_ITMP1);
2963 if (iptr->dst->flags & INMEMORY) {
2964 i386_fistl_membase(REG_SP, iptr->dst->regoff * 8);
2968 i386_mov_imm_reg(0, REG_ITMP1);
2969 dseg_adddata(mcodeptr);
2970 i386_fistpl_membase(REG_ITMP1, a);
2971 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2975 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2978 d = reg_of_var(iptr->dst, REG_ITMP1);
2979 if (iptr->dst->flags & INMEMORY) {
2980 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2982 panic("longs have to be in memory");
2986 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2991 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2996 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2999 d = reg_of_var(iptr->dst, REG_ITMP3);
3003 i386_alu_imm_reg(I386_AND, 0x00004500, I386_EAX);
3004 i386_test_imm_reg(0x00004500, I386_EAX);
3007 /* i386_testb_imm_reg(0x45, 4); */
3009 if (iptr->dst->flags & INMEMORY) {
3010 /* int offset = 7; */
3012 /* if (iptr->dst->regoff > 0) offset += 1; */
3013 /* if (iptr->dst->regoff > 31) offset += 3; */
3015 /* i386_jcc(I386_CC_E, offset + 5); */
3016 /* i386_mov_imm_membase(0, REG_SP, iptr->dst->regoff * 8); */
3017 /* i386_jmp(offset); */
3018 /* i386_mov_imm_membase(1, REG_SP, iptr->dst->regoff * 8); */
3020 /* i386_mov_imm_membase(0, REG_SP, iptr->dst->regoff * 8); */
3021 /* i386_setcc_membase(I386_CC_E, REG_SP, iptr->dst->regoff * 8); */
3023 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
3024 i386_setcc_reg(I386_CC_E, REG_ITMP2);
3025 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3028 i386_alu_reg_reg(I386_XOR, iptr->dst->regoff, iptr->dst->regoff);
3029 i386_setcc_reg(I386_CC_E, iptr->dst->regoff);
3033 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
3036 d = reg_of_var(iptr->dst, REG_ITMP3);
3039 i386_alu_imm_reg(I386_AND, 0x00000100, I386_EAX);
3040 i386_test_imm_reg(0x00000100, I386_EAX);
3042 if (iptr->dst->flags & INMEMORY) {
3045 if (iptr->dst->regoff > 0) offset += 1;
3046 if (iptr->dst->regoff > 31) offset += 3;
3048 i386_jcc(I386_CC_NE, offset + 5);
3049 i386_mov_imm_membase(-1, REG_SP, iptr->dst->regoff * 8);
3051 i386_mov_imm_membase(1, REG_SP, iptr->dst->regoff * 8);
3054 i386_jcc(I386_CC_NE, 5 + 5);
3055 i386_mov_imm_reg(-1, iptr->dst->regoff);
3057 i386_mov_imm_reg(1, iptr->dst->regoff);
3062 /* memory operations **************************************************/
3064 /* #define gen_bound_check \
3066 M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
3067 M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
3068 M_BEQZ(REG_ITMP3, 0);\
3069 mcode_addxboundrefs(mcodeptr);\
3074 /* #define gen_bound_check \ */
3075 /* if (checkbounds) { \ */
3076 /* M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\ */
3077 /* M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\ */
3078 /* M_BEQZ(REG_ITMP3, 0);\ */
3079 /* mcode_addxboundrefs(mcodeptr); \ */
3081 #define gen_bound_check \
3082 if (checkbounds) { \
3083 i386_alu_reg_membase(I386_CMP, s2, s1, OFFSET(java_arrayheader, size)); \
3084 i386_jcc(I386_CC_L, 0); \
3085 mcode_addxboundrefs(mcodeptr); \
3088 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
3090 var_to_reg_int(s1, src, REG_ITMP1);
3091 d = reg_of_var(iptr->dst, REG_ITMP3);
3092 gen_nullptr_check(s1);
3093 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
3094 store_reg_to_var_int(iptr->dst, d);
3097 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
3099 var_to_reg_int(s1, src->prev, REG_ITMP1);
3100 var_to_reg_int(s2, src, REG_ITMP2);
3101 d = reg_of_var(iptr->dst, REG_ITMP3);
3102 if (iptr->op1 == 0) {
3103 gen_nullptr_check(s1);
3106 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
3107 store_reg_to_var_int(iptr->dst, d);
3110 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
3112 var_to_reg_int(s1, src->prev, REG_ITMP1);
3113 var_to_reg_int(s2, src, REG_ITMP2);
3114 d = reg_of_var(iptr->dst, REG_ITMP3);
3115 if (iptr->op1 == 0) {
3116 gen_nullptr_check(s1);
3120 if (iptr->dst->flags & INMEMORY) {
3121 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 2, REG_ITMP3);
3122 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
3123 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 2, REG_ITMP3);
3124 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
3128 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
3130 var_to_reg_int(s1, src->prev, REG_ITMP1);
3131 var_to_reg_int(s2, src, REG_ITMP2);
3132 d = reg_of_var(iptr->dst, REG_ITMP3);
3133 if (iptr->op1 == 0) {
3134 gen_nullptr_check(s1);
3137 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
3138 store_reg_to_var_int(iptr->dst, d);
3141 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
3143 var_to_reg_int(s1, src->prev, REG_ITMP1);
3144 var_to_reg_int(s2, src, REG_ITMP2);
3145 d = reg_of_var(iptr->dst, REG_FTMP3);
3146 if (iptr->op1 == 0) {
3147 gen_nullptr_check(s1);
3150 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
3151 store_reg_to_var_flt(iptr->dst, d);
3154 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
3156 var_to_reg_int(s1, src->prev, REG_ITMP1);
3157 var_to_reg_int(s2, src, REG_ITMP2);
3158 d = reg_of_var(iptr->dst, REG_FTMP3);
3159 if (iptr->op1 == 0) {
3160 gen_nullptr_check(s1);
3163 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 2);
3164 store_reg_to_var_flt(iptr->dst, d);
3167 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
3169 var_to_reg_int(s1, src->prev, REG_ITMP1);
3170 var_to_reg_int(s2, src, REG_ITMP2);
3171 d = reg_of_var(iptr->dst, REG_ITMP3);
3172 if (iptr->op1 == 0) {
3173 gen_nullptr_check(s1);
3176 M_INTMOVE(s1, REG_ITMP1);
3177 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
3178 store_reg_to_var_int(iptr->dst, d);
3181 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
3183 var_to_reg_int(s1, src->prev, REG_ITMP1);
3184 var_to_reg_int(s2, src, REG_ITMP2);
3185 d = reg_of_var(iptr->dst, REG_ITMP3);
3186 if (iptr->op1 == 0) {
3187 gen_nullptr_check(s1);
3190 M_INTMOVE(s1, REG_ITMP1);
3191 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
3192 store_reg_to_var_int(iptr->dst, d);
3195 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
3197 var_to_reg_int(s1, src->prev, REG_ITMP1);
3198 var_to_reg_int(s2, src, REG_ITMP2);
3199 d = reg_of_var(iptr->dst, REG_ITMP3);
3200 if (iptr->op1 == 0) {
3201 gen_nullptr_check(s1);
3204 M_INTMOVE(s1, REG_ITMP1);
3205 i386_movzbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
3206 store_reg_to_var_int(iptr->dst, d);
3210 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
3212 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3213 var_to_reg_int(s2, src->prev, REG_ITMP2);
3214 if (iptr->op1 == 0) {
3215 gen_nullptr_check(s1);
3218 var_to_reg_int(s3, src, REG_ITMP3);
3219 i386_mov_reg_memindex(s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
3222 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
3224 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3225 var_to_reg_int(s2, src->prev, REG_ITMP2);
3226 if (iptr->op1 == 0) {
3227 gen_nullptr_check(s1);
3231 if (src->flags & INMEMORY) {
3232 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
3233 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 2);
3234 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
3235 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 2);
3239 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
3241 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3242 var_to_reg_int(s2, src->prev, REG_ITMP2);
3243 if (iptr->op1 == 0) {
3244 gen_nullptr_check(s1);
3247 var_to_reg_int(s3, src, REG_ITMP3);
3248 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
3251 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
3253 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3254 var_to_reg_int(s2, src->prev, REG_ITMP2);
3255 if (iptr->op1 == 0) {
3256 gen_nullptr_check(s1);
3259 i386_fsts_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
3262 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
3264 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3265 var_to_reg_int(s2, src->prev, REG_ITMP2);
3266 if (iptr->op1 == 0) {
3267 gen_nullptr_check(s1);
3270 i386_fstl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 2);
3273 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
3275 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3276 var_to_reg_int(s2, src->prev, REG_ITMP2);
3277 if (iptr->op1 == 0) {
3278 gen_nullptr_check(s1);
3281 var_to_reg_int(s3, src, REG_ITMP3);
3282 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
3285 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
3287 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3288 var_to_reg_int(s2, src->prev, REG_ITMP2);
3289 if (iptr->op1 == 0) {
3290 gen_nullptr_check(s1);
3293 var_to_reg_int(s3, src, REG_ITMP3);
3294 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
3297 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
3299 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3300 var_to_reg_int(s2, src->prev, REG_ITMP2);
3301 if (iptr->op1 == 0) {
3302 gen_nullptr_check(s1);
3305 var_to_reg_int(s3, src, REG_ITMP3);
3306 M_INTMOVE(s3, REG_ITMP3); /* because EBP, ESI, EDI have no xH and xL bytes */
3307 i386_movb_reg_memindex(REG_ITMP3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
3311 case ICMD_PUTSTATIC: /* ..., value ==> ... */
3312 /* op1 = type, val.a = field address */
3314 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3315 switch (iptr->op1) {
3318 var_to_reg_int(s2, src, REG_ITMP1);
3319 i386_mov_imm_reg(0, REG_ITMP2);
3320 dseg_adddata(mcodeptr);
3321 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP3);
3322 i386_mov_reg_membase(s2, REG_ITMP3, 0);
3325 if (src->flags & INMEMORY) {
3326 i386_mov_imm_reg(0, REG_ITMP2);
3327 dseg_adddata(mcodeptr);
3328 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP3);
3329 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3330 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3331 i386_mov_reg_membase(REG_ITMP1, REG_ITMP3, 0);
3332 i386_mov_reg_membase(REG_ITMP2, REG_ITMP3, 0 + 4);
3334 panic("longs have to be in memory");
3338 if (src->flags & INMEMORY) {
3339 i386_mov_imm_reg(0, REG_ITMP1);
3340 dseg_adddata(mcodeptr);
3341 i386_mov_membase_reg(REG_ITMP1, a, REG_ITMP2);
3342 i386_flds_membase(REG_SP, src->regoff * 8);
3343 i386_fsts_membase(REG_ITMP2, 0);
3345 panic("floats have to be in memory");
3349 if (src->flags & INMEMORY) {
3350 i386_mov_imm_reg(0, REG_ITMP1);
3351 dseg_adddata(mcodeptr);
3352 i386_mov_membase_reg(REG_ITMP1, a, REG_ITMP2);
3353 i386_fldl_membase(REG_SP, src->regoff * 8);
3354 i386_fstl_membase(REG_ITMP2, 0);
3356 panic("doubles have to be in memory");
3359 default: panic ("internal error");
3363 case ICMD_GETSTATIC: /* ... ==> ..., value */
3364 /* op1 = type, val.a = field address */
3366 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3367 i386_mov_imm_reg(0, REG_ITMP1);
3368 dseg_adddata(mcodeptr);
3369 i386_mov_membase_reg(REG_ITMP1, a, REG_ITMP1);
3370 switch (iptr->op1) {
3373 d = reg_of_var(iptr->dst, REG_ITMP3);
3374 i386_mov_membase_reg(REG_ITMP1, 0, d);
3375 store_reg_to_var_int(iptr->dst, d);
3378 d = reg_of_var(iptr->dst, REG_ITMP3);
3379 if (iptr->dst->flags & INMEMORY) {
3380 i386_mov_membase_reg(REG_ITMP1, 0, REG_ITMP2);
3381 i386_mov_membase_reg(REG_ITMP1, 4, REG_ITMP3);
3382 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3383 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
3385 panic("longs have to be in memory");
3389 d = reg_of_var(iptr->dst, REG_ITMP3);
3390 if (iptr->dst->flags & INMEMORY) {
3391 i386_flds_membase(REG_ITMP1, 0);
3392 i386_fsts_membase(REG_SP, iptr->dst->regoff * 8);
3394 panic("floats have to be in memory");
3398 d = reg_of_var(iptr->dst, REG_ITMP3);
3399 if (iptr->dst->flags & INMEMORY) {
3400 i386_fldl_membase(REG_ITMP1, 0);
3401 i386_fstl_membase(REG_SP, iptr->dst->regoff * 8);
3403 panic("doubles have to be in memory");
3406 default: panic ("internal error");
3410 case ICMD_PUTFIELD: /* ..., value ==> ... */
3411 /* op1 = type, val.i = field offset */
3413 a = ((fieldinfo *)(iptr->val.a))->offset;
3414 switch (iptr->op1) {
3417 var_to_reg_int(s1, src->prev, REG_ITMP1);
3418 var_to_reg_int(s2, src, REG_ITMP2);
3419 gen_nullptr_check(s1);
3420 i386_mov_reg_membase(s2, s1, a);
3423 var_to_reg_int(s1, src->prev, REG_ITMP1);
3424 gen_nullptr_check(s1);
3425 if (src->flags & INMEMORY) {
3426 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3427 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
3428 i386_mov_reg_membase(REG_ITMP2, s1, a);
3429 i386_mov_reg_membase(REG_ITMP3, s1, a + 4);
3431 panic("longs have to be in memory");
3435 var_to_reg_int(s1, src->prev, REG_ITMP1);
3436 gen_nullptr_check(s1);
3437 if (src->flags & INMEMORY) {
3438 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3439 i386_mov_reg_membase(REG_ITMP2, s1, a);
3441 panic("floats have to be in memory");
3445 var_to_reg_int(s1, src->prev, REG_ITMP1);
3446 gen_nullptr_check(s1);
3447 if (src->flags & INMEMORY) {
3448 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3449 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
3450 i386_mov_reg_membase(REG_ITMP2, s1, a);
3451 i386_mov_reg_membase(REG_ITMP3, s1, a + 4);
3453 panic("doubles have to be in memory");
3456 default: panic ("internal error");
3460 case ICMD_GETFIELD: /* ... ==> ..., value */
3461 /* op1 = type, val.i = field offset */
3463 a = ((fieldinfo *)(iptr->val.a))->offset;
3464 switch (iptr->op1) {
3466 var_to_reg_int(s1, src, REG_ITMP1);
3467 d = reg_of_var(iptr->dst, REG_ITMP3);
3468 gen_nullptr_check(s1);
3469 i386_mov_membase_reg(s1, a, d);
3470 store_reg_to_var_int(iptr->dst, d);
3473 var_to_reg_int(s1, src, REG_ITMP1);
3474 /* d = reg_of_var(iptr->dst, REG_ITMP3); */
3475 gen_nullptr_check(s1);
3476 i386_mov_membase_reg(s1, a, REG_ITMP2);
3477 i386_mov_membase_reg(s1, a + 4, REG_ITMP3);
3478 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3479 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
3480 /* store_reg_to_var_int(iptr->dst, d); */
3483 var_to_reg_int(s1, src, REG_ITMP1);
3484 d = reg_of_var(iptr->dst, REG_ITMP3);
3485 gen_nullptr_check(s1);
3486 i386_mov_membase_reg(s1, a, d);
3487 store_reg_to_var_int(iptr->dst, d);
3490 var_to_reg_int(s1, src, REG_ITMP1);
3491 d = reg_of_var(iptr->dst, REG_FTMP1);
3492 gen_nullptr_check(s1);
3493 i386_flds_membase(s1, a);
3494 /* store_reg_to_var_flt(iptr->dst, d); */
3497 var_to_reg_int(s1, src, REG_ITMP1);
3498 d = reg_of_var(iptr->dst, REG_FTMP1);
3499 gen_nullptr_check(s1);
3500 i386_fldl_membase(s1, a);
3501 /* store_reg_to_var_flt(iptr->dst, d); */
3503 default: panic ("internal error");
3508 /* branch operations **************************************************/
3511 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3512 #define ALIGNCODENOP do {} while (0)
3514 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3516 var_to_reg_int(s1, src, REG_ITMP1);
3517 M_INTMOVE(s1, REG_ITMP1_XPTR);
3518 i386_mov_imm_reg(asm_handle_exception, REG_ITMP2);
3519 i386_call_reg(REG_ITMP2);
3520 i386_nop(); /* nop ensures that XPC is less than the end */
3521 /* of basic block */
3525 case ICMD_GOTO: /* ... ==> ... */
3526 /* op1 = target JavaVM pc */
3529 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3533 case ICMD_JSR: /* ... ==> ... */
3534 /* op1 = target JavaVM pc */
3537 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3540 case ICMD_RET: /* ... ==> ... */
3541 /* op1 = local variable */
3546 case ICMD_IFNULL: /* ..., value ==> ... */
3547 /* op1 = target JavaVM pc */
3549 if (src->flags & INMEMORY) {
3550 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3553 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
3555 i386_jcc(I386_CC_E, 0);
3556 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3559 case ICMD_IFNONNULL: /* ..., value ==> ... */
3560 /* op1 = target JavaVM pc */
3562 if (src->flags & INMEMORY) {
3563 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3566 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
3568 i386_jcc(I386_CC_NE, 0);
3569 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3572 case ICMD_IFEQ: /* ..., value ==> ... */
3573 /* op1 = target JavaVM pc, val.i = constant */
3575 if (src->flags & INMEMORY) {
3576 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3579 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3581 i386_jcc(I386_CC_E, 0);
3582 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3585 case ICMD_IFLT: /* ..., value ==> ... */
3586 /* op1 = target JavaVM pc, val.i = constant */
3588 if (src->flags & INMEMORY) {
3589 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3592 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3594 i386_jcc(I386_CC_L, 0);
3595 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3598 case ICMD_IFLE: /* ..., value ==> ... */
3599 /* op1 = target JavaVM pc, val.i = constant */
3601 if (src->flags & INMEMORY) {
3602 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3605 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3607 i386_jcc(I386_CC_LE, 0);
3608 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3611 case ICMD_IFNE: /* ..., value ==> ... */
3612 /* op1 = target JavaVM pc, val.i = constant */
3614 if (src->flags & INMEMORY) {
3615 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3618 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3620 i386_jcc(I386_CC_NE, 0);
3621 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3624 case ICMD_IFGT: /* ..., value ==> ... */
3625 /* op1 = target JavaVM pc, val.i = constant */
3627 if (src->flags & INMEMORY) {
3628 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3631 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3633 i386_jcc(I386_CC_G, 0);
3634 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3637 case ICMD_IFGE: /* ..., value ==> ... */
3638 /* op1 = target JavaVM pc, val.i = constant */
3640 if (src->flags & INMEMORY) {
3641 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3644 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3646 i386_jcc(I386_CC_GE, 0);
3647 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3650 case ICMD_IF_LEQ: /* ..., value ==> ... */
3651 /* op1 = target JavaVM pc, val.l = constant */
3653 if (src->flags & INMEMORY) {
3654 if (iptr->val.l == 0) {
3655 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3656 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3658 } else if (iptr->val.l > 0 && iptr->val.l <= 0x00000000ffffffff) {
3659 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3660 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3661 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3664 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3665 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3666 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3667 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3668 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3671 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3672 i386_jcc(I386_CC_NE, 0);
3673 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3676 case ICMD_IF_LLT: /* ..., value ==> ... */
3677 /* op1 = target JavaVM pc, val.l = constant */
3679 /* TODO: optimize as in IF_LEQ */
3680 if (src->flags & INMEMORY) {
3682 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3683 i386_jcc(I386_CC_L, 0);
3684 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3687 if (src->regoff > 0) offset++;
3688 if (src->regoff > 31) offset += 3;
3690 i386_jcc(I386_CC_G, offset);
3692 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3693 i386_jcc(I386_CC_B, 0);
3694 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3698 case ICMD_IF_LLE: /* ..., value ==> ... */
3699 /* op1 = target JavaVM pc, val.l = constant */
3701 /* TODO: optimize as in IF_LEQ */
3702 if (src->flags & INMEMORY) {
3704 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3705 i386_jcc(I386_CC_L, 0);
3706 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3709 if (src->regoff > 0) offset++;
3710 if (src->regoff > 31) offset += 3;
3712 i386_jcc(I386_CC_G, offset);
3714 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3715 i386_jcc(I386_CC_BE, 0);
3716 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3720 case ICMD_IF_LNE: /* ..., value ==> ... */
3721 /* op1 = target JavaVM pc, val.l = constant */
3723 /* TODO: optimize for val.l == 0 */
3724 if (src->flags & INMEMORY) {
3725 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
3726 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
3727 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3728 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3729 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3730 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3732 i386_jcc(I386_CC_NE, 0);
3733 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3736 case ICMD_IF_LGT: /* ..., value ==> ... */
3737 /* op1 = target JavaVM pc, val.l = constant */
3739 /* TODO: optimize as in IF_LEQ */
3740 if (src->flags & INMEMORY) {
3742 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3743 i386_jcc(I386_CC_G, 0);
3744 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3747 if (src->regoff > 0) offset++;
3748 if (src->regoff > 31) offset += 3;
3749 if ((iptr->val.l & 0x00000000ffffffff) < -128 || (iptr->val.l & 0x00000000ffffffff) > 127) offset += 3;
3751 i386_jcc(I386_CC_L, offset);
3753 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3754 i386_jcc(I386_CC_A, 0);
3755 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3759 case ICMD_IF_LGE: /* ..., value ==> ... */
3760 /* op1 = target JavaVM pc, val.l = constant */
3762 /* TODO: optimize as in IF_LEQ */
3763 if (src->flags & INMEMORY) {
3765 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3766 i386_jcc(I386_CC_G, 0);
3767 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3770 if (src->regoff > 0) offset++;
3771 if (src->regoff > 31) offset += 3;
3773 i386_jcc(I386_CC_L, offset);
3775 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3776 i386_jcc(I386_CC_AE, 0);
3777 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3781 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3782 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3784 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3785 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3786 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3788 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3789 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3791 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3792 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3795 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3797 i386_jcc(I386_CC_E, 0);
3798 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3801 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3802 /* op1 = target JavaVM pc */
3804 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3805 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3806 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3807 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3808 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3809 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3810 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3812 i386_jcc(I386_CC_E, 0);
3813 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3816 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3817 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3819 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3820 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3821 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3823 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3824 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3826 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3827 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3830 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3832 i386_jcc(I386_CC_NE, 0);
3833 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3836 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3837 /* op1 = target JavaVM pc */
3839 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3840 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3841 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3842 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3843 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3844 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3845 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3847 i386_jcc(I386_CC_NE, 0);
3848 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3851 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3852 /* op1 = target JavaVM pc */
3854 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3855 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3856 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3858 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3859 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3861 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3862 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3865 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3867 i386_jcc(I386_CC_L, 0);
3868 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3871 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3872 /* op1 = target JavaVM pc */
3874 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3876 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3877 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3878 i386_jcc(I386_CC_L, 0);
3879 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3882 if (src->prev->regoff > 0) offset++;
3883 if (src->prev->regoff > 31) offset += 3;
3885 if (src->regoff > 0) offset++;
3886 if (src->regoff > 31) offset += 3;
3888 i386_jcc(I386_CC_G, offset);
3890 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3891 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3892 i386_jcc(I386_CC_B, 0);
3893 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3897 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3898 /* op1 = target JavaVM pc */
3900 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3901 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3902 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3904 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3905 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3907 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3908 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3911 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3913 i386_jcc(I386_CC_G, 0);
3914 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3917 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3918 /* op1 = target JavaVM pc */
3920 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3922 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3923 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3924 i386_jcc(I386_CC_G, 0);
3925 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3928 if (src->prev->regoff > 0) offset++;
3929 if (src->prev->regoff > 31) offset += 3;
3931 if (src->regoff > 0) offset++;
3932 if (src->regoff > 31) offset += 3;
3934 i386_jcc(I386_CC_L, offset);
3936 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3937 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3938 i386_jcc(I386_CC_A, 0);
3939 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3943 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3944 /* op1 = target JavaVM pc */
3946 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3947 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3948 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3950 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3951 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3953 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3954 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3957 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3959 i386_jcc(I386_CC_LE, 0);
3960 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3963 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3964 /* op1 = target JavaVM pc */
3966 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3968 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3969 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3970 i386_jcc(I386_CC_L, 0);
3971 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3974 if (src->prev->regoff > 0) offset++;
3975 if (src->prev->regoff > 31) offset += 3;
3977 if (src->regoff > 0) offset++;
3978 if (src->regoff > 31) offset += 3;
3980 i386_jcc(I386_CC_G, offset);
3982 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3983 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3984 i386_jcc(I386_CC_BE, 0);
3985 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3989 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3990 /* op1 = target JavaVM pc */
3992 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3993 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3994 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3996 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3997 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3999 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4000 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4003 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4005 i386_jcc(I386_CC_GE, 0);
4006 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4009 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
4010 /* op1 = target JavaVM pc */
4012 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4014 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
4015 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4016 i386_jcc(I386_CC_G, 0);
4017 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4020 if (src->prev->regoff > 0) offset++;
4021 if (src->prev->regoff > 31) offset += 3;
4023 if (src->regoff > 0) offset++;
4024 if (src->regoff > 31) offset += 3;
4026 i386_jcc(I386_CC_L, offset);
4028 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4029 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
4030 i386_jcc(I386_CC_AE, 0);
4031 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4035 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
4037 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
4040 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
4041 /* val.i = constant */
4043 var_to_reg_int(s1, src, REG_ITMP1);
4044 d = reg_of_var(iptr->dst, REG_ITMP3);
4046 if (iptr[1].opc == ICMD_ELSE_ICONST) {
4047 if ((s3 == 1) && (iptr[1].val.i == 0)) {
4048 M_CMPEQ(s1, REG_ZERO, d);
4049 store_reg_to_var_int(iptr->dst, d);
4052 if ((s3 == 0) && (iptr[1].val.i == 1)) {
4053 M_CMPEQ(s1, REG_ZERO, d);
4055 store_reg_to_var_int(iptr->dst, d);
4059 M_MOV(s1, REG_ITMP1);
4062 /* ICONST(d, iptr[1].val.i); */
4064 if ((s3 >= 0) && (s3 <= 255)) {
4065 M_CMOVEQ_IMM(s1, s3, d);
4068 /* ICONST(REG_ITMP2, s3); */
4069 M_CMOVEQ(s1, REG_ITMP2, d);
4071 store_reg_to_var_int(iptr->dst, d);
4074 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
4075 /* val.i = constant */
4077 var_to_reg_int(s1, src, REG_ITMP1);
4078 d = reg_of_var(iptr->dst, REG_ITMP3);
4080 if (iptr[1].opc == ICMD_ELSE_ICONST) {
4081 if ((s3 == 0) && (iptr[1].val.i == 1)) {
4082 M_CMPEQ(s1, REG_ZERO, d);
4083 store_reg_to_var_int(iptr->dst, d);
4086 if ((s3 == 1) && (iptr[1].val.i == 0)) {
4087 M_CMPEQ(s1, REG_ZERO, d);
4089 store_reg_to_var_int(iptr->dst, d);
4093 M_MOV(s1, REG_ITMP1);
4096 /* ICONST(d, iptr[1].val.i); */
4098 if ((s3 >= 0) && (s3 <= 255)) {
4099 M_CMOVNE_IMM(s1, s3, d);
4102 /* ICONST(REG_ITMP2, s3); */
4103 M_CMOVNE(s1, REG_ITMP2, d);
4105 store_reg_to_var_int(iptr->dst, d);
4108 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
4109 /* val.i = constant */
4111 var_to_reg_int(s1, src, REG_ITMP1);
4112 d = reg_of_var(iptr->dst, REG_ITMP3);
4114 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4115 if ((s3 == 1) && (iptr[1].val.i == 0)) {
4116 M_CMPLT(s1, REG_ZERO, d);
4117 store_reg_to_var_int(iptr->dst, d);
4120 if ((s3 == 0) && (iptr[1].val.i == 1)) {
4121 M_CMPLE(REG_ZERO, s1, d);
4122 store_reg_to_var_int(iptr->dst, d);
4126 M_MOV(s1, REG_ITMP1);
4129 /* ICONST(d, iptr[1].val.i); */
4131 if ((s3 >= 0) && (s3 <= 255)) {
4132 M_CMOVLT_IMM(s1, s3, d);
4135 /* ICONST(REG_ITMP2, s3); */
4136 M_CMOVLT(s1, REG_ITMP2, d);
4138 store_reg_to_var_int(iptr->dst, d);
4141 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
4142 /* val.i = constant */
4144 d = reg_of_var(iptr->dst, REG_ITMP3);
4145 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4146 if (iptr->dst->flags & INMEMORY) {
4147 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4150 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4154 if (iptr->dst->flags & INMEMORY) {
4157 if (iptr->dst->regoff > 0) offset += 1;
4158 if (iptr->dst->regoff > 31) offset += 3;
4160 if (src->flags & INMEMORY) {
4161 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4162 i386_jcc(I386_CC_L, offset);
4163 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4166 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4167 i386_jcc(I386_CC_L, offset);
4168 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4172 if (src->flags & INMEMORY) {
4173 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4174 i386_jcc(I386_CC_L, 5);
4175 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4178 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4179 i386_jcc(I386_CC_L, 5);
4180 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4185 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
4186 /* val.i = constant */
4188 var_to_reg_int(s1, src, REG_ITMP1);
4189 d = reg_of_var(iptr->dst, REG_ITMP3);
4191 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4192 if ((s3 == 1) && (iptr[1].val.i == 0)) {
4193 M_CMPLT(REG_ZERO, s1, d);
4194 store_reg_to_var_int(iptr->dst, d);
4197 if ((s3 == 0) && (iptr[1].val.i == 1)) {
4198 M_CMPLE(s1, REG_ZERO, d);
4199 store_reg_to_var_int(iptr->dst, d);
4203 M_MOV(s1, REG_ITMP1);
4206 /* ICONST(d, iptr[1].val.i); */
4208 if ((s3 >= 0) && (s3 <= 255)) {
4209 M_CMOVGT_IMM(s1, s3, d);
4212 /* ICONST(REG_ITMP2, s3); */
4213 M_CMOVGT(s1, REG_ITMP2, d);
4215 store_reg_to_var_int(iptr->dst, d);
4218 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
4219 /* val.i = constant */
4221 d = reg_of_var(iptr->dst, REG_ITMP3);
4222 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4223 if (iptr->dst->flags & INMEMORY) {
4224 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4227 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4231 if (iptr->dst->flags & INMEMORY) {
4234 if (iptr->dst->regoff > 0) offset += 1;
4235 if (iptr->dst->regoff > 31) offset += 3;
4237 if (src->flags & INMEMORY) {
4238 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4241 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4244 i386_jcc(I386_CC_G, offset);
4245 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4248 if (src->flags & INMEMORY) {
4249 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4252 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4255 i386_jcc(I386_CC_G, 5);
4256 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4261 case ICMD_IRETURN: /* ..., retvalue ==> ... */
4265 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4266 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4267 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4268 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4269 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4270 i386_call_reg(REG_ITMP1);
4271 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4274 var_to_reg_int(s1, src, REG_RESULT);
4275 M_INTMOVE(s1, REG_RESULT);
4276 goto nowperformreturn;
4278 case ICMD_LRETURN: /* ..., retvalue ==> ... */
4281 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4282 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4283 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4284 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4285 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4286 i386_call_reg(REG_ITMP1);
4287 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4290 if (src->flags & INMEMORY) {
4291 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
4292 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
4295 panic("longs have to be in memory");
4297 goto nowperformreturn;
4299 case ICMD_FRETURN: /* ..., retvalue ==> ... */
4303 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4304 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4305 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4306 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4307 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4308 i386_call_reg(REG_ITMP1);
4309 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4312 /* value should already be in st(0) */
4313 goto nowperformreturn;
4315 case ICMD_RETURN: /* ... ==> ... */
4318 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4319 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4320 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4321 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4322 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4323 i386_call_reg(REG_ITMP1);
4324 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4332 p = parentargs_base;
4334 /* restore return address */
4336 if (!isleafmethod) {
4337 /* p--; M_LLD (REG_RA, REG_SP, 8 * p); -- do we really need this on i386 */
4340 /* restore saved registers */
4342 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
4343 p--; i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
4345 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
4346 p--; M_DLD(savfltregs[r], REG_SP, 8 * p);
4349 /* deallocate stack */
4351 if (parentargs_base) {
4352 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
4355 /* call trace function */
4358 M_LDA (REG_SP, REG_SP, -24);
4359 M_AST(REG_RA, REG_SP, 0);
4360 M_LST(REG_RESULT, REG_SP, 8);
4361 M_DST(REG_FRESULT, REG_SP,16);
4362 a = dseg_addaddress (method);
4363 M_ALD(argintregs[0], REG_PV, a);
4364 M_MOV(REG_RESULT, argintregs[1]);
4365 M_FLTMOVE(REG_FRESULT, argfltregs[2]);
4366 a = dseg_addaddress ((void*) (builtin_displaymethodstop));
4367 M_ALD(REG_PV, REG_PV, a);
4368 M_JSR (REG_RA, REG_PV);
4369 s1 = (int)((u1*) mcodeptr - mcodebase);
4370 if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1);
4373 while (ml<-32768) { ml+=65536; mh--; }
4374 M_LDA (REG_PV, REG_RA, ml );
4375 M_LDAH (REG_PV, REG_PV, mh );
4377 M_DLD(REG_FRESULT, REG_SP,16);
4378 M_LLD(REG_RESULT, REG_SP, 8);
4379 M_ALD(REG_RA, REG_SP, 0);
4380 M_LDA (REG_SP, REG_SP, 24);
4389 case ICMD_TABLESWITCH: /* ..., index ==> ... */
4394 tptr = (void **) iptr->target;
4396 s4ptr = iptr->val.a;
4397 l = s4ptr[1]; /* low */
4398 i = s4ptr[2]; /* high */
4400 var_to_reg_int(s1, src, REG_ITMP1);
4402 M_INTMOVE(s1, REG_ITMP1);
4403 } else if (l <= 32768) {
4404 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
4410 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
4411 i386_jcc(I386_CC_A, 0);
4413 /* mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
4414 mcode_addreference((basicblock *) tptr[0], mcodeptr);
4416 /* build jump table top down and use address of lowest entry */
4418 /* s4ptr += 3 + i; */
4422 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
4423 dseg_addtarget((basicblock *) tptr[0]);
4427 /* length of dataseg after last dseg_addtarget is used by load */
4429 i386_mov_imm_reg(0, REG_ITMP2);
4430 dseg_adddata(mcodeptr);
4431 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP3);
4432 i386_jmp_reg(REG_ITMP3);
4438 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
4440 s4 i, l, val, *s4ptr;
4443 tptr = (void **) iptr->target;
4445 s4ptr = iptr->val.a;
4446 l = s4ptr[0]; /* default */
4447 i = s4ptr[1]; /* count */
4449 MCODECHECK((i<<2)+8);
4450 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
4456 i386_alu_imm_reg(I386_CMP, val, s1);
4457 i386_jcc(I386_CC_E, 0);
4458 /* mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
4459 mcode_addreference((basicblock *) tptr[0], mcodeptr);
4463 /* mcode_addreference(BlockPtrOfPC(l), mcodeptr); */
4465 tptr = (void **) iptr->target;
4466 mcode_addreference((basicblock *) tptr[0], mcodeptr);
4473 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
4474 /* op1 = return type, val.a = function pointer*/
4478 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
4479 /* op1 = return type, val.a = function pointer*/
4483 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
4484 /* op1 = return type, val.a = function pointer*/
4488 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
4489 /* op1 = arg count, val.a = method pointer */
4491 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
4492 /* op1 = arg count, val.a = method pointer */
4494 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
4495 /* op1 = arg count, val.a = method pointer */
4497 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
4498 /* op1 = arg count, val.a = method pointer */
4506 MCODECHECK((s3 << 1) + 64);
4508 /* copy arguments to registers or stack location */
4510 for (; --s3 >= 0; src = src->prev) {
4511 /* printf("regoff=%d\n", src->regoff); */
4512 if (src->varkind == ARGVAR) {
4513 /* printf("ARGVAR\n"); */
4516 if (IS_INT_LNG_TYPE(src->type)) {
4517 if (src->flags & INMEMORY) {
4518 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4519 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
4522 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 4);
4525 if (s3 < FLT_ARG_CNT) {
4526 s1 = argfltregs[s3];
4527 var_to_reg_flt(d, src, s1);
4531 var_to_reg_flt(d, src, REG_FTMP1);
4532 M_DST(d, REG_SP, 8 * (s3 - FLT_ARG_CNT));
4537 switch (iptr->opc) {
4544 i386_mov_imm_reg(a, REG_ITMP1);
4545 i386_call_reg(REG_ITMP1);
4546 goto makeactualcall;
4548 case ICMD_INVOKESTATIC:
4549 case ICMD_INVOKESPECIAL:
4551 a = (s4) m->stubroutine;
4553 i386_mov_imm_reg(a, REG_ITMP2);
4554 i386_call_reg(REG_ITMP2);
4555 goto makeactualcall;
4557 case ICMD_INVOKEVIRTUAL:
4559 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2);
4560 gen_nullptr_check(REG_ITMP2);
4561 i386_mov_membase_reg(REG_ITMP2, OFFSET(java_objectheader, vftbl), REG_ITMP3);
4562 i386_mov_membase32_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
4565 i386_call_reg(REG_ITMP1);
4566 goto makeactualcall;
4568 case ICMD_INVOKEINTERFACE:
4571 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2);
4572 gen_nullptr_check(REG_ITMP2);
4573 i386_mov_membase_reg(REG_ITMP2, OFFSET(java_objectheader, vftbl), REG_ITMP3);
4574 i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP3);
4575 i386_mov_membase32_reg(REG_ITMP3, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
4578 i386_call_reg(REG_ITMP1);
4579 goto makeactualcall;
4583 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
4589 /* d contains return type */
4591 if (d != TYPE_VOID) {
4592 d = reg_of_var(iptr->dst, REG_ITMP3);
4594 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4595 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4596 if (iptr->dst->flags & INMEMORY) {
4597 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4598 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4601 panic("longs have to be in memory");
4605 if (iptr->dst->flags & INMEMORY) {
4606 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4609 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4614 /* nothing to do for float/double */
4621 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4623 /* op1: 0 == array, 1 == class */
4624 /* val.a: (classinfo*) superclass */
4626 /* superclass is an interface:
4628 * return (sub != NULL) &&
4629 * (sub->vftbl->interfacetablelength > super->index) &&
4630 * (sub->vftbl->interfacetable[-super->index] != NULL);
4632 * superclass is a class:
4634 * return ((sub != NULL) && (0
4635 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4636 * super->vftbl->diffvall));
4640 classinfo *super = (classinfo*) iptr->val.a;
4642 var_to_reg_int(s1, src, REG_ITMP1);
4643 d = reg_of_var(iptr->dst, REG_ITMP3);
4644 /* if (s1 == d) { */
4645 /* M_MOV(s1, REG_ITMP1); */
4646 /* s1 = REG_ITMP1; */
4648 if (iptr->op1) { /* class/interface */
4649 if (super->flags & ACC_INTERFACE) { /* interface */
4651 i386_alu_imm_reg(I386_CMP, 0, s1);
4653 /* TODO: clean up this calculation */
4655 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
4658 CALCOFFSETBYTES(OFFSET(vftbl, interfacetablelength));
4661 CALCOFFSETBYTES(-super->index);
4667 CALCOFFSETBYTES(OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4672 i386_jcc(I386_CC_E, offset);
4674 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4675 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4676 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4677 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4679 /* TODO: clean up this calculation */
4682 CALCOFFSETBYTES(OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4687 offset += 6; /* jcc */
4690 i386_jcc(I386_CC_LE, offset);
4691 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4692 i386_alu_reg_reg(I386_XOR, d, d);
4693 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4694 /* i386_setcc_reg(I386_CC_A, d); */
4695 i386_jcc(I386_CC_BE, 5);
4696 i386_mov_imm_reg(1, d);
4699 } else { /* class */
4701 i386_alu_imm_reg(I386_CMP, 0, s1);
4703 /* TODO: clean up this calculation */
4705 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
4710 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
4713 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
4716 CALCOFFSETBYTES(OFFSET(vftbl, diffval));
4722 offset += 6; /* jcc */
4725 i386_jcc(I386_CC_E, offset);
4727 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4728 i386_mov_imm_reg((void *) super->vftbl, REG_ITMP2);
4729 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4730 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4731 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4732 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4733 i386_alu_reg_reg(I386_XOR, d, d);
4734 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4735 /* i386_setcc_reg(I386_CC_BE, d); */
4736 i386_jcc(I386_CC_A, 5);
4737 i386_mov_imm_reg(1, d);
4742 panic ("internal error: no inlined array instanceof");
4744 store_reg_to_var_int(iptr->dst, d);
4747 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4749 /* op1: 0 == array, 1 == class */
4750 /* val.a: (classinfo*) superclass */
4752 /* superclass is an interface:
4754 * OK if ((sub == NULL) ||
4755 * (sub->vftbl->interfacetablelength > super->index) &&
4756 * (sub->vftbl->interfacetable[-super->index] != NULL));
4758 * superclass is a class:
4760 * OK if ((sub == NULL) || (0
4761 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4762 * super->vftbl->diffvall));
4766 classinfo *super = (classinfo*) iptr->val.a;
4768 d = reg_of_var(iptr->dst, REG_ITMP3);
4769 var_to_reg_int(s1, src, d);
4770 if (iptr->op1) { /* class/interface */
4771 if (super->flags & ACC_INTERFACE) { /* interface */
4773 i386_alu_imm_reg(I386_CMP, 0, s1);
4775 /* TODO: clean up this calculation */
4777 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
4780 CALCOFFSETBYTES(OFFSET(vftbl, interfacetablelength));
4783 CALCOFFSETBYTES(-super->index);
4789 CALCOFFSETBYTES(OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4794 i386_jcc(I386_CC_E, offset);
4796 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4797 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4798 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4799 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4800 i386_jcc(I386_CC_LE, 0);
4801 mcode_addxcastrefs(mcodeptr);
4802 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4803 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4804 i386_jcc(I386_CC_E, 0);
4805 mcode_addxcastrefs(mcodeptr);
4807 } else { /* class */
4809 i386_alu_imm_reg(I386_CMP, 0, s1);
4811 /* TODO: clean up this calculation */
4813 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
4818 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
4820 if (d != REG_ITMP3) {
4822 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
4825 CALCOFFSETBYTES(OFFSET(vftbl, diffval));
4831 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
4838 CALCOFFSETBYTES(OFFSET(vftbl, diffval));
4845 i386_jcc(I386_CC_E, offset);
4847 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4848 i386_mov_imm_reg((void *) super->vftbl, REG_ITMP2);
4849 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4850 if (d != REG_ITMP3) {
4851 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4852 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4853 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4856 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
4857 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
4858 i386_mov_imm_reg((void *) super->vftbl, REG_ITMP2);
4859 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4861 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4862 i386_jcc(I386_CC_B, 0);
4863 mcode_addxcastrefs(mcodeptr);
4867 panic ("internal error: no inlined array checkcast");
4870 store_reg_to_var_int(iptr->dst, d);
4873 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4875 if (src->flags & INMEMORY) {
4876 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4879 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4881 i386_jcc(I386_CC_L, 0);
4882 mcode_addxcheckarefs(mcodeptr);
4885 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4886 /* op1 = dimension, val.a = array descriptor */
4888 /* check for negative sizes and copy sizes to stack if necessary */
4890 MCODECHECK((iptr->op1 << 1) + 64);
4892 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4893 /* var_to_reg_int(s2, src, REG_ITMP1); */
4894 if (src->flags & INMEMORY) {
4895 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4898 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4900 mcode_addxcheckarefs(mcodeptr);
4902 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4904 if (src->varkind != ARGVAR) {
4905 /* M_LST(s2, REG_SP, 8 * (s1 + INT_ARG_CNT)); */
4906 if (src->flags & INMEMORY) {
4907 i386_mov_membase_reg(REG_SP, (src->regoff + INT_ARG_CNT) * 8, REG_ITMP1);
4908 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + INT_ARG_CNT) * 8);
4911 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + INT_ARG_CNT) * 8);
4916 /* a0 = dimension count */
4919 /* ICONST(argintregs[0], iptr->op1); */
4920 i386_mov_imm_membase(iptr->op1, REG_SP, -12);
4922 /* a1 = arraydescriptor */
4924 /* a = dseg_addaddress(iptr->val.a); */
4925 /* M_ALD(argintregs[1], REG_PV, a); */
4926 i386_mov_imm_membase(iptr->val.a, REG_SP, -8);
4928 /* a2 = pointer to dimensions = stack pointer */
4930 /* M_INTMOVE(REG_SP, argintregs[2]); */
4931 i386_mov_reg_membase(REG_SP, REG_SP, -4);
4933 /* a = dseg_addaddress((void*) (builtin_nmultianewarray)); */
4934 /* M_ALD(REG_PV, REG_PV, a); */
4935 /* M_JSR(REG_RA, REG_PV); */
4936 i386_call_imm((void*) (builtin_nmultianewarray));
4937 s1 = (int)((u1*) mcodeptr - mcodebase);
4939 M_LDA (REG_PV, REG_RA, -s1);
4941 s4 ml = -s1, mh = 0;
4942 while (ml < -32768) {ml += 65536; mh--;}
4943 M_LDA(REG_PV, REG_RA, ml);
4944 M_LDAH(REG_PV, REG_PV, mh);
4946 s1 = reg_of_var(iptr->dst, REG_RESULT);
4947 M_INTMOVE(REG_RESULT, s1);
4948 store_reg_to_var_int(iptr->dst, s1);
4952 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
4959 } /* for instruction */
4961 /* copy values to interface registers */
4963 src = bptr->outstack;
4964 len = bptr->outdepth;
4968 if ((src->varkind != STACKVAR)) {
4970 if (IS_FLT_DBL_TYPE(s2)) {
4971 var_to_reg_flt(s1, src, REG_FTMP1);
4972 if (!(interfaces[len][s2].flags & INMEMORY)) {
4973 M_FLTMOVE(s1,interfaces[len][s2].regoff);
4976 M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
4980 var_to_reg_int(s1, src, REG_ITMP1);
4981 if (!(interfaces[len][s2].flags & INMEMORY)) {
4982 M_INTMOVE(s1,interfaces[len][s2].regoff);
4985 M_LST(s1, REG_SP, 8 * interfaces[len][s2].regoff);
4991 } /* if (bptr -> flags >= BBREACHED) */
4992 } /* for basic block */
4994 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
4998 /* generate bound check stubs */
4999 s4 *xcodeptr = NULL;
5001 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
5002 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5003 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
5004 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 3));
5009 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
5010 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
5014 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5015 dseg_adddata(mcodeptr);
5016 i386_alu_imm_reg(I386_ADD, xboundrefs->branchpos - 4, REG_ITMP2_XPC); /* 3 bytes */
5018 if (xcodeptr != NULL) {
5019 i386_jmp((xcodeptr - mcodeptr) - 1);
5022 xcodeptr = mcodeptr;
5024 i386_mov_imm_reg(proto_java_lang_ArrayIndexOutOfBoundsException, REG_ITMP1_XPTR);
5025 i386_mov_imm_reg(asm_handle_exception, REG_ITMP3);
5026 i386_jmp_reg(REG_ITMP3);
5030 /* generate negative array size check stubs */
5033 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
5034 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5035 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
5036 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 3));
5040 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
5041 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
5045 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5046 dseg_adddata(mcodeptr);
5047 i386_alu_imm_reg(I386_ADD, xcheckarefs->branchpos - 4, REG_ITMP2_XPC); /* 3 bytes */
5049 if (xcodeptr != NULL) {
5050 i386_jmp((xcodeptr - mcodeptr) - 1);
5053 xcodeptr = mcodeptr;
5055 i386_mov_imm_reg(proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR);
5056 i386_mov_imm_reg(asm_handle_exception, REG_ITMP3);
5057 i386_jmp_reg(REG_ITMP3);
5061 /* generate cast check stubs */
5064 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
5065 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5066 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
5067 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 3));
5071 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
5072 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
5076 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5077 dseg_adddata(mcodeptr);
5078 i386_alu_imm_reg(I386_ADD, xcastrefs->branchpos - 4, REG_ITMP2_XPC); /* 3 bytes (max. 6 bytes) */
5080 if (xcodeptr != NULL) {
5081 i386_jmp(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5084 xcodeptr = mcodeptr;
5086 i386_mov_imm_reg(proto_java_lang_ClassCastException, REG_ITMP1_XPTR);
5087 i386_mov_imm_reg(asm_handle_exception, REG_ITMP3);
5088 i386_jmp_reg(REG_ITMP3);
5092 #ifdef SOFTNULLPTRCHECK
5094 /* generate cast check stubs */
5097 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
5098 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5099 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
5100 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - 4);
5104 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
5105 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
5109 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5110 dseg_adddata(mcodeptr);
5111 i386_alu_imm_reg(I386_ADD, xnullrefs->branchpos - 4, REG_ITMP2_XPC); /* 3 bytes */
5113 if (xcodeptr != NULL) {
5114 i386_jmp((xcodeptr - mcodeptr) - 1);
5117 xcodeptr = mcodeptr;
5119 i386_mov_imm_reg(proto_java_lang_NullPointerException, REG_ITMP1_XPTR);
5120 i386_mov_imm_reg(asm_handle_exception, REG_ITMP3);
5121 i386_jmp_reg(REG_ITMP3);
5128 mcode_finish((int)((u1*) mcodeptr - mcodebase));
5132 /* function createcompilerstub *************************************************
5134 creates a stub routine which calls the compiler
5136 *******************************************************************************/
5138 #define COMPSTUBSIZE 3
5140 u1 *createcompilerstub (methodinfo *m)
5142 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
5143 s4 *p = (s4*) s; /* code generation pointer */
5145 s4 *mcodeptr = p; /* make macros work */
5147 /* code for the stub */
5148 i386_mov_imm_reg(m, I386_EAX); /* pass method pointer to compiler */
5149 i386_mov_imm_reg(asm_call_jit_compiler, REG_ITMP2); /* load address */
5150 i386_jmp_reg(REG_ITMP2); /* jump to compiler */
5153 count_cstub_len += COMPSTUBSIZE * 8;
5160 /* function removecompilerstub *************************************************
5162 deletes a compilerstub from memory (simply by freeing it)
5164 *******************************************************************************/
5166 void removecompilerstub (u1 *stub)
5168 CFREE (stub, COMPSTUBSIZE * 8);
5171 /* function: createnativestub **************************************************
5173 creates a stub routine which calls a native method
5175 *******************************************************************************/
5177 #define NATIVESTUBSIZE 18
5179 u1 *createnativestub (functionptr f, methodinfo *m)
5181 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
5182 s4 *p = (s4*) s; /* code generation pointer */
5184 /* TWISTI: get rid of those 2nd defines */
5190 /* M_MOV (argintregs[4],argintregs[5]); */
5191 /* M_FMOV (argfltregs[4],argfltregs[5]); */
5193 /* M_MOV (argintregs[3],argintregs[4]); */
5194 /* M_FMOV (argfltregs[3],argfltregs[4]); */
5196 /* M_MOV (argintregs[2],argintregs[3]); */
5197 /* M_FMOV (argfltregs[2],argfltregs[3]); */
5199 /* M_MOV (argintregs[1],argintregs[2]); */
5200 /* M_FMOV (argfltregs[1],argfltregs[2]); */
5202 /* M_MOV (argintregs[0],argintregs[1]); */
5203 /* M_FMOV (argfltregs[0],argfltregs[1]); */
5205 /* M_ALD (argintregs[0], REG_PV, 17*8); /* load adress of jni_environement */
5207 /* M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */
5208 /* M_AST (REG_RA, REG_SP, 0); /* store return address */
5210 /* M_ALD (REG_PV, REG_PV, 14*8); /* load adress of native method */
5211 /* M_JSR (REG_RA, REG_PV); /* call native method */
5213 i386_alu_imm_reg(I386_SUB, 24, REG_SP); /* 20 = 5 * 4 (5 params * 4 bytes) */
5215 i386_mov_membase_reg(REG_SP, 24 + 4, REG_ITMP1);
5216 i386_mov_reg_membase(REG_ITMP1, REG_SP, 4);
5218 i386_mov_membase_reg(REG_SP, 32 + 4, REG_ITMP1);
5219 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
5221 i386_mov_membase_reg(REG_SP, 40 + 4, REG_ITMP1);
5222 i386_mov_reg_membase(REG_ITMP1, REG_SP, 12);
5224 i386_mov_membase_reg(REG_SP, 48 + 4, REG_ITMP1);
5225 i386_mov_reg_membase(REG_ITMP1, REG_SP, 16);
5227 i386_mov_membase_reg(REG_SP, 56 + 4, REG_ITMP1);
5228 i386_mov_reg_membase(REG_ITMP1, REG_SP, 20);
5230 i386_mov_imm_membase(&env, REG_SP, 0);
5232 i386_mov_imm_reg(f, REG_ITMP1);
5233 i386_call_reg(REG_ITMP1);
5235 i386_alu_imm_reg(I386_ADD, 24, REG_SP);
5237 /* M_LDA (REG_PV, REG_RA, -15*4); /* recompute pv from ra */
5238 /* M_ALD (REG_ITMP3, REG_PV, 15*8); /* get address of exceptionptr */
5240 /* M_ALD (REG_RA, REG_SP, 0); /* load return address */
5241 /* M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
5243 /* M_LDA (REG_SP, REG_SP, 8); /* remove stackframe */
5244 /* M_BNEZ (REG_ITMP1, 1); /* if no exception then return */
5246 /* M_RET (REG_ZERO, REG_RA); /* return to caller */
5249 /* M_AST (REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
5250 /* M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
5252 /* M_ALD (REG_ITMP3, REG_PV,16*8); /* load asm exception handler address */
5253 /* M_JMP (REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
5257 /* s[14] = (u8) f; /* address of native method */
5258 /* s[15] = (u8) (&exceptionptr); /* address of exceptionptr */
5259 /* s[16] = (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
5260 /* s[17] = (u8) (&env); /* addr of jni_environement */
5261 s[14] = (u4) f; /* address of native method */
5262 s[15] = (u8) (&exceptionptr); /* address of exceptionptr */
5263 s[16] = (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
5264 s[17] = (u8) (&env); /* addr of jni_environement */
5267 count_nstub_len += NATIVESTUBSIZE * 8;
5273 /* function: removenativestub **************************************************
5275 removes a previously created native-stub from memory
5277 *******************************************************************************/
5279 void removenativestub (u1 *stub)
5281 CFREE (stub, NATIVESTUBSIZE * 8);
5286 * These are local overrides for various environment variables in Emacs.
5287 * Please do not remove this and leave it at the end of the file, where
5288 * Emacs will automagically detect them.
5289 * ---------------------------------------------------------------------
5292 * indent-tabs-mode: t