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 294 2003-05-12 21:01:48Z 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) \
34 if ((s4) (val) < -128 || (s4) (val) > 127) offset += 4; \
35 else if ((s4) (val) != 0) offset += 1;
38 #define CALCREGOFFBYTES(val) \
39 if ((val) > 15) offset += 4; \
40 else if ((val) != 0) offset += 1;
43 #define CALCIMMEDIATEBYTES(val) \
44 if ((s4) (val) < -128 || (s4) (val) > 127) offset += 4; \
48 /* gen_nullptr_check(objreg) */
50 #ifdef SOFTNULLPTRCHECK
51 #define gen_nullptr_check(objreg) \
53 i386_alu_imm_reg(I386_CMP, 0, (objreg)); \
54 i386_jcc(I386_CC_E, 0); \
55 mcode_addxnullrefs(mcodeptr); \
58 #define gen_nullptr_check(objreg)
62 /* MCODECHECK(icnt) */
64 #define MCODECHECK(icnt) \
65 if ((mcodeptr + (icnt)) > mcodeend) mcodeptr = mcode_increase((u1*) mcodeptr)
68 generates an integer-move from register a to b.
69 if a and b are the same int-register, no code will be generated.
72 #define M_INTMOVE(reg,dreg) if ((reg) != (dreg)) { i386_mov_reg_reg((reg),(dreg)); }
76 generates a floating-point-move from register a to b.
77 if a and b are the same float-register, no code will be generated
80 #define M_FLTMOVE(reg,dreg) if ((reg) != (dreg)){ M_OP3(0,0,0,0,0,0); }
82 #define M_LNGMEMMOVE(reg,dreg) \
84 i386_mov_membase_reg(REG_SP, (reg) * 8, REG_ITMP1); \
85 i386_mov_membase_reg(REG_SP, (reg) * 8 + 4, REG_ITMP2); \
86 i386_mov_reg_membase(REG_ITMP1, REG_SP, (dreg) * 8); \
87 i386_mov_reg_membase(REG_ITMP2, REG_SP, (dreg) * 8 + 4); \
92 this function generates code to fetch data from a pseudo-register
94 If the pseudo-register has actually been assigned to a real
95 register, no code will be emitted, since following operations
96 can use this register directly.
98 v: pseudoregister to be fetched from
99 tempregnum: temporary register to be used if v is actually spilled to ram
101 return: the register number, where the operand can be found after
102 fetching (this wil be either tempregnum or the register
103 number allready given to v)
106 #define var_to_reg_int(regnr,v,tempnr) \
107 if ((v)->flags & INMEMORY) { \
109 i386_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
112 regnr = (v)->regoff; \
117 #define var_to_reg_flt(regnr,v,tempnr) \
118 if ((v)->type == TYPE_FLT) { \
119 if ((v)->flags & INMEMORY) { \
121 i386_flds_membase(REG_SP, (v)->regoff * 8); \
125 i386_fld_reg((v)->regoff + fpu_st_offset); \
127 regnr = (v)->regoff; \
130 if ((v)->flags & INMEMORY) { \
132 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
136 i386_fld_reg((v)->regoff + fpu_st_offset); \
138 regnr = (v)->regoff; \
142 #define NEW_var_to_reg_flt(regnr,v,tempnr) \
143 if ((v)->type == TYPE_FLT) { \
144 if ((v)->flags & INMEMORY) { \
146 i386_flds_membase(REG_SP, (v)->regoff * 8); \
150 regnr = (v)->regoff; \
153 if ((v)->flags & INMEMORY) { \
155 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
159 regnr = (v)->regoff; \
165 This function determines a register, to which the result of an operation
166 should go, when it is ultimatively intended to store the result in
168 If v is assigned to an actual register, this register will be returned.
169 Otherwise (when v is spilled) this function returns tempregnum.
170 If not already done, regoff and flags are set in the stack location.
173 static int reg_of_var(stackptr v, int tempregnum)
177 switch (v->varkind) {
179 if (!(v->flags & INMEMORY))
183 var = &(interfaces[v->varnum][v->type]);
184 v->regoff = var->regoff;
185 if (!(var->flags & INMEMORY))
189 var = &(locals[v->varnum][v->type]);
190 v->regoff = var->regoff;
191 if (!(var->flags & INMEMORY))
195 v->regoff = v->varnum;
196 if (IS_FLT_DBL_TYPE(v->type)) {
197 if (v->varnum < fltreg_argnum) {
198 v->regoff = argfltregs[v->varnum];
199 return(argfltregs[v->varnum]);
203 if (v->varnum < intreg_argnum) {
204 v->regoff = argintregs[v->varnum];
205 return(argintregs[v->varnum]);
207 v->regoff -= intreg_argnum;
210 v->flags |= INMEMORY;
215 /* store_reg_to_var_xxx:
216 This function generates the code to store the result of an operation
217 back into a spilled pseudo-variable.
218 If the pseudo-variable has not been spilled in the first place, this
219 function will generate nothing.
221 v ............ Pseudovariable
222 tempregnum ... Number of the temporary registers as returned by
226 #define store_reg_to_var_int(sptr, tempregnum) \
227 if ((sptr)->flags & INMEMORY) { \
229 i386_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
233 #define store_reg_to_var_flt(sptr, tempregnum) \
234 if ((sptr)->type == TYPE_FLT) { \
235 if ((sptr)->flags & INMEMORY) { \
237 i386_fstps_membase(REG_SP, (sptr)->regoff * 8); \
240 /* i386_fxch_reg((sptr)->regoff);*/ \
241 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
245 if ((sptr)->flags & INMEMORY) { \
247 i386_fstpl_membase(REG_SP, (sptr)->regoff * 8); \
250 /* i386_fxch_reg((sptr)->regoff);*/ \
251 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
257 /* NullPointerException signal handler for hardware null pointer check */
259 void catch_NullPointerException(int sig)
265 void **_p = (void **) &sig;
266 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
268 fprintf(stderr, "null=%d %x\n", sig, sigctx);
270 /* Reset signal handler - necessary for SysV, does no harm for BSD */
272 instr = *((int*)(sigctx->eip));
273 /* faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; */
276 if (faultaddr == 0) {
277 signal(sig, (void *) catch_NullPointerException); /* reinstall handler */
279 sigaddset(&nsig, sig);
280 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
281 sigctx->eax = (long) proto_java_lang_NullPointerException; /* REG_ITMP1_XPTR */
282 sigctx->edx = sigctx->eip; /* REG_ITMP2_XPC */
283 sigctx->eip = (long) asm_handle_nat_exception;
288 faultaddr += (long) ((instr << 16) >> 16);
289 fprintf(stderr, "faulting address: 0x%08x\n", faultaddr);
290 panic("Stack overflow");
294 /* ArithmeticException signal handler for hardware divide by zero check */
296 void catch_ArithmeticException(int sig)
300 void **_p = (void **) &sig;
301 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
303 fprintf(stderr, "arith=%d %x\n", sig, sigctx);
305 /* Reset signal handler - necessary for SysV, does no harm for BSD */
307 signal(sig, (void *) catch_ArithmeticException); /* reinstall handler */
309 sigaddset(&nsig, sig);
310 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
311 sigctx->eax = (long) proto_java_lang_ArithmeticException; /* REG_ITMP1_XPTR */
312 sigctx->edx = sigctx->eip; /* REG_ITMP2_XPC */
313 sigctx->eip = (long) asm_handle_nat_exception;
318 void init_exceptions(void)
320 /* install signal handlers we need to convert to exceptions */
325 signal(SIGSEGV, (void *) catch_NullPointerException);
329 signal(SIGBUS, (void *) catch_NullPointerException);
333 /* signal(SIGFPE, (void *) catch_ArithmeticException); */
337 /* function gen_mcode **********************************************************
339 generates machine code
341 *******************************************************************************/
343 static void gen_mcode()
345 int len, s1, s2, s3, d, bbs;
354 int fpu_st_offset = 0;
362 /* savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
365 /* space to save used callee saved registers */
367 savedregs_num += (savintregcnt - maxsavintreguse);
368 savedregs_num += (savfltregcnt - maxsavfltreguse);
370 parentargs_base = maxmemuse + savedregs_num;
372 #ifdef USE_THREADS /* space to save argument of monitor_enter */
374 if (checksync && (method->flags & ACC_SYNCHRONIZED))
379 /* create method header */
381 (void) dseg_addaddress(method); /* MethodPointer */
382 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
386 /* IsSync contains the offset relative to the stack pointer for the
387 argument of monitor_exit used in the exception handler. Since the
388 offset could be zero and give a wrong meaning of the flag it is
392 if (checksync && (method->flags & ACC_SYNCHRONIZED))
393 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
398 (void) dseg_adds4(0); /* IsSync */
400 (void) dseg_adds4(isleafmethod); /* IsLeaf */
401 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
402 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
403 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
405 /* create exception table */
407 for (ex = extable; ex != NULL; ex = ex->down) {
410 if (ex->start != NULL)
411 printf("adding start - %d - ", ex->start->debug_nr);
413 printf("PANIC - start is NULL");
418 dseg_addtarget(ex->start);
422 printf("adding end - %d - ", ex->end->debug_nr);
424 printf("PANIC - end is NULL");
429 dseg_addtarget(ex->end);
432 if (ex->handler != NULL)
433 printf("adding handler - %d\n", ex->handler->debug_nr);
435 printf("PANIC - handler is NULL");
440 dseg_addtarget(ex->handler);
442 (void) dseg_addaddress(ex->catchtype);
445 /* initialize mcode variables */
447 mcodeptr = (s4*) mcodebase;
448 mcodeend = (s4*) (mcodebase + mcodesize);
449 MCODECHECK(128 + mparamcount);
451 /* create stack frame (if necessary) */
453 if (parentargs_base) {
454 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
457 /* save return address and used callee saved registers */
461 /* p--; M_AST (REG_RA, REG_SP, 8*p); -- do we really need this on i386 */
463 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
465 i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
467 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
469 i386_fld_reg(savfltregs[r]);
470 i386_fstpl_membase(REG_SP, p * 8);
473 /* save monitorenter argument */
476 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
477 if (method->flags & ACC_STATIC) {
478 i386_mov_imm_reg(class, REG_ITMP1);
479 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
482 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
483 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
488 /* copy argument registers to stack and call trace function with pointer
489 to arguments on stack.
493 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
495 for (p = 0; p < mparamcount; p++) {
497 if (IS_INT_LNG_TYPE(t)) {
498 if (IS_2_WORD_TYPE(t)) {
499 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
500 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
501 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
502 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
504 } else if (t == TYPE_ADR) {
505 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
506 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
507 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
508 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
511 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
513 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
514 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
519 i386_flds_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
520 i386_fstps_membase(REG_SP, p * 8);
521 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
522 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
525 i386_fldl_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
526 i386_fstpl_membase(REG_SP, p * 8);
531 /* fill up the remaining arguments */
532 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
533 for (p = mparamcount; p < TRACE_ARGS_NUM; p++) {
534 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
535 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
538 i386_mov_imm_membase(method, REG_SP, TRACE_ARGS_NUM * 8);
540 i386_mov_imm_reg(builtin_trace_args, REG_ITMP1);
541 i386_call_reg(REG_ITMP1);
543 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
546 /* take arguments out of register or stack frame */
548 for (p = 0, l = 0; p < mparamcount; p++) {
550 var = &(locals[l][t]);
552 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
557 if (IS_INT_LNG_TYPE(t)) { /* integer args */
558 if (p < intreg_argnum) { /* register arguments */
559 panic("integer register argument");
560 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
561 /* M_INTMOVE (argintregs[p], r); */
563 } else { /* reg arg -> spilled */
564 /* M_LST (argintregs[p], REG_SP, 8 * r); */
566 } else { /* stack arguments */
567 pa = p - intreg_argnum;
568 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
569 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
570 } else { /* stack arg -> spilled */
571 if (!IS_2_WORD_TYPE(t)) {
572 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
573 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
576 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
577 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP2); /* + 4 for return address */
578 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
579 i386_mov_reg_membase(REG_ITMP2, REG_SP, r * 8 + 4);
584 } else { /* floating args */
585 if (p < fltreg_argnum) { /* register arguments */
586 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
587 panic("There are no float argument registers!");
589 } else { /* reg arg -> spilled */
590 panic("There are no float argument registers!");
593 } else { /* stack arguments */
594 pa = p - fltreg_argnum;
595 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
597 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
599 i386_fstp_reg(r + fpu_st_offset);
603 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
605 i386_fstp_reg(r + fpu_st_offset);
609 } else { /* stack-arg -> spilled */
610 /* i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
611 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8); */
613 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
614 i386_fstps_membase(REG_SP, r * 8);
617 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
618 i386_fstpl_membase(REG_SP, r * 8);
625 /* call monitorenter function */
628 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
629 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
630 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
631 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
632 i386_mov_imm_reg(builtin_monitorenter, REG_ITMP2);
633 i386_call_reg(REG_ITMP2);
634 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
639 /* end of header generation */
641 /* walk through all basic blocks */
642 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
644 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
646 if (bptr->flags >= BBREACHED) {
648 /* branch resolving */
651 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
652 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
653 brefs->branchpos, bptr->mpc);
656 /* copy interface registers to their destination */
661 while (src != NULL) {
663 /* if ((len == 0) && (bptr->type != BBTYPE_STD)) { */
664 if ((len == 0) && (bptr->type == BBTYPE_SBR)) {
665 if (!IS_2_WORD_TYPE(src->type)) {
666 d = reg_of_var(src, REG_ITMP1);
668 store_reg_to_var_int(src, d);
671 panic("copy interface registers: longs have to me in memory (begin 1)");
675 d = reg_of_var(src, REG_ITMP1);
676 if ((src->varkind != STACKVAR)) {
678 if (IS_FLT_DBL_TYPE(s2)) {
679 s1 = interfaces[len][s2].regoff;
680 if (!(interfaces[len][s2].flags & INMEMORY)) {
684 if (s2 == TYPE_FLT) {
685 i386_flds_membase(REG_SP, s1 * 8);
688 i386_fldl_membase(REG_SP, s1 * 8);
691 store_reg_to_var_flt(src, d);
694 s1 = interfaces[len][s2].regoff;
695 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
696 if (!(interfaces[len][s2].flags & INMEMORY)) {
700 i386_mov_membase_reg(REG_SP, s1 * 8, d);
702 store_reg_to_var_int(src, d);
705 if (!(interfaces[len][s2].flags & INMEMORY)) {
709 panic("copy interface registers: longs have to be in memory (begin 2)");
718 /* walk through all instructions */
722 for (iptr = bptr->iinstr;
724 src = iptr->dst, len--, iptr++) {
726 MCODECHECK(64); /* an instruction usually needs < 64 words */
729 case ICMD_NOP: /* ... ==> ... */
732 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
733 if (src->flags & INMEMORY) {
734 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
737 i386_test_reg_reg(src->regoff, src->regoff);
739 i386_jcc(I386_CC_E, 0);
740 mcode_addxnullrefs(mcodeptr);
743 /* constant operations ************************************************/
745 case ICMD_ICONST: /* ... ==> ..., constant */
746 /* op1 = 0, val.i = constant */
748 d = reg_of_var(iptr->dst, REG_ITMP1);
749 if (iptr->dst->flags & INMEMORY) {
750 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
753 i386_mov_imm_reg(iptr->val.i, d);
757 case ICMD_LCONST: /* ... ==> ..., constant */
758 /* op1 = 0, val.l = constant */
760 d = reg_of_var(iptr->dst, REG_ITMP1);
761 if (iptr->dst->flags & INMEMORY) {
762 i386_mov_imm_membase(iptr->val.l, REG_SP, iptr->dst->regoff * 8);
763 i386_mov_imm_membase(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
766 panic("LCONST: longs have to be in memory");
770 case ICMD_FCONST: /* ... ==> ..., constant */
771 /* op1 = 0, val.f = constant */
773 d = reg_of_var(iptr->dst, REG_FTMP1);
774 if (iptr->val.f == 0.0) {
778 } else if (iptr->val.f == 1.0) {
783 a = dseg_addfloat(iptr->val.f);
784 i386_mov_imm_reg(0, REG_ITMP1);
785 dseg_adddata(mcodeptr);
786 i386_flds_membase(REG_ITMP1, a);
789 store_reg_to_var_flt(iptr->dst, d);
792 case ICMD_DCONST: /* ... ==> ..., constant */
793 /* op1 = 0, val.d = constant */
795 d = reg_of_var(iptr->dst, REG_FTMP1);
796 if (iptr->val.d == 0.0) {
800 } else if (iptr->val.d == 1.0) {
805 a = dseg_adddouble(iptr->val.d);
806 i386_mov_imm_reg(0, REG_ITMP1);
807 dseg_adddata(mcodeptr);
808 i386_fldl_membase(REG_ITMP1, a);
811 store_reg_to_var_flt(iptr->dst, d);
814 case ICMD_ACONST: /* ... ==> ..., constant */
815 /* op1 = 0, val.a = constant */
817 d = reg_of_var(iptr->dst, REG_ITMP1);
818 if (iptr->dst->flags & INMEMORY) {
819 i386_mov_imm_membase(iptr->val.a, REG_SP, iptr->dst->regoff * 8);
822 i386_mov_imm_reg(iptr->val.a, d);
827 /* load/store operations **********************************************/
829 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
830 /* op1 = local variable */
832 d = reg_of_var(iptr->dst, REG_ITMP1);
833 if ((iptr->dst->varkind == LOCALVAR) &&
834 (iptr->dst->varnum == iptr->op1)) {
837 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
838 if (iptr->dst->flags & INMEMORY) {
839 if (var->flags & INMEMORY) {
840 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
841 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
844 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
848 if (var->flags & INMEMORY) {
849 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
852 M_INTMOVE(var->regoff, iptr->dst->regoff);
857 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
858 /* op1 = local variable */
860 d = reg_of_var(iptr->dst, REG_ITMP1);
861 if ((iptr->dst->varkind == LOCALVAR) &&
862 (iptr->dst->varnum == iptr->op1)) {
865 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
866 if (iptr->dst->flags & INMEMORY) {
867 if (var->flags & INMEMORY) {
868 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
869 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
872 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
876 if (var->flags & INMEMORY) {
877 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
880 M_INTMOVE(var->regoff, iptr->dst->regoff);
885 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
886 /* op1 = local variable */
888 d = reg_of_var(iptr->dst, REG_ITMP1);
889 if ((iptr->dst->varkind == LOCALVAR) &&
890 (iptr->dst->varnum == iptr->op1)) {
893 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
894 if (iptr->dst->flags & INMEMORY) {
895 if (var->flags & INMEMORY) {
896 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
899 panic("LLOAD: longs have to be in memory");
903 panic("LLOAD: longs have to be in memory");
907 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
908 /* op1 = local variable */
910 d = reg_of_var(iptr->dst, REG_FTMP1);
911 if ((iptr->dst->varkind == LOCALVAR) &&
912 (iptr->dst->varnum == iptr->op1)) {
915 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
916 if (var->flags & INMEMORY) {
917 i386_flds_membase(REG_SP, var->regoff * 8);
920 i386_fld_reg(var->regoff + fpu_st_offset);
923 store_reg_to_var_flt(iptr->dst, d);
926 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
927 /* op1 = local variable */
929 d = reg_of_var(iptr->dst, REG_FTMP1);
930 if ((iptr->dst->varkind == LOCALVAR) &&
931 (iptr->dst->varnum == iptr->op1)) {
934 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
935 if (var->flags & INMEMORY) {
936 i386_fldl_membase(REG_SP, var->regoff * 8);
939 i386_fld_reg(var->regoff + fpu_st_offset);
942 store_reg_to_var_flt(iptr->dst, d);
945 case ICMD_ISTORE: /* ..., value ==> ... */
946 /* op1 = local variable */
948 if ((src->varkind == LOCALVAR) &&
949 (src->varnum == iptr->op1)) {
952 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
953 if (var->flags & INMEMORY) {
954 if (src->flags & INMEMORY) {
955 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
956 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
959 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
963 var_to_reg_int(s1, src, var->regoff);
964 M_INTMOVE(s1, var->regoff);
968 case ICMD_ASTORE: /* ..., value ==> ... */
969 /* op1 = local variable */
971 if ((src->varkind == LOCALVAR) &&
972 (src->varnum == iptr->op1)) {
975 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
976 if (var->flags & INMEMORY) {
977 if (src->flags & INMEMORY) {
978 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
979 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
982 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
986 var_to_reg_int(s1, src, var->regoff);
987 M_INTMOVE(s1, var->regoff);
991 case ICMD_LSTORE: /* ..., value ==> ... */
992 /* op1 = local variable */
994 if ((src->varkind == LOCALVAR) &&
995 (src->varnum == iptr->op1)) {
998 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
999 if (var->flags & INMEMORY) {
1000 if (src->flags & INMEMORY) {
1001 M_LNGMEMMOVE(src->regoff, var->regoff);
1004 panic("LSTORE: longs have to be in memory");
1008 panic("LSTORE: longs have to be in memory");
1012 case ICMD_FSTORE: /* ..., value ==> ... */
1013 /* op1 = local variable */
1015 if ((src->varkind == LOCALVAR) &&
1016 (src->varnum == iptr->op1)) {
1019 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1020 if (var->flags & INMEMORY) {
1021 var_to_reg_flt(s1, src, REG_FTMP1);
1022 i386_fstps_membase(REG_SP, var->regoff * 8);
1025 var_to_reg_flt(s1, src, var->regoff);
1026 /* M_FLTMOVE(s1, var->regoff); */
1027 i386_fstp_reg(var->regoff + fpu_st_offset);
1032 case ICMD_DSTORE: /* ..., value ==> ... */
1033 /* op1 = local variable */
1035 if ((src->varkind == LOCALVAR) &&
1036 (src->varnum == iptr->op1)) {
1039 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1040 if (var->flags & INMEMORY) {
1041 var_to_reg_flt(s1, src, REG_FTMP1);
1042 i386_fstpl_membase(REG_SP, var->regoff * 8);
1045 var_to_reg_flt(s1, src, var->regoff);
1046 /* M_FLTMOVE(s1, var->regoff); */
1047 i386_fstp_reg(var->regoff + fpu_st_offset);
1053 /* pop/dup/swap operations ********************************************/
1055 /* attention: double and longs are only one entry in CACAO ICMDs */
1057 case ICMD_POP: /* ..., value ==> ... */
1058 case ICMD_POP2: /* ..., value, value ==> ... */
1061 #define M_COPY(from,to) \
1062 d = reg_of_var(to, REG_ITMP1); \
1063 if ((from->regoff != to->regoff) || \
1064 ((from->flags ^ to->flags) & INMEMORY)) { \
1065 if (IS_FLT_DBL_TYPE(from->type)) { \
1066 var_to_reg_flt(s1, from, d); \
1068 store_reg_to_var_flt(to, d); \
1070 if (!IS_2_WORD_TYPE(from->type)) { \
1071 var_to_reg_int(s1, from, d); \
1073 store_reg_to_var_int(to, d); \
1075 M_LNGMEMMOVE(from->regoff,to->regoff); \
1080 case ICMD_DUP: /* ..., a ==> ..., a, a */
1081 M_COPY(src, iptr->dst);
1084 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1086 M_COPY(src, iptr->dst->prev->prev);
1088 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1090 M_COPY(src, iptr->dst);
1091 M_COPY(src->prev, iptr->dst->prev);
1094 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1096 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1098 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1100 M_COPY(src, iptr->dst);
1101 M_COPY(src->prev, iptr->dst->prev);
1102 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1103 M_COPY(src, iptr->dst->prev->prev->prev);
1106 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1108 M_COPY(src, iptr->dst);
1109 M_COPY(src->prev, iptr->dst->prev);
1110 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1111 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1112 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1113 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1116 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1118 M_COPY(src, iptr->dst->prev);
1119 M_COPY(src->prev, iptr->dst);
1123 /* integer operations *************************************************/
1125 case ICMD_INEG: /* ..., value ==> ..., - value */
1127 d = reg_of_var(iptr->dst, REG_ITMP3);
1128 if (iptr->dst->flags & INMEMORY) {
1129 if (src->flags & INMEMORY) {
1130 if (src->regoff == iptr->dst->regoff) {
1131 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1134 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1135 i386_neg_reg(REG_ITMP1);
1136 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1140 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1141 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1145 if (src->flags & INMEMORY) {
1146 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1147 i386_neg_reg(iptr->dst->regoff);
1150 M_INTMOVE(src->regoff, iptr->dst->regoff);
1151 i386_neg_reg(iptr->dst->regoff);
1156 case ICMD_LNEG: /* ..., value ==> ..., - value */
1158 d = reg_of_var(iptr->dst, REG_ITMP3);
1159 if (iptr->dst->flags & INMEMORY) {
1160 if (src->flags & INMEMORY) {
1161 if (src->regoff == iptr->dst->regoff) {
1162 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1163 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1164 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1167 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1168 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1169 i386_neg_reg(REG_ITMP1);
1170 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1171 i386_neg_reg(REG_ITMP2);
1172 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1173 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1179 case ICMD_I2L: /* ..., value ==> ..., value */
1181 d = reg_of_var(iptr->dst, REG_ITMP3);
1182 if (iptr->dst->flags & INMEMORY) {
1183 if (src->flags & INMEMORY) {
1184 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_EAX);
1186 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1187 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1190 M_INTMOVE(src->regoff, I386_EAX);
1192 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1193 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1198 case ICMD_L2I: /* ..., value ==> ..., value */
1200 d = reg_of_var(iptr->dst, REG_ITMP3);
1201 if (iptr->dst->flags & INMEMORY) {
1202 if (src->flags & INMEMORY) {
1203 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1204 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1208 if (src->flags & INMEMORY) {
1209 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1214 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1216 d = reg_of_var(iptr->dst, REG_ITMP3);
1217 if (iptr->dst->flags & INMEMORY) {
1218 if (src->flags & INMEMORY) {
1219 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1220 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1221 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1222 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1225 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1226 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1227 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1231 if (src->flags & INMEMORY) {
1232 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1233 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1234 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1237 M_INTMOVE(src->regoff, iptr->dst->regoff);
1238 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1239 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1244 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1246 d = reg_of_var(iptr->dst, REG_ITMP3);
1247 if (iptr->dst->flags & INMEMORY) {
1248 if (src->flags & INMEMORY) {
1249 if (src->regoff == iptr->dst->regoff) {
1250 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1253 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1254 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1255 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1259 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1260 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1264 if (src->flags & INMEMORY) {
1265 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1266 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1269 M_INTMOVE(src->regoff, iptr->dst->regoff);
1270 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1275 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1277 d = reg_of_var(iptr->dst, REG_ITMP3);
1278 if (iptr->dst->flags & INMEMORY) {
1279 if (src->flags & INMEMORY) {
1280 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1281 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1282 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1283 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1286 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1287 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1288 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1292 if (src->flags & INMEMORY) {
1293 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1294 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1295 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1298 M_INTMOVE(src->regoff, iptr->dst->regoff);
1299 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1300 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1306 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1308 d = reg_of_var(iptr->dst, REG_ITMP3);
1309 if (iptr->dst->flags & INMEMORY) {
1310 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1311 if (src->regoff == iptr->dst->regoff) {
1312 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1313 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1315 } else if (src->prev->regoff == iptr->dst->regoff) {
1316 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1317 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1320 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1321 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1322 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1325 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1326 if (src->regoff == iptr->dst->regoff) {
1327 i386_alu_reg_membase(I386_ADD, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1330 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1331 i386_alu_reg_reg(I386_ADD, src->prev->regoff, REG_ITMP1);
1332 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1335 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1336 if (src->prev->regoff == iptr->dst->regoff) {
1337 i386_alu_reg_membase(I386_ADD, src->regoff, REG_SP, iptr->dst->regoff * 8);
1340 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1341 i386_alu_reg_reg(I386_ADD, src->regoff, REG_ITMP1);
1342 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1346 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1347 i386_alu_reg_membase(I386_ADD, src->regoff, REG_SP, iptr->dst->regoff * 8);
1351 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1352 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1353 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, iptr->dst->regoff);
1355 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1356 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1357 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, iptr->dst->regoff);
1359 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1360 M_INTMOVE(src->regoff, iptr->dst->regoff);
1361 i386_alu_membase_reg(I386_ADD, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1364 if (src->regoff == iptr->dst->regoff) {
1365 i386_alu_reg_reg(I386_ADD, src->prev->regoff, iptr->dst->regoff);
1368 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1369 i386_alu_reg_reg(I386_ADD, src->regoff, iptr->dst->regoff);
1375 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1376 /* val.i = constant */
1378 d = reg_of_var(iptr->dst, REG_ITMP3);
1379 if (iptr->dst->flags & INMEMORY) {
1380 if (src->flags & INMEMORY) {
1382 * do not use inc optimization, because it's slower (???)
1384 if (src->regoff == iptr->dst->regoff) {
1385 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1388 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1390 if (iptr->val.i == 1) {
1391 i386_inc_reg(REG_ITMP1);
1394 i386_alu_imm_reg(I386_ADD, iptr->val.i, REG_ITMP1);
1397 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1401 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1402 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1406 if (src->flags & INMEMORY) {
1407 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1409 if (iptr->val.i == 1) {
1410 i386_inc_reg(iptr->dst->regoff);
1413 i386_alu_imm_reg(I386_ADD, iptr->val.i, iptr->dst->regoff);
1417 M_INTMOVE(src->regoff, iptr->dst->regoff);
1419 if (iptr->val.i == 1) {
1420 i386_inc_reg(iptr->dst->regoff);
1423 i386_alu_imm_reg(I386_ADD, iptr->val.i, iptr->dst->regoff);
1429 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1431 d = reg_of_var(iptr->dst, REG_ITMP3);
1432 if (iptr->dst->flags & INMEMORY) {
1433 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1434 if (src->regoff == iptr->dst->regoff) {
1435 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1436 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1437 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1438 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1440 } else if (src->prev->regoff == iptr->dst->regoff) {
1441 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1442 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1443 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1444 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1447 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1448 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1449 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1450 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1451 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1452 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1459 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1460 /* val.l = constant */
1462 d = reg_of_var(iptr->dst, REG_ITMP3);
1463 if (iptr->dst->flags & INMEMORY) {
1464 if (src->flags & INMEMORY) {
1465 if (src->regoff == iptr->dst->regoff) {
1466 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1467 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1470 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1471 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1472 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1473 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP2);
1474 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1475 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1481 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1483 d = reg_of_var(iptr->dst, REG_ITMP3);
1484 if (iptr->dst->flags & INMEMORY) {
1485 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1486 if (src->prev->regoff == iptr->dst->regoff) {
1487 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1488 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1491 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1492 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1493 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1496 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1497 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1498 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1499 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1501 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1502 if (src->prev->regoff == iptr->dst->regoff) {
1503 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1506 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1507 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1508 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1512 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1513 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1517 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1518 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1519 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, iptr->dst->regoff);
1521 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1522 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1523 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, iptr->dst->regoff);
1525 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1526 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1527 i386_alu_reg_reg(I386_SUB, src->regoff, iptr->dst->regoff);
1530 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1531 i386_alu_reg_reg(I386_SUB, src->regoff, iptr->dst->regoff);
1536 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1537 /* val.i = constant */
1539 d = reg_of_var(iptr->dst, REG_ITMP3);
1540 if (iptr->dst->flags & INMEMORY) {
1541 if (src->flags & INMEMORY) {
1542 if (src->regoff == iptr->dst->regoff) {
1543 i386_alu_imm_membase(I386_SUB, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1546 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1547 i386_alu_imm_reg(I386_SUB, iptr->val.i, REG_ITMP1);
1548 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1552 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1553 i386_alu_imm_membase(I386_SUB, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1557 if (src->flags & INMEMORY) {
1558 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1559 i386_alu_imm_reg(I386_SUB, iptr->val.i, iptr->dst->regoff);
1562 M_INTMOVE(src->regoff, iptr->dst->regoff);
1563 i386_alu_imm_reg(I386_SUB, iptr->val.i, iptr->dst->regoff);
1568 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1570 d = reg_of_var(iptr->dst, REG_ITMP3);
1571 if (iptr->dst->flags & INMEMORY) {
1572 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1573 if (src->prev->regoff == iptr->dst->regoff) {
1574 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1575 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1576 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1577 i386_alu_reg_membase(I386_SBB, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1580 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1581 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1582 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1583 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1584 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1585 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1591 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1592 /* val.l = constant */
1594 d = reg_of_var(iptr->dst, REG_ITMP3);
1595 if (iptr->dst->flags & INMEMORY) {
1596 if (src->flags & INMEMORY) {
1597 if (src->regoff == iptr->dst->regoff) {
1598 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1599 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1602 /* TODO: could be size optimized with lea -- see gcc output */
1603 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1604 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1605 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1606 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP2);
1607 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1608 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1614 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1616 d = reg_of_var(iptr->dst, REG_ITMP3);
1617 if (iptr->dst->flags & INMEMORY) {
1618 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1619 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1620 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1621 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1623 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1624 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1625 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1626 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1628 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1629 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1630 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1631 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1634 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1635 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1636 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1640 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1641 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1642 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1644 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1645 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1646 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1648 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1649 M_INTMOVE(src->regoff, iptr->dst->regoff);
1650 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1653 if (src->regoff == iptr->dst->regoff) {
1654 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1657 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1658 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1664 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1665 /* val.i = constant */
1667 d = reg_of_var(iptr->dst, REG_ITMP3);
1668 if (iptr->dst->flags & INMEMORY) {
1669 if (src->flags & INMEMORY) {
1670 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1671 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1674 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1675 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1679 if (src->flags & INMEMORY) {
1680 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1683 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1688 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1690 d = reg_of_var(iptr->dst, REG_ITMP1);
1691 if (iptr->dst->flags & INMEMORY) {
1692 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1693 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX); /* mem -> EAX */
1694 /* optimize move EAX -> REG_ITMP3 is slower??? */
1695 /* i386_mov_reg_reg(I386_EAX, REG_ITMP3); */
1696 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1698 /* TODO: optimize move EAX -> REG_ITMP3 */
1699 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3); /* mem -> ITMP3 */
1700 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1701 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1703 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP3); /* mem -> ITMP3 */
1704 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1706 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1707 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1708 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1713 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1714 /* val.l = constant */
1716 d = reg_of_var(iptr->dst, REG_ITMP1);
1717 if (iptr->dst->flags & INMEMORY) {
1718 if (src->flags & INMEMORY) {
1719 i386_mov_imm_reg(iptr->val.l, I386_EAX); /* imm -> EAX */
1720 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1721 /* TODO: optimize move EAX -> REG_ITMP3 */
1722 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP3); /* imm -> ITMP3 */
1723 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1725 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1726 i386_mov_imm_reg(iptr->val.l, REG_ITMP3); /* imm -> ITMP3 */
1727 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1729 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1730 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1731 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1736 #define gen_div_check(v) \
1738 if ((v)->flags & INMEMORY) { \
1739 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8); \
1741 i386_test_reg_reg(src->regoff, src->regoff); \
1743 i386_jcc(I386_CC_E, 0); \
1744 mcode_addxdivrefs(mcodeptr); \
1747 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1749 d = reg_of_var(iptr->dst, REG_ITMP3);
1751 if (src->prev->flags & INMEMORY) {
1752 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1755 M_INTMOVE(src->prev->regoff, I386_EAX);
1760 if (src->flags & INMEMORY) {
1761 i386_idiv_membase(REG_SP, src->regoff * 8);
1764 i386_idiv_reg(src->regoff);
1767 if (iptr->dst->flags & INMEMORY) {
1768 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1771 M_INTMOVE(I386_EAX, iptr->dst->regoff);
1775 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1777 d = reg_of_var(iptr->dst, REG_ITMP3);
1779 if (src->prev->flags & INMEMORY) {
1780 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1783 M_INTMOVE(src->prev->regoff, I386_EAX);
1788 if (src->flags & INMEMORY) {
1789 i386_idiv_membase(REG_SP, src->regoff * 8);
1792 i386_idiv_reg(src->regoff);
1795 if (iptr->dst->flags & INMEMORY) {
1796 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8);
1799 M_INTMOVE(I386_EDX, iptr->dst->regoff);
1803 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1804 /* val.i = constant */
1806 /* TODO: optimize for `/ 2' */
1809 var_to_reg_int(s1, src, REG_ITMP1);
1810 d = reg_of_var(iptr->dst, REG_ITMP1);
1813 i386_test_reg_reg(d, d);
1815 CALCIMMEDIATEBYTES((1 << iptr->val.i) - 1);
1816 i386_jcc(I386_CC_NS, offset);
1817 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, d);
1819 i386_shift_imm_reg(I386_SAR, iptr->val.i, d);
1820 store_reg_to_var_int(iptr->dst, d);
1824 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1825 /* val.i = constant */
1827 d = reg_of_var(iptr->dst, REG_ITMP3);
1828 if (iptr->dst->flags & INMEMORY) {
1829 if (src->flags & INMEMORY) {
1832 CALCIMMEDIATEBYTES((1 << iptr->val.i) - 1);
1834 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1835 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1837 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
1838 i386_jcc(I386_CC_NS, offset);
1839 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1840 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1841 i386_shrd_imm_reg_reg(iptr->val.i, REG_ITMP2, REG_ITMP1);
1842 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP2);
1844 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1845 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1850 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1852 d = reg_of_var(iptr->dst, REG_ITMP2);
1853 if (iptr->dst->flags & INMEMORY) {
1854 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1855 if (src->prev->regoff == iptr->dst->regoff) {
1856 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1857 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1860 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1861 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1862 i386_shift_reg(I386_SHL, REG_ITMP1);
1863 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1866 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1867 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1868 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1869 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1871 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1872 if (src->prev->regoff == iptr->dst->regoff) {
1873 M_INTMOVE(src->regoff, I386_ECX);
1874 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1877 M_INTMOVE(src->regoff, I386_ECX);
1878 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1879 i386_shift_reg(I386_SHL, REG_ITMP1);
1880 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1884 M_INTMOVE(src->regoff, I386_ECX);
1885 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1886 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1890 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1891 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1892 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1893 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1895 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1896 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1897 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1898 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1900 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1901 M_INTMOVE(src->regoff, I386_ECX);
1902 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1903 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1906 M_INTMOVE(src->regoff, I386_ECX);
1907 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1908 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1913 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1914 /* val.i = constant */
1916 d = reg_of_var(iptr->dst, REG_ITMP1);
1917 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1918 if (src->regoff == iptr->dst->regoff) {
1919 i386_shift_imm_membase(I386_SHL, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1922 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1923 i386_shift_imm_reg(I386_SHL, iptr->val.i, REG_ITMP1);
1924 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1927 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
1928 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1929 i386_shift_imm_reg(I386_SHL, iptr->val.i, iptr->dst->regoff);
1931 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1932 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1933 i386_shift_imm_membase(I386_SHL, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1936 M_INTMOVE(src->regoff, iptr->dst->regoff);
1937 i386_shift_imm_reg(I386_SHL, iptr->val.i, iptr->dst->regoff);
1941 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1943 d = reg_of_var(iptr->dst, REG_ITMP2);
1944 if (iptr->dst->flags & INMEMORY) {
1945 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1946 if (src->prev->regoff == iptr->dst->regoff) {
1947 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1948 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1951 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1952 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1953 i386_shift_reg(I386_SAR, REG_ITMP1);
1954 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1957 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1958 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1959 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1960 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1962 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1963 if (src->prev->regoff == iptr->dst->regoff) {
1964 M_INTMOVE(src->regoff, I386_ECX);
1965 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1968 M_INTMOVE(src->regoff, I386_ECX);
1969 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1970 i386_shift_reg(I386_SAR, REG_ITMP1);
1971 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1975 M_INTMOVE(src->regoff, I386_ECX);
1976 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1977 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1981 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1982 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1983 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1984 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1986 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1987 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1988 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1989 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1991 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1992 M_INTMOVE(src->regoff, I386_ECX);
1993 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1994 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1997 M_INTMOVE(src->regoff, I386_ECX);
1998 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1999 i386_shift_reg(I386_SAR, iptr->dst->regoff);
2004 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
2005 /* val.i = constant */
2007 d = reg_of_var(iptr->dst, REG_ITMP1);
2008 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
2009 if (src->regoff == iptr->dst->regoff) {
2010 i386_shift_imm_membase(I386_SAR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2013 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2014 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP1);
2015 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2018 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
2019 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2020 i386_shift_imm_reg(I386_SAR, iptr->val.i, iptr->dst->regoff);
2022 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
2023 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2024 i386_shift_imm_membase(I386_SAR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2027 M_INTMOVE(src->regoff, iptr->dst->regoff);
2028 i386_shift_imm_reg(I386_SAR, iptr->val.i, iptr->dst->regoff);
2032 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2034 d = reg_of_var(iptr->dst, REG_ITMP2);
2035 if (iptr->dst->flags & INMEMORY) {
2036 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2037 if (src->prev->regoff == iptr->dst->regoff) {
2038 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2039 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2042 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2043 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2044 i386_shift_reg(I386_SHR, REG_ITMP1);
2045 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2048 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2049 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2050 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2051 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2053 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2054 if (src->prev->regoff == iptr->dst->regoff) {
2055 M_INTMOVE(src->regoff, I386_ECX);
2056 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2059 M_INTMOVE(src->regoff, I386_ECX);
2060 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2061 i386_shift_reg(I386_SHR, REG_ITMP1);
2062 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2066 M_INTMOVE(src->regoff, I386_ECX);
2067 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2068 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2072 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2073 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2074 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2075 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2077 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2078 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2079 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2080 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2082 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2083 M_INTMOVE(src->regoff, I386_ECX);
2084 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2085 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2088 M_INTMOVE(src->regoff, I386_ECX);
2089 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2090 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2095 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
2096 /* val.i = constant */
2098 d = reg_of_var(iptr->dst, REG_ITMP1);
2099 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
2100 if (src->regoff == iptr->dst->regoff) {
2101 i386_shift_imm_membase(I386_SHR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2104 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2105 i386_shift_imm_reg(I386_SHR, iptr->val.i, REG_ITMP1);
2106 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2109 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
2110 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2111 i386_shift_imm_reg(I386_SHR, iptr->val.i, iptr->dst->regoff);
2113 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
2114 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2115 i386_shift_imm_membase(I386_SHR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2118 M_INTMOVE(src->regoff, iptr->dst->regoff);
2119 i386_shift_imm_reg(I386_SHR, iptr->val.i, iptr->dst->regoff);
2123 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
2125 d = reg_of_var(iptr->dst, REG_ITMP1);
2126 if (iptr->dst->flags & INMEMORY ){
2127 if (src->prev->flags & INMEMORY) {
2128 /* if (src->prev->regoff == iptr->dst->regoff) { */
2129 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2131 /* if (src->flags & INMEMORY) { */
2132 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2134 /* M_INTMOVE(src->regoff, I386_ECX); */
2137 /* i386_test_imm_reg(32, I386_ECX); */
2138 /* i386_jcc(I386_CC_E, 2 + 2); */
2139 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); */
2140 /* i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1); */
2142 /* i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
2143 /* i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8); */
2146 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2147 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2149 if (src->flags & INMEMORY) {
2150 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2152 M_INTMOVE(src->regoff, I386_ECX);
2155 i386_test_imm_reg(32, I386_ECX);
2156 i386_jcc(I386_CC_E, 2 + 2);
2157 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
2158 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2160 i386_shld_reg_reg(REG_ITMP1, REG_ITMP2);
2161 i386_shift_reg(I386_SHL, REG_ITMP1);
2162 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2163 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2169 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
2170 /* val.i = constant */
2172 d = reg_of_var(iptr->dst, REG_ITMP1);
2173 if (iptr->dst->flags & INMEMORY ) {
2174 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2175 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2177 if (iptr->val.i & 0x20) {
2178 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
2179 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2180 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2183 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2184 i386_shift_imm_reg(I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
2187 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2188 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2192 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
2194 d = reg_of_var(iptr->dst, REG_ITMP1);
2195 if (iptr->dst->flags & INMEMORY ){
2196 if (src->prev->flags & INMEMORY) {
2197 /* if (src->prev->regoff == iptr->dst->regoff) { */
2198 /* /* TODO: optimize */
2199 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2200 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2202 /* if (src->flags & INMEMORY) { */
2203 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2205 /* M_INTMOVE(src->regoff, I386_ECX); */
2208 /* i386_test_imm_reg(32, I386_ECX); */
2209 /* i386_jcc(I386_CC_E, 2 + 3); */
2210 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2211 /* i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2); */
2213 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2214 /* i386_shift_reg(I386_SAR, REG_ITMP2); */
2215 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2216 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2219 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2220 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2222 if (src->flags & INMEMORY) {
2223 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2225 M_INTMOVE(src->regoff, I386_ECX);
2228 i386_test_imm_reg(32, I386_ECX);
2229 i386_jcc(I386_CC_E, 2 + 3);
2230 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2231 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2233 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2234 i386_shift_reg(I386_SAR, REG_ITMP2);
2235 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2236 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2242 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2243 /* val.i = constant */
2245 d = reg_of_var(iptr->dst, REG_ITMP1);
2246 if (iptr->dst->flags & INMEMORY ) {
2247 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2248 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2250 if (iptr->val.i & 0x20) {
2251 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2252 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2253 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2256 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2257 i386_shift_imm_reg(I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
2260 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2261 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2265 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2267 d = reg_of_var(iptr->dst, REG_ITMP1);
2268 if (iptr->dst->flags & INMEMORY ){
2269 if (src->prev->flags & INMEMORY) {
2270 /* if (src->prev->regoff == iptr->dst->regoff) { */
2271 /* /* TODO: optimize */
2272 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2273 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2275 /* if (src->flags & INMEMORY) { */
2276 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2278 /* M_INTMOVE(src->regoff, I386_ECX); */
2281 /* i386_test_imm_reg(32, I386_ECX); */
2282 /* i386_jcc(I386_CC_E, 2 + 2); */
2283 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2284 /* i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2); */
2286 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2287 /* i386_shift_reg(I386_SHR, REG_ITMP2); */
2288 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2289 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2292 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2293 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2295 if (src->flags & INMEMORY) {
2296 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2298 M_INTMOVE(src->regoff, I386_ECX);
2301 i386_test_imm_reg(32, I386_ECX);
2302 i386_jcc(I386_CC_E, 2 + 2);
2303 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2304 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2306 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2307 i386_shift_reg(I386_SHR, REG_ITMP2);
2308 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2309 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2315 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2316 /* val.l = constant */
2318 d = reg_of_var(iptr->dst, REG_ITMP1);
2319 if (iptr->dst->flags & INMEMORY ) {
2320 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2321 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2323 if (iptr->val.i & 0x20) {
2324 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2325 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2326 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2329 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2330 i386_shift_imm_reg(I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
2333 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2334 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2338 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2340 d = reg_of_var(iptr->dst, REG_ITMP1);
2341 if (iptr->dst->flags & INMEMORY) {
2342 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2343 if (src->regoff == iptr->dst->regoff) {
2344 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2345 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2347 } else if (src->prev->regoff == iptr->dst->regoff) {
2348 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2349 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2352 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2353 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, REG_ITMP1);
2354 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2357 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2358 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2359 i386_alu_reg_reg(I386_AND, src->prev->regoff, REG_ITMP1);
2360 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2362 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2363 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2364 i386_alu_reg_reg(I386_AND, src->regoff, REG_ITMP1);
2365 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2368 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2369 i386_alu_reg_membase(I386_AND, src->regoff, REG_SP, iptr->dst->regoff * 8);
2373 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2374 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2375 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, iptr->dst->regoff);
2377 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2378 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2379 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, iptr->dst->regoff);
2381 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2382 M_INTMOVE(src->regoff, iptr->dst->regoff);
2383 i386_alu_membase_reg(I386_AND, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2386 if (src->regoff == iptr->dst->regoff) {
2387 i386_alu_reg_reg(I386_AND, src->prev->regoff, iptr->dst->regoff);
2390 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2391 i386_alu_reg_reg(I386_AND, src->regoff, iptr->dst->regoff);
2397 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2398 /* val.i = constant */
2400 d = reg_of_var(iptr->dst, REG_ITMP1);
2401 if (iptr->dst->flags & INMEMORY) {
2402 if (src->flags & INMEMORY) {
2403 if (src->regoff == iptr->dst->regoff) {
2404 i386_alu_imm_membase(I386_AND, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2407 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2408 i386_alu_imm_reg(I386_AND, iptr->val.i, REG_ITMP1);
2409 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2413 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2414 i386_alu_imm_membase(I386_AND, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2418 if (src->flags & INMEMORY) {
2419 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2420 i386_alu_imm_reg(I386_AND, iptr->val.i, iptr->dst->regoff);
2423 M_INTMOVE(src->regoff, iptr->dst->regoff);
2424 i386_alu_imm_reg(I386_AND, iptr->val.i, iptr->dst->regoff);
2429 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2431 d = reg_of_var(iptr->dst, REG_ITMP1);
2432 if (iptr->dst->flags & INMEMORY) {
2433 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2434 if (src->regoff == iptr->dst->regoff) {
2435 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2436 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2437 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2438 i386_alu_reg_membase(I386_AND, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2440 } else if (src->prev->regoff == iptr->dst->regoff) {
2441 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2442 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2443 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2444 i386_alu_reg_membase(I386_AND, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2447 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2448 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2449 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, REG_ITMP1);
2450 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2451 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2452 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2458 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2459 /* val.l = constant */
2461 d = reg_of_var(iptr->dst, REG_ITMP1);
2462 if (iptr->dst->flags & INMEMORY) {
2463 if (src->flags & INMEMORY) {
2464 if (src->regoff == iptr->dst->regoff) {
2465 i386_alu_imm_membase(I386_AND, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
2466 i386_alu_imm_membase(I386_AND, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
2469 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2470 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2471 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
2472 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
2473 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2474 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2480 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
2481 /* val.i = constant */
2483 var_to_reg_int(s1, src, REG_ITMP1);
2484 d = reg_of_var(iptr->dst, REG_ITMP3);
2486 M_INTMOVE(s1, REG_ITMP1);
2496 CALCIMMEDIATEBYTES(iptr->val.i);
2499 /* TODO: optimize */
2501 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
2502 i386_test_reg_reg(s1, s1);
2503 i386_jcc(I386_CC_GE, offset);
2504 i386_mov_reg_reg(s1, d);
2506 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
2510 /* M_INTMOVE(s1, I386_EAX); */
2512 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
2513 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
2514 /* i386_alu_reg_reg(I386_AND, iptr->val.i, I386_EAX); */
2515 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
2516 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
2517 /* M_INTMOVE(I386_EAX, d); */
2519 /* i386_alu_reg_reg(I386_XOR, d, d); */
2520 /* i386_mov_imm_reg(iptr->val.i, I386_ECX); */
2521 /* i386_shrd_reg_reg(s1, d); */
2522 /* i386_shift_imm_reg(I386_SHR, 32 - iptr->val.i, d); */
2524 store_reg_to_var_int(iptr->dst, d);
2527 case ICMD_IREM0X10001: /* ..., value ==> ..., value % 0x100001 */
2529 /* b = value & 0xffff;
2531 a = ((b - a) & 0xffff) + (b < a);
2535 var_to_reg_int(s1, src, REG_ITMP1);
2536 d = reg_of_var(iptr->dst, REG_ITMP3);
2538 M_MOV(s1, REG_ITMP3);
2542 /* is value negative? */
2543 i386_test_reg_reg(s1, s1);
2544 i386_jcc(I386_CC_L, 2 + 6 + 2 + 3 + 2 + 2 + 3 + 2 + 2 + 6 + 2 + 5);
2546 /* b = value & 0xffff; */
2547 M_INTMOVE(s1, REG_ITMP2);
2548 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP2);
2550 /* a = value >> 16; */
2552 i386_shift_imm_reg(I386_SAR, 16, d);
2555 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2556 i386_alu_reg_reg(I386_CMP, d, REG_ITMP2);
2557 i386_setcc_reg(I386_CC_L, REG_ITMP1);
2560 i386_alu_reg_reg(I386_SUB, d, REG_ITMP2);
2562 /* ((b - a) & 0xffff) */
2563 M_INTMOVE(REG_ITMP2, d);
2564 i386_alu_imm_reg(I386_AND, 0x0000ffff, d);
2566 /* ((b - a) & 0xffff) + (b < a) */
2567 i386_alu_reg_reg(I386_ADD, REG_ITMP1, d);
2569 /* jump over the negative stuff */
2570 offset = 2 + 2 + 2 + 6 + 2 + 3 + 2 + 2 + 3 + 2 + 2 + 6 + 2 + 2;
2571 if (s1 == REG_ITMP1) {
2573 CALCOFFSETBYTES(src->regoff * 8);
2575 offset += 2 + 2 + 2 + 5 + 3 + 2;
2576 i386_jmp_imm(offset);
2578 /* value = -value */
2579 i386_mov_reg_reg(s1, REG_ITMP1);
2580 i386_neg_reg(REG_ITMP1);
2582 /* b = value & 0xffff; */
2583 M_INTMOVE(REG_ITMP1, REG_ITMP2);
2584 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP2);
2586 /* a = value >> 16; */
2587 M_INTMOVE(REG_ITMP1, d);
2588 i386_shift_imm_reg(I386_SAR, 16, d);
2591 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2592 i386_alu_reg_reg(I386_CMP, d, REG_ITMP2);
2593 i386_setcc_reg(I386_CC_L, REG_ITMP1);
2596 i386_alu_reg_reg(I386_SUB, d, REG_ITMP2);
2598 /* ((b - a) & 0xffff) */
2599 M_INTMOVE(REG_ITMP2, d);
2600 i386_alu_imm_reg(I386_AND, 0x0000ffff, d);
2602 /* ((b - a) & 0xffff) + (b < a) */
2603 i386_alu_reg_reg(I386_ADD, REG_ITMP1, d);
2608 if (s1 == REG_ITMP1) {
2609 var_to_reg_int(s1, src, REG_ITMP1);
2612 /* a = a - ((value << 1) == 0) */
2613 M_INTMOVE(s1, REG_ITMP2);
2614 i386_shift_imm_reg(I386_SHL, 1, REG_ITMP2);
2615 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
2616 i386_mov_imm_reg(0, REG_ITMP2);
2617 i386_setcc_reg(I386_CC_E, REG_ITMP2);
2618 i386_alu_reg_reg(I386_SUB, REG_ITMP2, d);
2620 store_reg_to_var_int(iptr->dst, d);
2624 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
2625 /* val.l = constant */
2627 d = reg_of_var(iptr->dst, REG_ITMP3);
2628 if (iptr->dst->flags & INMEMORY) {
2629 if (src->flags & INMEMORY) {
2631 /* Intel algorithm -- does not work, because constant is wrong */
2632 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
2633 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
2635 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
2636 /* i386_test_reg_reg(REG_ITMP3, REG_ITMP3); */
2637 /* i386_jcc(I386_CC_NS, offset); */
2638 /* i386_alu_imm_reg(I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
2639 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP3); */
2641 /* i386_shrd_imm_reg_reg(iptr->val.l, REG_ITMP3, REG_ITMP2); */
2642 /* i386_shift_imm_reg(I386_SAR, iptr->val.l, REG_ITMP3); */
2643 /* i386_shld_imm_reg_reg(iptr->val.l, REG_ITMP2, REG_ITMP3); */
2645 /* i386_shift_imm_reg(I386_SHL, iptr->val.l, REG_ITMP2); */
2647 /* i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1); */
2648 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
2649 /* i386_alu_reg_reg(I386_SBB, REG_ITMP3, REG_ITMP2); */
2651 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2652 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2654 /* Alpha algorithm */
2656 CALCOFFSETBYTES(src->regoff * 8);
2658 CALCOFFSETBYTES(src->regoff * 8 + 4);
2664 /* TODO: hmm, don't know if this is always correct */
2666 CALCIMMEDIATEBYTES(iptr->val.l & 0x00000000ffffffff);
2668 CALCIMMEDIATEBYTES(iptr->val.l >> 32);
2674 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2675 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2677 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
2678 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
2679 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
2680 i386_jcc(I386_CC_GE, offset);
2682 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2683 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2685 i386_neg_reg(REG_ITMP1);
2686 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
2687 i386_neg_reg(REG_ITMP2);
2689 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
2690 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
2692 i386_neg_reg(REG_ITMP1);
2693 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
2694 i386_neg_reg(REG_ITMP2);
2696 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2697 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2702 case ICMD_LREM0X10001:/* ..., value ==> ..., value % 0x10001 */
2704 /* b = value & 0xffff;
2706 a = ((b - a) & 0xffff) + (b < a);
2709 d = reg_of_var(iptr->dst, REG_ITMP3);
2710 if (iptr->dst->flags & INMEMORY) {
2711 if (src->flags & INMEMORY) {
2714 /* a = value >> 16; */
2715 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2716 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2718 /* is value negative? */
2719 /* i386_test_reg_reg(REG_ITMP2, REG_ITMP2); */
2721 /* offset = 4 + 3; */
2722 /* offset += 3 + 3; */
2723 /* CALCREGOFFBYTES(iptr->dst->regoff); */
2724 /* CALCREGOFFBYTES(iptr->dst->regoff); */
2726 /* CALCREGOFFBYTES(src->regoff); */
2727 /* offset += 6 + 2 + 2; */
2729 /* CALCREGOFFBYTES(iptr->dst->regoff); */
2732 /* CALCREGOFFBYTES(iptr->dst->regoff); */
2734 /* offset += 3 + 3; */
2735 /* CALCREGOFFBYTES(iptr->dst->regoff); */
2736 /* CALCREGOFFBYTES(iptr->dst->regoff); */
2737 /* offset += 6 + 2 + 2 + 2; */
2738 /* offset += 3 + 3; */
2739 /* CALCREGOFFBYTES(iptr->dst->regoff); */
2740 /* CALCREGOFFBYTES(iptr->dst->regoff); */
2742 /* i386_jcc(I386_CC_L, offset); */
2744 /* a = value >> 16; */
2745 i386_shrd_imm_reg_reg(16, REG_ITMP2, REG_ITMP1);
2746 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP2);
2748 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2749 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2751 /* b = value & 0xffff; */
2752 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2753 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
2755 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
2756 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2758 /* a = ((b - a) & 0xffff) + (b < a); */
2760 i386_alu_reg_reg(I386_XOR, REG_ITMP3, REG_ITMP3);
2761 i386_alu_membase_reg(I386_CMP, REG_SP, iptr->dst->regoff * 8 + 4, REG_ITMP2);
2763 CALCREGOFFBYTES(iptr->dst->regoff);
2765 i386_jcc(I386_CC_G, offset);
2766 i386_alu_membase_reg(I386_CMP, REG_SP, iptr->dst->regoff * 8, REG_ITMP1);
2767 i386_setcc_reg(I386_CC_B, REG_ITMP3);
2770 i386_alu_membase_reg(I386_SUB, REG_SP, iptr->dst->regoff * 8, REG_ITMP1);
2771 i386_alu_membase_reg(I386_SBB, REG_SP, iptr->dst->regoff * 8 + 4, REG_ITMP2);
2773 /* ((b - a) & 0xffff) */
2774 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
2775 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2777 /* ((b - a) & 0xffff) + (b < a); */
2778 i386_alu_reg_reg(I386_ADD, REG_ITMP3, REG_ITMP1);
2779 i386_alu_reg_reg(I386_ADC, 0, REG_ITMP2);
2781 /* i386_test_reg_reg(REG_ITMP2, REG_ITMP2); */
2782 /* i386_jcc(I386_CC_NS, 2 + 3 + 2); */
2784 /* i386_neg_reg(REG_ITMP1); */
2785 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2); */
2786 /* i386_neg_reg(REG_ITMP2); */
2788 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2789 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2793 /* value = -value */
2794 i386_neg_reg(REG_ITMP1);
2795 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
2796 i386_neg_reg(REG_ITMP2);
2798 /* a = value >> 16; */
2799 i386_shrd_imm_reg_reg(16, REG_ITMP2, REG_ITMP1);
2800 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP2);
2802 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2803 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2805 /* b = value & 0xffff; */
2806 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2807 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
2809 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
2810 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2812 /* a = ((b - a) & 0xffff) + (b < a); */
2814 i386_alu_reg_reg(I386_XOR, REG_ITMP3, REG_ITMP3);
2815 i386_alu_membase_reg(I386_CMP, REG_SP, iptr->dst->regoff * 8 + 4, REG_ITMP2);
2817 CALCREGOFFBYTES(iptr->dst->regoff);
2819 i386_jcc(I386_CC_G, offset);
2820 i386_alu_membase_reg(I386_CMP, REG_SP, iptr->dst->regoff * 8, REG_ITMP1);
2821 i386_setcc_reg(I386_CC_B, REG_ITMP3);
2824 i386_alu_membase_reg(I386_SUB, REG_SP, iptr->dst->regoff * 8, REG_ITMP1);
2825 i386_alu_membase_reg(I386_SBB, REG_SP, iptr->dst->regoff * 8 + 4, REG_ITMP2);
2827 /* ((b - a) & 0xffff) */
2828 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
2829 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2831 /* ((b - a) & 0xffff) + (b < a); */
2832 i386_alu_reg_reg(I386_ADD, REG_ITMP3, REG_ITMP1);
2833 i386_alu_reg_reg(I386_ADC, REG_ITMP3, REG_ITMP2);
2836 i386_neg_reg(REG_ITMP1);
2837 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
2838 i386_neg_reg(REG_ITMP2);
2840 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2841 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2843 /* a = a - ((value << 1) == 0) */
2844 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2845 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 2, REG_ITMP2);
2847 i386_shld_imm_reg_reg(1, REG_ITMP1, REG_ITMP2);
2848 i386_shift_imm_reg(I386_SHL, 1, REG_ITMP1);
2850 i386_alu_reg_reg(I386_XOR, REG_ITMP3, REG_ITMP3);
2851 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
2852 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
2853 i386_setcc_reg(I386_CC_E, REG_ITMP3);
2855 i386_alu_reg_membase(I386_SUB, REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2856 i386_alu_imm_membase(I386_SBB, 0, REG_SP, iptr->dst->regoff * 8 + 4);
2862 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2864 d = reg_of_var(iptr->dst, REG_ITMP1);
2865 if (iptr->dst->flags & INMEMORY) {
2866 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2867 if (src->regoff == iptr->dst->regoff) {
2868 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2869 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2871 } else if (src->prev->regoff == iptr->dst->regoff) {
2872 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2873 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2876 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2877 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, REG_ITMP1);
2878 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2881 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2882 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2883 i386_alu_reg_reg(I386_OR, src->prev->regoff, REG_ITMP1);
2884 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2886 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2887 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2888 i386_alu_reg_reg(I386_OR, src->regoff, REG_ITMP1);
2889 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2892 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2893 i386_alu_reg_membase(I386_OR, src->regoff, REG_SP, iptr->dst->regoff * 8);
2897 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2898 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2899 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2901 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2902 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2903 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2905 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2906 M_INTMOVE(src->regoff, iptr->dst->regoff);
2907 i386_alu_membase_reg(I386_OR, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2910 if (src->regoff == iptr->dst->regoff) {
2911 i386_alu_reg_reg(I386_OR, src->prev->regoff, iptr->dst->regoff);
2914 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2915 i386_alu_reg_reg(I386_OR, src->regoff, iptr->dst->regoff);
2921 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2922 /* val.i = constant */
2924 d = reg_of_var(iptr->dst, REG_ITMP1);
2925 if (iptr->dst->flags & INMEMORY) {
2926 if (src->flags & INMEMORY) {
2927 if (src->regoff == iptr->dst->regoff) {
2928 i386_alu_imm_membase(I386_OR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2931 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2932 i386_alu_imm_reg(I386_OR, iptr->val.i, REG_ITMP1);
2933 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2937 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2938 i386_alu_imm_membase(I386_OR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2942 if (src->flags & INMEMORY) {
2943 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2944 i386_alu_imm_reg(I386_OR, iptr->val.i, iptr->dst->regoff);
2947 M_INTMOVE(src->regoff, iptr->dst->regoff);
2948 i386_alu_imm_reg(I386_OR, iptr->val.i, iptr->dst->regoff);
2953 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2955 d = reg_of_var(iptr->dst, REG_ITMP1);
2956 if (iptr->dst->flags & INMEMORY) {
2957 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2958 if (src->regoff == iptr->dst->regoff) {
2959 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2960 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2961 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2962 i386_alu_reg_membase(I386_OR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2964 } else if (src->prev->regoff == iptr->dst->regoff) {
2965 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2966 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2967 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2968 i386_alu_reg_membase(I386_OR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2971 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2972 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2973 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, REG_ITMP1);
2974 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2975 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2976 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2982 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2983 /* val.l = constant */
2985 d = reg_of_var(iptr->dst, REG_ITMP1);
2986 if (iptr->dst->flags & INMEMORY) {
2987 if (src->flags & INMEMORY) {
2988 if (src->regoff == iptr->dst->regoff) {
2989 i386_alu_imm_membase(I386_OR, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
2990 i386_alu_imm_membase(I386_OR, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
2993 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2994 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2995 i386_alu_imm_reg(I386_OR, iptr->val.l, REG_ITMP1);
2996 i386_alu_imm_reg(I386_OR, iptr->val.l >> 32, REG_ITMP2);
2997 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2998 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3004 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
3006 d = reg_of_var(iptr->dst, REG_ITMP1);
3007 if (iptr->dst->flags & INMEMORY) {
3008 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3009 if (src->regoff == iptr->dst->regoff) {
3010 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3011 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3013 } else if (src->prev->regoff == iptr->dst->regoff) {
3014 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3015 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3018 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3019 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3020 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3023 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3024 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3025 i386_alu_reg_reg(I386_XOR, src->prev->regoff, REG_ITMP1);
3026 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3028 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3029 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3030 i386_alu_reg_reg(I386_XOR, src->regoff, REG_ITMP1);
3031 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3034 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
3035 i386_alu_reg_membase(I386_XOR, src->regoff, REG_SP, iptr->dst->regoff * 8);
3039 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3040 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
3041 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, iptr->dst->regoff);
3043 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3044 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
3045 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, iptr->dst->regoff);
3047 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3048 M_INTMOVE(src->regoff, iptr->dst->regoff);
3049 i386_alu_membase_reg(I386_XOR, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
3052 if (src->regoff == iptr->dst->regoff) {
3053 i386_alu_reg_reg(I386_XOR, src->prev->regoff, iptr->dst->regoff);
3056 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
3057 i386_alu_reg_reg(I386_XOR, src->regoff, iptr->dst->regoff);
3063 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
3064 /* val.i = constant */
3066 d = reg_of_var(iptr->dst, REG_ITMP1);
3067 if (iptr->dst->flags & INMEMORY) {
3068 if (src->flags & INMEMORY) {
3069 if (src->regoff == iptr->dst->regoff) {
3070 i386_alu_imm_membase(I386_XOR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
3073 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3074 i386_alu_imm_reg(I386_XOR, iptr->val.i, REG_ITMP1);
3075 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3079 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
3080 i386_alu_imm_membase(I386_XOR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
3084 if (src->flags & INMEMORY) {
3085 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
3086 i386_alu_imm_reg(I386_XOR, iptr->val.i, iptr->dst->regoff);
3089 M_INTMOVE(src->regoff, iptr->dst->regoff);
3090 i386_alu_imm_reg(I386_XOR, iptr->val.i, iptr->dst->regoff);
3095 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
3097 d = reg_of_var(iptr->dst, REG_ITMP1);
3098 if (iptr->dst->flags & INMEMORY) {
3099 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3100 if (src->regoff == iptr->dst->regoff) {
3101 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3102 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3103 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3104 i386_alu_reg_membase(I386_XOR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3106 } else if (src->prev->regoff == iptr->dst->regoff) {
3107 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3108 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3109 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3110 i386_alu_reg_membase(I386_XOR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3113 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3114 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3115 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3116 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3117 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3118 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3124 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
3125 /* val.l = constant */
3127 d = reg_of_var(iptr->dst, REG_ITMP1);
3128 if (iptr->dst->flags & INMEMORY) {
3129 if (src->flags & INMEMORY) {
3130 if (src->regoff == iptr->dst->regoff) {
3131 i386_alu_imm_membase(I386_XOR, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
3132 i386_alu_imm_membase(I386_XOR, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
3135 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3136 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3137 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3138 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3139 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3140 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3147 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
3152 case ICMD_IINC: /* ..., value ==> ..., value + constant */
3153 /* op1 = variable, val.i = constant */
3155 var = &(locals[iptr->op1][TYPE_INT]);
3156 if (var->flags & INMEMORY) {
3157 if (iptr->val.i == 1) {
3158 i386_inc_membase(REG_SP, var->regoff * 8);
3160 } else if (iptr->val.i == -1) {
3161 i386_dec_membase(REG_SP, var->regoff * 8);
3164 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
3168 if (iptr->val.i == 1) {
3169 i386_inc_reg(var->regoff);
3171 } else if (iptr->val.i == -1) {
3172 i386_dec_reg(var->regoff);
3175 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
3181 /* floating operations ************************************************/
3183 case ICMD_FNEG: /* ..., value ==> ..., - value */
3184 case ICMD_DNEG: /* ..., value ==> ..., - value */
3186 var_to_reg_flt(s1, src, REG_FTMP1);
3187 d = reg_of_var(iptr->dst, REG_FTMP3);
3189 store_reg_to_var_flt(iptr->dst, d);
3192 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
3193 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
3195 d = reg_of_var(iptr->dst, REG_FTMP3);
3196 if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) {
3197 if (iptr->dst->regoff == src->prev->regoff) {
3198 NEW_var_to_reg_flt(s1, src->prev, REG_FTMP1);
3199 var_to_reg_flt(s2, src, REG_FTMP2);
3200 i386_faddp_st_reg(s1 + fpu_st_offset);
3203 } else if (iptr->dst->regoff == src->regoff) {
3204 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3205 NEW_var_to_reg_flt(s2, src, REG_FTMP2);
3206 i386_faddp_st_reg(s2 + fpu_st_offset);
3210 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3211 NEW_var_to_reg_flt(s2, src, REG_FTMP2);
3212 i386_fadd_reg_st(s2 + fpu_st_offset);
3213 store_reg_to_var_flt(iptr->dst, d);
3217 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3218 var_to_reg_flt(s2, src, REG_FTMP2);
3221 store_reg_to_var_flt(iptr->dst, d);
3225 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
3226 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
3228 d = reg_of_var(iptr->dst, REG_FTMP3);
3229 if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) {
3230 if (iptr->dst->regoff == src->prev->regoff) {
3231 NEW_var_to_reg_flt(s1, src->prev, REG_FTMP1);
3232 var_to_reg_flt(s2, src, REG_FTMP2);
3233 i386_fsubp_st_reg(s1 + fpu_st_offset);
3237 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3238 NEW_var_to_reg_flt(s2, src, REG_FTMP2);
3239 i386_fsub_reg_st(s2 + fpu_st_offset);
3240 store_reg_to_var_flt(iptr->dst, d);
3244 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3245 var_to_reg_flt(s2, src, REG_FTMP2);
3248 store_reg_to_var_flt(iptr->dst, d);
3252 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
3253 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
3255 d = reg_of_var(iptr->dst, REG_FTMP3);
3256 if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) {
3257 if (iptr->dst->regoff == src->prev->regoff) {
3258 NEW_var_to_reg_flt(s1, src->prev, REG_FTMP1);
3259 var_to_reg_flt(s2, src, REG_FTMP2);
3260 i386_fmulp_st_reg(s1 + fpu_st_offset);
3263 } else if (iptr->dst->regoff == src->regoff) {
3264 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3265 NEW_var_to_reg_flt(s2, src, REG_FTMP2);
3266 i386_fmulp_st_reg(s2 + fpu_st_offset);
3270 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3271 NEW_var_to_reg_flt(s2, src, REG_FTMP2);
3272 i386_fmul_reg_st(s2 + fpu_st_offset);
3273 store_reg_to_var_flt(iptr->dst, d);
3277 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3278 var_to_reg_flt(s2, src, REG_FTMP2);
3281 store_reg_to_var_flt(iptr->dst, d);
3285 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
3286 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
3288 d = reg_of_var(iptr->dst, REG_FTMP3);
3289 if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) {
3290 if (src->prev->regoff == iptr->dst->regoff) {
3291 NEW_var_to_reg_flt(s1, src->prev, REG_FTMP1);
3292 var_to_reg_flt(s2, src, REG_FTMP2);
3293 i386_fdivp_st_reg(s1 + fpu_st_offset);
3297 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3298 NEW_var_to_reg_flt(s2, src, REG_FTMP2);
3299 i386_fdiv_reg_st(s2 + fpu_st_offset);
3300 store_reg_to_var_flt(iptr->dst, d);
3304 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3305 var_to_reg_flt(s2, src, REG_FTMP2);
3308 store_reg_to_var_flt(iptr->dst, d);
3312 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
3313 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
3315 /* exchanged to skip fxch */
3316 var_to_reg_flt(s2, src, REG_FTMP2);
3317 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3318 d = reg_of_var(iptr->dst, REG_FTMP3);
3324 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
3325 store_reg_to_var_flt(iptr->dst, d);
3331 case ICMD_I2F: /* ..., value ==> ..., (float) value */
3332 case ICMD_I2D: /* ..., value ==> ..., (double) value */
3334 d = reg_of_var(iptr->dst, REG_FTMP1);
3335 if (src->flags & INMEMORY) {
3336 i386_fildl_membase(REG_SP, src->regoff * 8);
3341 i386_mov_imm_reg(0, REG_ITMP1);
3342 dseg_adddata(mcodeptr);
3343 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
3344 i386_fildl_membase(REG_ITMP1, a);
3347 store_reg_to_var_flt(iptr->dst, d);
3350 case ICMD_L2F: /* ..., value ==> ..., (float) value */
3351 case ICMD_L2D: /* ..., value ==> ..., (double) value */
3353 d = reg_of_var(iptr->dst, REG_FTMP1);
3354 if (src->flags & INMEMORY) {
3355 i386_fildll_membase(REG_SP, src->regoff * 8);
3359 panic("L2F: longs have to be in memory");
3361 store_reg_to_var_flt(iptr->dst, d);
3364 case ICMD_F2I: /* ..., value ==> ..., (int) value */
3367 var_to_reg_flt(s1, src, REG_FTMP1);
3368 d = reg_of_var(iptr->dst, REG_ITMP1);
3370 a = dseg_adds4(0x0d7f); /* Round to zero, 53-bit mode, exception masked */
3371 i386_mov_imm_reg(0, REG_ITMP1);
3372 dseg_adddata(mcodeptr);
3373 i386_fldcw_membase(REG_ITMP1, a);
3375 if (iptr->dst->flags & INMEMORY) {
3376 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
3378 /* i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8); */
3382 i386_fistpl_membase(REG_ITMP1, a);
3384 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
3387 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
3388 i386_fldcw_membase(REG_ITMP1, a);
3391 case ICMD_F2L: /* ..., value ==> ..., (long) value */
3394 var_to_reg_flt(s1, src, REG_FTMP1);
3395 d = reg_of_var(iptr->dst, REG_ITMP1);
3397 a = dseg_adds4(0x0d7f); /* Round to zero, 53-bit mode, exception masked */
3398 i386_mov_imm_reg(0, REG_ITMP1);
3399 dseg_adddata(mcodeptr);
3400 i386_fldcw_membase(REG_ITMP1, a);
3402 if (iptr->dst->flags & INMEMORY) {
3403 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
3407 panic("F2L: longs have to be in memory");
3410 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
3411 i386_fldcw_membase(REG_ITMP1, a);
3414 case ICMD_F2D: /* ..., value ==> ..., (double) value */
3416 var_to_reg_flt(s1, src, REG_FTMP1);
3417 d = reg_of_var(iptr->dst, REG_ITMP3);
3419 store_reg_to_var_flt(iptr->dst, d);
3422 case ICMD_D2F: /* ..., value ==> ..., (float) value */
3424 var_to_reg_flt(s1, src, REG_FTMP1);
3425 d = reg_of_var(iptr->dst, REG_ITMP3);
3427 store_reg_to_var_flt(iptr->dst, d);
3430 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
3432 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
3435 /* exchanged to skip fxch */
3436 /* if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) { */
3437 /* fprintf(stderr, "new FCMP\n"); */
3438 /* NEW_var_to_reg_flt(s2, src->prev, REG_FTMP1); */
3439 /* NEW_var_to_reg_flt(s1, src, REG_FTMP2); */
3440 /* d = reg_of_var(iptr->dst, REG_ITMP3); */
3441 /* i386_alu_reg_reg(I386_XOR, d, d); */
3442 /* i386_fxch_reg(s1 + fpu_st_offset); */
3443 /* i386_fucom_reg(s2 + fpu_st_offset); */
3444 /* i386_fxch_reg(s1 + fpu_st_offset); */
3446 var_to_reg_flt(s2, src->prev, REG_FTMP1);
3447 var_to_reg_flt(s1, src, REG_FTMP2);
3448 d = reg_of_var(iptr->dst, REG_ITMP3);
3449 i386_alu_reg_reg(I386_XOR, d, d);
3456 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
3457 i386_jcc(I386_CC_B, 1 + 5);
3461 store_reg_to_var_int(iptr->dst, d);
3465 /* memory operations **************************************************/
3467 #define gen_bound_check \
3468 if (checkbounds) { \
3469 i386_alu_membase_reg(I386_CMP, s1, OFFSET(java_arrayheader, size), s2); \
3470 i386_jcc(I386_CC_A, 0); \
3471 mcode_addxboundrefs(mcodeptr); \
3474 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
3476 var_to_reg_int(s1, src, REG_ITMP1);
3477 d = reg_of_var(iptr->dst, REG_ITMP3);
3478 gen_nullptr_check(s1);
3479 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
3480 store_reg_to_var_int(iptr->dst, d);
3483 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
3485 var_to_reg_int(s1, src->prev, REG_ITMP1);
3486 var_to_reg_int(s2, src, REG_ITMP2);
3487 d = reg_of_var(iptr->dst, REG_ITMP3);
3488 if (iptr->op1 == 0) {
3489 gen_nullptr_check(s1);
3492 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
3493 store_reg_to_var_int(iptr->dst, d);
3496 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
3498 var_to_reg_int(s1, src->prev, REG_ITMP1);
3499 var_to_reg_int(s2, src, REG_ITMP2);
3500 d = reg_of_var(iptr->dst, REG_ITMP3);
3501 if (iptr->op1 == 0) {
3502 gen_nullptr_check(s1);
3506 if (iptr->dst->flags & INMEMORY) {
3507 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
3508 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
3509 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
3510 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
3514 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
3516 var_to_reg_int(s1, src->prev, REG_ITMP1);
3517 var_to_reg_int(s2, src, REG_ITMP2);
3518 d = reg_of_var(iptr->dst, REG_ITMP3);
3519 if (iptr->op1 == 0) {
3520 gen_nullptr_check(s1);
3523 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
3524 store_reg_to_var_int(iptr->dst, d);
3527 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
3529 var_to_reg_int(s1, src->prev, REG_ITMP1);
3530 var_to_reg_int(s2, src, REG_ITMP2);
3531 d = reg_of_var(iptr->dst, REG_FTMP3);
3532 if (iptr->op1 == 0) {
3533 gen_nullptr_check(s1);
3536 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
3538 store_reg_to_var_flt(iptr->dst, d);
3541 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
3543 var_to_reg_int(s1, src->prev, REG_ITMP1);
3544 var_to_reg_int(s2, src, REG_ITMP2);
3545 d = reg_of_var(iptr->dst, REG_FTMP3);
3546 if (iptr->op1 == 0) {
3547 gen_nullptr_check(s1);
3550 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
3552 store_reg_to_var_flt(iptr->dst, d);
3555 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
3557 var_to_reg_int(s1, src->prev, REG_ITMP1);
3558 var_to_reg_int(s2, src, REG_ITMP2);
3559 d = reg_of_var(iptr->dst, REG_ITMP3);
3560 if (iptr->op1 == 0) {
3561 gen_nullptr_check(s1);
3564 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
3565 store_reg_to_var_int(iptr->dst, d);
3568 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
3570 var_to_reg_int(s1, src->prev, REG_ITMP1);
3571 var_to_reg_int(s2, src, REG_ITMP2);
3572 d = reg_of_var(iptr->dst, REG_ITMP3);
3573 if (iptr->op1 == 0) {
3574 gen_nullptr_check(s1);
3577 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
3578 store_reg_to_var_int(iptr->dst, d);
3581 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
3583 var_to_reg_int(s1, src->prev, REG_ITMP1);
3584 var_to_reg_int(s2, src, REG_ITMP2);
3585 d = reg_of_var(iptr->dst, REG_ITMP3);
3586 if (iptr->op1 == 0) {
3587 gen_nullptr_check(s1);
3590 i386_movzbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
3591 store_reg_to_var_int(iptr->dst, d);
3595 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
3597 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3598 var_to_reg_int(s2, src->prev, REG_ITMP2);
3599 if (iptr->op1 == 0) {
3600 gen_nullptr_check(s1);
3603 var_to_reg_int(s3, src, REG_ITMP3);
3604 i386_mov_reg_memindex(s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
3607 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
3609 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3610 var_to_reg_int(s2, src->prev, REG_ITMP2);
3611 if (iptr->op1 == 0) {
3612 gen_nullptr_check(s1);
3616 if (src->flags & INMEMORY) {
3617 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
3618 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
3619 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
3620 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
3624 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
3626 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3627 var_to_reg_int(s2, src->prev, REG_ITMP2);
3628 if (iptr->op1 == 0) {
3629 gen_nullptr_check(s1);
3632 var_to_reg_int(s3, src, REG_ITMP3);
3633 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
3636 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
3638 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3639 var_to_reg_int(s2, src->prev, REG_ITMP2);
3640 if (iptr->op1 == 0) {
3641 gen_nullptr_check(s1);
3644 var_to_reg_flt(s3, src, REG_FTMP3);
3645 i386_fstps_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
3649 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
3651 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3652 var_to_reg_int(s2, src->prev, REG_ITMP2);
3653 if (iptr->op1 == 0) {
3654 gen_nullptr_check(s1);
3657 var_to_reg_flt(s3, src, REG_FTMP3);
3658 i386_fstpl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
3662 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
3664 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3665 var_to_reg_int(s2, src->prev, REG_ITMP2);
3666 if (iptr->op1 == 0) {
3667 gen_nullptr_check(s1);
3670 var_to_reg_int(s3, src, REG_ITMP3);
3671 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
3674 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
3676 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3677 var_to_reg_int(s2, src->prev, REG_ITMP2);
3678 if (iptr->op1 == 0) {
3679 gen_nullptr_check(s1);
3682 var_to_reg_int(s3, src, REG_ITMP3);
3683 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
3686 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
3688 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3689 var_to_reg_int(s2, src->prev, REG_ITMP2);
3690 if (iptr->op1 == 0) {
3691 gen_nullptr_check(s1);
3694 var_to_reg_int(s3, src, REG_ITMP3);
3695 M_INTMOVE(s3, REG_ITMP3); /* because EBP, ESI, EDI have no xH and xL bytes */
3696 i386_movb_reg_memindex(REG_ITMP3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
3700 case ICMD_PUTSTATIC: /* ..., value ==> ... */
3701 /* op1 = type, val.a = field address */
3703 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3704 /* here it's slightly slower */
3705 i386_mov_imm_reg(0, REG_ITMP2);
3706 dseg_adddata(mcodeptr);
3707 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP3);
3708 switch (iptr->op1) {
3710 var_to_reg_int(s2, src, REG_ITMP1);
3711 i386_mov_reg_membase(s2, REG_ITMP3, 0);
3714 if (src->flags & INMEMORY) {
3715 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3716 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3717 i386_mov_reg_membase(REG_ITMP1, REG_ITMP3, 0);
3718 i386_mov_reg_membase(REG_ITMP2, REG_ITMP3, 0 + 4);
3720 panic("PUTSTATIC: longs have to be in memory");
3724 var_to_reg_int(s2, src, REG_ITMP1);
3725 i386_mov_reg_membase(s2, REG_ITMP3, 0);
3728 var_to_reg_flt(s2, src, REG_FTMP2);
3729 i386_fstps_membase(REG_ITMP3, 0);
3733 var_to_reg_flt(s2, src, REG_FTMP2);
3734 i386_fstpl_membase(REG_ITMP3, 0);
3737 default: panic ("internal error");
3741 case ICMD_GETSTATIC: /* ... ==> ..., value */
3742 /* op1 = type, val.a = field address */
3744 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3745 i386_mov_imm_reg(0, REG_ITMP2);
3746 dseg_adddata(mcodeptr);
3747 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP3);
3748 switch (iptr->op1) {
3750 d = reg_of_var(iptr->dst, REG_ITMP1);
3751 i386_mov_membase_reg(REG_ITMP3, 0, d);
3752 store_reg_to_var_int(iptr->dst, d);
3755 d = reg_of_var(iptr->dst, REG_ITMP3);
3756 if (iptr->dst->flags & INMEMORY) {
3757 i386_mov_membase_reg(REG_ITMP3, 0, REG_ITMP1);
3758 i386_mov_membase_reg(REG_ITMP3, 4, REG_ITMP2);
3759 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3760 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3762 panic("GETSTATIC: longs have to be in memory");
3766 d = reg_of_var(iptr->dst, REG_ITMP1);
3767 i386_mov_membase_reg(REG_ITMP3, 0, d);
3768 store_reg_to_var_int(iptr->dst, d);
3771 d = reg_of_var(iptr->dst, REG_ITMP1);
3772 i386_flds_membase(REG_ITMP3, 0);
3774 store_reg_to_var_flt(iptr->dst, d);
3777 d = reg_of_var(iptr->dst, REG_ITMP1);
3778 i386_fldl_membase(REG_ITMP3, 0);
3780 store_reg_to_var_flt(iptr->dst, d);
3782 default: panic ("internal error");
3786 case ICMD_PUTFIELD: /* ..., value ==> ... */
3787 /* op1 = type, val.i = field offset */
3789 a = ((fieldinfo *)(iptr->val.a))->offset;
3790 switch (iptr->op1) {
3792 var_to_reg_int(s1, src->prev, REG_ITMP1);
3793 var_to_reg_int(s2, src, REG_ITMP2);
3794 gen_nullptr_check(s1);
3795 i386_mov_reg_membase(s2, s1, a);
3798 var_to_reg_int(s1, src->prev, REG_ITMP1);
3799 gen_nullptr_check(s1);
3800 if (src->flags & INMEMORY) {
3801 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3802 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
3803 i386_mov_reg_membase(REG_ITMP2, s1, a);
3804 i386_mov_reg_membase(REG_ITMP3, s1, a + 4);
3806 panic("PUTFIELD: longs have to be in memory");
3810 var_to_reg_int(s1, src->prev, REG_ITMP1);
3811 var_to_reg_int(s2, src, REG_ITMP2);
3812 gen_nullptr_check(s1);
3813 i386_mov_reg_membase(s2, s1, a);
3816 var_to_reg_int(s1, src->prev, REG_ITMP1);
3817 var_to_reg_flt(s2, src, REG_FTMP2);
3818 gen_nullptr_check(s1);
3819 i386_fstps_membase(s1, a);
3823 var_to_reg_int(s1, src->prev, REG_ITMP1);
3824 var_to_reg_flt(s2, src, REG_FTMP2);
3825 gen_nullptr_check(s1);
3826 i386_fstpl_membase(s1, a);
3829 default: panic ("internal error");
3833 case ICMD_GETFIELD: /* ... ==> ..., value */
3834 /* op1 = type, val.i = field offset */
3836 a = ((fieldinfo *)(iptr->val.a))->offset;
3837 switch (iptr->op1) {
3839 var_to_reg_int(s1, src, REG_ITMP1);
3840 d = reg_of_var(iptr->dst, REG_ITMP3);
3841 gen_nullptr_check(s1);
3842 i386_mov_membase_reg(s1, a, d);
3843 store_reg_to_var_int(iptr->dst, d);
3846 var_to_reg_int(s1, src, REG_ITMP1);
3847 d = reg_of_var(iptr->dst, REG_ITMP3);
3848 gen_nullptr_check(s1);
3849 i386_mov_membase_reg(s1, a, REG_ITMP2);
3850 i386_mov_membase_reg(s1, a + 4, REG_ITMP3);
3851 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3852 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
3855 var_to_reg_int(s1, src, REG_ITMP1);
3856 d = reg_of_var(iptr->dst, REG_ITMP3);
3857 gen_nullptr_check(s1);
3858 i386_mov_membase_reg(s1, a, d);
3859 store_reg_to_var_int(iptr->dst, d);
3862 var_to_reg_int(s1, src, REG_ITMP1);
3863 d = reg_of_var(iptr->dst, REG_FTMP1);
3864 gen_nullptr_check(s1);
3865 i386_flds_membase(s1, a);
3867 store_reg_to_var_flt(iptr->dst, d);
3870 var_to_reg_int(s1, src, REG_ITMP1);
3871 d = reg_of_var(iptr->dst, REG_FTMP1);
3872 gen_nullptr_check(s1);
3873 i386_fldl_membase(s1, a);
3875 store_reg_to_var_flt(iptr->dst, d);
3877 default: panic ("internal error");
3882 /* branch operations **************************************************/
3885 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3886 #define ALIGNCODENOP do {} while (0)
3888 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3890 var_to_reg_int(s1, src, REG_ITMP1);
3891 M_INTMOVE(s1, REG_ITMP1_XPTR);
3893 i386_call_imm(0); /* passing exception pointer */
3894 i386_pop_reg(REG_ITMP2_XPC);
3896 i386_mov_imm_reg(0, REG_ITMP3); /* we need data segment pointer */
3897 dseg_adddata(mcodeptr);
3899 i386_push_imm(asm_handle_exception);
3901 i386_nop(); /* nop ensures that XPC is less than the end */
3902 /* of basic block */
3906 case ICMD_GOTO: /* ... ==> ... */
3907 /* op1 = target JavaVM pc */
3910 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3914 case ICMD_JSR: /* ... ==> ... */
3915 /* op1 = target JavaVM pc */
3918 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3921 case ICMD_RET: /* ... ==> ... */
3922 /* op1 = local variable */
3924 var = &(locals[iptr->op1][TYPE_ADR]);
3925 var_to_reg_int(s1, var, REG_ITMP1);
3929 case ICMD_IFNULL: /* ..., value ==> ... */
3930 /* op1 = target JavaVM pc */
3932 if (src->flags & INMEMORY) {
3933 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3937 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
3939 i386_jcc(I386_CC_E, 0);
3940 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3943 case ICMD_IFNONNULL: /* ..., value ==> ... */
3944 /* op1 = target JavaVM pc */
3946 if (src->flags & INMEMORY) {
3947 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3951 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
3953 i386_jcc(I386_CC_NE, 0);
3954 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3957 case ICMD_IFEQ: /* ..., value ==> ... */
3958 /* op1 = target JavaVM pc, val.i = constant */
3960 if (src->flags & INMEMORY) {
3961 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3964 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3966 i386_jcc(I386_CC_E, 0);
3967 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3970 case ICMD_IFLT: /* ..., value ==> ... */
3971 /* op1 = target JavaVM pc, val.i = constant */
3973 if (src->flags & INMEMORY) {
3974 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3977 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3979 i386_jcc(I386_CC_L, 0);
3980 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3983 case ICMD_IFLE: /* ..., value ==> ... */
3984 /* op1 = target JavaVM pc, val.i = constant */
3986 if (src->flags & INMEMORY) {
3987 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3990 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3992 i386_jcc(I386_CC_LE, 0);
3993 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3996 case ICMD_IFNE: /* ..., value ==> ... */
3997 /* op1 = target JavaVM pc, val.i = constant */
3999 if (src->flags & INMEMORY) {
4000 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
4003 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
4005 i386_jcc(I386_CC_NE, 0);
4006 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4009 case ICMD_IFGT: /* ..., value ==> ... */
4010 /* op1 = target JavaVM pc, val.i = constant */
4012 if (src->flags & INMEMORY) {
4013 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
4016 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
4018 i386_jcc(I386_CC_G, 0);
4019 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4022 case ICMD_IFGE: /* ..., value ==> ... */
4023 /* op1 = target JavaVM pc, val.i = constant */
4025 if (src->flags & INMEMORY) {
4026 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
4029 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
4031 i386_jcc(I386_CC_GE, 0);
4032 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4035 case ICMD_IF_LEQ: /* ..., value ==> ... */
4036 /* op1 = target JavaVM pc, val.l = constant */
4038 if (src->flags & INMEMORY) {
4039 if (iptr->val.l == 0) {
4040 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4041 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4043 } else if (iptr->val.l > 0 && iptr->val.l <= 0x00000000ffffffff) {
4044 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4045 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
4046 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4049 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
4050 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
4051 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4052 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
4053 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
4056 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
4057 i386_jcc(I386_CC_E, 0);
4058 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4061 case ICMD_IF_LLT: /* ..., value ==> ... */
4062 /* op1 = target JavaVM pc, val.l = constant */
4064 /* TODO: optimize as in IF_LEQ */
4065 if (src->flags & INMEMORY) {
4067 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
4068 i386_jcc(I386_CC_L, 0);
4069 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4072 CALCREGOFFBYTES(src->regoff);
4073 CALCIMMEDIATEBYTES(iptr->val.l);
4075 i386_jcc(I386_CC_G, offset);
4077 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
4078 i386_jcc(I386_CC_B, 0);
4079 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4083 case ICMD_IF_LLE: /* ..., value ==> ... */
4084 /* op1 = target JavaVM pc, val.l = constant */
4086 /* TODO: optimize as in IF_LEQ */
4087 if (src->flags & INMEMORY) {
4089 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
4090 i386_jcc(I386_CC_L, 0);
4091 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4094 CALCREGOFFBYTES(src->regoff);
4095 CALCIMMEDIATEBYTES(iptr->val.l);
4097 i386_jcc(I386_CC_G, offset);
4099 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
4100 i386_jcc(I386_CC_BE, 0);
4101 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4105 case ICMD_IF_LNE: /* ..., value ==> ... */
4106 /* op1 = target JavaVM pc, val.l = constant */
4108 /* TODO: optimize for val.l == 0 */
4109 if (src->flags & INMEMORY) {
4110 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
4111 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
4112 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
4113 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
4114 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
4115 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
4117 i386_jcc(I386_CC_NE, 0);
4118 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4121 case ICMD_IF_LGT: /* ..., value ==> ... */
4122 /* op1 = target JavaVM pc, val.l = constant */
4124 /* TODO: optimize as in IF_LEQ */
4125 if (src->flags & INMEMORY) {
4127 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
4128 i386_jcc(I386_CC_G, 0);
4129 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4132 CALCREGOFFBYTES(src->regoff);
4133 CALCIMMEDIATEBYTES(iptr->val.l);
4135 i386_jcc(I386_CC_L, offset);
4137 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
4138 i386_jcc(I386_CC_A, 0);
4139 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4143 case ICMD_IF_LGE: /* ..., value ==> ... */
4144 /* op1 = target JavaVM pc, val.l = constant */
4146 /* TODO: optimize as in IF_LEQ */
4147 if (src->flags & INMEMORY) {
4149 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
4150 i386_jcc(I386_CC_G, 0);
4151 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4154 CALCREGOFFBYTES(src->regoff);
4155 CALCIMMEDIATEBYTES(iptr->val.l);
4157 i386_jcc(I386_CC_L, offset);
4159 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
4160 i386_jcc(I386_CC_AE, 0);
4161 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4165 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
4166 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
4168 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4169 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4170 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
4172 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4173 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
4175 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4176 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4179 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4181 i386_jcc(I386_CC_E, 0);
4182 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4185 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
4186 /* op1 = target JavaVM pc */
4188 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4189 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4190 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
4191 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
4192 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
4193 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
4194 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
4196 i386_jcc(I386_CC_E, 0);
4197 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4200 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
4201 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
4203 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4204 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4205 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
4207 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4208 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
4210 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4211 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4214 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4216 i386_jcc(I386_CC_NE, 0);
4217 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4220 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
4221 /* op1 = target JavaVM pc */
4223 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4224 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4225 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
4226 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
4227 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
4228 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
4229 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
4231 i386_jcc(I386_CC_NE, 0);
4232 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4235 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
4236 /* op1 = target JavaVM pc */
4238 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4239 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4240 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
4242 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4243 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
4245 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4246 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4249 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4251 i386_jcc(I386_CC_L, 0);
4252 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4255 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
4256 /* op1 = target JavaVM pc */
4258 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4260 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
4261 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4262 i386_jcc(I386_CC_L, 0);
4263 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4266 CALCREGOFFBYTES(src->prev->regoff);
4267 CALCREGOFFBYTES(src->regoff);
4269 i386_jcc(I386_CC_G, offset);
4271 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4272 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
4273 i386_jcc(I386_CC_B, 0);
4274 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4278 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
4279 /* op1 = target JavaVM pc */
4281 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4282 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4283 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
4285 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4286 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
4288 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4289 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4292 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4294 i386_jcc(I386_CC_G, 0);
4295 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4298 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
4299 /* op1 = target JavaVM pc */
4301 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4303 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
4304 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4305 i386_jcc(I386_CC_G, 0);
4306 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4309 CALCREGOFFBYTES(src->prev->regoff);
4310 CALCREGOFFBYTES(src->regoff);
4312 i386_jcc(I386_CC_L, offset);
4314 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4315 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
4316 i386_jcc(I386_CC_A, 0);
4317 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4321 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
4322 /* op1 = target JavaVM pc */
4324 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4325 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4326 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
4328 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4329 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
4331 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4332 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4335 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4337 i386_jcc(I386_CC_LE, 0);
4338 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4341 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
4342 /* op1 = target JavaVM pc */
4344 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4346 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
4347 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4348 i386_jcc(I386_CC_L, 0);
4349 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4352 CALCREGOFFBYTES(src->prev->regoff);
4353 CALCREGOFFBYTES(src->regoff);
4355 i386_jcc(I386_CC_G, offset);
4357 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4358 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
4359 i386_jcc(I386_CC_BE, 0);
4360 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4364 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
4365 /* op1 = target JavaVM pc */
4367 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4368 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4369 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
4371 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4372 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
4374 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4375 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4378 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4380 i386_jcc(I386_CC_GE, 0);
4381 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4384 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
4385 /* op1 = target JavaVM pc */
4387 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4389 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
4390 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4391 i386_jcc(I386_CC_G, 0);
4392 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4395 CALCREGOFFBYTES(src->prev->regoff);
4396 CALCREGOFFBYTES(src->regoff);
4398 i386_jcc(I386_CC_L, offset);
4400 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4401 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
4402 i386_jcc(I386_CC_AE, 0);
4403 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4407 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
4409 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
4412 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
4413 /* val.i = constant */
4415 d = reg_of_var(iptr->dst, REG_ITMP3);
4416 if (iptr->dst->flags & INMEMORY) {
4419 if (src->flags & INMEMORY) {
4420 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4424 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4428 CALCOFFSETBYTES(iptr->dst->regoff * 8);
4430 i386_jcc(I386_CC_NE, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4431 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4433 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4434 i386_jmp_imm(offset);
4435 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4439 if (src->flags & INMEMORY) {
4440 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4444 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4447 i386_jcc(I386_CC_NE, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4448 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4450 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4452 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4457 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
4458 /* val.i = constant */
4460 d = reg_of_var(iptr->dst, REG_ITMP3);
4461 if (iptr->dst->flags & INMEMORY) {
4464 if (src->flags & INMEMORY) {
4465 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4469 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4473 CALCREGOFFBYTES(iptr->dst->regoff);
4475 i386_jcc(I386_CC_E, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4476 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4478 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4479 i386_jmp_imm(offset);
4480 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4484 if (src->flags & INMEMORY) {
4485 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4489 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4492 i386_jcc(I386_CC_E, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4493 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4495 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4497 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4502 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
4503 /* val.i = constant */
4505 d = reg_of_var(iptr->dst, REG_ITMP3);
4506 if (iptr->dst->flags & INMEMORY) {
4509 if (src->flags & INMEMORY) {
4510 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4514 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4518 CALCREGOFFBYTES(iptr->dst->regoff);
4520 i386_jcc(I386_CC_GE, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4521 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4523 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4524 i386_jmp_imm(offset);
4525 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4529 if (src->flags & INMEMORY) {
4530 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4534 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4537 i386_jcc(I386_CC_GE, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4538 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4540 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4542 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4547 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
4548 /* val.i = constant */
4550 d = reg_of_var(iptr->dst, REG_ITMP3);
4551 if (iptr->dst->flags & INMEMORY) {
4554 if (src->flags & INMEMORY) {
4555 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4559 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4563 CALCREGOFFBYTES(iptr->dst->regoff);
4565 i386_jcc(I386_CC_L, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4566 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4568 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4569 i386_jmp_imm(offset);
4570 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4574 if (src->flags & INMEMORY) {
4575 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4579 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4582 i386_jcc(I386_CC_L, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4583 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4585 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4587 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4592 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
4593 /* val.i = constant */
4595 d = reg_of_var(iptr->dst, REG_ITMP3);
4596 if (iptr->dst->flags & INMEMORY) {
4599 if (src->flags & INMEMORY) {
4600 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4604 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4608 CALCREGOFFBYTES(iptr->dst->regoff);
4610 i386_jcc(I386_CC_LE, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4611 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4613 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4614 i386_jmp_imm(offset);
4615 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4619 if (src->flags & INMEMORY) {
4620 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4624 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4627 i386_jcc(I386_CC_LE, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4628 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4630 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4632 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4637 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
4638 /* val.i = constant */
4640 /* TWISTI: checked */
4641 d = reg_of_var(iptr->dst, REG_ITMP3);
4642 if (iptr->dst->flags & INMEMORY) {
4645 if (src->flags & INMEMORY) {
4646 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4650 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4654 CALCREGOFFBYTES(iptr->dst->regoff);
4656 i386_jcc(I386_CC_G, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4657 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4659 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4660 i386_jmp_imm(offset);
4661 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4665 if (src->flags & INMEMORY) {
4666 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4670 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
4673 i386_jcc(I386_CC_G, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4674 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4676 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4678 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4684 case ICMD_IRETURN: /* ..., retvalue ==> ... */
4688 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4689 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4690 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4691 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4692 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4693 i386_call_reg(REG_ITMP1);
4694 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4697 var_to_reg_int(s1, src, REG_RESULT);
4698 M_INTMOVE(s1, REG_RESULT);
4699 goto nowperformreturn;
4701 case ICMD_LRETURN: /* ..., retvalue ==> ... */
4704 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4705 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4706 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4707 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4708 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4709 i386_call_reg(REG_ITMP1);
4710 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4713 if (src->flags & INMEMORY) {
4714 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
4715 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
4718 panic("LRETURN: longs have to be in memory");
4720 goto nowperformreturn;
4722 case ICMD_FRETURN: /* ..., retvalue ==> ... */
4725 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4726 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4727 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4728 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4729 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4730 i386_call_reg(REG_ITMP1);
4731 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4734 var_to_reg_flt(s1, src, REG_FRESULT);
4735 /* this may be an early return -- keep the offset correct for the remaining code */
4737 goto nowperformreturn;
4739 case ICMD_DRETURN: /* ..., retvalue ==> ... */
4742 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4743 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4744 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4745 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4746 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4747 i386_call_reg(REG_ITMP1);
4748 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4751 var_to_reg_flt(s1, src, REG_FRESULT);
4752 /* this may be an early return -- keep the offset correct for the remaining code */
4754 goto nowperformreturn;
4756 case ICMD_RETURN: /* ... ==> ... */
4759 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4760 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4761 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4762 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4763 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4764 i386_call_reg(REG_ITMP1);
4765 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4773 p = parentargs_base;
4775 /* restore return address */
4776 if (!isleafmethod) {
4777 /* p--; M_LLD (REG_RA, REG_SP, 8 * p); -- do we really need this on i386 */
4780 /* restore saved registers */
4781 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
4783 i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
4785 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
4787 i386_fldl_membase(REG_SP, p * 8);
4789 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
4790 i386_fstp_reg(savfltregs[r] + fpu_st_offset + 1);
4792 i386_fstp_reg(savfltregs[r] + fpu_st_offset);
4797 /* deallocate stack */
4798 if (parentargs_base) {
4799 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
4802 /* call trace function */
4804 i386_alu_imm_reg(I386_SUB, 4 + 8 + 4 + 8, REG_SP);
4806 i386_mov_imm_membase(method, REG_SP, 0);
4808 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
4809 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
4811 i386_fsts_membase(REG_SP, 4 + 8);
4812 i386_fstl_membase(REG_SP, 4 + 8 + 4);
4814 i386_mov_imm_reg(builtin_displaymethodstop, REG_ITMP1);
4815 i386_call_reg(REG_ITMP1);
4817 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
4818 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
4820 i386_alu_imm_reg(I386_ADD, 4 + 8 + 4 + 8, REG_SP);
4829 case ICMD_TABLESWITCH: /* ..., index ==> ... */
4834 tptr = (void **) iptr->target;
4836 s4ptr = iptr->val.a;
4837 l = s4ptr[1]; /* low */
4838 i = s4ptr[2]; /* high */
4840 var_to_reg_int(s1, src, REG_ITMP1);
4842 M_INTMOVE(s1, REG_ITMP1);
4844 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
4850 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
4851 i386_jcc(I386_CC_A, 0);
4853 /* mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
4854 mcode_addreference((basicblock *) tptr[0], mcodeptr);
4856 /* build jump table top down and use address of lowest entry */
4858 /* s4ptr += 3 + i; */
4862 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
4863 dseg_addtarget((basicblock *) tptr[0]);
4867 /* length of dataseg after last dseg_addtarget is used by load */
4869 i386_mov_imm_reg(0, REG_ITMP2);
4870 dseg_adddata(mcodeptr);
4871 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
4872 i386_jmp_reg(REG_ITMP1);
4878 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
4880 s4 i, l, val, *s4ptr;
4883 tptr = (void **) iptr->target;
4885 s4ptr = iptr->val.a;
4886 l = s4ptr[0]; /* default */
4887 i = s4ptr[1]; /* count */
4889 MCODECHECK((i<<2)+8);
4890 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
4896 i386_alu_imm_reg(I386_CMP, val, s1);
4897 i386_jcc(I386_CC_E, 0);
4898 /* mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
4899 mcode_addreference((basicblock *) tptr[0], mcodeptr);
4903 /* mcode_addreference(BlockPtrOfPC(l), mcodeptr); */
4905 tptr = (void **) iptr->target;
4906 mcode_addreference((basicblock *) tptr[0], mcodeptr);
4913 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
4914 /* op1 = return type, val.a = function pointer*/
4918 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
4919 /* op1 = return type, val.a = function pointer*/
4923 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
4924 /* op1 = return type, val.a = function pointer*/
4928 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
4929 /* op1 = arg count, val.a = method pointer */
4931 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
4932 /* op1 = arg count, val.a = method pointer */
4934 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
4935 /* op1 = arg count, val.a = method pointer */
4937 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
4938 /* op1 = arg count, val.a = method pointer */
4946 MCODECHECK((s3 << 1) + 64);
4948 /* copy arguments to registers or stack location */
4950 for (; --s3 >= 0; src = src->prev) {
4951 if (src->varkind == ARGVAR) {
4955 if (IS_INT_LNG_TYPE(src->type)) {
4956 if (s3 < intreg_argnum) {
4957 panic("No integer argument registers available!");
4960 if (!IS_2_WORD_TYPE(src->type)) {
4961 if (src->flags & INMEMORY) {
4962 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4963 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
4966 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 8);
4970 if (src->flags & INMEMORY) {
4971 M_LNGMEMMOVE(src->regoff, s3);
4974 panic("copy arguments: longs have to be in memory");
4980 if (s3 < fltreg_argnum) {
4981 panic("No float argument registers available!");
4984 var_to_reg_flt(d, src, REG_FTMP1);
4985 if (src->type == TYPE_FLT) {
4986 i386_fstps_membase(REG_SP, s3 * 8);
4989 i386_fstpl_membase(REG_SP, s3 * 8);
4996 switch (iptr->opc) {
5004 i386_mov_imm_reg(0, REG_ITMP3); /* we need the data segment address in asmpart */
5005 dseg_adddata(mcodeptr);
5007 i386_mov_imm_reg(a, REG_ITMP1);
5008 i386_call_reg(REG_ITMP1);
5011 case ICMD_INVOKESTATIC:
5012 case ICMD_INVOKESPECIAL:
5014 a = (s4) m->stubroutine;
5016 i386_mov_imm_reg(a, REG_ITMP2);
5017 i386_call_reg(REG_ITMP2);
5020 case ICMD_INVOKEVIRTUAL:
5022 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2);
5023 gen_nullptr_check(REG_ITMP2);
5024 i386_mov_membase_reg(REG_ITMP2, OFFSET(java_objectheader, vftbl), REG_ITMP3);
5025 i386_mov_membase32_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
5028 i386_call_reg(REG_ITMP1);
5031 case ICMD_INVOKEINTERFACE:
5034 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2);
5035 gen_nullptr_check(REG_ITMP2);
5036 i386_mov_membase_reg(REG_ITMP2, OFFSET(java_objectheader, vftbl), REG_ITMP3);
5037 i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP3);
5038 i386_mov_membase32_reg(REG_ITMP3, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
5041 i386_call_reg(REG_ITMP1);
5046 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
5050 /* d contains return type */
5052 if (d != TYPE_VOID) {
5053 d = reg_of_var(iptr->dst, REG_ITMP3);
5055 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
5056 if (IS_2_WORD_TYPE(iptr->dst->type)) {
5057 if (iptr->dst->flags & INMEMORY) {
5058 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
5059 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
5062 panic("RETURN: longs have to be in memory");
5066 if (iptr->dst->flags & INMEMORY) {
5067 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
5070 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
5075 /* fld from called function -- has other fpu_st_offset counter */
5077 store_reg_to_var_flt(iptr->dst, d);
5084 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
5086 /* op1: 0 == array, 1 == class */
5087 /* val.a: (classinfo*) superclass */
5089 /* superclass is an interface:
5091 * return (sub != NULL) &&
5092 * (sub->vftbl->interfacetablelength > super->index) &&
5093 * (sub->vftbl->interfacetable[-super->index] != NULL);
5095 * superclass is a class:
5097 * return ((sub != NULL) && (0
5098 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
5099 * super->vftbl->diffvall));
5103 classinfo *super = (classinfo*) iptr->val.a;
5105 var_to_reg_int(s1, src, REG_ITMP1);
5106 d = reg_of_var(iptr->dst, REG_ITMP3);
5107 /* if (s1 == d) { */
5108 /* M_MOV(s1, REG_ITMP1); */
5109 /* s1 = REG_ITMP1; */
5111 i386_alu_reg_reg(I386_XOR, d, d);
5112 if (iptr->op1) { /* class/interface */
5113 if (super->flags & ACC_INTERFACE) { /* interface */
5116 i386_alu_imm_reg(I386_CMP, 0, s1);
5118 /* TODO: clean up this calculation */
5120 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
5123 CALCOFFSETBYTES(OFFSET(vftbl, interfacetablelength));
5126 CALCOFFSETBYTES(-super->index);
5132 CALCOFFSETBYTES(OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
5136 offset += 6; /* jcc */
5139 i386_jcc(I386_CC_E, offset);
5141 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
5142 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
5143 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
5145 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
5147 /* TODO: clean up this calculation */
5150 CALCOFFSETBYTES(OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
5154 offset += 6; /* jcc */
5157 i386_jcc(I386_CC_LE, offset);
5158 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
5160 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
5161 /* i386_setcc_reg(I386_CC_A, d); */
5162 /* i386_jcc(I386_CC_BE, 5); */
5163 i386_jcc(I386_CC_E, 5);
5164 i386_mov_imm_reg(1, d);
5167 } else { /* class */
5170 i386_alu_imm_reg(I386_CMP, 0, s1);
5172 /* TODO: clean up this calculation */
5174 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
5179 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
5182 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
5185 CALCOFFSETBYTES(OFFSET(vftbl, diffval));
5190 offset += 2; /* xor */
5192 offset += 6; /* jcc */
5195 i386_jcc(I386_CC_E, offset);
5197 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
5198 i386_mov_imm_reg((void *) super->vftbl, REG_ITMP2);
5199 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
5200 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
5201 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
5202 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
5203 i386_alu_reg_reg(I386_XOR, d, d);
5204 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
5205 /* i386_setcc_reg(I386_CC_BE, d); */
5206 i386_jcc(I386_CC_A, 5);
5207 i386_mov_imm_reg(1, d);
5212 panic ("internal error: no inlined array instanceof");
5214 store_reg_to_var_int(iptr->dst, d);
5217 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
5219 /* op1: 0 == array, 1 == class */
5220 /* val.a: (classinfo*) superclass */
5222 /* superclass is an interface:
5224 * OK if ((sub == NULL) ||
5225 * (sub->vftbl->interfacetablelength > super->index) &&
5226 * (sub->vftbl->interfacetable[-super->index] != NULL));
5228 * superclass is a class:
5230 * OK if ((sub == NULL) || (0
5231 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
5232 * super->vftbl->diffvall));
5236 classinfo *super = (classinfo*) iptr->val.a;
5238 d = reg_of_var(iptr->dst, REG_ITMP3);
5239 var_to_reg_int(s1, src, d);
5240 if (iptr->op1) { /* class/interface */
5241 if (super->flags & ACC_INTERFACE) { /* interface */
5244 i386_alu_imm_reg(I386_CMP, 0, s1);
5246 /* TODO: clean up this calculation */
5248 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
5251 CALCOFFSETBYTES(OFFSET(vftbl, interfacetablelength));
5254 CALCOFFSETBYTES(-super->index);
5260 CALCOFFSETBYTES(OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
5265 i386_jcc(I386_CC_E, offset);
5267 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
5268 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
5269 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
5271 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
5272 i386_jcc(I386_CC_LE, 0);
5273 mcode_addxcastrefs(mcodeptr);
5274 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
5276 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
5277 i386_jcc(I386_CC_E, 0);
5278 mcode_addxcastrefs(mcodeptr);
5280 } else { /* class */
5283 i386_alu_imm_reg(I386_CMP, 0, s1);
5285 /* TODO: clean up this calculation */
5287 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
5292 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
5294 if (d != REG_ITMP3) {
5296 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
5299 CALCOFFSETBYTES(OFFSET(vftbl, diffval));
5305 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
5312 CALCOFFSETBYTES(OFFSET(vftbl, diffval));
5319 i386_jcc(I386_CC_E, offset);
5321 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
5322 i386_mov_imm_reg((void *) super->vftbl, REG_ITMP2);
5323 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
5324 if (d != REG_ITMP3) {
5325 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
5326 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
5327 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
5330 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
5331 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
5332 i386_mov_imm_reg((void *) super->vftbl, REG_ITMP2);
5333 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
5335 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
5336 i386_jcc(I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
5337 mcode_addxcastrefs(mcodeptr);
5341 panic ("internal error: no inlined array checkcast");
5344 store_reg_to_var_int(iptr->dst, d);
5347 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
5349 if (src->flags & INMEMORY) {
5350 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5354 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
5356 i386_jcc(I386_CC_L, 0);
5357 mcode_addxcheckarefs(mcodeptr);
5360 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
5361 /* op1 = dimension, val.a = array descriptor */
5363 /* check for negative sizes and copy sizes to stack if necessary */
5365 MCODECHECK((iptr->op1 << 1) + 64);
5367 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
5368 if (src->flags & INMEMORY) {
5369 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5373 i386_alu_imm_reg(I386_CMP, 0, src->regoff);
5375 i386_jcc(I386_CC_L, 0);
5376 mcode_addxcheckarefs(mcodeptr);
5379 * copy sizes to new stack location, be cause native function
5380 * builtin_nmultianewarray access them as (int *)
5382 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5383 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
5385 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
5387 if (src->varkind != ARGVAR) {
5388 if (src->flags & INMEMORY) {
5389 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
5390 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
5393 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
5397 i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
5399 /* a0 = dimension count */
5401 /* save stack pointer */
5402 M_INTMOVE(REG_SP, REG_ITMP1);
5404 i386_alu_imm_reg(I386_SUB, 12, REG_SP);
5405 i386_mov_imm_membase(iptr->op1, REG_SP, 0);
5407 /* a1 = arraydescriptor */
5409 i386_mov_imm_membase(iptr->val.a, REG_SP, 4);
5411 /* a2 = pointer to dimensions = stack pointer */
5413 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
5415 i386_mov_imm_reg((void*) (builtin_nmultianewarray), REG_ITMP1);
5416 i386_call_reg(REG_ITMP1);
5417 i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
5419 s1 = reg_of_var(iptr->dst, REG_RESULT);
5420 M_INTMOVE(REG_RESULT, s1);
5421 store_reg_to_var_int(iptr->dst, s1);
5425 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
5432 } /* for instruction */
5434 /* copy values to interface registers */
5436 src = bptr->outstack;
5437 len = bptr->outdepth;
5441 if ((src->varkind != STACKVAR)) {
5443 if (IS_FLT_DBL_TYPE(s2)) {
5444 var_to_reg_flt(s1, src, REG_FTMP1);
5445 if (!(interfaces[len][s2].flags & INMEMORY)) {
5446 M_FLTMOVE(s1,interfaces[len][s2].regoff);
5449 panic("double store");
5450 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
5454 var_to_reg_int(s1, src, REG_ITMP1);
5455 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
5456 if (!(interfaces[len][s2].flags & INMEMORY)) {
5457 M_INTMOVE(s1, interfaces[len][s2].regoff);
5460 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
5464 if (!(interfaces[len][s2].flags & INMEMORY)) {
5465 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
5468 panic("copy interface registers: longs have to be in memory (end)");
5475 } /* if (bptr -> flags >= BBREACHED) */
5476 } /* for basic block */
5478 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
5482 /* generate bound check stubs */
5483 s4 *xcodeptr = NULL;
5485 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
5486 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5487 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
5488 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5493 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
5494 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
5498 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5499 dseg_adddata(mcodeptr);
5500 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5501 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5503 if (xcodeptr != NULL) {
5504 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5507 xcodeptr = mcodeptr;
5509 i386_mov_imm_reg(0, REG_ITMP3); /* mov data segment pointer into reg */
5510 dseg_adddata(mcodeptr);
5512 i386_mov_imm_reg(proto_java_lang_ArrayIndexOutOfBoundsException, REG_ITMP1_XPTR);
5513 i386_push_imm(asm_handle_exception);
5518 /* generate negative array size check stubs */
5521 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
5522 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5523 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
5524 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5528 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
5529 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
5533 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5534 dseg_adddata(mcodeptr);
5535 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5536 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5538 if (xcodeptr != NULL) {
5539 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5542 xcodeptr = mcodeptr;
5544 i386_mov_imm_reg(0, REG_ITMP3); /* mov data segment pointer into reg */
5545 dseg_adddata(mcodeptr);
5547 i386_mov_imm_reg(proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR);
5548 i386_push_imm(asm_handle_exception);
5553 /* generate cast check stubs */
5556 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
5557 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5558 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
5559 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5563 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
5564 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
5568 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5569 dseg_adddata(mcodeptr);
5570 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5571 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5573 if (xcodeptr != NULL) {
5574 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5577 xcodeptr = mcodeptr;
5579 i386_mov_imm_reg(0, REG_ITMP3); /* mov data segment pointer into reg */
5580 dseg_adddata(mcodeptr);
5582 i386_mov_imm_reg(proto_java_lang_ClassCastException, REG_ITMP1_XPTR);
5583 i386_push_imm(asm_handle_exception);
5588 /* generate divide by zero check stubs */
5591 for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
5592 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5593 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
5594 xdivrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5598 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
5599 xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
5603 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5604 dseg_adddata(mcodeptr);
5605 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5606 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5608 if (xcodeptr != NULL) {
5609 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5612 xcodeptr = mcodeptr;
5614 i386_mov_imm_reg(0, REG_ITMP3); /* mov data segment pointer into reg */
5615 dseg_adddata(mcodeptr);
5617 i386_mov_imm_reg(proto_java_lang_ArithmeticException, REG_ITMP1_XPTR);
5618 i386_push_imm(asm_handle_exception);
5623 #ifdef SOFTNULLPTRCHECK
5624 /* generate null pointer check stubs */
5627 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
5628 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5629 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
5630 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5634 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
5635 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
5639 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5640 dseg_adddata(mcodeptr);
5641 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5642 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5644 if (xcodeptr != NULL) {
5645 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5648 xcodeptr = mcodeptr;
5650 i386_mov_imm_reg(0, REG_ITMP3); /* mov data segment pointer into reg */
5651 dseg_adddata(mcodeptr);
5653 i386_mov_imm_reg(proto_java_lang_NullPointerException, REG_ITMP1_XPTR);
5654 i386_push_imm(asm_handle_exception);
5662 mcode_finish((int)((u1*) mcodeptr - mcodebase));
5666 /* function createcompilerstub *************************************************
5668 creates a stub routine which calls the compiler
5670 *******************************************************************************/
5672 #define COMPSTUBSIZE 3
5674 u1 *createcompilerstub (methodinfo *m)
5676 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
5677 s4 *p = (s4*) s; /* code generation pointer */
5679 s4 *mcodeptr = p; /* make macros work */
5681 /* code for the stub */
5682 i386_mov_imm_reg(m, REG_ITMP1); /* pass method pointer to compiler */
5683 i386_mov_imm_reg(asm_call_jit_compiler, REG_ITMP2); /* load address */
5684 i386_jmp_reg(REG_ITMP2); /* jump to compiler */
5687 count_cstub_len += COMPSTUBSIZE * 8;
5694 /* function removecompilerstub *************************************************
5696 deletes a compilerstub from memory (simply by freeing it)
5698 *******************************************************************************/
5700 void removecompilerstub (u1 *stub)
5702 CFREE (stub, COMPSTUBSIZE * 8);
5705 /* function: createnativestub **************************************************
5707 creates a stub routine which calls a native method
5709 *******************************************************************************/
5711 #define NATIVESTUBSIZE 18
5713 u1 *createnativestub (functionptr f, methodinfo *m)
5715 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
5716 s4 *p = (s4*) s; /* code generation pointer */
5718 s4 *mcodeptr = p; /* make macros work */
5722 int stackframesize = 4; /* initial 4 bytes is space for jni env */
5723 int stackframeoffset = 4;
5727 descriptor2types(m); /* set paramcount and paramtypes */
5730 * calculate stackframe size for native function
5732 tptr = m->paramtypes;
5733 for (i = 0; i < m->paramcount; i++) {
5738 stackframesize += 4;
5743 stackframesize += 8;
5747 panic("unknown parameter type in native function");
5751 i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
5753 tptr = m->paramtypes;
5754 for (i = 0; i < m->paramcount; i++) {
5759 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5760 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
5761 stackframeoffset += 4;
5766 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5767 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
5768 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
5769 i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
5770 stackframeoffset += 8;
5774 panic("unknown parameter type in native function");
5778 i386_mov_imm_membase(&env, REG_SP, 0);
5779 i386_mov_imm_reg(f, REG_ITMP1);
5780 i386_call_reg(REG_ITMP1);
5781 i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
5785 /* s[14] = (u8) f; /* address of native method */
5786 /* s[15] = (u8) (&exceptionptr); /* address of exceptionptr */
5787 /* s[16] = (u8) (asm_handle_nat_exception); /* addr of asm exception handler */
5788 /* s[17] = (u8) (&env); /* addr of jni_environement */
5791 count_nstub_len += NATIVESTUBSIZE * 8;
5797 /* function: removenativestub **************************************************
5799 removes a previously created native-stub from memory
5801 *******************************************************************************/
5803 void removenativestub (u1 *stub)
5805 CFREE (stub, NATIVESTUBSIZE * 8);
5810 * These are local overrides for various environment variables in Emacs.
5811 * Please do not remove this and leave it at the end of the file, where
5812 * Emacs will automagically detect them.
5813 * ---------------------------------------------------------------------
5816 * indent-tabs-mode: t