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 376 2003-06-19 15:40:54Z twisti $
16 *******************************************************************************/
18 #include "jitdef.h" /* phil */
19 #include "methodtable.c"
21 /* additional functions and macros to generate code ***************************/
23 /* #define BlockPtrOfPC(pc) block+block_index[pc] */
24 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
28 #define COUNT_SPILLS count_spills++
34 #define CALCOFFSETBYTES(val) \
35 if ((s4) (val) < -128 || (s4) (val) > 127) offset += 4; \
36 else if ((s4) (val) != 0) offset += 1;
39 #define CALCREGOFFBYTES(val) \
40 if ((val) > 15) offset += 4; \
41 else if ((val) != 0) offset += 1;
44 #define CALCIMMEDIATEBYTES(val) \
45 if ((s4) (val) < -128 || (s4) (val) > 127) offset += 4; \
49 /* gen_nullptr_check(objreg) */
51 #ifdef SOFTNULLPTRCHECK
52 #define gen_nullptr_check(objreg) \
54 i386_alu_imm_reg(I386_CMP, 0, (objreg)); \
55 i386_jcc(I386_CC_E, 0); \
56 mcode_addxnullrefs(mcodeptr); \
59 #define gen_nullptr_check(objreg)
63 /* MCODECHECK(icnt) */
65 #define MCODECHECK(icnt) \
66 if ((mcodeptr + (icnt)) > mcodeend) mcodeptr = mcode_increase((u1*) mcodeptr)
69 generates an integer-move from register a to b.
70 if a and b are the same int-register, no code will be generated.
73 #define M_INTMOVE(reg,dreg) if ((reg) != (dreg)) { i386_mov_reg_reg((reg),(dreg)); }
77 generates a floating-point-move from register a to b.
78 if a and b are the same float-register, no code will be generated
81 #define M_FLTMOVE(reg,dreg) if ((reg) != (dreg)){ M_OP3(0,0,0,0,0,0); }
83 #define M_LNGMEMMOVE(reg,dreg) \
85 i386_mov_membase_reg(REG_SP, (reg) * 8, REG_ITMP1); \
86 i386_mov_membase_reg(REG_SP, (reg) * 8 + 4, REG_ITMP2); \
87 i386_mov_reg_membase(REG_ITMP1, REG_SP, (dreg) * 8); \
88 i386_mov_reg_membase(REG_ITMP2, REG_SP, (dreg) * 8 + 4); \
93 this function generates code to fetch data from a pseudo-register
95 If the pseudo-register has actually been assigned to a real
96 register, no code will be emitted, since following operations
97 can use this register directly.
99 v: pseudoregister to be fetched from
100 tempregnum: temporary register to be used if v is actually spilled to ram
102 return: the register number, where the operand can be found after
103 fetching (this wil be either tempregnum or the register
104 number allready given to v)
107 #define var_to_reg_int(regnr,v,tempnr) \
108 if ((v)->flags & INMEMORY) { \
110 i386_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
113 regnr = (v)->regoff; \
118 #define var_to_reg_flt(regnr,v,tempnr) \
119 if ((v)->type == TYPE_FLT) { \
120 if ((v)->flags & INMEMORY) { \
122 i386_flds_membase(REG_SP, (v)->regoff * 8); \
126 i386_fld_reg((v)->regoff + fpu_st_offset); \
128 regnr = (v)->regoff; \
131 if ((v)->flags & INMEMORY) { \
133 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
137 i386_fld_reg((v)->regoff + fpu_st_offset); \
139 regnr = (v)->regoff; \
143 #define NEW_var_to_reg_flt(regnr,v,tempnr) \
144 if ((v)->type == TYPE_FLT) { \
145 if ((v)->flags & INMEMORY) { \
147 i386_flds_membase(REG_SP, (v)->regoff * 8); \
151 regnr = (v)->regoff; \
154 if ((v)->flags & INMEMORY) { \
156 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
160 regnr = (v)->regoff; \
166 This function determines a register, to which the result of an operation
167 should go, when it is ultimatively intended to store the result in
169 If v is assigned to an actual register, this register will be returned.
170 Otherwise (when v is spilled) this function returns tempregnum.
171 If not already done, regoff and flags are set in the stack location.
174 static int reg_of_var(stackptr v, int tempregnum)
178 switch (v->varkind) {
180 if (!(v->flags & INMEMORY))
184 var = &(interfaces[v->varnum][v->type]);
185 v->regoff = var->regoff;
186 if (!(var->flags & INMEMORY))
190 var = &(locals[v->varnum][v->type]);
191 v->regoff = var->regoff;
192 if (!(var->flags & INMEMORY))
196 v->regoff = v->varnum;
197 if (IS_FLT_DBL_TYPE(v->type)) {
198 if (v->varnum < fltreg_argnum) {
199 v->regoff = argfltregs[v->varnum];
200 return(argfltregs[v->varnum]);
204 if (v->varnum < intreg_argnum) {
205 v->regoff = argintregs[v->varnum];
206 return(argintregs[v->varnum]);
208 v->regoff -= intreg_argnum;
211 v->flags |= INMEMORY;
216 /* store_reg_to_var_xxx:
217 This function generates the code to store the result of an operation
218 back into a spilled pseudo-variable.
219 If the pseudo-variable has not been spilled in the first place, this
220 function will generate nothing.
222 v ............ Pseudovariable
223 tempregnum ... Number of the temporary registers as returned by
227 #define store_reg_to_var_int(sptr, tempregnum) \
228 if ((sptr)->flags & INMEMORY) { \
230 i386_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
234 #define store_reg_to_var_flt(sptr, tempregnum) \
235 if ((sptr)->type == TYPE_FLT) { \
236 if ((sptr)->flags & INMEMORY) { \
238 i386_fstps_membase(REG_SP, (sptr)->regoff * 8); \
241 /* i386_fxch_reg((sptr)->regoff);*/ \
242 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
246 if ((sptr)->flags & INMEMORY) { \
248 i386_fstpl_membase(REG_SP, (sptr)->regoff * 8); \
251 /* i386_fxch_reg((sptr)->regoff);*/ \
252 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
258 /* NullPointerException signal handler for hardware null pointer check */
260 void catch_NullPointerException(int sig)
266 void **_p = (void **) &sig;
267 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
269 /* Reset signal handler - necessary for SysV, does no harm for BSD */
271 instr = *((int*)(sigctx->eip));
272 /* faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; */
274 /* fprintf(stderr, "null=%d %p addr=%p\n", sig, sigctx, sigctx->eip); */
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_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 /* Reset signal handler - necessary for SysV, does no harm for BSD */
305 signal(sig, (void *) catch_ArithmeticException); /* reinstall handler */
307 sigaddset(&nsig, sig);
308 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
309 sigctx->eax = (long) proto_java_lang_ArithmeticException; /* REG_ITMP1_XPTR */
310 sigctx->edx = sigctx->eip; /* REG_ITMP2_XPC */
311 sigctx->eip = (long) asm_handle_exception;
316 void init_exceptions(void)
318 /* install signal handlers we need to convert to exceptions */
323 signal(SIGSEGV, (void *) catch_NullPointerException);
327 signal(SIGBUS, (void *) catch_NullPointerException);
331 signal(SIGFPE, (void *) catch_ArithmeticException);
335 /* function gen_mcode **********************************************************
337 generates machine code
339 *******************************************************************************/
341 static void gen_mcode()
343 int len, s1, s2, s3, d, bbs;
352 int fpu_st_offset = 0;
359 /* savedregs_num = (isleafmethod) ? 0 : 1; /* space to save the RA */
362 /* space to save used callee saved registers */
364 savedregs_num += (savintregcnt - maxsavintreguse);
365 savedregs_num += (savfltregcnt - maxsavfltreguse);
367 parentargs_base = maxmemuse + savedregs_num;
369 #ifdef USE_THREADS /* space to save argument of monitor_enter */
371 if (checksync && (method->flags & ACC_SYNCHRONIZED))
376 /* create method header */
378 (void) dseg_addaddress(method); /* MethodPointer */
379 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
383 /* IsSync contains the offset relative to the stack pointer for the
384 argument of monitor_exit used in the exception handler. Since the
385 offset could be zero and give a wrong meaning of the flag it is
389 if (checksync && (method->flags & ACC_SYNCHRONIZED))
390 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
395 (void) dseg_adds4(0); /* IsSync */
397 (void) dseg_adds4(isleafmethod); /* IsLeaf */
398 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
399 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
400 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
402 /* create exception table */
404 for (ex = extable; ex != NULL; ex = ex->down) {
407 if (ex->start != NULL)
408 printf("adding start - %d - ", ex->start->debug_nr);
410 printf("PANIC - start is NULL");
415 dseg_addtarget(ex->start);
419 printf("adding end - %d - ", ex->end->debug_nr);
421 printf("PANIC - end is NULL");
426 dseg_addtarget(ex->end);
429 if (ex->handler != NULL)
430 printf("adding handler - %d\n", ex->handler->debug_nr);
432 printf("PANIC - handler is NULL");
437 dseg_addtarget(ex->handler);
439 (void) dseg_addaddress(ex->catchtype);
442 /* initialize mcode variables */
444 mcodeptr = (s4*) mcodebase;
445 mcodeend = (s4*) (mcodebase + mcodesize);
446 MCODECHECK(128 + mparamcount);
448 /* create stack frame (if necessary) */
450 if (parentargs_base) {
451 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
454 /* save return address and used callee saved registers */
458 /* p--; M_AST (REG_RA, REG_SP, 8*p); -- do we really need this on i386 */
460 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
462 i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
464 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
466 i386_fld_reg(savfltregs[r]);
467 i386_fstpl_membase(REG_SP, p * 8);
470 /* save monitorenter argument */
473 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
474 if (method->flags & ACC_STATIC) {
475 i386_mov_imm_reg(class, REG_ITMP1);
476 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
479 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
480 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
485 /* copy argument registers to stack and call trace function with pointer
486 to arguments on stack.
490 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
492 for (p = 0; p < mparamcount; p++) {
494 if (IS_INT_LNG_TYPE(t)) {
495 if (IS_2_WORD_TYPE(t)) {
496 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
497 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
499 } else if (t == TYPE_ADR) {
500 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
501 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
504 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
507 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
508 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
512 i386_flds_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
513 i386_fstps_membase(REG_SP, p * 8);
514 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
515 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
518 i386_fldl_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
519 i386_fstpl_membase(REG_SP, p * 8);
524 /* fill up the remaining arguments */
525 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
526 for (p = mparamcount; p < TRACE_ARGS_NUM; p++) {
527 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
528 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
531 i386_mov_imm_membase(method, REG_SP, TRACE_ARGS_NUM * 8);
533 i386_mov_imm_reg(builtin_trace_args, REG_ITMP1);
534 /* i386_mov_imm_reg(asm_builtin_trace, REG_ITMP1); */
535 i386_call_reg(REG_ITMP1);
537 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
540 /* take arguments out of register or stack frame */
542 for (p = 0, l = 0; p < mparamcount; p++) {
544 var = &(locals[l][t]);
546 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
551 if (IS_INT_LNG_TYPE(t)) { /* integer args */
552 if (p < intreg_argnum) { /* register arguments */
553 panic("integer register argument");
554 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
555 /* M_INTMOVE (argintregs[p], r); */
557 } else { /* reg arg -> spilled */
558 /* M_LST (argintregs[p], REG_SP, 8 * r); */
560 } else { /* stack arguments */
561 pa = p - intreg_argnum;
562 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
563 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
564 } else { /* stack arg -> spilled */
565 if (!IS_2_WORD_TYPE(t)) {
566 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
567 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
570 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
571 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP2); /* + 4 for return address */
572 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
573 i386_mov_reg_membase(REG_ITMP2, REG_SP, r * 8 + 4);
578 } else { /* floating args */
579 if (p < fltreg_argnum) { /* register arguments */
580 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
581 panic("There are no float argument registers!");
583 } else { /* reg arg -> spilled */
584 panic("There are no float argument registers!");
587 } else { /* stack arguments */
588 pa = p - fltreg_argnum;
589 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
591 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
593 i386_fstp_reg(r + fpu_st_offset);
597 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
599 i386_fstp_reg(r + fpu_st_offset);
603 } else { /* stack-arg -> spilled */
604 /* i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
605 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8); */
607 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
608 i386_fstps_membase(REG_SP, r * 8);
611 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
612 i386_fstpl_membase(REG_SP, r * 8);
619 /* call monitorenter function */
622 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
623 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP1);
624 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
625 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
626 i386_mov_imm_reg(builtin_monitorenter, REG_ITMP2);
627 i386_call_reg(REG_ITMP2);
628 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
633 /* end of header generation */
635 /* walk through all basic blocks */
636 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
638 bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
640 if (bptr->flags >= BBREACHED) {
642 /* branch resolving */
645 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
646 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
647 brefs->branchpos, bptr->mpc);
650 /* copy interface registers to their destination */
655 while (src != NULL) {
657 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
658 if (!IS_2_WORD_TYPE(src->type)) {
659 if (bptr->type == BBTYPE_SBR) {
660 d = reg_of_var(src, REG_ITMP1);
662 store_reg_to_var_int(src, d);
664 } else if (bptr->type == BBTYPE_EXH) {
665 d = reg_of_var(src, REG_ITMP1);
666 M_INTMOVE(REG_ITMP1, d);
667 store_reg_to_var_int(src, d);
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 case ICMD_ALOAD: /* 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_LLOAD: /* ... ==> ..., 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 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
871 panic("LLOAD: longs have to be in memory");
875 panic("LLOAD: longs have to be in memory");
879 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
880 /* op1 = local variable */
882 d = reg_of_var(iptr->dst, REG_FTMP1);
883 if ((iptr->dst->varkind == LOCALVAR) &&
884 (iptr->dst->varnum == iptr->op1)) {
887 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
888 if (var->flags & INMEMORY) {
889 i386_flds_membase(REG_SP, var->regoff * 8);
892 i386_fld_reg(var->regoff + fpu_st_offset);
895 store_reg_to_var_flt(iptr->dst, d);
898 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
899 /* op1 = local variable */
901 d = reg_of_var(iptr->dst, REG_FTMP1);
902 if ((iptr->dst->varkind == LOCALVAR) &&
903 (iptr->dst->varnum == iptr->op1)) {
906 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
907 if (var->flags & INMEMORY) {
908 i386_fldl_membase(REG_SP, var->regoff * 8);
911 i386_fld_reg(var->regoff + fpu_st_offset);
914 store_reg_to_var_flt(iptr->dst, d);
917 case ICMD_ISTORE: /* ..., value ==> ... */
918 case ICMD_ASTORE: /* op1 = local variable */
920 if ((src->varkind == LOCALVAR) &&
921 (src->varnum == iptr->op1)) {
924 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
925 if (var->flags & INMEMORY) {
926 if (src->flags & INMEMORY) {
927 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
928 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
931 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
935 var_to_reg_int(s1, src, var->regoff);
936 M_INTMOVE(s1, var->regoff);
940 case ICMD_LSTORE: /* ..., value ==> ... */
941 /* op1 = local variable */
943 if ((src->varkind == LOCALVAR) &&
944 (src->varnum == iptr->op1)) {
947 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
948 if (var->flags & INMEMORY) {
949 if (src->flags & INMEMORY) {
950 M_LNGMEMMOVE(src->regoff, var->regoff);
953 panic("LSTORE: longs have to be in memory");
957 panic("LSTORE: longs have to be in memory");
961 case ICMD_FSTORE: /* ..., value ==> ... */
962 /* op1 = local variable */
964 if ((src->varkind == LOCALVAR) &&
965 (src->varnum == iptr->op1)) {
968 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
969 if (var->flags & INMEMORY) {
970 var_to_reg_flt(s1, src, REG_FTMP1);
971 i386_fstps_membase(REG_SP, var->regoff * 8);
974 var_to_reg_flt(s1, src, var->regoff);
975 /* M_FLTMOVE(s1, var->regoff); */
976 i386_fstp_reg(var->regoff + fpu_st_offset);
981 case ICMD_DSTORE: /* ..., value ==> ... */
982 /* op1 = local variable */
984 if ((src->varkind == LOCALVAR) &&
985 (src->varnum == iptr->op1)) {
988 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
989 if (var->flags & INMEMORY) {
990 var_to_reg_flt(s1, src, REG_FTMP1);
991 i386_fstpl_membase(REG_SP, var->regoff * 8);
994 var_to_reg_flt(s1, src, var->regoff);
995 /* M_FLTMOVE(s1, var->regoff); */
996 i386_fstp_reg(var->regoff + fpu_st_offset);
1002 /* pop/dup/swap operations ********************************************/
1004 /* attention: double and longs are only one entry in CACAO ICMDs */
1006 case ICMD_POP: /* ..., value ==> ... */
1007 case ICMD_POP2: /* ..., value, value ==> ... */
1010 #define M_COPY(from,to) \
1011 d = reg_of_var(to, REG_ITMP1); \
1012 if ((from->regoff != to->regoff) || \
1013 ((from->flags ^ to->flags) & INMEMORY)) { \
1014 if (IS_FLT_DBL_TYPE(from->type)) { \
1015 var_to_reg_flt(s1, from, d); \
1016 /* M_FLTMOVE(s1, d);*/ \
1017 store_reg_to_var_flt(to, d); \
1019 if (!IS_2_WORD_TYPE(from->type)) { \
1020 var_to_reg_int(s1, from, d); \
1022 store_reg_to_var_int(to, d); \
1024 M_LNGMEMMOVE(from->regoff,to->regoff); \
1029 case ICMD_DUP: /* ..., a ==> ..., a, a */
1030 M_COPY(src, iptr->dst);
1033 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1035 M_COPY(src, iptr->dst->prev->prev);
1037 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1039 M_COPY(src, iptr->dst);
1040 M_COPY(src->prev, iptr->dst->prev);
1043 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1045 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1047 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1049 M_COPY(src, iptr->dst);
1050 M_COPY(src->prev, iptr->dst->prev);
1051 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1052 M_COPY(src, iptr->dst->prev->prev->prev);
1055 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1057 M_COPY(src, iptr->dst);
1058 M_COPY(src->prev, iptr->dst->prev);
1059 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1060 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1061 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1062 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1065 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1067 M_COPY(src, iptr->dst->prev);
1068 M_COPY(src->prev, iptr->dst);
1072 /* integer operations *************************************************/
1074 case ICMD_INEG: /* ..., value ==> ..., - value */
1076 d = reg_of_var(iptr->dst, REG_ITMP3);
1077 if (iptr->dst->flags & INMEMORY) {
1078 if (src->flags & INMEMORY) {
1079 if (src->regoff == iptr->dst->regoff) {
1080 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1083 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1084 i386_neg_reg(REG_ITMP1);
1085 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1089 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1090 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1094 if (src->flags & INMEMORY) {
1095 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1096 i386_neg_reg(iptr->dst->regoff);
1099 M_INTMOVE(src->regoff, iptr->dst->regoff);
1100 i386_neg_reg(iptr->dst->regoff);
1105 case ICMD_LNEG: /* ..., value ==> ..., - value */
1107 d = reg_of_var(iptr->dst, REG_ITMP3);
1108 if (iptr->dst->flags & INMEMORY) {
1109 if (src->flags & INMEMORY) {
1110 if (src->regoff == iptr->dst->regoff) {
1111 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1112 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1113 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1116 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1117 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1118 i386_neg_reg(REG_ITMP1);
1119 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1120 i386_neg_reg(REG_ITMP2);
1121 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1122 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1128 case ICMD_I2L: /* ..., value ==> ..., value */
1130 d = reg_of_var(iptr->dst, REG_ITMP3);
1131 if (iptr->dst->flags & INMEMORY) {
1132 if (src->flags & INMEMORY) {
1133 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_EAX);
1135 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1136 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1139 M_INTMOVE(src->regoff, I386_EAX);
1141 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1142 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1147 case ICMD_L2I: /* ..., value ==> ..., value */
1149 d = reg_of_var(iptr->dst, REG_ITMP3);
1150 if (iptr->dst->flags & INMEMORY) {
1151 if (src->flags & INMEMORY) {
1152 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1153 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1157 if (src->flags & INMEMORY) {
1158 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1163 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1165 d = reg_of_var(iptr->dst, REG_ITMP3);
1166 if (iptr->dst->flags & INMEMORY) {
1167 if (src->flags & INMEMORY) {
1168 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1169 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1170 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1171 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1174 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1175 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1176 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1180 if (src->flags & INMEMORY) {
1181 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1182 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1183 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1186 M_INTMOVE(src->regoff, iptr->dst->regoff);
1187 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1188 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1193 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1195 d = reg_of_var(iptr->dst, REG_ITMP3);
1196 if (iptr->dst->flags & INMEMORY) {
1197 if (src->flags & INMEMORY) {
1198 if (src->regoff == iptr->dst->regoff) {
1199 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1202 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1203 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1204 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1208 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1209 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1213 if (src->flags & INMEMORY) {
1214 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1215 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1218 M_INTMOVE(src->regoff, iptr->dst->regoff);
1219 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1224 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1226 d = reg_of_var(iptr->dst, REG_ITMP3);
1227 if (iptr->dst->flags & INMEMORY) {
1228 if (src->flags & INMEMORY) {
1229 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1230 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1231 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1232 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1235 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1236 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1237 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1241 if (src->flags & INMEMORY) {
1242 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1243 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1244 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1247 M_INTMOVE(src->regoff, iptr->dst->regoff);
1248 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1249 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1255 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1257 d = reg_of_var(iptr->dst, REG_ITMP3);
1258 if (iptr->dst->flags & INMEMORY) {
1259 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1260 if (src->regoff == iptr->dst->regoff) {
1261 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1262 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1264 } else if (src->prev->regoff == iptr->dst->regoff) {
1265 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1266 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1269 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1270 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1271 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1274 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1275 if (src->regoff == iptr->dst->regoff) {
1276 i386_alu_reg_membase(I386_ADD, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1279 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1280 i386_alu_reg_reg(I386_ADD, src->prev->regoff, REG_ITMP1);
1281 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1284 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1285 if (src->prev->regoff == iptr->dst->regoff) {
1286 i386_alu_reg_membase(I386_ADD, src->regoff, REG_SP, iptr->dst->regoff * 8);
1289 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1290 i386_alu_reg_reg(I386_ADD, src->regoff, REG_ITMP1);
1291 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1295 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1296 i386_alu_reg_membase(I386_ADD, src->regoff, REG_SP, iptr->dst->regoff * 8);
1300 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1301 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1302 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, iptr->dst->regoff);
1304 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1305 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1306 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, iptr->dst->regoff);
1308 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1309 M_INTMOVE(src->regoff, iptr->dst->regoff);
1310 i386_alu_membase_reg(I386_ADD, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1313 if (src->regoff == iptr->dst->regoff) {
1314 i386_alu_reg_reg(I386_ADD, src->prev->regoff, iptr->dst->regoff);
1317 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1318 i386_alu_reg_reg(I386_ADD, src->regoff, iptr->dst->regoff);
1324 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1325 /* val.i = constant */
1327 d = reg_of_var(iptr->dst, REG_ITMP3);
1328 if (iptr->dst->flags & INMEMORY) {
1329 if (src->flags & INMEMORY) {
1331 * do not use inc optimization, because it's slower (???)
1333 if (src->regoff == iptr->dst->regoff) {
1334 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1337 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1339 if (iptr->val.i == 1) {
1340 i386_inc_reg(REG_ITMP1);
1343 i386_alu_imm_reg(I386_ADD, iptr->val.i, REG_ITMP1);
1346 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1350 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1351 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1355 if (src->flags & INMEMORY) {
1356 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1358 if (iptr->val.i == 1) {
1359 i386_inc_reg(iptr->dst->regoff);
1362 i386_alu_imm_reg(I386_ADD, iptr->val.i, iptr->dst->regoff);
1366 M_INTMOVE(src->regoff, iptr->dst->regoff);
1368 if (iptr->val.i == 1) {
1369 i386_inc_reg(iptr->dst->regoff);
1372 i386_alu_imm_reg(I386_ADD, iptr->val.i, iptr->dst->regoff);
1378 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1380 d = reg_of_var(iptr->dst, REG_ITMP3);
1381 if (iptr->dst->flags & INMEMORY) {
1382 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1383 if (src->regoff == iptr->dst->regoff) {
1384 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1385 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1386 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1387 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1389 } else if (src->prev->regoff == iptr->dst->regoff) {
1390 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1391 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1392 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1393 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1396 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1397 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1398 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1399 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1400 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1401 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1408 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1409 /* val.l = constant */
1411 d = reg_of_var(iptr->dst, REG_ITMP3);
1412 if (iptr->dst->flags & INMEMORY) {
1413 if (src->flags & INMEMORY) {
1414 if (src->regoff == iptr->dst->regoff) {
1415 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1416 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1419 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1420 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1421 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1422 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP2);
1423 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1424 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1430 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1432 d = reg_of_var(iptr->dst, REG_ITMP3);
1433 if (iptr->dst->flags & INMEMORY) {
1434 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1435 if (src->prev->regoff == iptr->dst->regoff) {
1436 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1437 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1440 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1441 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1442 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1445 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1446 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1447 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1448 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1450 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1451 if (src->prev->regoff == iptr->dst->regoff) {
1452 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1455 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1456 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1457 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1461 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1462 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1466 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1467 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1468 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1470 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1471 M_INTMOVE(src->prev->regoff, d);
1472 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1474 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1475 /* workaround for reg alloc */
1476 if (src->regoff == iptr->dst->regoff) {
1477 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1478 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1479 M_INTMOVE(REG_ITMP1, d);
1482 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1483 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1487 /* workaround for reg alloc */
1488 if (src->regoff == iptr->dst->regoff) {
1489 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1490 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1491 M_INTMOVE(REG_ITMP1, d);
1494 M_INTMOVE(src->prev->regoff, d);
1495 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1501 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1502 /* val.i = constant */
1504 d = reg_of_var(iptr->dst, REG_ITMP3);
1505 if (iptr->dst->flags & INMEMORY) {
1506 if (src->flags & INMEMORY) {
1507 if (src->regoff == iptr->dst->regoff) {
1508 i386_alu_imm_membase(I386_SUB, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1511 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1512 i386_alu_imm_reg(I386_SUB, iptr->val.i, REG_ITMP1);
1513 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1517 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1518 i386_alu_imm_membase(I386_SUB, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1522 if (src->flags & INMEMORY) {
1523 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1524 i386_alu_imm_reg(I386_SUB, iptr->val.i, iptr->dst->regoff);
1527 M_INTMOVE(src->regoff, iptr->dst->regoff);
1528 i386_alu_imm_reg(I386_SUB, iptr->val.i, iptr->dst->regoff);
1533 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1535 d = reg_of_var(iptr->dst, REG_ITMP3);
1536 if (iptr->dst->flags & INMEMORY) {
1537 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1538 if (src->prev->regoff == iptr->dst->regoff) {
1539 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1540 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1541 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1542 i386_alu_reg_membase(I386_SBB, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1545 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1546 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1547 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1548 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1549 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1550 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1556 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1557 /* val.l = constant */
1559 d = reg_of_var(iptr->dst, REG_ITMP3);
1560 if (iptr->dst->flags & INMEMORY) {
1561 if (src->flags & INMEMORY) {
1562 if (src->regoff == iptr->dst->regoff) {
1563 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1564 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1567 /* TODO: could be size optimized with lea -- see gcc output */
1568 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1569 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1570 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1571 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP2);
1572 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1573 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1579 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1581 d = reg_of_var(iptr->dst, REG_ITMP3);
1582 if (iptr->dst->flags & INMEMORY) {
1583 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1584 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1585 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1586 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1588 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1589 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1590 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1591 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1593 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1594 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1595 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1596 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1599 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1600 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1601 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1605 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1606 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1607 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1609 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1610 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1611 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1613 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1614 M_INTMOVE(src->regoff, iptr->dst->regoff);
1615 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1618 if (src->regoff == iptr->dst->regoff) {
1619 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1622 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1623 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1629 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1630 /* val.i = constant */
1632 d = reg_of_var(iptr->dst, REG_ITMP3);
1633 if (iptr->dst->flags & INMEMORY) {
1634 if (src->flags & INMEMORY) {
1635 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1636 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1639 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1640 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1644 if (src->flags & INMEMORY) {
1645 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1648 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1653 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1655 d = reg_of_var(iptr->dst, REG_ITMP1);
1656 if (iptr->dst->flags & INMEMORY) {
1657 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1658 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX); /* mem -> EAX */
1659 /* optimize move EAX -> REG_ITMP3 is slower??? */
1660 /* i386_mov_reg_reg(I386_EAX, REG_ITMP3); */
1661 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1663 /* TODO: optimize move EAX -> REG_ITMP3 */
1664 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3); /* mem -> ITMP3 */
1665 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1666 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1668 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP3); /* mem -> ITMP3 */
1669 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1671 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1672 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1673 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1678 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1679 /* val.l = constant */
1681 d = reg_of_var(iptr->dst, REG_ITMP1);
1682 if (iptr->dst->flags & INMEMORY) {
1683 if (src->flags & INMEMORY) {
1684 i386_mov_imm_reg(iptr->val.l, I386_EAX); /* imm -> EAX */
1685 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1686 /* TODO: optimize move EAX -> REG_ITMP3 */
1687 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP3); /* imm -> ITMP3 */
1688 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1690 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1691 i386_mov_imm_reg(iptr->val.l, REG_ITMP3); /* imm -> ITMP3 */
1692 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1694 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1695 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1696 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1701 #define gen_div_check(v) \
1703 if ((v)->flags & INMEMORY) { \
1704 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8); \
1706 i386_test_reg_reg(src->regoff, src->regoff); \
1708 i386_jcc(I386_CC_E, 0); \
1709 mcode_addxdivrefs(mcodeptr); \
1712 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1714 d = reg_of_var(iptr->dst, REG_ITMP3);
1716 if (src->prev->flags & INMEMORY) {
1717 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1720 M_INTMOVE(src->prev->regoff, I386_EAX);
1725 if (src->flags & INMEMORY) {
1726 i386_idiv_membase(REG_SP, src->regoff * 8);
1729 i386_idiv_reg(src->regoff);
1732 if (iptr->dst->flags & INMEMORY) {
1733 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1736 M_INTMOVE(I386_EAX, iptr->dst->regoff);
1740 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1742 d = reg_of_var(iptr->dst, REG_ITMP3);
1744 if (src->prev->flags & INMEMORY) {
1745 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1748 M_INTMOVE(src->prev->regoff, I386_EAX);
1753 if (src->flags & INMEMORY) {
1754 i386_idiv_membase(REG_SP, src->regoff * 8);
1757 i386_idiv_reg(src->regoff);
1760 if (iptr->dst->flags & INMEMORY) {
1761 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8);
1764 M_INTMOVE(I386_EDX, iptr->dst->regoff);
1768 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1769 /* val.i = constant */
1771 /* TODO: optimize for `/ 2' */
1774 var_to_reg_int(s1, src, REG_ITMP1);
1775 d = reg_of_var(iptr->dst, REG_ITMP1);
1778 i386_test_reg_reg(d, d);
1780 CALCIMMEDIATEBYTES((1 << iptr->val.i) - 1);
1781 i386_jcc(I386_CC_NS, offset);
1782 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, d);
1784 i386_shift_imm_reg(I386_SAR, iptr->val.i, d);
1785 store_reg_to_var_int(iptr->dst, d);
1789 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1790 /* val.i = constant */
1792 d = reg_of_var(iptr->dst, REG_ITMP3);
1793 if (iptr->dst->flags & INMEMORY) {
1794 if (src->flags & INMEMORY) {
1797 CALCIMMEDIATEBYTES((1 << iptr->val.i) - 1);
1799 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1800 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1802 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
1803 i386_jcc(I386_CC_NS, offset);
1804 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1805 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1806 i386_shrd_imm_reg_reg(iptr->val.i, REG_ITMP2, REG_ITMP1);
1807 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP2);
1809 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1810 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1815 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1817 d = reg_of_var(iptr->dst, REG_ITMP2);
1818 if (iptr->dst->flags & INMEMORY) {
1819 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1820 if (src->prev->regoff == iptr->dst->regoff) {
1821 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1822 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1825 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1826 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1827 i386_shift_reg(I386_SHL, REG_ITMP1);
1828 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1831 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1832 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1833 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1834 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1836 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1837 if (src->prev->regoff == iptr->dst->regoff) {
1838 M_INTMOVE(src->regoff, I386_ECX);
1839 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1842 M_INTMOVE(src->regoff, I386_ECX);
1843 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1844 i386_shift_reg(I386_SHL, REG_ITMP1);
1845 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1849 M_INTMOVE(src->regoff, I386_ECX);
1850 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1851 i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8);
1855 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1856 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1857 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1858 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1860 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1861 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1862 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1863 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1865 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1866 M_INTMOVE(src->regoff, I386_ECX);
1867 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1868 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1871 M_INTMOVE(src->regoff, I386_ECX);
1872 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1873 i386_shift_reg(I386_SHL, iptr->dst->regoff);
1878 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1879 /* val.i = constant */
1881 d = reg_of_var(iptr->dst, REG_ITMP1);
1882 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1883 if (src->regoff == iptr->dst->regoff) {
1884 i386_shift_imm_membase(I386_SHL, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1887 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1888 i386_shift_imm_reg(I386_SHL, iptr->val.i, REG_ITMP1);
1889 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1892 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
1893 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1894 i386_shift_imm_reg(I386_SHL, iptr->val.i, iptr->dst->regoff);
1896 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1897 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1898 i386_shift_imm_membase(I386_SHL, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1901 M_INTMOVE(src->regoff, iptr->dst->regoff);
1902 i386_shift_imm_reg(I386_SHL, iptr->val.i, iptr->dst->regoff);
1906 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1908 d = reg_of_var(iptr->dst, REG_ITMP2);
1909 if (iptr->dst->flags & INMEMORY) {
1910 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1911 if (src->prev->regoff == iptr->dst->regoff) {
1912 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1913 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1916 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1917 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1918 i386_shift_reg(I386_SAR, REG_ITMP1);
1919 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1922 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1923 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1924 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1925 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1927 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1928 if (src->prev->regoff == iptr->dst->regoff) {
1929 M_INTMOVE(src->regoff, I386_ECX);
1930 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1933 M_INTMOVE(src->regoff, I386_ECX);
1934 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1935 i386_shift_reg(I386_SAR, REG_ITMP1);
1936 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1940 M_INTMOVE(src->regoff, I386_ECX);
1941 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1942 i386_shift_membase(I386_SAR, REG_SP, iptr->dst->regoff * 8);
1946 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1947 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1948 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1949 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1951 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1952 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1953 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1954 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1956 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1957 M_INTMOVE(src->regoff, I386_ECX);
1958 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1959 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1962 M_INTMOVE(src->regoff, I386_ECX);
1963 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1964 i386_shift_reg(I386_SAR, iptr->dst->regoff);
1969 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1970 /* val.i = constant */
1972 d = reg_of_var(iptr->dst, REG_ITMP1);
1973 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1974 if (src->regoff == iptr->dst->regoff) {
1975 i386_shift_imm_membase(I386_SAR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1978 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1979 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP1);
1980 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1983 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
1984 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1985 i386_shift_imm_reg(I386_SAR, iptr->val.i, iptr->dst->regoff);
1987 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
1988 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1989 i386_shift_imm_membase(I386_SAR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
1992 M_INTMOVE(src->regoff, iptr->dst->regoff);
1993 i386_shift_imm_reg(I386_SAR, iptr->val.i, iptr->dst->regoff);
1997 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1999 d = reg_of_var(iptr->dst, REG_ITMP2);
2000 if (iptr->dst->flags & INMEMORY) {
2001 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2002 if (src->prev->regoff == iptr->dst->regoff) {
2003 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2004 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2007 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2008 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2009 i386_shift_reg(I386_SHR, REG_ITMP1);
2010 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2013 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2014 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2015 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2016 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2018 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2019 if (src->prev->regoff == iptr->dst->regoff) {
2020 M_INTMOVE(src->regoff, I386_ECX);
2021 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2024 M_INTMOVE(src->regoff, I386_ECX);
2025 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2026 i386_shift_reg(I386_SHR, REG_ITMP1);
2027 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2031 M_INTMOVE(src->regoff, I386_ECX);
2032 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2033 i386_shift_membase(I386_SHR, REG_SP, iptr->dst->regoff * 8);
2037 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2038 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2039 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2040 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2042 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2043 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2044 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2045 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2047 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2048 M_INTMOVE(src->regoff, I386_ECX);
2049 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2050 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2053 M_INTMOVE(src->regoff, I386_ECX);
2054 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2055 i386_shift_reg(I386_SHR, iptr->dst->regoff);
2060 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
2061 /* val.i = constant */
2063 d = reg_of_var(iptr->dst, REG_ITMP1);
2064 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
2065 if (src->regoff == iptr->dst->regoff) {
2066 i386_shift_imm_membase(I386_SHR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2069 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2070 i386_shift_imm_reg(I386_SHR, iptr->val.i, REG_ITMP1);
2071 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2074 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
2075 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2076 i386_shift_imm_reg(I386_SHR, iptr->val.i, iptr->dst->regoff);
2078 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
2079 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2080 i386_shift_imm_membase(I386_SHR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2083 M_INTMOVE(src->regoff, iptr->dst->regoff);
2084 i386_shift_imm_reg(I386_SHR, iptr->val.i, iptr->dst->regoff);
2088 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
2090 d = reg_of_var(iptr->dst, REG_ITMP1);
2091 if (iptr->dst->flags & INMEMORY ){
2092 if (src->prev->flags & INMEMORY) {
2093 /* if (src->prev->regoff == iptr->dst->regoff) { */
2094 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2096 /* if (src->flags & INMEMORY) { */
2097 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2099 /* M_INTMOVE(src->regoff, I386_ECX); */
2102 /* i386_test_imm_reg(32, I386_ECX); */
2103 /* i386_jcc(I386_CC_E, 2 + 2); */
2104 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); */
2105 /* i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1); */
2107 /* i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
2108 /* i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8); */
2111 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2112 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2114 if (src->flags & INMEMORY) {
2115 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2117 M_INTMOVE(src->regoff, I386_ECX);
2120 i386_test_imm_reg(32, I386_ECX);
2121 i386_jcc(I386_CC_E, 2 + 2);
2122 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
2123 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2125 i386_shld_reg_reg(REG_ITMP1, REG_ITMP2);
2126 i386_shift_reg(I386_SHL, REG_ITMP1);
2127 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2128 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2134 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
2135 /* val.i = constant */
2137 d = reg_of_var(iptr->dst, REG_ITMP1);
2138 if (iptr->dst->flags & INMEMORY ) {
2139 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2140 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2142 if (iptr->val.i & 0x20) {
2143 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
2144 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2145 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2148 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2149 i386_shift_imm_reg(I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
2152 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2153 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2157 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
2159 d = reg_of_var(iptr->dst, REG_ITMP1);
2160 if (iptr->dst->flags & INMEMORY ){
2161 if (src->prev->flags & INMEMORY) {
2162 /* if (src->prev->regoff == iptr->dst->regoff) { */
2163 /* /* TODO: optimize */
2164 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2165 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2167 /* if (src->flags & INMEMORY) { */
2168 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2170 /* M_INTMOVE(src->regoff, I386_ECX); */
2173 /* i386_test_imm_reg(32, I386_ECX); */
2174 /* i386_jcc(I386_CC_E, 2 + 3); */
2175 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2176 /* i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2); */
2178 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2179 /* i386_shift_reg(I386_SAR, REG_ITMP2); */
2180 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2181 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2184 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2185 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2187 if (src->flags & INMEMORY) {
2188 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2190 M_INTMOVE(src->regoff, I386_ECX);
2193 i386_test_imm_reg(32, I386_ECX);
2194 i386_jcc(I386_CC_E, 2 + 3);
2195 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2196 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2198 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2199 i386_shift_reg(I386_SAR, REG_ITMP2);
2200 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2201 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2207 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2208 /* val.i = constant */
2210 d = reg_of_var(iptr->dst, REG_ITMP1);
2211 if (iptr->dst->flags & INMEMORY ) {
2212 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2213 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2215 if (iptr->val.i & 0x20) {
2216 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2217 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2218 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2221 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2222 i386_shift_imm_reg(I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
2225 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2226 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2230 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2232 d = reg_of_var(iptr->dst, REG_ITMP1);
2233 if (iptr->dst->flags & INMEMORY ){
2234 if (src->prev->flags & INMEMORY) {
2235 /* if (src->prev->regoff == iptr->dst->regoff) { */
2236 /* /* TODO: optimize */
2237 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2238 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2240 /* if (src->flags & INMEMORY) { */
2241 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2243 /* M_INTMOVE(src->regoff, I386_ECX); */
2246 /* i386_test_imm_reg(32, I386_ECX); */
2247 /* i386_jcc(I386_CC_E, 2 + 2); */
2248 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2249 /* i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2); */
2251 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2252 /* i386_shift_reg(I386_SHR, REG_ITMP2); */
2253 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2254 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2257 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2258 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2260 if (src->flags & INMEMORY) {
2261 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2263 M_INTMOVE(src->regoff, I386_ECX);
2266 i386_test_imm_reg(32, I386_ECX);
2267 i386_jcc(I386_CC_E, 2 + 2);
2268 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2269 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2271 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2272 i386_shift_reg(I386_SHR, REG_ITMP2);
2273 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2274 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2280 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2281 /* val.l = constant */
2283 d = reg_of_var(iptr->dst, REG_ITMP1);
2284 if (iptr->dst->flags & INMEMORY ) {
2285 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2286 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2288 if (iptr->val.i & 0x20) {
2289 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2290 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2291 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2294 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2295 i386_shift_imm_reg(I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
2298 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2299 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2303 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2305 d = reg_of_var(iptr->dst, REG_ITMP1);
2306 if (iptr->dst->flags & INMEMORY) {
2307 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2308 if (src->regoff == iptr->dst->regoff) {
2309 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2310 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2312 } else if (src->prev->regoff == iptr->dst->regoff) {
2313 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2314 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2317 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2318 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, REG_ITMP1);
2319 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2322 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2323 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2324 i386_alu_reg_reg(I386_AND, src->prev->regoff, REG_ITMP1);
2325 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2327 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2328 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2329 i386_alu_reg_reg(I386_AND, src->regoff, REG_ITMP1);
2330 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2333 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2334 i386_alu_reg_membase(I386_AND, src->regoff, REG_SP, iptr->dst->regoff * 8);
2338 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2339 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2340 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, iptr->dst->regoff);
2342 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2343 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2344 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, iptr->dst->regoff);
2346 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2347 M_INTMOVE(src->regoff, iptr->dst->regoff);
2348 i386_alu_membase_reg(I386_AND, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2351 if (src->regoff == iptr->dst->regoff) {
2352 i386_alu_reg_reg(I386_AND, src->prev->regoff, iptr->dst->regoff);
2355 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2356 i386_alu_reg_reg(I386_AND, src->regoff, iptr->dst->regoff);
2362 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2363 /* val.i = constant */
2365 d = reg_of_var(iptr->dst, REG_ITMP1);
2366 if (iptr->dst->flags & INMEMORY) {
2367 if (src->flags & INMEMORY) {
2368 if (src->regoff == iptr->dst->regoff) {
2369 i386_alu_imm_membase(I386_AND, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2372 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2373 i386_alu_imm_reg(I386_AND, iptr->val.i, REG_ITMP1);
2374 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2378 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2379 i386_alu_imm_membase(I386_AND, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2383 if (src->flags & INMEMORY) {
2384 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2385 i386_alu_imm_reg(I386_AND, iptr->val.i, iptr->dst->regoff);
2388 M_INTMOVE(src->regoff, iptr->dst->regoff);
2389 i386_alu_imm_reg(I386_AND, iptr->val.i, iptr->dst->regoff);
2394 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2396 d = reg_of_var(iptr->dst, REG_ITMP1);
2397 if (iptr->dst->flags & INMEMORY) {
2398 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2399 if (src->regoff == iptr->dst->regoff) {
2400 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2401 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2402 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2403 i386_alu_reg_membase(I386_AND, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2405 } else if (src->prev->regoff == iptr->dst->regoff) {
2406 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2407 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2408 i386_alu_reg_membase(I386_AND, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2409 i386_alu_reg_membase(I386_AND, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2412 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2413 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2414 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8, REG_ITMP1);
2415 i386_alu_membase_reg(I386_AND, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2416 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2417 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2423 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2424 /* val.l = constant */
2426 d = reg_of_var(iptr->dst, REG_ITMP1);
2427 if (iptr->dst->flags & INMEMORY) {
2428 if (src->flags & INMEMORY) {
2429 if (src->regoff == iptr->dst->regoff) {
2430 i386_alu_imm_membase(I386_AND, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
2431 i386_alu_imm_membase(I386_AND, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
2434 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2435 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2436 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
2437 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
2438 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2439 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2445 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
2446 /* val.i = constant */
2448 var_to_reg_int(s1, src, REG_ITMP1);
2449 d = reg_of_var(iptr->dst, REG_ITMP3);
2451 M_INTMOVE(s1, REG_ITMP1);
2461 CALCIMMEDIATEBYTES(iptr->val.i);
2464 /* TODO: optimize */
2466 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
2467 i386_test_reg_reg(s1, s1);
2468 i386_jcc(I386_CC_GE, offset);
2469 i386_mov_reg_reg(s1, d);
2471 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
2475 /* M_INTMOVE(s1, I386_EAX); */
2477 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
2478 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
2479 /* i386_alu_reg_reg(I386_AND, iptr->val.i, I386_EAX); */
2480 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
2481 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
2482 /* M_INTMOVE(I386_EAX, d); */
2484 /* i386_alu_reg_reg(I386_XOR, d, d); */
2485 /* i386_mov_imm_reg(iptr->val.i, I386_ECX); */
2486 /* i386_shrd_reg_reg(s1, d); */
2487 /* i386_shift_imm_reg(I386_SHR, 32 - iptr->val.i, d); */
2489 store_reg_to_var_int(iptr->dst, d);
2492 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
2493 /* val.l = constant */
2495 d = reg_of_var(iptr->dst, REG_ITMP3);
2496 if (iptr->dst->flags & INMEMORY) {
2497 if (src->flags & INMEMORY) {
2499 /* Intel algorithm -- does not work, because constant is wrong */
2500 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
2501 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
2503 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
2504 /* i386_test_reg_reg(REG_ITMP3, REG_ITMP3); */
2505 /* i386_jcc(I386_CC_NS, offset); */
2506 /* i386_alu_imm_reg(I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
2507 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP3); */
2509 /* i386_shrd_imm_reg_reg(iptr->val.l, REG_ITMP3, REG_ITMP2); */
2510 /* i386_shift_imm_reg(I386_SAR, iptr->val.l, REG_ITMP3); */
2511 /* i386_shld_imm_reg_reg(iptr->val.l, REG_ITMP2, REG_ITMP3); */
2513 /* i386_shift_imm_reg(I386_SHL, iptr->val.l, REG_ITMP2); */
2515 /* i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1); */
2516 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
2517 /* i386_alu_reg_reg(I386_SBB, REG_ITMP3, REG_ITMP2); */
2519 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2520 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2522 /* Alpha algorithm */
2524 CALCOFFSETBYTES(src->regoff * 8);
2526 CALCOFFSETBYTES(src->regoff * 8 + 4);
2532 /* TODO: hmm, don't know if this is always correct */
2534 CALCIMMEDIATEBYTES(iptr->val.l & 0x00000000ffffffff);
2536 CALCIMMEDIATEBYTES(iptr->val.l >> 32);
2542 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2543 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2545 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
2546 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
2547 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
2548 i386_jcc(I386_CC_GE, offset);
2550 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2551 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2553 i386_neg_reg(REG_ITMP1);
2554 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
2555 i386_neg_reg(REG_ITMP2);
2557 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
2558 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
2560 i386_neg_reg(REG_ITMP1);
2561 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
2562 i386_neg_reg(REG_ITMP2);
2564 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2565 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2570 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2572 d = reg_of_var(iptr->dst, REG_ITMP1);
2573 if (iptr->dst->flags & INMEMORY) {
2574 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2575 if (src->regoff == iptr->dst->regoff) {
2576 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2577 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2579 } else if (src->prev->regoff == iptr->dst->regoff) {
2580 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2581 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2584 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2585 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, REG_ITMP1);
2586 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2589 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2590 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2591 i386_alu_reg_reg(I386_OR, src->prev->regoff, REG_ITMP1);
2592 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2594 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2595 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2596 i386_alu_reg_reg(I386_OR, src->regoff, REG_ITMP1);
2597 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2600 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2601 i386_alu_reg_membase(I386_OR, src->regoff, REG_SP, iptr->dst->regoff * 8);
2605 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2606 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2607 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2609 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2610 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2611 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2613 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2614 M_INTMOVE(src->regoff, iptr->dst->regoff);
2615 i386_alu_membase_reg(I386_OR, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2618 if (src->regoff == iptr->dst->regoff) {
2619 i386_alu_reg_reg(I386_OR, src->prev->regoff, iptr->dst->regoff);
2622 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2623 i386_alu_reg_reg(I386_OR, src->regoff, iptr->dst->regoff);
2629 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2630 /* val.i = constant */
2632 d = reg_of_var(iptr->dst, REG_ITMP1);
2633 if (iptr->dst->flags & INMEMORY) {
2634 if (src->flags & INMEMORY) {
2635 if (src->regoff == iptr->dst->regoff) {
2636 i386_alu_imm_membase(I386_OR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2639 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2640 i386_alu_imm_reg(I386_OR, iptr->val.i, REG_ITMP1);
2641 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2645 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2646 i386_alu_imm_membase(I386_OR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2650 if (src->flags & INMEMORY) {
2651 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2652 i386_alu_imm_reg(I386_OR, iptr->val.i, iptr->dst->regoff);
2655 M_INTMOVE(src->regoff, iptr->dst->regoff);
2656 i386_alu_imm_reg(I386_OR, iptr->val.i, iptr->dst->regoff);
2661 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2663 d = reg_of_var(iptr->dst, REG_ITMP1);
2664 if (iptr->dst->flags & INMEMORY) {
2665 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2666 if (src->regoff == iptr->dst->regoff) {
2667 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2668 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2669 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2670 i386_alu_reg_membase(I386_OR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2672 } else if (src->prev->regoff == iptr->dst->regoff) {
2673 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2674 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2675 i386_alu_reg_membase(I386_OR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2676 i386_alu_reg_membase(I386_OR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2679 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2680 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2681 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8, REG_ITMP1);
2682 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2683 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2684 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2690 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2691 /* val.l = constant */
2693 d = reg_of_var(iptr->dst, REG_ITMP1);
2694 if (iptr->dst->flags & INMEMORY) {
2695 if (src->flags & INMEMORY) {
2696 if (src->regoff == iptr->dst->regoff) {
2697 i386_alu_imm_membase(I386_OR, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
2698 i386_alu_imm_membase(I386_OR, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
2701 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2702 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2703 i386_alu_imm_reg(I386_OR, iptr->val.l, REG_ITMP1);
2704 i386_alu_imm_reg(I386_OR, iptr->val.l >> 32, REG_ITMP2);
2705 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2706 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2712 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2714 d = reg_of_var(iptr->dst, REG_ITMP1);
2715 if (iptr->dst->flags & INMEMORY) {
2716 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2717 if (src->regoff == iptr->dst->regoff) {
2718 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2719 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2721 } else if (src->prev->regoff == iptr->dst->regoff) {
2722 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2723 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2726 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2727 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
2728 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2731 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2732 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2733 i386_alu_reg_reg(I386_XOR, src->prev->regoff, REG_ITMP1);
2734 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2736 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2737 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2738 i386_alu_reg_reg(I386_XOR, src->regoff, REG_ITMP1);
2739 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2742 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
2743 i386_alu_reg_membase(I386_XOR, src->regoff, REG_SP, iptr->dst->regoff * 8);
2747 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2748 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2749 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2751 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
2752 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2753 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, iptr->dst->regoff);
2755 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2756 M_INTMOVE(src->regoff, iptr->dst->regoff);
2757 i386_alu_membase_reg(I386_XOR, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
2760 if (src->regoff == iptr->dst->regoff) {
2761 i386_alu_reg_reg(I386_XOR, src->prev->regoff, iptr->dst->regoff);
2764 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
2765 i386_alu_reg_reg(I386_XOR, src->regoff, iptr->dst->regoff);
2771 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2772 /* val.i = constant */
2774 d = reg_of_var(iptr->dst, REG_ITMP1);
2775 if (iptr->dst->flags & INMEMORY) {
2776 if (src->flags & INMEMORY) {
2777 if (src->regoff == iptr->dst->regoff) {
2778 i386_alu_imm_membase(I386_XOR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2781 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2782 i386_alu_imm_reg(I386_XOR, iptr->val.i, REG_ITMP1);
2783 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2787 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
2788 i386_alu_imm_membase(I386_XOR, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
2792 if (src->flags & INMEMORY) {
2793 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
2794 i386_alu_imm_reg(I386_XOR, iptr->val.i, iptr->dst->regoff);
2797 M_INTMOVE(src->regoff, iptr->dst->regoff);
2798 i386_alu_imm_reg(I386_XOR, iptr->val.i, iptr->dst->regoff);
2803 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2805 d = reg_of_var(iptr->dst, REG_ITMP1);
2806 if (iptr->dst->flags & INMEMORY) {
2807 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
2808 if (src->regoff == iptr->dst->regoff) {
2809 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2810 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2811 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2812 i386_alu_reg_membase(I386_XOR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2814 } else if (src->prev->regoff == iptr->dst->regoff) {
2815 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2816 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2817 i386_alu_reg_membase(I386_XOR, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2818 i386_alu_reg_membase(I386_XOR, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2821 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2822 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2823 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
2824 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2825 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2826 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2832 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2833 /* val.l = constant */
2835 d = reg_of_var(iptr->dst, REG_ITMP1);
2836 if (iptr->dst->flags & INMEMORY) {
2837 if (src->flags & INMEMORY) {
2838 if (src->regoff == iptr->dst->regoff) {
2839 i386_alu_imm_membase(I386_XOR, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
2840 i386_alu_imm_membase(I386_XOR, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
2843 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2844 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2845 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
2846 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
2847 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2848 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2855 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
2860 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2861 /* op1 = variable, val.i = constant */
2863 var = &(locals[iptr->op1][TYPE_INT]);
2864 if (var->flags & INMEMORY) {
2865 if (iptr->val.i == 1) {
2866 i386_inc_membase(REG_SP, var->regoff * 8);
2868 } else if (iptr->val.i == -1) {
2869 i386_dec_membase(REG_SP, var->regoff * 8);
2872 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2876 if (iptr->val.i == 1) {
2877 i386_inc_reg(var->regoff);
2879 } else if (iptr->val.i == -1) {
2880 i386_dec_reg(var->regoff);
2883 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
2889 /* floating operations ************************************************/
2891 case ICMD_FNEG: /* ..., value ==> ..., - value */
2892 case ICMD_DNEG: /* ..., value ==> ..., - value */
2894 var_to_reg_flt(s1, src, REG_FTMP1);
2895 d = reg_of_var(iptr->dst, REG_FTMP3);
2897 store_reg_to_var_flt(iptr->dst, d);
2900 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2901 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2903 d = reg_of_var(iptr->dst, REG_FTMP3);
2904 /* if (iptr->dst->flags & INMEMORY) { */
2905 /* if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) { */
2906 /* var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2907 /* NEW_var_to_reg_flt(s2, src, REG_FTMP2); */
2908 /* i386_fadd_reg_st(s2 + fpu_st_offset); */
2909 /* store_reg_to_var_flt(iptr->dst, d); */
2912 /* var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2913 /* var_to_reg_flt(s2, src, REG_FTMP2); */
2915 /* fpu_st_offset--; */
2916 /* store_reg_to_var_flt(iptr->dst, d); */
2920 /* if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) { */
2921 /* if (iptr->dst->regoff == src->prev->regoff) { */
2922 /* NEW_var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2923 /* var_to_reg_flt(s2, src, REG_FTMP2); */
2924 /* i386_faddp_st_reg(s1 + fpu_st_offset); */
2925 /* fpu_st_offset--; */
2927 /* } else if (iptr->dst->regoff == src->regoff) { */
2928 /* var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2929 /* NEW_var_to_reg_flt(s2, src, REG_FTMP2); */
2930 /* i386_faddp_st_reg(s2 + fpu_st_offset); */
2931 /* fpu_st_offset--; */
2934 /* var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2935 /* NEW_var_to_reg_flt(s2, src, REG_FTMP2); */
2936 /* i386_fadd_reg_st(s2 + fpu_st_offset); */
2937 /* store_reg_to_var_flt(iptr->dst, d); */
2941 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2942 var_to_reg_flt(s2, src, REG_FTMP2);
2945 store_reg_to_var_flt(iptr->dst, d);
2950 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2951 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2953 d = reg_of_var(iptr->dst, REG_FTMP3);
2954 /* if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) { */
2955 /* if (iptr->dst->regoff == src->prev->regoff) { */
2956 /* NEW_var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2957 /* var_to_reg_flt(s2, src, REG_FTMP2); */
2958 /* i386_fsubp_st_reg(s1 + fpu_st_offset); */
2959 /* fpu_st_offset--; */
2960 /* store_reg_to_var_flt(iptr->dst, d); */
2963 /* var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2964 /* NEW_var_to_reg_flt(s2, src, REG_FTMP2); */
2965 /* i386_fsub_reg_st(s2 + fpu_st_offset); */
2966 /* store_reg_to_var_flt(iptr->dst, d); */
2970 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2971 var_to_reg_flt(s2, src, REG_FTMP2);
2974 store_reg_to_var_flt(iptr->dst, d);
2978 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2979 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2981 d = reg_of_var(iptr->dst, REG_FTMP3);
2982 /* if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) { */
2983 /* if (iptr->dst->regoff == src->prev->regoff) { */
2984 /* NEW_var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2985 /* var_to_reg_flt(s2, src, REG_FTMP2); */
2986 /* i386_fmulp_st_reg(s1 + fpu_st_offset); */
2987 /* fpu_st_offset--; */
2988 /* store_reg_to_var_flt(iptr->dst, d); */
2990 /* } else if (iptr->dst->regoff == src->regoff) { */
2991 /* var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2992 /* NEW_var_to_reg_flt(s2, src, REG_FTMP2); */
2993 /* i386_fmulp_st_reg(s2 + fpu_st_offset); */
2994 /* fpu_st_offset--; */
2995 /* store_reg_to_var_flt(iptr->dst, d); */
2998 /* var_to_reg_flt(s1, src->prev, REG_FTMP1); */
2999 /* NEW_var_to_reg_flt(s2, src, REG_FTMP2); */
3000 /* i386_fmul_reg_st(s2 + fpu_st_offset); */
3001 /* store_reg_to_var_flt(iptr->dst, d); */
3005 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3006 var_to_reg_flt(s2, src, REG_FTMP2);
3009 store_reg_to_var_flt(iptr->dst, d);
3013 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
3014 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
3016 d = reg_of_var(iptr->dst, REG_FTMP3);
3017 /* if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) { */
3018 /* if (src->prev->regoff == iptr->dst->regoff) { */
3019 /* NEW_var_to_reg_flt(s1, src->prev, REG_FTMP1); */
3020 /* var_to_reg_flt(s2, src, REG_FTMP2); */
3021 /* i386_fdivp_st_reg(s1 + fpu_st_offset); */
3022 /* fpu_st_offset--; */
3023 /* store_reg_to_var_flt(iptr->dst, d); */
3026 /* var_to_reg_flt(s1, src->prev, REG_FTMP1); */
3027 /* NEW_var_to_reg_flt(s2, src, REG_FTMP2); */
3028 /* i386_fdiv_reg_st(s2 + fpu_st_offset); */
3029 /* store_reg_to_var_flt(iptr->dst, d); */
3033 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3034 var_to_reg_flt(s2, src, REG_FTMP2);
3037 store_reg_to_var_flt(iptr->dst, d);
3041 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
3042 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
3044 /* exchanged to skip fxch */
3045 var_to_reg_flt(s2, src, REG_FTMP2);
3046 var_to_reg_flt(s1, src->prev, REG_FTMP1);
3047 d = reg_of_var(iptr->dst, REG_FTMP3);
3053 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
3054 store_reg_to_var_flt(iptr->dst, d);
3060 case ICMD_I2F: /* ..., value ==> ..., (float) value */
3061 case ICMD_I2D: /* ..., value ==> ..., (double) value */
3063 d = reg_of_var(iptr->dst, REG_FTMP1);
3064 if (src->flags & INMEMORY) {
3065 i386_fildl_membase(REG_SP, src->regoff * 8);
3070 i386_mov_imm_reg(0, REG_ITMP1);
3071 dseg_adddata(mcodeptr);
3072 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
3073 i386_fildl_membase(REG_ITMP1, a);
3076 store_reg_to_var_flt(iptr->dst, d);
3079 case ICMD_L2F: /* ..., value ==> ..., (float) value */
3080 case ICMD_L2D: /* ..., value ==> ..., (double) value */
3082 d = reg_of_var(iptr->dst, REG_FTMP1);
3083 if (src->flags & INMEMORY) {
3084 i386_fildll_membase(REG_SP, src->regoff * 8);
3088 panic("L2F: longs have to be in memory");
3090 store_reg_to_var_flt(iptr->dst, d);
3093 case ICMD_F2I: /* ..., value ==> ..., (int) value */
3096 var_to_reg_flt(s1, src, REG_FTMP1);
3097 d = reg_of_var(iptr->dst, REG_ITMP1);
3099 a = dseg_adds4(0x0d7f); /* Round to zero, 53-bit mode, exception masked */
3100 i386_mov_imm_reg(0, REG_ITMP1);
3101 dseg_adddata(mcodeptr);
3102 i386_fldcw_membase(REG_ITMP1, a);
3104 if (iptr->dst->flags & INMEMORY) {
3105 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
3107 /* i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8); */
3111 i386_fistpl_membase(REG_ITMP1, a);
3113 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
3116 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
3117 i386_fldcw_membase(REG_ITMP1, a);
3120 case ICMD_F2L: /* ..., value ==> ..., (long) value */
3123 var_to_reg_flt(s1, src, REG_FTMP1);
3124 d = reg_of_var(iptr->dst, REG_ITMP1);
3126 a = dseg_adds4(0x0d7f); /* Round to zero, 53-bit mode, exception masked */
3127 i386_mov_imm_reg(0, REG_ITMP1);
3128 dseg_adddata(mcodeptr);
3129 i386_fldcw_membase(REG_ITMP1, a);
3131 if (iptr->dst->flags & INMEMORY) {
3132 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
3136 panic("F2L: longs have to be in memory");
3139 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
3140 i386_fldcw_membase(REG_ITMP1, a);
3143 case ICMD_F2D: /* ..., value ==> ..., (double) value */
3145 var_to_reg_flt(s1, src, REG_FTMP1);
3146 d = reg_of_var(iptr->dst, REG_ITMP3);
3148 store_reg_to_var_flt(iptr->dst, d);
3151 case ICMD_D2F: /* ..., value ==> ..., (float) value */
3153 var_to_reg_flt(s1, src, REG_FTMP1);
3154 d = reg_of_var(iptr->dst, REG_ITMP3);
3156 store_reg_to_var_flt(iptr->dst, d);
3159 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
3162 /* exchanged to skip fxch */
3163 /* if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) { */
3164 /* fprintf(stderr, "new FCMP\n"); */
3165 /* NEW_var_to_reg_flt(s2, src->prev, REG_FTMP1); */
3166 /* NEW_var_to_reg_flt(s1, src, REG_FTMP2); */
3167 /* d = reg_of_var(iptr->dst, REG_ITMP3); */
3168 /* i386_alu_reg_reg(I386_XOR, d, d); */
3169 /* i386_fxch_reg(s1 + fpu_st_offset); */
3170 /* i386_fucom_reg(s2 + fpu_st_offset); */
3171 /* i386_fxch_reg(s1 + fpu_st_offset); */
3173 var_to_reg_flt(s2, src->prev, REG_FTMP1);
3174 var_to_reg_flt(s1, src, REG_FTMP2);
3175 d = reg_of_var(iptr->dst, REG_ITMP3);
3176 i386_alu_reg_reg(I386_XOR, d, d);
3182 i386_test_imm_reg(0x400, I386_EAX); /* unordered treat as GT */
3183 i386_jcc(I386_CC_E, 3);
3184 i386_movb_imm_reg(0, I386_AH);
3186 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
3187 i386_jcc(I386_CC_B, 1 + 5);
3191 store_reg_to_var_int(iptr->dst, d);
3194 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
3197 /* exchanged to skip fxch */
3198 /* if (!(src->prev->flags & INMEMORY) && !(src->flags & INMEMORY)) { */
3199 /* fprintf(stderr, "new FCMP\n"); */
3200 /* NEW_var_to_reg_flt(s2, src->prev, REG_FTMP1); */
3201 /* NEW_var_to_reg_flt(s1, src, REG_FTMP2); */
3202 /* d = reg_of_var(iptr->dst, REG_ITMP3); */
3203 /* i386_alu_reg_reg(I386_XOR, d, d); */
3204 /* i386_fxch_reg(s1 + fpu_st_offset); */
3205 /* i386_fucom_reg(s2 + fpu_st_offset); */
3206 /* i386_fxch_reg(s1 + fpu_st_offset); */
3208 var_to_reg_flt(s2, src->prev, REG_FTMP1);
3209 var_to_reg_flt(s1, src, REG_FTMP2);
3210 d = reg_of_var(iptr->dst, REG_ITMP3);
3211 i386_alu_reg_reg(I386_XOR, d, d);
3217 i386_test_imm_reg(0x400, I386_EAX); /* unordered treat as LT */
3218 i386_jcc(I386_CC_E, 3);
3219 i386_movb_imm_reg(1, I386_AH);
3221 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
3222 i386_jcc(I386_CC_B, 1 + 5);
3226 store_reg_to_var_int(iptr->dst, d);
3230 /* memory operations **************************************************/
3232 #define gen_bound_check \
3233 if (checkbounds) { \
3234 i386_alu_membase_reg(I386_CMP, s1, OFFSET(java_arrayheader, size), s2); \
3235 i386_jcc(I386_CC_AE, 0); \
3236 mcode_addxboundrefs(mcodeptr); \
3239 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
3241 var_to_reg_int(s1, src, REG_ITMP1);
3242 d = reg_of_var(iptr->dst, REG_ITMP3);
3243 gen_nullptr_check(s1);
3244 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
3245 store_reg_to_var_int(iptr->dst, d);
3248 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
3250 var_to_reg_int(s1, src->prev, REG_ITMP1);
3251 var_to_reg_int(s2, src, REG_ITMP2);
3252 d = reg_of_var(iptr->dst, REG_ITMP3);
3253 if (iptr->op1 == 0) {
3254 gen_nullptr_check(s1);
3257 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
3258 store_reg_to_var_int(iptr->dst, d);
3261 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
3263 var_to_reg_int(s1, src->prev, REG_ITMP1);
3264 var_to_reg_int(s2, src, REG_ITMP2);
3265 d = reg_of_var(iptr->dst, REG_ITMP3);
3266 if (iptr->op1 == 0) {
3267 gen_nullptr_check(s1);
3271 if (iptr->dst->flags & INMEMORY) {
3272 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
3273 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
3274 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
3275 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
3279 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
3281 var_to_reg_int(s1, src->prev, REG_ITMP1);
3282 var_to_reg_int(s2, src, REG_ITMP2);
3283 d = reg_of_var(iptr->dst, REG_ITMP3);
3284 if (iptr->op1 == 0) {
3285 gen_nullptr_check(s1);
3288 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
3289 store_reg_to_var_int(iptr->dst, d);
3292 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
3294 var_to_reg_int(s1, src->prev, REG_ITMP1);
3295 var_to_reg_int(s2, src, REG_ITMP2);
3296 d = reg_of_var(iptr->dst, REG_FTMP3);
3297 if (iptr->op1 == 0) {
3298 gen_nullptr_check(s1);
3301 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
3303 store_reg_to_var_flt(iptr->dst, d);
3306 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
3308 var_to_reg_int(s1, src->prev, REG_ITMP1);
3309 var_to_reg_int(s2, src, REG_ITMP2);
3310 d = reg_of_var(iptr->dst, REG_FTMP3);
3311 if (iptr->op1 == 0) {
3312 gen_nullptr_check(s1);
3315 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
3317 store_reg_to_var_flt(iptr->dst, d);
3320 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
3322 var_to_reg_int(s1, src->prev, REG_ITMP1);
3323 var_to_reg_int(s2, src, REG_ITMP2);
3324 d = reg_of_var(iptr->dst, REG_ITMP3);
3325 if (iptr->op1 == 0) {
3326 gen_nullptr_check(s1);
3329 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
3330 store_reg_to_var_int(iptr->dst, d);
3333 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
3335 var_to_reg_int(s1, src->prev, REG_ITMP1);
3336 var_to_reg_int(s2, src, REG_ITMP2);
3337 d = reg_of_var(iptr->dst, REG_ITMP3);
3338 if (iptr->op1 == 0) {
3339 gen_nullptr_check(s1);
3342 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
3343 store_reg_to_var_int(iptr->dst, d);
3346 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
3348 var_to_reg_int(s1, src->prev, REG_ITMP1);
3349 var_to_reg_int(s2, src, REG_ITMP2);
3350 d = reg_of_var(iptr->dst, REG_ITMP3);
3351 if (iptr->op1 == 0) {
3352 gen_nullptr_check(s1);
3355 i386_movsbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
3356 store_reg_to_var_int(iptr->dst, d);
3360 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
3362 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3363 var_to_reg_int(s2, src->prev, REG_ITMP2);
3364 if (iptr->op1 == 0) {
3365 gen_nullptr_check(s1);
3368 var_to_reg_int(s3, src, REG_ITMP3);
3369 i386_mov_reg_memindex(s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
3372 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
3374 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3375 var_to_reg_int(s2, src->prev, REG_ITMP2);
3376 if (iptr->op1 == 0) {
3377 gen_nullptr_check(s1);
3381 if (src->flags & INMEMORY) {
3382 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
3383 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
3384 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
3385 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
3389 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
3391 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3392 var_to_reg_int(s2, src->prev, REG_ITMP2);
3393 if (iptr->op1 == 0) {
3394 gen_nullptr_check(s1);
3397 var_to_reg_int(s3, src, REG_ITMP3);
3398 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
3401 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
3403 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3404 var_to_reg_int(s2, src->prev, REG_ITMP2);
3405 if (iptr->op1 == 0) {
3406 gen_nullptr_check(s1);
3409 var_to_reg_flt(s3, src, REG_FTMP3);
3410 i386_fstps_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
3414 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
3416 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3417 var_to_reg_int(s2, src->prev, REG_ITMP2);
3418 if (iptr->op1 == 0) {
3419 gen_nullptr_check(s1);
3422 var_to_reg_flt(s3, src, REG_FTMP3);
3423 i386_fstpl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
3427 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
3429 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3430 var_to_reg_int(s2, src->prev, REG_ITMP2);
3431 if (iptr->op1 == 0) {
3432 gen_nullptr_check(s1);
3435 var_to_reg_int(s3, src, REG_ITMP3);
3436 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
3439 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
3441 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3442 var_to_reg_int(s2, src->prev, REG_ITMP2);
3443 if (iptr->op1 == 0) {
3444 gen_nullptr_check(s1);
3447 var_to_reg_int(s3, src, REG_ITMP3);
3448 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
3451 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
3453 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3454 var_to_reg_int(s2, src->prev, REG_ITMP2);
3455 if (iptr->op1 == 0) {
3456 gen_nullptr_check(s1);
3459 var_to_reg_int(s3, src, REG_ITMP3);
3460 M_INTMOVE(s3, REG_ITMP3); /* because EBP, ESI, EDI have no xH and xL bytes */
3461 i386_movb_reg_memindex(REG_ITMP3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
3465 case ICMD_PUTSTATIC: /* ..., value ==> ... */
3466 /* op1 = type, val.a = field address */
3468 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3469 /* here it's slightly slower */
3470 i386_mov_imm_reg(0, REG_ITMP2);
3471 dseg_adddata(mcodeptr);
3472 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP3);
3473 switch (iptr->op1) {
3476 var_to_reg_int(s2, src, REG_ITMP1);
3477 i386_mov_reg_membase(s2, REG_ITMP3, 0);
3480 if (src->flags & INMEMORY) {
3481 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3482 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3483 i386_mov_reg_membase(REG_ITMP1, REG_ITMP3, 0);
3484 i386_mov_reg_membase(REG_ITMP2, REG_ITMP3, 0 + 4);
3486 panic("PUTSTATIC: longs have to be in memory");
3490 var_to_reg_flt(s2, src, REG_FTMP2);
3491 i386_fstps_membase(REG_ITMP3, 0);
3495 var_to_reg_flt(s2, src, REG_FTMP2);
3496 i386_fstpl_membase(REG_ITMP3, 0);
3499 default: panic ("internal error");
3503 case ICMD_GETSTATIC: /* ... ==> ..., value */
3504 /* op1 = type, val.a = field address */
3506 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3507 i386_mov_imm_reg(0, REG_ITMP2);
3508 dseg_adddata(mcodeptr);
3509 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP3);
3510 switch (iptr->op1) {
3513 d = reg_of_var(iptr->dst, REG_ITMP1);
3514 i386_mov_membase_reg(REG_ITMP3, 0, d);
3515 store_reg_to_var_int(iptr->dst, d);
3518 d = reg_of_var(iptr->dst, REG_ITMP3);
3519 if (iptr->dst->flags & INMEMORY) {
3520 i386_mov_membase_reg(REG_ITMP3, 0, REG_ITMP1);
3521 i386_mov_membase_reg(REG_ITMP3, 4, REG_ITMP2);
3522 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3523 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3525 panic("GETSTATIC: longs have to be in memory");
3529 d = reg_of_var(iptr->dst, REG_ITMP1);
3530 i386_flds_membase(REG_ITMP3, 0);
3532 store_reg_to_var_flt(iptr->dst, d);
3535 d = reg_of_var(iptr->dst, REG_ITMP1);
3536 i386_fldl_membase(REG_ITMP3, 0);
3538 store_reg_to_var_flt(iptr->dst, d);
3540 default: panic ("internal error");
3544 case ICMD_PUTFIELD: /* ..., value ==> ... */
3545 /* op1 = type, val.i = field offset */
3547 a = ((fieldinfo *)(iptr->val.a))->offset;
3548 switch (iptr->op1) {
3551 var_to_reg_int(s1, src->prev, REG_ITMP1);
3552 var_to_reg_int(s2, src, REG_ITMP2);
3553 gen_nullptr_check(s1);
3554 i386_mov_reg_membase(s2, s1, a);
3557 var_to_reg_int(s1, src->prev, REG_ITMP1);
3558 gen_nullptr_check(s1);
3559 if (src->flags & INMEMORY) {
3560 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3561 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
3562 i386_mov_reg_membase(REG_ITMP2, s1, a);
3563 i386_mov_reg_membase(REG_ITMP3, s1, a + 4);
3565 panic("PUTFIELD: longs have to be in memory");
3569 var_to_reg_int(s1, src->prev, REG_ITMP1);
3570 var_to_reg_flt(s2, src, REG_FTMP2);
3571 gen_nullptr_check(s1);
3572 i386_fstps_membase(s1, a);
3576 var_to_reg_int(s1, src->prev, REG_ITMP1);
3577 var_to_reg_flt(s2, src, REG_FTMP2);
3578 gen_nullptr_check(s1);
3579 i386_fstpl_membase(s1, a);
3582 default: panic ("internal error");
3586 case ICMD_GETFIELD: /* ... ==> ..., value */
3587 /* op1 = type, val.i = field offset */
3589 a = ((fieldinfo *)(iptr->val.a))->offset;
3590 switch (iptr->op1) {
3593 var_to_reg_int(s1, src, REG_ITMP1);
3594 d = reg_of_var(iptr->dst, REG_ITMP3);
3595 gen_nullptr_check(s1);
3596 i386_mov_membase_reg(s1, a, d);
3597 store_reg_to_var_int(iptr->dst, d);
3600 var_to_reg_int(s1, src, REG_ITMP1);
3601 d = reg_of_var(iptr->dst, REG_ITMP3);
3602 gen_nullptr_check(s1);
3603 i386_mov_membase_reg(s1, a, REG_ITMP2);
3604 i386_mov_membase_reg(s1, a + 4, REG_ITMP3);
3605 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3606 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
3609 var_to_reg_int(s1, src, REG_ITMP1);
3610 d = reg_of_var(iptr->dst, REG_FTMP1);
3611 gen_nullptr_check(s1);
3612 i386_flds_membase(s1, a);
3614 store_reg_to_var_flt(iptr->dst, d);
3617 var_to_reg_int(s1, src, REG_ITMP1);
3618 d = reg_of_var(iptr->dst, REG_FTMP1);
3619 gen_nullptr_check(s1);
3620 i386_fldl_membase(s1, a);
3622 store_reg_to_var_flt(iptr->dst, d);
3624 default: panic ("internal error");
3629 /* branch operations **************************************************/
3632 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3633 #define ALIGNCODENOP do {} while (0)
3635 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3637 var_to_reg_int(s1, src, REG_ITMP1);
3638 M_INTMOVE(s1, REG_ITMP1_XPTR);
3640 i386_call_imm(0); /* passing exception pointer */
3641 i386_pop_reg(REG_ITMP2_XPC);
3643 i386_mov_imm_reg(0, REG_ITMP3); /* we need data segment pointer */
3644 dseg_adddata(mcodeptr);
3646 i386_push_imm(asm_handle_exception);
3648 i386_nop(); /* nop ensures that XPC is less than the end */
3649 /* of basic block */
3653 case ICMD_GOTO: /* ... ==> ... */
3654 /* op1 = target JavaVM pc */
3657 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3661 case ICMD_JSR: /* ... ==> ... */
3662 /* op1 = target JavaVM pc */
3665 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3668 case ICMD_RET: /* ... ==> ... */
3669 /* op1 = local variable */
3671 var = &(locals[iptr->op1][TYPE_ADR]);
3672 var_to_reg_int(s1, var, REG_ITMP1);
3676 case ICMD_IFNULL: /* ..., value ==> ... */
3677 /* op1 = target JavaVM pc */
3679 if (src->flags & INMEMORY) {
3680 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3683 i386_test_reg_reg(src->regoff, src->regoff);
3685 i386_jcc(I386_CC_E, 0);
3686 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3689 case ICMD_IFNONNULL: /* ..., value ==> ... */
3690 /* op1 = target JavaVM pc */
3692 if (src->flags & INMEMORY) {
3693 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3696 i386_test_reg_reg(src->regoff, src->regoff);
3698 i386_jcc(I386_CC_NE, 0);
3699 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3702 case ICMD_IFEQ: /* ..., value ==> ... */
3703 /* op1 = target JavaVM pc, val.i = constant */
3705 if (src->flags & INMEMORY) {
3706 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3709 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3711 i386_jcc(I386_CC_E, 0);
3712 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3715 case ICMD_IFLT: /* ..., value ==> ... */
3716 /* op1 = target JavaVM pc, val.i = constant */
3718 if (src->flags & INMEMORY) {
3719 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3722 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3724 i386_jcc(I386_CC_L, 0);
3725 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3728 case ICMD_IFLE: /* ..., value ==> ... */
3729 /* op1 = target JavaVM pc, val.i = constant */
3731 if (src->flags & INMEMORY) {
3732 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3735 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3737 i386_jcc(I386_CC_LE, 0);
3738 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3741 case ICMD_IFNE: /* ..., value ==> ... */
3742 /* op1 = target JavaVM pc, val.i = constant */
3744 if (src->flags & INMEMORY) {
3745 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3748 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3750 i386_jcc(I386_CC_NE, 0);
3751 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3754 case ICMD_IFGT: /* ..., value ==> ... */
3755 /* op1 = target JavaVM pc, val.i = constant */
3757 if (src->flags & INMEMORY) {
3758 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3761 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3763 i386_jcc(I386_CC_G, 0);
3764 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3767 case ICMD_IFGE: /* ..., value ==> ... */
3768 /* op1 = target JavaVM pc, val.i = constant */
3770 if (src->flags & INMEMORY) {
3771 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3774 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3776 i386_jcc(I386_CC_GE, 0);
3777 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3780 case ICMD_IF_LEQ: /* ..., value ==> ... */
3781 /* op1 = target JavaVM pc, val.l = constant */
3783 if (src->flags & INMEMORY) {
3784 if (iptr->val.l == 0) {
3785 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3786 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3788 } else if (iptr->val.l > 0 && iptr->val.l <= 0x00000000ffffffff) {
3789 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3790 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3791 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3794 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3795 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3796 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3797 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3798 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3801 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3802 i386_jcc(I386_CC_E, 0);
3803 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3806 case ICMD_IF_LLT: /* ..., value ==> ... */
3807 /* op1 = target JavaVM pc, val.l = constant */
3809 /* TODO: optimize as in IF_LEQ */
3810 if (src->flags & INMEMORY) {
3812 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3813 i386_jcc(I386_CC_L, 0);
3814 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3817 CALCREGOFFBYTES(src->regoff);
3818 CALCIMMEDIATEBYTES(iptr->val.l);
3820 i386_jcc(I386_CC_G, offset);
3822 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3823 i386_jcc(I386_CC_B, 0);
3824 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3828 case ICMD_IF_LLE: /* ..., value ==> ... */
3829 /* op1 = target JavaVM pc, val.l = constant */
3831 /* TODO: optimize as in IF_LEQ */
3832 if (src->flags & INMEMORY) {
3834 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3835 i386_jcc(I386_CC_L, 0);
3836 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3839 CALCREGOFFBYTES(src->regoff);
3840 CALCIMMEDIATEBYTES(iptr->val.l);
3842 i386_jcc(I386_CC_G, offset);
3844 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3845 i386_jcc(I386_CC_BE, 0);
3846 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3850 case ICMD_IF_LNE: /* ..., value ==> ... */
3851 /* op1 = target JavaVM pc, val.l = constant */
3853 /* TODO: optimize for val.l == 0 */
3854 if (src->flags & INMEMORY) {
3855 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
3856 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
3857 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3858 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3859 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3860 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3862 i386_jcc(I386_CC_NE, 0);
3863 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3866 case ICMD_IF_LGT: /* ..., value ==> ... */
3867 /* op1 = target JavaVM pc, val.l = constant */
3869 /* TODO: optimize as in IF_LEQ */
3870 if (src->flags & INMEMORY) {
3872 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3873 i386_jcc(I386_CC_G, 0);
3874 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3877 CALCREGOFFBYTES(src->regoff);
3878 CALCIMMEDIATEBYTES(iptr->val.l);
3880 i386_jcc(I386_CC_L, offset);
3882 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3883 i386_jcc(I386_CC_A, 0);
3884 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3888 case ICMD_IF_LGE: /* ..., value ==> ... */
3889 /* op1 = target JavaVM pc, val.l = constant */
3891 /* TODO: optimize as in IF_LEQ */
3892 if (src->flags & INMEMORY) {
3894 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3895 i386_jcc(I386_CC_G, 0);
3896 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3899 CALCREGOFFBYTES(src->regoff);
3900 CALCIMMEDIATEBYTES(iptr->val.l);
3902 i386_jcc(I386_CC_L, offset);
3904 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3905 i386_jcc(I386_CC_AE, 0);
3906 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3910 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3911 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3913 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3914 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3915 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3917 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3918 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3920 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3921 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3924 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3926 i386_jcc(I386_CC_E, 0);
3927 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3930 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3931 /* op1 = target JavaVM pc */
3933 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3934 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3935 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3936 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3937 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3938 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3939 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3941 i386_jcc(I386_CC_E, 0);
3942 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3945 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3946 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3948 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3949 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3950 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3952 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3953 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3955 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3956 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3959 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3961 i386_jcc(I386_CC_NE, 0);
3962 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3965 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3966 /* op1 = target JavaVM pc */
3968 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3969 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3970 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3971 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3972 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3973 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3974 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3976 i386_jcc(I386_CC_NE, 0);
3977 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3980 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3981 /* op1 = target JavaVM pc */
3983 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3984 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3985 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3987 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3988 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3990 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3991 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3994 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3996 i386_jcc(I386_CC_L, 0);
3997 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4000 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
4001 /* op1 = target JavaVM pc */
4003 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4005 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
4006 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4007 i386_jcc(I386_CC_L, 0);
4008 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4011 CALCREGOFFBYTES(src->prev->regoff);
4012 CALCREGOFFBYTES(src->regoff);
4014 i386_jcc(I386_CC_G, offset);
4016 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4017 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
4018 i386_jcc(I386_CC_B, 0);
4019 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4023 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
4024 /* op1 = target JavaVM pc */
4026 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4027 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4028 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
4030 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4031 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
4033 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4034 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4037 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4039 i386_jcc(I386_CC_G, 0);
4040 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4043 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
4044 /* op1 = target JavaVM pc */
4046 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4048 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
4049 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4050 i386_jcc(I386_CC_G, 0);
4051 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4054 CALCREGOFFBYTES(src->prev->regoff);
4055 CALCREGOFFBYTES(src->regoff);
4057 i386_jcc(I386_CC_L, offset);
4059 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4060 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
4061 i386_jcc(I386_CC_A, 0);
4062 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4066 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
4067 /* op1 = target JavaVM pc */
4069 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4070 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4071 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
4073 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4074 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
4076 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4077 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4080 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4082 i386_jcc(I386_CC_LE, 0);
4083 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4086 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
4087 /* op1 = target JavaVM pc */
4089 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4091 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
4092 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4093 i386_jcc(I386_CC_L, 0);
4094 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4097 CALCREGOFFBYTES(src->prev->regoff);
4098 CALCREGOFFBYTES(src->regoff);
4100 i386_jcc(I386_CC_G, offset);
4102 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4103 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
4104 i386_jcc(I386_CC_BE, 0);
4105 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4109 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
4110 /* op1 = target JavaVM pc */
4112 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4113 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4114 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
4116 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4117 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
4119 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4120 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
4123 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
4125 i386_jcc(I386_CC_GE, 0);
4126 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4129 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
4130 /* op1 = target JavaVM pc */
4132 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4134 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
4135 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
4136 i386_jcc(I386_CC_G, 0);
4137 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4140 CALCREGOFFBYTES(src->prev->regoff);
4141 CALCREGOFFBYTES(src->regoff);
4143 i386_jcc(I386_CC_L, offset);
4145 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4146 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
4147 i386_jcc(I386_CC_AE, 0);
4148 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
4152 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
4154 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
4157 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
4158 /* val.i = constant */
4160 d = reg_of_var(iptr->dst, REG_ITMP3);
4161 if (iptr->dst->flags & INMEMORY) {
4164 if (src->flags & INMEMORY) {
4165 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4168 i386_test_reg_reg(src->regoff, src->regoff);
4172 CALCOFFSETBYTES(iptr->dst->regoff * 8);
4174 i386_jcc(I386_CC_NE, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4175 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4177 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4178 i386_jmp_imm(offset);
4179 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4183 if (src->flags & INMEMORY) {
4184 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4187 i386_test_reg_reg(src->regoff, src->regoff);
4190 i386_jcc(I386_CC_NE, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4191 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4193 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4195 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4200 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
4201 /* val.i = constant */
4203 d = reg_of_var(iptr->dst, REG_ITMP3);
4204 if (iptr->dst->flags & INMEMORY) {
4207 if (src->flags & INMEMORY) {
4208 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4211 i386_test_reg_reg(src->regoff, src->regoff);
4215 CALCREGOFFBYTES(iptr->dst->regoff);
4217 i386_jcc(I386_CC_E, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4218 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4220 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4221 i386_jmp_imm(offset);
4222 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4226 if (src->flags & INMEMORY) {
4227 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4230 i386_test_reg_reg(src->regoff, src->regoff);
4233 i386_jcc(I386_CC_E, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4234 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4236 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4238 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4243 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
4244 /* val.i = constant */
4246 d = reg_of_var(iptr->dst, REG_ITMP3);
4247 if (iptr->dst->flags & INMEMORY) {
4250 if (src->flags & INMEMORY) {
4251 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4254 i386_test_reg_reg(src->regoff, src->regoff);
4258 CALCREGOFFBYTES(iptr->dst->regoff);
4260 i386_jcc(I386_CC_GE, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4261 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4263 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4264 i386_jmp_imm(offset);
4265 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4269 if (src->flags & INMEMORY) {
4270 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4273 i386_test_reg_reg(src->regoff, src->regoff);
4276 i386_jcc(I386_CC_GE, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4277 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4279 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4281 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4286 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
4287 /* val.i = constant */
4289 d = reg_of_var(iptr->dst, REG_ITMP3);
4290 if (iptr->dst->flags & INMEMORY) {
4293 if (src->flags & INMEMORY) {
4294 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4297 i386_test_reg_reg(src->regoff, src->regoff);
4301 CALCREGOFFBYTES(iptr->dst->regoff);
4303 i386_jcc(I386_CC_L, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4304 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4306 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4307 i386_jmp_imm(offset);
4308 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4312 if (src->flags & INMEMORY) {
4313 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4316 i386_test_reg_reg(src->regoff, src->regoff);
4319 i386_jcc(I386_CC_L, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4320 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4322 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4324 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4329 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
4330 /* val.i = constant */
4332 d = reg_of_var(iptr->dst, REG_ITMP3);
4333 if (iptr->dst->flags & INMEMORY) {
4336 if (src->flags & INMEMORY) {
4337 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4340 i386_test_reg_reg(src->regoff, src->regoff);
4344 CALCREGOFFBYTES(iptr->dst->regoff);
4346 i386_jcc(I386_CC_LE, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4347 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4349 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4350 i386_jmp_imm(offset);
4351 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4355 if (src->flags & INMEMORY) {
4356 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4359 i386_test_reg_reg(src->regoff, src->regoff);
4362 i386_jcc(I386_CC_LE, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4363 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4365 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4367 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4372 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
4373 /* val.i = constant */
4375 /* TWISTI: checked */
4376 d = reg_of_var(iptr->dst, REG_ITMP3);
4377 if (iptr->dst->flags & INMEMORY) {
4380 if (src->flags & INMEMORY) {
4381 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4384 i386_test_reg_reg(src->regoff, src->regoff);
4388 CALCREGOFFBYTES(iptr->dst->regoff);
4390 i386_jcc(I386_CC_G, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
4391 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4393 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4394 i386_jmp_imm(offset);
4395 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
4399 if (src->flags & INMEMORY) {
4400 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4403 i386_test_reg_reg(src->regoff, src->regoff);
4406 i386_jcc(I386_CC_G, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
4407 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
4409 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
4411 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
4417 case ICMD_IRETURN: /* ..., retvalue ==> ... */
4421 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4422 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4423 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4424 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4425 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4426 i386_call_reg(REG_ITMP1);
4427 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4430 var_to_reg_int(s1, src, REG_RESULT);
4431 M_INTMOVE(s1, REG_RESULT);
4432 goto nowperformreturn;
4434 case ICMD_LRETURN: /* ..., retvalue ==> ... */
4437 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4438 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4439 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4440 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4441 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4442 i386_call_reg(REG_ITMP1);
4443 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4446 if (src->flags & INMEMORY) {
4447 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
4448 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
4451 panic("LRETURN: longs have to be in memory");
4453 goto nowperformreturn;
4455 case ICMD_FRETURN: /* ..., retvalue ==> ... */
4458 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4459 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4460 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4461 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4462 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4463 i386_call_reg(REG_ITMP1);
4464 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4467 var_to_reg_flt(s1, src, REG_FRESULT);
4468 /* this may be an early return -- keep the offset correct for the remaining code */
4470 goto nowperformreturn;
4472 case ICMD_DRETURN: /* ..., retvalue ==> ... */
4475 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4476 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4477 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4478 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4479 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4480 i386_call_reg(REG_ITMP1);
4481 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4484 var_to_reg_flt(s1, src, REG_FRESULT);
4485 /* this may be an early return -- keep the offset correct for the remaining code */
4487 goto nowperformreturn;
4489 case ICMD_RETURN: /* ... ==> ... */
4492 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
4493 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
4494 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
4495 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
4496 i386_mov_imm_reg(builtin_monitorexit, REG_ITMP1);
4497 i386_call_reg(REG_ITMP1);
4498 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
4506 p = parentargs_base;
4508 /* restore return address */
4509 if (!isleafmethod) {
4510 /* p--; M_LLD (REG_RA, REG_SP, 8 * p); -- do we really need this on i386 */
4513 /* restore saved registers */
4514 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
4516 i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
4518 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
4520 i386_fldl_membase(REG_SP, p * 8);
4522 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
4523 i386_fstp_reg(savfltregs[r] + fpu_st_offset + 1);
4525 i386_fstp_reg(savfltregs[r] + fpu_st_offset);
4530 /* deallocate stack */
4531 if (parentargs_base) {
4532 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
4535 /* call trace function */
4537 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
4539 i386_mov_imm_membase(method, REG_SP, 0);
4541 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
4542 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
4544 i386_fstl_membase(REG_SP, 4 + 8);
4545 i386_fsts_membase(REG_SP, 4 + 8 + 8);
4547 i386_mov_imm_reg(builtin_displaymethodstop, REG_ITMP1);
4548 /* i386_mov_imm_reg(asm_builtin_exittrace, REG_ITMP1); */
4549 i386_call_reg(REG_ITMP1);
4551 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
4552 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
4554 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
4563 case ICMD_TABLESWITCH: /* ..., index ==> ... */
4568 tptr = (void **) iptr->target;
4570 s4ptr = iptr->val.a;
4571 l = s4ptr[1]; /* low */
4572 i = s4ptr[2]; /* high */
4574 var_to_reg_int(s1, src, REG_ITMP1);
4576 M_INTMOVE(s1, REG_ITMP1);
4578 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
4584 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
4585 i386_jcc(I386_CC_A, 0);
4587 /* mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
4588 mcode_addreference((basicblock *) tptr[0], mcodeptr);
4590 /* build jump table top down and use address of lowest entry */
4592 /* s4ptr += 3 + i; */
4596 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
4597 dseg_addtarget((basicblock *) tptr[0]);
4601 /* length of dataseg after last dseg_addtarget is used by load */
4603 i386_mov_imm_reg(0, REG_ITMP2);
4604 dseg_adddata(mcodeptr);
4605 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
4606 i386_jmp_reg(REG_ITMP1);
4612 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
4614 s4 i, l, val, *s4ptr;
4617 tptr = (void **) iptr->target;
4619 s4ptr = iptr->val.a;
4620 l = s4ptr[0]; /* default */
4621 i = s4ptr[1]; /* count */
4623 MCODECHECK((i<<2)+8);
4624 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
4630 i386_alu_imm_reg(I386_CMP, val, s1);
4631 i386_jcc(I386_CC_E, 0);
4632 /* mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
4633 mcode_addreference((basicblock *) tptr[0], mcodeptr);
4637 /* mcode_addreference(BlockPtrOfPC(l), mcodeptr); */
4639 tptr = (void **) iptr->target;
4640 mcode_addreference((basicblock *) tptr[0], mcodeptr);
4647 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
4648 /* op1 = return type, val.a = function pointer*/
4652 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
4653 /* op1 = return type, val.a = function pointer*/
4657 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
4658 /* op1 = return type, val.a = function pointer*/
4662 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
4663 /* op1 = arg count, val.a = method pointer */
4665 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
4666 /* op1 = arg count, val.a = method pointer */
4668 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
4669 /* op1 = arg count, val.a = method pointer */
4671 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
4672 /* op1 = arg count, val.a = method pointer */
4680 MCODECHECK((s3 << 1) + 64);
4682 /* copy arguments to registers or stack location */
4684 for (; --s3 >= 0; src = src->prev) {
4685 if (src->varkind == ARGVAR) {
4689 if (IS_INT_LNG_TYPE(src->type)) {
4690 if (s3 < intreg_argnum) {
4691 panic("No integer argument registers available!");
4694 if (!IS_2_WORD_TYPE(src->type)) {
4695 if (src->flags & INMEMORY) {
4696 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4697 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
4700 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 8);
4704 if (src->flags & INMEMORY) {
4705 M_LNGMEMMOVE(src->regoff, s3);
4708 panic("copy arguments: longs have to be in memory");
4714 if (s3 < fltreg_argnum) {
4715 panic("No float argument registers available!");
4718 var_to_reg_flt(d, src, REG_FTMP1);
4719 if (src->type == TYPE_FLT) {
4720 i386_fstps_membase(REG_SP, s3 * 8);
4723 i386_fstpl_membase(REG_SP, s3 * 8);
4730 switch (iptr->opc) {
4738 i386_mov_imm_reg(0, REG_ITMP3); /* we need the data segment address in asmpart */
4739 dseg_adddata(mcodeptr);
4741 i386_mov_imm_reg(a, REG_ITMP1);
4742 i386_call_reg(REG_ITMP1);
4745 case ICMD_INVOKESTATIC:
4746 case ICMD_INVOKESPECIAL:
4748 a = (s4) m->stubroutine;
4750 i386_mov_imm_reg(a, REG_ITMP2);
4751 i386_call_reg(REG_ITMP2);
4754 case ICMD_INVOKEVIRTUAL:
4756 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2);
4757 gen_nullptr_check(REG_ITMP2);
4758 i386_mov_membase_reg(REG_ITMP2, OFFSET(java_objectheader, vftbl), REG_ITMP3);
4759 i386_mov_membase32_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
4762 i386_call_reg(REG_ITMP1);
4765 case ICMD_INVOKEINTERFACE:
4768 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2);
4769 gen_nullptr_check(REG_ITMP2);
4770 i386_mov_membase_reg(REG_ITMP2, OFFSET(java_objectheader, vftbl), REG_ITMP3);
4771 i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP3);
4772 i386_mov_membase32_reg(REG_ITMP3, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
4775 i386_call_reg(REG_ITMP1);
4780 sprintf (logtext, "Unkown ICMD-Command: %d", iptr->opc);
4784 /* d contains return type */
4786 if (d != TYPE_VOID) {
4787 d = reg_of_var(iptr->dst, REG_ITMP3);
4789 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4790 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4791 if (iptr->dst->flags & INMEMORY) {
4792 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4793 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4796 panic("RETURN: longs have to be in memory");
4800 if (iptr->dst->flags & INMEMORY) {
4801 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4804 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4809 /* fld from called function -- has other fpu_st_offset counter */
4811 store_reg_to_var_flt(iptr->dst, d);
4818 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4820 /* op1: 0 == array, 1 == class */
4821 /* val.a: (classinfo*) superclass */
4823 /* superclass is an interface:
4825 * return (sub != NULL) &&
4826 * (sub->vftbl->interfacetablelength > super->index) &&
4827 * (sub->vftbl->interfacetable[-super->index] != NULL);
4829 * superclass is a class:
4831 * return ((sub != NULL) && (0
4832 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4833 * super->vftbl->diffvall));
4837 classinfo *super = (classinfo*) iptr->val.a;
4839 var_to_reg_int(s1, src, REG_ITMP1);
4840 d = reg_of_var(iptr->dst, REG_ITMP3);
4842 M_INTMOVE(s1, REG_ITMP1);
4845 i386_alu_reg_reg(I386_XOR, d, d);
4846 if (iptr->op1) { /* class/interface */
4847 if (super->flags & ACC_INTERFACE) { /* interface */
4849 i386_test_reg_reg(s1, s1);
4851 /* TODO: clean up this calculation */
4853 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
4856 CALCOFFSETBYTES(OFFSET(vftbl, interfacetablelength));
4859 CALCOFFSETBYTES(-super->index);
4865 CALCOFFSETBYTES(OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4869 offset += 6; /* jcc */
4872 i386_jcc(I386_CC_E, offset);
4874 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4875 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4876 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4878 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4880 /* TODO: clean up this calculation */
4883 CALCOFFSETBYTES(OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4887 offset += 6; /* jcc */
4890 i386_jcc(I386_CC_LE, offset);
4891 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4893 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4894 /* i386_setcc_reg(I386_CC_A, d); */
4895 /* i386_jcc(I386_CC_BE, 5); */
4896 i386_jcc(I386_CC_E, 5);
4897 i386_mov_imm_reg(1, d);
4900 } else { /* class */
4902 i386_test_reg_reg(s1, s1);
4904 /* TODO: clean up this calculation */
4906 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
4911 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
4914 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
4917 CALCOFFSETBYTES(OFFSET(vftbl, diffval));
4922 offset += 2; /* xor */
4924 offset += 6; /* jcc */
4927 i386_jcc(I386_CC_E, offset);
4929 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4930 i386_mov_imm_reg((void *) super->vftbl, REG_ITMP2);
4931 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4932 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4933 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4934 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4935 i386_alu_reg_reg(I386_XOR, d, d);
4936 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4937 /* i386_setcc_reg(I386_CC_BE, d); */
4938 i386_jcc(I386_CC_A, 5);
4939 i386_mov_imm_reg(1, d);
4944 panic ("internal error: no inlined array instanceof");
4946 store_reg_to_var_int(iptr->dst, d);
4949 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4951 /* op1: 0 == array, 1 == class */
4952 /* val.a: (classinfo*) superclass */
4954 /* superclass is an interface:
4956 * OK if ((sub == NULL) ||
4957 * (sub->vftbl->interfacetablelength > super->index) &&
4958 * (sub->vftbl->interfacetable[-super->index] != NULL));
4960 * superclass is a class:
4962 * OK if ((sub == NULL) || (0
4963 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4964 * super->vftbl->diffvall));
4968 classinfo *super = (classinfo*) iptr->val.a;
4970 d = reg_of_var(iptr->dst, REG_ITMP3);
4971 var_to_reg_int(s1, src, d);
4972 if (iptr->op1) { /* class/interface */
4973 if (super->flags & ACC_INTERFACE) { /* interface */
4975 i386_test_reg_reg(s1, s1);
4977 /* TODO: clean up this calculation */
4979 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
4982 CALCOFFSETBYTES(OFFSET(vftbl, interfacetablelength));
4985 CALCOFFSETBYTES(-super->index);
4991 CALCOFFSETBYTES(OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4996 i386_jcc(I386_CC_E, offset);
4998 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4999 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
5000 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
5002 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
5003 i386_jcc(I386_CC_LE, 0);
5004 mcode_addxcastrefs(mcodeptr);
5005 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
5007 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
5008 i386_jcc(I386_CC_E, 0);
5009 mcode_addxcastrefs(mcodeptr);
5011 } else { /* class */
5013 i386_test_reg_reg(s1, s1);
5015 /* TODO: clean up this calculation */
5017 CALCOFFSETBYTES(OFFSET(java_objectheader, vftbl));
5022 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
5024 if (d != REG_ITMP3) {
5026 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
5029 CALCOFFSETBYTES(OFFSET(vftbl, diffval));
5035 CALCOFFSETBYTES(OFFSET(vftbl, baseval));
5042 CALCOFFSETBYTES(OFFSET(vftbl, diffval));
5049 i386_jcc(I386_CC_E, offset);
5051 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
5052 i386_mov_imm_reg((void *) super->vftbl, REG_ITMP2);
5053 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
5054 if (d != REG_ITMP3) {
5055 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
5056 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
5057 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
5060 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
5061 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
5062 i386_mov_imm_reg((void *) super->vftbl, REG_ITMP2);
5063 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
5065 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
5066 i386_jcc(I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
5067 mcode_addxcastrefs(mcodeptr);
5071 panic ("internal error: no inlined array checkcast");
5074 store_reg_to_var_int(iptr->dst, d);
5077 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
5079 if (src->flags & INMEMORY) {
5080 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5083 i386_test_reg_reg(src->regoff, src->regoff);
5085 i386_jcc(I386_CC_L, 0);
5086 mcode_addxcheckarefs(mcodeptr);
5089 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
5090 /* op1 = dimension, val.a = array descriptor */
5092 /* check for negative sizes and copy sizes to stack if necessary */
5094 MCODECHECK((iptr->op1 << 1) + 64);
5096 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
5097 if (src->flags & INMEMORY) {
5098 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5101 i386_test_reg_reg(src->regoff, src->regoff);
5103 i386_jcc(I386_CC_L, 0);
5104 mcode_addxcheckarefs(mcodeptr);
5107 * copy sizes to new stack location, be cause native function
5108 * builtin_nmultianewarray access them as (int *)
5110 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5111 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
5113 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
5115 if (src->varkind != ARGVAR) {
5116 if (src->flags & INMEMORY) {
5117 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
5118 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
5121 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
5125 i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
5127 /* a0 = dimension count */
5129 /* save stack pointer */
5130 M_INTMOVE(REG_SP, REG_ITMP1);
5132 i386_alu_imm_reg(I386_SUB, 12, REG_SP);
5133 i386_mov_imm_membase(iptr->op1, REG_SP, 0);
5135 /* a1 = arraydescriptor */
5137 i386_mov_imm_membase(iptr->val.a, REG_SP, 4);
5139 /* a2 = pointer to dimensions = stack pointer */
5141 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
5143 i386_mov_imm_reg((void*) (builtin_nmultianewarray), REG_ITMP1);
5144 i386_call_reg(REG_ITMP1);
5145 i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
5147 s1 = reg_of_var(iptr->dst, REG_RESULT);
5148 M_INTMOVE(REG_RESULT, s1);
5149 store_reg_to_var_int(iptr->dst, s1);
5153 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
5160 } /* for instruction */
5162 /* copy values to interface registers */
5164 src = bptr->outstack;
5165 len = bptr->outdepth;
5169 if ((src->varkind != STACKVAR)) {
5171 if (IS_FLT_DBL_TYPE(s2)) {
5172 var_to_reg_flt(s1, src, REG_FTMP1);
5173 if (!(interfaces[len][s2].flags & INMEMORY)) {
5174 M_FLTMOVE(s1,interfaces[len][s2].regoff);
5177 panic("double store");
5178 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
5182 var_to_reg_int(s1, src, REG_ITMP1);
5183 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
5184 if (!(interfaces[len][s2].flags & INMEMORY)) {
5185 M_INTMOVE(s1, interfaces[len][s2].regoff);
5188 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
5192 if (interfaces[len][s2].flags & INMEMORY) {
5193 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
5196 panic("copy interface registers: longs have to be in memory (end)");
5203 } /* if (bptr -> flags >= BBREACHED) */
5204 } /* for basic block */
5206 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
5210 /* generate bound check stubs */
5211 s4 *xcodeptr = NULL;
5213 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
5214 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5215 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
5216 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5221 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
5222 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
5226 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5227 dseg_adddata(mcodeptr);
5228 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5229 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5231 if (xcodeptr != NULL) {
5232 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5235 xcodeptr = mcodeptr;
5237 i386_mov_imm_reg(0, REG_ITMP3); /* mov data segment pointer into reg */
5238 dseg_adddata(mcodeptr);
5240 i386_mov_imm_reg(proto_java_lang_ArrayIndexOutOfBoundsException, REG_ITMP1_XPTR);
5241 i386_push_imm(asm_handle_exception);
5246 /* generate negative array size check stubs */
5249 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
5250 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5251 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
5252 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5256 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
5257 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
5261 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5262 dseg_adddata(mcodeptr);
5263 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5264 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5266 if (xcodeptr != NULL) {
5267 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5270 xcodeptr = mcodeptr;
5272 i386_mov_imm_reg(0, REG_ITMP3); /* mov data segment pointer into reg */
5273 dseg_adddata(mcodeptr);
5275 i386_mov_imm_reg(proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR);
5276 i386_push_imm(asm_handle_exception);
5281 /* generate cast check stubs */
5284 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
5285 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5286 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
5287 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5291 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
5292 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
5296 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5297 dseg_adddata(mcodeptr);
5298 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5299 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5301 if (xcodeptr != NULL) {
5302 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5305 xcodeptr = mcodeptr;
5307 i386_mov_imm_reg(0, REG_ITMP3); /* mov data segment pointer into reg */
5308 dseg_adddata(mcodeptr);
5310 i386_mov_imm_reg(proto_java_lang_ClassCastException, REG_ITMP1_XPTR);
5311 i386_push_imm(asm_handle_exception);
5316 /* generate divide by zero check stubs */
5319 for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
5320 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5321 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
5322 xdivrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5326 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
5327 xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
5331 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5332 dseg_adddata(mcodeptr);
5333 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5334 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5336 if (xcodeptr != NULL) {
5337 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5340 xcodeptr = mcodeptr;
5342 i386_mov_imm_reg(0, REG_ITMP3); /* mov data segment pointer into reg */
5343 dseg_adddata(mcodeptr);
5345 i386_mov_imm_reg(proto_java_lang_ArithmeticException, REG_ITMP1_XPTR);
5346 i386_push_imm(asm_handle_exception);
5351 #ifdef SOFTNULLPTRCHECK
5352 /* generate null pointer check stubs */
5355 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
5356 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
5357 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
5358 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
5362 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
5363 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
5367 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
5368 dseg_adddata(mcodeptr);
5369 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
5370 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
5372 if (xcodeptr != NULL) {
5373 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 4);
5376 xcodeptr = mcodeptr;
5378 i386_mov_imm_reg(0, REG_ITMP3); /* move data segment pointer into reg */
5379 dseg_adddata(mcodeptr);
5381 i386_mov_imm_reg(proto_java_lang_NullPointerException, REG_ITMP1_XPTR);
5382 i386_push_imm(asm_handle_exception);
5390 mcode_finish((int)((u1*) mcodeptr - mcodebase));
5394 /* function createcompilerstub *************************************************
5396 creates a stub routine which calls the compiler
5398 *******************************************************************************/
5400 #define COMPSTUBSIZE 3
5402 u1 *createcompilerstub (methodinfo *m)
5404 u8 *s = CNEW (u8, COMPSTUBSIZE); /* memory to hold the stub */
5405 s4 *p = (s4*) s; /* code generation pointer */
5407 s4 *mcodeptr = p; /* make macros work */
5409 /* code for the stub */
5410 i386_mov_imm_reg(m, REG_ITMP1); /* pass method pointer to compiler */
5411 i386_mov_imm_reg(asm_call_jit_compiler, REG_ITMP2); /* load address */
5412 i386_jmp_reg(REG_ITMP2); /* jump to compiler */
5415 count_cstub_len += COMPSTUBSIZE * 8;
5422 /* function removecompilerstub *************************************************
5424 deletes a compilerstub from memory (simply by freeing it)
5426 *******************************************************************************/
5428 void removecompilerstub (u1 *stub)
5430 CFREE (stub, COMPSTUBSIZE * 8);
5433 /* function: createnativestub **************************************************
5435 creates a stub routine which calls a native method
5437 *******************************************************************************/
5439 #define NATIVESTUBSIZE 40
5441 u1 *createnativestub(functionptr f, methodinfo *m)
5443 u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */
5444 s4 *mcodeptr = (s4*) s; /* make macros work */
5448 int stackframesize = 4; /* initial 4 bytes is space for jni env */
5449 int stackframeoffset = 4;
5455 descriptor2types(m); /* set paramcount and paramtypes */
5458 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
5460 for (p = 0; p < m->paramcount; p++) {
5461 t = m->paramtypes[p];
5462 if (IS_INT_LNG_TYPE(t)) {
5463 if (IS_2_WORD_TYPE(t)) {
5464 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
5465 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
5467 } else if (t == TYPE_ADR) {
5468 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
5469 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
5472 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
5475 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
5476 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
5479 if (t == TYPE_FLT) {
5480 i386_flds_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
5481 i386_fstps_membase(REG_SP, p * 8);
5482 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
5483 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
5486 i386_fldl_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
5487 i386_fstpl_membase(REG_SP, p * 8);
5493 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
5494 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
5495 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
5496 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
5499 i386_mov_imm_membase(m, REG_SP, TRACE_ARGS_NUM * 8);
5501 i386_mov_imm_reg(asm_builtin_trace, REG_ITMP1);
5502 i386_call_reg(REG_ITMP1);
5504 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
5508 * mark the whole fpu stack as free for native functions
5509 * (only for zero saved registers)
5521 * calculate stackframe size for native function
5523 tptr = m->paramtypes;
5524 for (i = 0; i < m->paramcount; i++) {
5529 stackframesize += 4;
5534 stackframesize += 8;
5538 panic("unknown parameter type in native function");
5542 i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
5544 tptr = m->paramtypes;
5545 for (i = 0; i < m->paramcount; i++) {
5550 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5551 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
5552 stackframeoffset += 4;
5557 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5558 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
5559 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
5560 i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
5561 stackframeoffset += 8;
5565 panic("unknown parameter type in native function");
5569 i386_mov_imm_membase(&env, REG_SP, 0);
5570 i386_mov_imm_reg(f, REG_ITMP1);
5571 i386_call_reg(REG_ITMP1);
5572 i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
5575 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
5577 i386_mov_imm_membase(m, REG_SP, 0);
5579 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
5580 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
5582 i386_fstl_membase(REG_SP, 4 + 8);
5583 i386_fsts_membase(REG_SP, 4 + 8 + 8);
5585 i386_mov_imm_reg(asm_builtin_exittrace, REG_ITMP1);
5586 i386_call_reg(REG_ITMP1);
5588 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
5589 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
5591 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
5594 i386_mov_imm_reg(&exceptionptr, REG_ITMP3);
5595 i386_mov_membase_reg(REG_ITMP3, 0, REG_ITMP3);
5596 i386_test_reg_reg(REG_ITMP3, REG_ITMP3);
5597 i386_jcc(I386_CC_NE, 1);
5601 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1_XPTR);
5602 i386_mov_imm_reg(&exceptionptr, REG_ITMP3);
5603 i386_mov_imm_membase(0, REG_ITMP3, 0);
5604 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2_XPC);
5605 i386_alu_imm_reg(I386_SUB, REG_ITMP2_XPC, 2);
5607 i386_mov_imm_reg(asm_handle_nat_exception, REG_ITMP3);
5608 i386_jmp_reg(REG_ITMP3);
5611 count_nstub_len += NATIVESTUBSIZE * 8;
5617 /* function: removenativestub **************************************************
5619 removes a previously created native-stub from memory
5621 *******************************************************************************/
5623 void removenativestub (u1 *stub)
5625 CFREE (stub, NATIVESTUBSIZE * 8);
5630 * These are local overrides for various environment variables in Emacs.
5631 * Please do not remove this and leave it at the end of the file, where
5632 * Emacs will automagically detect them.
5633 * ---------------------------------------------------------------------
5636 * indent-tabs-mode: t